Loading system/stack/btm/btm_ble.cc +23 −6 Original line number Diff line number Diff line Loading @@ -1518,13 +1518,30 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, BTM_TRACE_ERROR("key size = %d", p_rec->ble.keys.key_size); if (use_stk) { btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk); } else /* calculate LTK using peer device */ { if (p_rec->ble.key_type & BTM_LE_KEY_LENC) return; } /* calculate LTK using peer device */ if (p_rec->ble.key_type & BTM_LE_KEY_LENC) { btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk); else return; } p_rec = btm_find_dev_with_lenc(bda); if (!p_rec) { btsnd_hcic_ble_ltk_req_neg_reply(btm_cb.enc_handle); return; } LOG_INFO("Found second sec_dev_rec for device that have LTK"); /* This can happen when remote established LE connection using RPA to this * device, but then pair with us using Classing transport while still keeping * LE connection. If remote attempts to encrypt the LE connection, we might * end up here. We will eventually consolidate both entries, this is to avoid * race conditions. */ LOG_ASSERT(p_rec->ble.key_type & BTM_LE_KEY_LENC); p_cb->key_size = p_rec->ble.keys.key_size; btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk); } /******************************************************************************* Loading system/stack/btm/btm_dev.cc +84 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <string.h> #include "btm_api.h" #include "btm_ble_int.h" #include "device/include/controller.h" #include "l2c_api.h" #include "main/shim/btm_api.h" Loading Loading @@ -372,6 +373,32 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr) { return NULL; } static bool has_lenc_and_address_is_equal(void* data, void* context) { tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data); if (!(p_dev_rec->ble.key_type & BTM_LE_KEY_LENC)) return false; return is_address_equal(data, context); } /******************************************************************************* * * Function btm_find_dev_with_lenc * * Description Look for the record in the device database with LTK and * specified BD address * * Returns Pointer to the record or NULL * ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr) { if (btm_cb.sec_dev_rec == nullptr) return nullptr; list_node_t* n = list_foreach(btm_cb.sec_dev_rec, has_lenc_and_address_is_equal, (void*)&bd_addr); if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n)); return NULL; } /******************************************************************************* * * Function btm_consolidate_dev Loading Loading @@ -429,6 +456,63 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec) { } } /* combine security records of established LE connections after Classic pairing * succeeded. */ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_target_rec = btm_find_dev(bd_addr); if (!p_target_rec) { LOG_ERROR("No security record for just bonded device!?!?"); return; } if (p_target_rec->ble_hci_handle != HCI_INVALID_HANDLE) { LOG_INFO("Not consolidating - already have LE connection"); return; } LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); list_node_t* end = list_end(btm_cb.sec_dev_rec); list_node_t* node = list_begin(btm_cb.sec_dev_rec); while (node != end) { tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(list_node(node)); // we do list_remove in some cases, must grab next before removing node = list_next(node); if (p_target_rec == p_dev_rec) continue; /* an RPA device entry is a duplicate of the target record */ if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) { if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { LOG_INFO("already disconnected - erasing entry %s", ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); wipe_secrets_and_remove(p_dev_rec); continue; } LOG_INFO( "Found existing LE connection to just bonded device on %s handle 0x%04x", ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->ble_hci_handle); RawAddress ble_conn_addr = p_dev_rec->bd_addr; p_target_rec->ble_hci_handle = p_dev_rec->ble_hci_handle; /* remove the old LE record */ wipe_secrets_and_remove(p_dev_rec); /* To avoid race conditions between central/peripheral starting encryption * at same time, initiate it just from central. */ if (L2CA_GetBleConnRole(ble_conn_addr) == HCI_ROLE_CENTRAL) { LOG_INFO("Will encrypt existing connection"); BTM_SetEncryption(ble_conn_addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); } } } } /******************************************************************************* * * Function btm_find_or_alloc_dev Loading system/stack/btm/btm_dev.h +27 −1 Original line number Diff line number Diff line Loading @@ -109,10 +109,22 @@ bool is_address_equal(void* data, void* context); ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_find_dev_with_lenc * * Description Look for the record in the device database with LTK and * specified BD address * * Returns Pointer to the record or NULL * ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_consolidate_dev 5** * * Description combine security records if identified as same peer * * Returns none Loading @@ -120,6 +132,20 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr); ******************************************************************************/ void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec); /******************************************************************************* * * Function btm_consolidate_dev * * Description When pairing is finished (i.e. on BR/EDR), this function * checks if there are existing LE connections to same device * that can now be encrypted and used for profiles requiring * encryption. * * Returns none * ******************************************************************************/ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_find_or_alloc_dev Loading system/stack/smp/smp_act.cc +1 −1 Original line number Diff line number Diff line Loading @@ -1044,7 +1044,7 @@ void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_LE_KEY_VALUE pid_key = { .pid_key = {}, }; ; STREAM_TO_UINT8(pid_key.pid_key.identity_addr_type, p); STREAM_TO_BDADDR(pid_key.pid_key.identity_addr, p); pid_key.pid_key.irk = p_cb->tk; Loading system/stack/smp/smp_utils.cc +6 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include "stack/include/stack_metrics_logging.h" #include "types/raw_address.h" void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr); #define SMP_PAIRING_REQ_SIZE 7 #define SMP_CONFIRM_CMD_SIZE (OCTET16_LEN + 1) #define SMP_RAND_CMD_SIZE (OCTET16_LEN + 1) Loading Loading @@ -1000,6 +1002,10 @@ void smp_proc_pairing_cmpl(tSMP_CB* p_cb) { metric_status); } if (p_cb->status == SMP_SUCCESS && p_cb->smp_over_br) { btm_dev_consolidate_existing_connections(pairing_bda); } smp_reset_control_value(p_cb); if (p_callback) (*p_callback)(SMP_COMPLT_EVT, pairing_bda, &evt_data); Loading Loading
system/stack/btm/btm_ble.cc +23 −6 Original line number Diff line number Diff line Loading @@ -1518,13 +1518,30 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, BTM_TRACE_ERROR("key size = %d", p_rec->ble.keys.key_size); if (use_stk) { btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk); } else /* calculate LTK using peer device */ { if (p_rec->ble.key_type & BTM_LE_KEY_LENC) return; } /* calculate LTK using peer device */ if (p_rec->ble.key_type & BTM_LE_KEY_LENC) { btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk); else return; } p_rec = btm_find_dev_with_lenc(bda); if (!p_rec) { btsnd_hcic_ble_ltk_req_neg_reply(btm_cb.enc_handle); return; } LOG_INFO("Found second sec_dev_rec for device that have LTK"); /* This can happen when remote established LE connection using RPA to this * device, but then pair with us using Classing transport while still keeping * LE connection. If remote attempts to encrypt the LE connection, we might * end up here. We will eventually consolidate both entries, this is to avoid * race conditions. */ LOG_ASSERT(p_rec->ble.key_type & BTM_LE_KEY_LENC); p_cb->key_size = p_rec->ble.keys.key_size; btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk); } /******************************************************************************* Loading
system/stack/btm/btm_dev.cc +84 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <string.h> #include "btm_api.h" #include "btm_ble_int.h" #include "device/include/controller.h" #include "l2c_api.h" #include "main/shim/btm_api.h" Loading Loading @@ -372,6 +373,32 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr) { return NULL; } static bool has_lenc_and_address_is_equal(void* data, void* context) { tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data); if (!(p_dev_rec->ble.key_type & BTM_LE_KEY_LENC)) return false; return is_address_equal(data, context); } /******************************************************************************* * * Function btm_find_dev_with_lenc * * Description Look for the record in the device database with LTK and * specified BD address * * Returns Pointer to the record or NULL * ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr) { if (btm_cb.sec_dev_rec == nullptr) return nullptr; list_node_t* n = list_foreach(btm_cb.sec_dev_rec, has_lenc_and_address_is_equal, (void*)&bd_addr); if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n)); return NULL; } /******************************************************************************* * * Function btm_consolidate_dev Loading Loading @@ -429,6 +456,63 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec) { } } /* combine security records of established LE connections after Classic pairing * succeeded. */ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_target_rec = btm_find_dev(bd_addr); if (!p_target_rec) { LOG_ERROR("No security record for just bonded device!?!?"); return; } if (p_target_rec->ble_hci_handle != HCI_INVALID_HANDLE) { LOG_INFO("Not consolidating - already have LE connection"); return; } LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); list_node_t* end = list_end(btm_cb.sec_dev_rec); list_node_t* node = list_begin(btm_cb.sec_dev_rec); while (node != end) { tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(list_node(node)); // we do list_remove in some cases, must grab next before removing node = list_next(node); if (p_target_rec == p_dev_rec) continue; /* an RPA device entry is a duplicate of the target record */ if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) { if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { LOG_INFO("already disconnected - erasing entry %s", ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); wipe_secrets_and_remove(p_dev_rec); continue; } LOG_INFO( "Found existing LE connection to just bonded device on %s handle 0x%04x", ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->ble_hci_handle); RawAddress ble_conn_addr = p_dev_rec->bd_addr; p_target_rec->ble_hci_handle = p_dev_rec->ble_hci_handle; /* remove the old LE record */ wipe_secrets_and_remove(p_dev_rec); /* To avoid race conditions between central/peripheral starting encryption * at same time, initiate it just from central. */ if (L2CA_GetBleConnRole(ble_conn_addr) == HCI_ROLE_CENTRAL) { LOG_INFO("Will encrypt existing connection"); BTM_SetEncryption(ble_conn_addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); } } } } /******************************************************************************* * * Function btm_find_or_alloc_dev Loading
system/stack/btm/btm_dev.h +27 −1 Original line number Diff line number Diff line Loading @@ -109,10 +109,22 @@ bool is_address_equal(void* data, void* context); ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_find_dev_with_lenc * * Description Look for the record in the device database with LTK and * specified BD address * * Returns Pointer to the record or NULL * ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_consolidate_dev 5** * * Description combine security records if identified as same peer * * Returns none Loading @@ -120,6 +132,20 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr); ******************************************************************************/ void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec); /******************************************************************************* * * Function btm_consolidate_dev * * Description When pairing is finished (i.e. on BR/EDR), this function * checks if there are existing LE connections to same device * that can now be encrypted and used for profiles requiring * encryption. * * Returns none * ******************************************************************************/ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr); /******************************************************************************* * * Function btm_find_or_alloc_dev Loading
system/stack/smp/smp_act.cc +1 −1 Original line number Diff line number Diff line Loading @@ -1044,7 +1044,7 @@ void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_LE_KEY_VALUE pid_key = { .pid_key = {}, }; ; STREAM_TO_UINT8(pid_key.pid_key.identity_addr_type, p); STREAM_TO_BDADDR(pid_key.pid_key.identity_addr, p); pid_key.pid_key.irk = p_cb->tk; Loading
system/stack/smp/smp_utils.cc +6 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include "stack/include/stack_metrics_logging.h" #include "types/raw_address.h" void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr); #define SMP_PAIRING_REQ_SIZE 7 #define SMP_CONFIRM_CMD_SIZE (OCTET16_LEN + 1) #define SMP_RAND_CMD_SIZE (OCTET16_LEN + 1) Loading Loading @@ -1000,6 +1002,10 @@ void smp_proc_pairing_cmpl(tSMP_CB* p_cb) { metric_status); } if (p_cb->status == SMP_SUCCESS && p_cb->smp_over_br) { btm_dev_consolidate_existing_connections(pairing_bda); } smp_reset_control_value(p_cb); if (p_callback) (*p_callback)(SMP_COMPLT_EVT, pairing_bda, &evt_data); Loading