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:
Zhi Wei Jian
2026-06-10 19:53:46 +08:00
parent ed8e4b6a37
commit 665b52b20f
3 changed files with 114 additions and 34 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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