]> granicus.if.org Git - esp-idf/commitdiff
component/bt: Fixed a very important bug of the SMP security module when use SMP...
authorYulong <huangyulong@espressif.com>
Mon, 26 Jun 2017 09:02:57 +0000 (05:02 -0400)
committerYulong <huangyulong@espressif.com>
Mon, 26 Jun 2017 09:02:57 +0000 (05:02 -0400)
components/bt/bluedroid/btc/core/btc_ble_storage.c
components/bt/bluedroid/btc/core/btc_config.c
components/bt/bluedroid/btc/core/btc_dm.c
components/bt/bluedroid/btc/core/btc_main.c
components/bt/bluedroid/btc/include/btc_ble_storage.h
components/bt/bluedroid/btc/include/btc_config.h
components/bt/bluedroid/include/bt_target.h
components/bt/bluedroid/osi/config.c
components/bt/bluedroid/osi/include/config.h

index 1c885f4b5c6a9763eda9ac19af89b8f2f23a975f..5e588012ea4522cbec8e16030077c423bdf4dea2 100644 (file)
@@ -19,6 +19,7 @@
 #include "bdaddr.h"
 #include "btc_ble_storage.h"
 #include "bta_gatts_co.h"
+#include "btc_util.h"
 
 #if (SMP_INCLUDED == TRUE)
 
@@ -55,9 +56,8 @@ bt_status_t btc_in_fetch_bonded_ble_devices(int add)
             continue;
         }
 
-        if (!(btc_in_fetch_bonded_ble_device(name, add, &bonded_devices)) ) {
+        if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) {
             LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
-            return BT_STATUS_FAIL;
         }
     }
 
@@ -78,6 +78,9 @@ void btc_save_ble_bonding_keys(void)
     bt_bdaddr_t bd_addr;
 
     bdcpy(bd_addr.address, pairing_cb.bd_addr);
+    bdstr_t bdstr;
+    bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr));
+    btc_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE);
     if (pairing_cb.ble.is_penc_key_rcvd) {
         btc_storage_add_ble_bonding_key(&bd_addr,
                                         (char *) &pairing_cb.ble.penc_key,
@@ -131,7 +134,6 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda
 
     char buffer[100];
     memset(buffer, 0, sizeof(buffer));
-
     if (btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) == BT_STATUS_SUCCESS) {
         if (add_key) {
             BD_ADDR bta_bd_addr;
@@ -152,13 +154,12 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda
     }
 }
 
-
 bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
                                             char *key,
                                             uint8_t key_type,
                                             uint8_t key_length)
 {
-    char bdstr[6] = {0};
+    bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     const char* name;
     switch (key_type) {
@@ -205,7 +206,7 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
                                             char *key_value,
                                             int key_length)
 {
-    char bdstr[6] = {0};
+    bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     const char* name;
     switch (key_type) {
@@ -235,6 +236,35 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
 
 }
 
+bool btc_storage_compare_address_key_value(uint8_t key_type, void *key_value, int key_length)
+{
+    const char *key_type_str;
+    switch (key_type) {
+    case BTM_LE_KEY_PENC:
+        key_type_str = "LE_KEY_PENC";
+        break;
+    case BTM_LE_KEY_PID:
+        key_type_str = "LE_KEY_PID";
+        break;
+    case BTM_LE_KEY_PCSRK:
+        key_type_str = "LE_KEY_PCSRK";
+        break;
+    case BTM_LE_KEY_LENC:
+        key_type_str = "LE_KEY_LENC";
+        break;
+    case BTM_LE_KEY_LCSRK:
+        key_type_str = "LE_KEY_LCSRK";
+        break;
+    case BTM_LE_KEY_LID:
+        key_type_str =  "LE_KEY_LID";
+    default:
+        return false;
+    }
+
+    return btc_compare_address_key_value(key_type_str, key_value, key_length);
+}
+
+
 /*******************************************************************************
 **
 ** Function         btc_storage_remove_ble_bonding_keys
@@ -247,7 +277,7 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
 *******************************************************************************/
 bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
 {
-    char bdstr[6] = {0};
+    bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
     int ret = 1;
@@ -382,7 +412,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
     bool device_added = false;
     bool key_found = false;
 
-    if (!btc_config_get_int(remote_bd_addr, "AddrType", &device_type)) {
+    if (!btc_config_get_int(remote_bd_addr, "DevType", &device_type)) {
         LOG_ERROR("%s, device_type = %x", __func__, device_type);
         return BT_STATUS_FAIL;
     }
@@ -423,7 +453,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
 bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
         uint8_t addr_type)
 {
-    char bdstr[6] = {0};
+    bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bt_bdaddr_t));
     int ret = btc_config_set_int(bdstr, "AddrType", (int)addr_type);
     btc_config_save();
@@ -443,7 +473,7 @@ bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
 bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
                                              int*addr_type)
 {
-    char bdstr[6] = {0};
+    bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     int ret = btc_config_get_int(bdstr, "AddrType", addr_type);
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
index bd0bd031878278c07465d825ba3c07efafda302d..e2c30291b5c1a77db6021b297d23a3dd7c26f193 100644 (file)
@@ -31,7 +31,7 @@
 static const char *CONFIG_FILE_PATH = "bt_config.conf";
 static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
 
-static void timer_config_save(void *data);
+static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length);
 
 // TODO(zachoverflow): Move these two functions out, because they are too specific for this file
 // {grumpy-cat/no, monty-python/you-make-me-sad}
@@ -77,7 +77,36 @@ bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
 
 static pthread_mutex_t lock;  // protects operations on |config|.
 static config_t *config;
-static osi_alarm_t *alarm_timer;
+
+bool btc_compare_address_key_value(char *key_type, void *key_value, int key_length)
+{
+    assert(key_value != NULL);
+    bool status = false;
+    char value_str[100] = {0};
+    if(key_length > sizeof(value_str)/2) {
+        return false;
+    }
+    btc_key_value_to_string((uint8_t *)key_value, value_str, key_length);
+    pthread_mutex_lock(&lock);
+    status = config_has_key_in_section(config, key_type, value_str);
+    pthread_mutex_unlock(&lock);
+    return status;
+}
+
+static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length)
+{
+    const char *lookup = "0123456789abcdef";
+
+    assert(key_vaule != NULL);
+    assert(value_str != NULL);
+
+    for (size_t i = 0; i < key_length; ++i) {
+        value_str[(i * 2) + 0] = lookup[(key_vaule[i] >> 4) & 0x0F];
+        value_str[(i * 2) + 1] = lookup[key_vaule[i] & 0x0F];
+    }
+
+    return;
+}
 
 // Module lifecycle functions
 
@@ -93,27 +122,15 @@ bool btc_config_init(void)
             goto error;
         }
     }
-
     if (config_save(config, CONFIG_FILE_PATH)) {
         // unlink(LEGACY_CONFIG_FILE_PATH);
     }
 
-    // TODO(sharvil): use a non-wake alarm for this once we have
-    // API support for it. There's no need to wake the system to
-    // write back to disk.
-    alarm_timer = osi_alarm_new("btc_config", timer_config_save, NULL, CONFIG_SETTLE_PERIOD_MS);
-    if (!alarm_timer) {
-        LOG_ERROR("%s unable to create alarm.\n", __func__);
-        goto error;
-    }
-
     return true;
 
 error:;
-    osi_alarm_free(alarm_timer);
     config_free(config);
     pthread_mutex_destroy(&lock);
-    alarm_timer = NULL;
     config = NULL;
     LOG_ERROR("%s failed\n", __func__);
     return false;
@@ -129,10 +146,8 @@ bool btc_config_clean_up(void)
 {
     btc_config_flush();
 
-    osi_alarm_free(alarm_timer);
     config_free(config);
     pthread_mutex_destroy(&lock);
-    alarm_timer = NULL;
     config = NULL;
     return true;
 }
@@ -352,49 +367,7 @@ bool btc_config_remove(const char *section, const char *key)
 
 void btc_config_save(void)
 {
-    assert(alarm_timer != NULL);
-    assert(config != NULL);
-
-    osi_alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS);
-}
-
-void btc_config_flush(void)
-{
-    assert(config != NULL);
-    assert(alarm_timer != NULL);
-    osi_alarm_cancel(alarm_timer);
-
-    pthread_mutex_lock(&lock);
-    config_save(config, CONFIG_FILE_PATH);
-    pthread_mutex_unlock(&lock);
-}
-
-int btc_config_clear(void)
-{
-    assert(config != NULL);
-    assert(alarm_timer != NULL);
-
-    osi_alarm_cancel(alarm_timer);
-
-    pthread_mutex_lock(&lock);
-    config_free(config);
-
-    config = config_new_empty();
-    if (config == NULL) {
-        pthread_mutex_unlock(&lock);
-        return false;
-    }
-
-    int ret = config_save(config, CONFIG_FILE_PATH);
-    pthread_mutex_unlock(&lock);
-    return ret;
-}
-
-static void timer_config_save(UNUSED_ATTR void *data)
-{
-    assert(config != NULL);
-    assert(alarm_timer != NULL);
-
+       assert(config != NULL);
     // Garbage collection process: the config file accumulates
     // cached information about remote devices during regular
     // inquiry scans. We remove some of these junk entries
@@ -433,7 +406,33 @@ static void timer_config_save(UNUSED_ATTR void *data)
         while (num_keys > 0) {
             config_remove_section(config, keys[--num_keys]);
         }
+    config_save(config, CONFIG_FILE_PATH);
+    pthread_mutex_unlock(&lock);
+}
 
+void btc_config_flush(void)
+{
+    assert(config != NULL);
+    pthread_mutex_lock(&lock);
     config_save(config, CONFIG_FILE_PATH);
     pthread_mutex_unlock(&lock);
 }
+
+int btc_config_clear(void)
+{
+    assert(config != NULL);
+
+
+    pthread_mutex_lock(&lock);
+    config_free(config);
+
+    config = config_new_empty();
+    if (config == NULL) {
+        pthread_mutex_unlock(&lock);
+        return false;
+    }
+    int ret = config_save(config, CONFIG_FILE_PATH);
+    pthread_mutex_unlock(&lock);
+    return ret;
+}
+
index 1f98d17da9350ac439f00661c4d04a774c7c1584..2e0d1675b38cd6a4617e406e64a298a24bc2a6ea 100644 (file)
@@ -125,10 +125,21 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
         bt_bdaddr_t bdaddr;
         bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
         bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
+        LOG_DEBUG ("%s, -  p_auth_cmpl->bd_addr: %08x%04x", __func__,
+                             (p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3],
+                             (p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]);
+        LOG_DEBUG ("%s, -  pairing_cb.bd_addr: %08x%04x", __func__,
+                             (pairing_cb.bd_addr[0] << 24) + (pairing_cb.bd_addr[1] << 16) + (pairing_cb.bd_addr[2] << 8) + pairing_cb.bd_addr[3],
+                             (pairing_cb.bd_addr[4] << 8) + pairing_cb.bd_addr[5]);
          if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) {
             btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type);
         }
-
+        /* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding
+           before. */
+        if(pairing_cb.ble.is_pid_key_rcvd) {
+            btc_storage_compare_address_key_value(BTM_LE_KEY_PID,
+                                                  (void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS));
+        }
         btc_save_ble_bonding_keys();
     } else {
         /*Map the HCI fail reason  to  bt status  */
@@ -312,6 +323,8 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
 #if (SMP_INCLUDED == TRUE)
         //load the ble local key whitch has been store in the flash
         btc_dm_load_ble_local_keys();
+        //load the bonding device to the btm layer
+        btc_storage_load_bonded_ble_devices();
 #endif  ///SMP_INCLUDED == TRUE
         btc_enable_bluetooth_evt(p_data->enable.status);
         break;
index d251782e4055c1aa87ed034f87dd10359629b06d..fc1f56829bcbba959a87a6d6b0787de1dc7ddacb 100644 (file)
@@ -54,8 +54,8 @@ static void btc_init_bluetooth(void)
 {
     osi_alarm_create_mux();
     osi_alarm_init();
-    btc_config_init();
     bte_main_boot_entry(btc_init_callback);
+    btc_config_init();
 }
 
 
index 2884d6acf3b02ba80a632dbc1be6d6f6b9f4d5e2..cbb6229ca1ee7787bfd7df799d1511c1429d7082 100644 (file)
@@ -89,6 +89,9 @@ bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
                                                                                       uint8_t key_type,
                                                                                       uint8_t key_length);
 
+bool btc_compare_le_key_value(const uint8_t key_type, const size_t key_len, const tBTA_LE_KEY_VALUE *key_vaule,
+                    bt_bdaddr_t bd_addr);
+
 void btc_save_ble_bonding_keys(void);
 
 bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, 
@@ -99,6 +102,8 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
                                                                 char *key_value,
                                                                 int key_length);
 
+bool btc_storage_compare_address_key_value(uint8_t key_type, void *key_value, int key_length);
+
 bt_status_t btc_storage_add_ble_local_key(char *key,
                                                                               uint8_t key_type,
                                                                               uint8_t key_length);
index 1472cc83c45ac2269ce8428989b97d46cf7c50f3..e0d6d6ec08ba8e067ea87d92ab3a89039a8b49ff 100644 (file)
@@ -49,6 +49,7 @@ int btc_config_clear(void);
 
 // TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general.
 bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
+bool btc_compare_address_key_value(char *key_type, void *key_value, int key_length);
 bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
 
 #endif
index a7ed5bd3b8c9b95c7b3f2fb2ebcb2f591d917c01..a426d69fe6e339fbebdd41328c29f3b54c3eb691 100644 (file)
 
 /* The number of security records for peer devices. 100 AS Default*/
 #ifndef BTM_SEC_MAX_DEVICE_RECORDS
-#define BTM_SEC_MAX_DEVICE_RECORDS  8 // 100
+#if SMP_INCLUDED == TRUE
+#define BTM_SEC_MAX_DEVICE_RECORDS  15 // 100
+#else
+#define BTM_SEC_MAX_DEVICE_RECORDS  8
+#endif /* SMP_INCLUDED == TRUE */
 #endif
 
 /* The number of security records for services. 32 AS Default*/
index 7c876b8430f4c4b74407eec93d0456bd0ff5c53e..38281ed9dab3d285a7c78f0c5250bf82295e74d6 100644 (file)
@@ -28,7 +28,7 @@
 #include "list.h"
 #include "bt_trace.h"
 
-#define CONFIG_FILE_MAX_SIZE      (1024)
+#define CONFIG_FILE_MAX_SIZE      (2048)
 #define CONFIG_KEY                "bt_cfg_key"
 typedef struct {
     char *key;
@@ -128,6 +128,26 @@ bool config_has_key(const config_t *config, const char *section, const char *key
     return (entry_find(config, section, key) != NULL);
 }
 
+bool config_has_key_in_section(config_t *config, char *key, char *key_value)
+{\r
+    LOG_DEBUG("key = %s, value = %s", key, key_value);
+    for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
+        const section_t *section = (const section_t *)list_node(node);
+
+        for (const list_node_t *node = list_begin(section->entries); node != list_end(section->entries); node = list_next(node)) {
+            entry_t *entry = list_node(node);
+            LOG_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value);
+            if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) {
+                LOG_DEBUG("%s, the irk aready in the flash.", __func__);
+                section_free((void *)section);
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
 int config_get_int(const config_t *config, const char *section, const char *key, int def_value)
 {
     assert(config != NULL);
@@ -303,8 +323,8 @@ bool config_save(const config_t *config, const char *filename)
     int w_cnt, w_cnt_total = 0;
     for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
         const section_t *section = (const section_t *)list_node(node);
-        LOG_DEBUG("section name: %s\n", section->name);
         w_cnt = snprintf(line, 1024, "[%s]\n", section->name);
+        LOG_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total);
         if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) {
             memcpy(buf + w_cnt_total, line, w_cnt);
             w_cnt_total += w_cnt;
@@ -316,6 +336,7 @@ bool config_save(const config_t *config, const char *filename)
             const entry_t *entry = (const entry_t *)list_node(enode);
             LOG_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value);
             w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value);
+            LOG_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total);
             if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) {
                 memcpy(buf + w_cnt_total, line, w_cnt);
                 w_cnt_total += w_cnt;
index 4f0e2cd8ae331f67967d1ad6e9eaa6e5d30e6d5c..41f5ddb18a01290a81c2e84ba38fbb2ca78b870b 100644 (file)
@@ -66,6 +66,10 @@ bool config_has_section(const config_t *config, const char *section);
 // Returns false otherwise. |config|, |section|, and |key| must not be NULL.
 bool config_has_key(const config_t *config, const char *section, const char *key);
 
+// Returns true if the config file has a key named |key| and the key_value.
+// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL.
+bool config_has_key_in_section(config_t *config, char *key, char *key_value);
+
 // Returns the integral value for a given |key| in |section|. If |section|
 // or |key| do not exist, or the value cannot be fully converted to an integer,
 // this function returns |def_value|. |config|, |section|, and |key| must not