mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(ble/bluedroid): fix BLE bonding key storage validation
(cherry picked from commit 62cdd4ac38)
Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -90,6 +90,17 @@ void btc_storage_save(void)
|
||||
}
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
static bool btc_storage_is_all_zeros(const void *buf, size_t len)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)buf;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (p[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bt_status_t _btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
|
||||
char *key,
|
||||
uint8_t key_type,
|
||||
@@ -158,33 +169,48 @@ static bt_status_t _btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
const char* name;
|
||||
const char *name;
|
||||
size_t expected_len;
|
||||
switch (key_type) {
|
||||
case BTM_LE_KEY_PENC:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_PENC_STR;
|
||||
expected_len = sizeof(tBTM_LE_PENC_KEYS);
|
||||
break;
|
||||
case BTM_LE_KEY_PID:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_PID_STR;
|
||||
expected_len = sizeof(tBTM_LE_PID_KEYS);
|
||||
break;
|
||||
case BTM_LE_KEY_PCSRK:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR;
|
||||
expected_len = sizeof(tBTM_LE_PCSRK_KEYS);
|
||||
break;
|
||||
case BTM_LE_KEY_LENC:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_LENC_STR;
|
||||
expected_len = sizeof(tBTM_LE_LENC_KEYS);
|
||||
break;
|
||||
case BTM_LE_KEY_LCSRK:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR;
|
||||
expected_len = sizeof(tBTM_LE_LCSRK_KEYS);
|
||||
break;
|
||||
case BTM_LE_KEY_LID:
|
||||
name = BTC_BLE_STORAGE_LE_KEY_LID_STR;
|
||||
/* LID is a flag-only key; no payload is persisted. */
|
||||
name = BTC_BLE_STORAGE_LE_KEY_LID_STR;
|
||||
expected_len = 0;
|
||||
break;
|
||||
default:
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
size_t length = key_length;
|
||||
int ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
|
||||
if (key_length < 0 || (size_t)key_length < expected_len) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
size_t length = (size_t)key_length;
|
||||
bool ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length);
|
||||
if (!ret || length != expected_len) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
|
||||
@@ -237,17 +263,22 @@ static bt_status_t _btc_storage_remove_all_ble_keys(const char *name)
|
||||
void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del_pid_key)
|
||||
{
|
||||
bt_bdaddr_t bd_addr;
|
||||
uint32_t device_type = 0;
|
||||
|
||||
if (del_pid_key == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only use valid static address for de-duplication.
|
||||
if (btc_storage_is_all_zeros(del_pid_key->static_addr, sizeof(del_pid_key->static_addr))) {
|
||||
return;
|
||||
}
|
||||
|
||||
btc_config_lock();
|
||||
|
||||
const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
|
||||
while (iter != btc_config_section_end()) {
|
||||
uint32_t device_type = 0;
|
||||
//store the next iter, if remove section, then will not loss the point
|
||||
|
||||
const char *section = btc_config_section_name(iter);
|
||||
@@ -276,13 +307,19 @@ void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del
|
||||
|
||||
char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
|
||||
|
||||
if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) {
|
||||
size_t pid_len = sizeof(tBTM_LE_PID_KEYS);
|
||||
bool pid_ok = btc_config_get_bin(section, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)buffer, &pid_len);
|
||||
|
||||
if (pid_ok && pid_len >= sizeof(tBTM_LE_PID_KEYS)) {
|
||||
|
||||
tBTM_LE_PID_KEYS *pid_key = (tBTM_LE_PID_KEYS *) buffer;
|
||||
|
||||
iter = btc_config_section_next(iter);
|
||||
|
||||
if (memcmp(del_pid_key->static_addr, pid_key->static_addr, 6) == 0 && memcmp(cur_addr, bd_addr.address, 6) != 0 && del_pid_key->addr_type == pid_key->addr_type) {
|
||||
if (del_pid_key->addr_type == pid_key->addr_type &&
|
||||
!btc_storage_is_all_zeros(pid_key->static_addr, sizeof(pid_key->static_addr)) &&
|
||||
memcmp(del_pid_key->static_addr, pid_key->static_addr, sizeof(pid_key->static_addr)) == 0 &&
|
||||
memcmp(cur_addr, bd_addr.address, sizeof(bd_addr.address)) != 0) {
|
||||
if (device_type == BT_DEVICE_TYPE_DUMO) {
|
||||
btc_config_set_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR);
|
||||
_btc_storage_remove_all_ble_keys(section);
|
||||
@@ -308,13 +345,13 @@ void btc_storage_delete_duplicate_ble_devices(void)
|
||||
char temp_buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
|
||||
tBTM_LE_PID_KEYS *pid_key;
|
||||
tBTM_LE_PID_KEYS *temp_pid_key;
|
||||
uint32_t device_type = 0;
|
||||
|
||||
bt_bdaddr_t temp_bd_addr;
|
||||
|
||||
btc_config_lock();
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
uint32_t device_type = 0;
|
||||
const char *name = btc_config_section_name(iter);
|
||||
|
||||
if (!string_is_bdaddr(name) ||
|
||||
@@ -324,27 +361,36 @@ void btc_storage_delete_duplicate_ble_devices(void)
|
||||
}
|
||||
|
||||
string_to_bdaddr(name, &bd_addr);
|
||||
if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS)
|
||||
size_t pid_len = sizeof(tBTM_LE_PID_KEYS);
|
||||
bool pid_ok = btc_config_get_bin(name, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)buffer, &pid_len);
|
||||
if (pid_ok && pid_len >= sizeof(tBTM_LE_PID_KEYS))
|
||||
{
|
||||
pid_key = (tBTM_LE_PID_KEYS *) buffer;
|
||||
if (btc_storage_is_all_zeros(pid_key->static_addr, sizeof(pid_key->static_addr))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const btc_config_section_iter_t *temp_iter = btc_config_section_next(iter);
|
||||
while (temp_iter != NULL)
|
||||
{
|
||||
uint32_t temp_device_type = 0;
|
||||
const char *temp_name = btc_config_section_name(temp_iter);
|
||||
if (!string_is_bdaddr(temp_name) || !btc_config_get_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
|
||||
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
|
||||
if (!string_is_bdaddr(temp_name) || !btc_config_get_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&temp_device_type) ||
|
||||
((temp_device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
|
||||
temp_iter = btc_config_section_next(temp_iter);
|
||||
continue;
|
||||
}
|
||||
string_to_bdaddr(temp_name, &temp_bd_addr);
|
||||
if (_btc_storage_get_ble_bonding_key(&temp_bd_addr, BTM_LE_KEY_PID, temp_buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS)
|
||||
size_t temp_pid_len = sizeof(tBTM_LE_PID_KEYS);
|
||||
bool temp_pid_ok = btc_config_get_bin(temp_name, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)temp_buffer, &temp_pid_len);
|
||||
if (temp_pid_ok && temp_pid_len >= sizeof(tBTM_LE_PID_KEYS))
|
||||
{
|
||||
temp_pid_key = (tBTM_LE_PID_KEYS *) temp_buffer;
|
||||
if (memcmp(pid_key->static_addr, temp_pid_key->static_addr, 6) == 0 && pid_key->addr_type == temp_pid_key->addr_type) {
|
||||
const char *temp_name = btc_config_section_name(temp_iter);
|
||||
if (pid_key->addr_type == temp_pid_key->addr_type &&
|
||||
!btc_storage_is_all_zeros(temp_pid_key->static_addr, sizeof(temp_pid_key->static_addr)) &&
|
||||
memcmp(pid_key->static_addr, temp_pid_key->static_addr, sizeof(pid_key->static_addr)) == 0) {
|
||||
temp_iter = btc_config_section_next(temp_iter);
|
||||
if (device_type == BT_DEVICE_TYPE_DUMO) {
|
||||
if (temp_device_type == BT_DEVICE_TYPE_DUMO) {
|
||||
btc_config_set_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR);
|
||||
_btc_storage_remove_all_ble_keys(temp_name);
|
||||
} else {
|
||||
@@ -484,9 +530,11 @@ static bt_status_t _btc_storage_get_ble_local_key(uint8_t key_type,
|
||||
}
|
||||
size_t length = key_length;
|
||||
|
||||
int ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length);
|
||||
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
bool ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length);
|
||||
if (!ret || length != (size_t)key_length) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
|
||||
@@ -905,8 +953,8 @@ static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bd
|
||||
}
|
||||
bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add)
|
||||
{
|
||||
uint32_t device_type;
|
||||
int addr_type;
|
||||
uint32_t device_type = 0;
|
||||
int addr_type = BLE_ADDR_PUBLIC;
|
||||
bt_bdaddr_t bd_addr;
|
||||
BD_ADDR bta_bd_addr;
|
||||
bool device_added = false;
|
||||
@@ -1015,11 +1063,11 @@ bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev
|
||||
int btc_storage_get_num_ble_bond_devices(void)
|
||||
{
|
||||
int num_dev = 0;
|
||||
uint32_t device_type = 0;
|
||||
|
||||
btc_config_lock();
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
uint32_t device_type = 0;
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (!string_is_bdaddr(name) ||
|
||||
!btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
|
||||
@@ -1037,18 +1085,30 @@ int btc_storage_get_num_ble_bond_devices(void)
|
||||
bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t *)&len);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
bool ret;
|
||||
size_t length = len;
|
||||
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
|
||||
ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, &length);
|
||||
btc_config_unlock();
|
||||
|
||||
if (!ret || length != (size_t)len) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len)
|
||||
{
|
||||
int ret;
|
||||
bool ret;
|
||||
bdstr_t bdstr;
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
|
||||
ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t)len);
|
||||
if (ret) {
|
||||
_btc_storage_save();
|
||||
}
|
||||
btc_config_unlock();
|
||||
if (ret == false) {
|
||||
return BT_STATUS_FAIL;
|
||||
@@ -1060,18 +1120,33 @@ bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8
|
||||
bt_status_t btc_storage_get_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t *)&len);
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
bool ret;
|
||||
size_t length = len;
|
||||
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
|
||||
ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, &length);
|
||||
btc_config_unlock();
|
||||
|
||||
if (!ret || length != (size_t)len) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_set_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len)
|
||||
{
|
||||
int ret;
|
||||
bool ret;
|
||||
bdstr_t bdstr;
|
||||
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
|
||||
ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t)len);
|
||||
if (ret) {
|
||||
_btc_storage_save();
|
||||
}
|
||||
btc_config_unlock();
|
||||
|
||||
if (ret == false) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
@@ -1084,9 +1159,11 @@ bt_status_t btc_storage_remove_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr)
|
||||
bool ret = true;
|
||||
bdstr_t bdstr;
|
||||
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
|
||||
ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR);
|
||||
btc_config_unlock();
|
||||
|
||||
if (ret == false) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
@@ -1099,9 +1176,11 @@ bt_status_t btc_storage_remove_gatt_db_hash(bt_bdaddr_t *remote_bd_addr)
|
||||
bool ret = true;
|
||||
bdstr_t bdstr;
|
||||
|
||||
btc_config_lock();
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
|
||||
ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR);
|
||||
btc_config_unlock();
|
||||
|
||||
if (ret == false) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
@@ -277,6 +277,7 @@ bool btc_config_set_bin(const char *section, const char *key, const uint8_t *val
|
||||
|
||||
config_set_string(config, section, key, str, false);
|
||||
|
||||
memset(str, 0, length * 2 + 1);
|
||||
osi_free(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
|
||||
}
|
||||
|
||||
#if BLE_SMP_BOND_NVS_FLASH
|
||||
int addr_type;
|
||||
int addr_type = BLE_ADDR_PUBLIC;
|
||||
|
||||
if (btc_dm_cb.pairing_cb.ble.is_pid_key_rcvd) {
|
||||
// delete unused section in NVS
|
||||
|
||||
Reference in New Issue
Block a user