diff options
author | 2023-05-16 12:43:18 +0000 | |
---|---|---|
committer | 2023-05-19 13:47:38 +0000 | |
commit | 8c491c778e8ea89ef5d693827ad4419f2a79a00b (patch) | |
tree | d9144e98ed6e06de5ef0536f2f9e14b2f9acc38e | |
parent | 90d8834251126de7d6fe390a961af9243fde7dc2 (diff) |
smp: Add SIRK verification callback
Don't bond with not valid CSIS devices if device was presented as member
of group by using matching RSI.
This part extends SMP module and related with callback to SIRK for
verification of potential members.
Tag: #feature
Bug: 278514112
Test: atest bluetooth_csis_test
Change-Id: If67b829b8dd1e5e4d2a9de08df92cff45b5c27f9
23 files changed, 357 insertions, 15 deletions
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 23d79f7686..b67608f2f3 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -138,6 +138,7 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, tBTM_LE_EVT_DATA* p_data); static void bta_dm_ble_id_key_cback(uint8_t key_type, tBTM_BLE_LOCAL_KEYS* p_key); +static uint8_t bta_dm_sirk_verifiction_cback(const RawAddress& bd_addr); static void bta_dm_gattc_register(void); static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr); static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); @@ -349,7 +350,8 @@ const tBTM_APPL_INFO bta_security = { .p_bond_cancel_cmpl_callback = &bta_dm_bond_cancel_complete_cback, .p_sp_callback = &bta_dm_sp_cback, .p_le_callback = &bta_dm_ble_smp_cback, - .p_le_key_callback = &bta_dm_ble_id_key_cback}; + .p_le_key_callback = &bta_dm_ble_id_key_cback, + .p_sirk_verification_callback = &bta_dm_sirk_verifiction_cback}; #define MAX_DISC_RAW_DATA_BUF (4096) uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF]; @@ -367,6 +369,20 @@ void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) { btm_local_io_caps = btif_storage_get_local_io_caps(); } +void bta_dm_ble_sirk_sec_cb_register(tBTA_DM_SEC_CBACK* p_cback) { + /* Save the callback to be called when a request of member validation will be + * needed. */ + LOG_DEBUG(""); + bta_dm_cb.p_sec_sirk_cback = p_cback; +} + +void bta_dm_ble_sirk_confirm_device_reply(const RawAddress& bd_addr, + bool accept) { + LOG_DEBUG(""); + get_btm_client_interface().security.BTM_BleSirkConfirmDeviceReply( + bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED); +} + void bta_dm_search_set_state(tBTA_DM_STATE state) { bta_dm_search_cb.state = state; } @@ -4023,6 +4039,31 @@ static void bta_dm_ble_id_key_cback(uint8_t key_type, /******************************************************************************* * + * Function bta_dm_sirk_verifiction_cback + * + * Description SIRK verification when pairing CSIP set member. + * + * Returns void + * + ******************************************************************************/ +static uint8_t bta_dm_sirk_verifiction_cback(const RawAddress& bd_addr) { + tBTA_DM_SEC sec_event = {.ble_req = { + .bd_addr = bd_addr, + }}; + + if (bta_dm_cb.p_sec_sirk_cback) { + LOG_DEBUG("callback called"); + bta_dm_cb.p_sec_sirk_cback(BTA_DM_SIRK_VERIFICATION_REQ_EVT, &sec_event); + return BTM_CMD_STARTED; + } + + LOG_DEBUG("no callback registered"); + + return BTM_SUCCESS_NO_SECURITY; +} + +/******************************************************************************* + * * Function bta_dm_add_blekey * * Description This function adds an BLE Key to an security database entry. diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc index d917b09954..b8be10a4c3 100644 --- a/system/bta/dm/bta_dm_api.cc +++ b/system/bta/dm/bta_dm_api.cc @@ -798,6 +798,43 @@ void BTA_DmBleSubrateRequest(const RawAddress& bd_addr, uint16_t subrate_min, subrate_max, max_latency, cont_num, timeout)); } +/******************************************************************************* + * + * Function BTA_DmSirkSecCbRegister + * + * Description This procedure registeres in requested a callback for + * verification by CSIP potential set member. + * + * Parameters p_cback - callback to member verificator + * + * Returns void + * + ******************************************************************************/ +void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback) { + LOG_DEBUG(""); + do_in_main_thread(FROM_HERE, + base::Bind(bta_dm_ble_sirk_sec_cb_register, p_cback)); +} + +/******************************************************************************* + * + * Function BTA_DmSirkConfirmDeviceReply + * + * Description This procedure confirms requested to validate set device. + * + * Parameters bd_addr - BD address of the peer + * accept - True if device is authorized by CSIP, false + * otherwise. + * + * Returns void + * + ******************************************************************************/ +void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, bool accept) { + LOG_DEBUG(""); + do_in_main_thread(FROM_HERE, base::Bind(bta_dm_ble_sirk_confirm_device_reply, + bd_addr, accept)); +} + bool BTA_DmCheckLeAudioCapable(const RawAddress& address) { for (tBTM_INQ_INFO* inq_ent = BTM_InqDbFirst(); inq_ent != nullptr; inq_ent = BTM_InqDbNext(inq_ent)) { diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h index 96f1f16ad0..96dc42febd 100644 --- a/system/bta/dm/bta_dm_int.h +++ b/system/bta/dm/bta_dm_int.h @@ -332,6 +332,7 @@ extern tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs; typedef struct { tBTA_DM_ACTIVE_LINK device_list; tBTA_DM_SEC_CBACK* p_sec_cback; + tBTA_DM_SEC_CBACK* p_sec_sirk_cback; tBTA_BLE_ENERGY_INFO_CBACK* p_energy_info_cback; bool disabling; alarm_t* disable_timer; @@ -510,6 +511,9 @@ void bta_dm_enable(tBTA_DM_SEC_CBACK*); void bta_dm_disable(); void bta_dm_init_cb(void); void bta_dm_deinit_cb(void); +void bta_dm_ble_sirk_sec_cb_register(tBTA_DM_SEC_CBACK*); +void bta_dm_ble_sirk_confirm_device_reply(const RawAddress& bd_addr, + bool accept); void bta_dm_set_dev_name(const std::vector<uint8_t>&); void bta_dm_set_visibility(tBTA_DM_DISC, tBTA_DM_CONN); void bta_dm_set_scan_config(tBTA_DM_MSG* p_data); diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 5ce2778f16..e183897da4 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -249,6 +249,7 @@ typedef enum : uint8_t { BTA_DM_REPORT_BONDING_EVT = 32, /*handle for pin or key missing*/ BTA_DM_LE_ADDR_ASSOC_EVT = 33, /* identity address association event */ BTA_DM_LINK_UP_FAILED_EVT = 34, /* Create connection failed event */ + BTA_DM_SIRK_VERIFICATION_REQ_EVT = 35, } tBTA_DM_SEC_EVT; /* Structure associated with BTA_DM_PIN_REQ_EVT */ @@ -1183,6 +1184,35 @@ void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb); /******************************************************************************* * + * Function BTA_DmSirkSecCbRegister + * + * Description This procedure registeres in requested a callback for + * verification by CSIS potential set member. + * + * Parameters p_cback - callback to member verificator + * + * Returns void + * + ******************************************************************************/ +void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback); + +/******************************************************************************* + * + * Function BTA_DmSirkConfirmDeviceReply + * + * Description This procedure confirms requested to validate set device. + * + * Parameters bd_addr - BD address of the peer + * accept - True if device is authorized by CSIS, false + * otherwise. + * + * Returns void + * + ******************************************************************************/ +void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, bool accept); + +/******************************************************************************* + * * Function BTA_DmBleConfigLocalPrivacy * * Description Enable/disable privacy on the local device diff --git a/system/bta/test/common/bta_dm_api_mock.cc b/system/bta/test/common/bta_dm_api_mock.cc index e0c9941e3f..ef61b5244b 100644 --- a/system/bta/test/common/bta_dm_api_mock.cc +++ b/system/bta/test/common/bta_dm_api_mock.cc @@ -32,3 +32,13 @@ void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) { LOG_ASSERT(dm_interface) << "Mock BTA DM interface not set!"; return dm_interface->BTA_DmBleCsisObserve(observe, p_results_cb); } + +void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback) { + LOG_ASSERT(dm_interface) << "Mock BTA DM interface not set!"; + return dm_interface->BTA_DmSirkSecCbRegister(p_cback); +} + +void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, bool accept) { + LOG_ASSERT(dm_interface) << "Mock BTA DM interface not set!"; + return dm_interface->BTA_DmSirkConfirmDeviceReply(bd_addr, accept); +} diff --git a/system/bta/test/common/bta_dm_api_mock.h b/system/bta/test/common/bta_dm_api_mock.h index 9093bd3b29..0fd39c226a 100644 --- a/system/bta/test/common/bta_dm_api_mock.h +++ b/system/bta/test/common/bta_dm_api_mock.h @@ -30,6 +30,9 @@ class BtaDmInterface { bool low_latency_scan) = 0; virtual void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) = 0; + virtual void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback) = 0; + virtual void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, + bool accept) = 0; virtual ~BtaDmInterface() = default; }; @@ -39,6 +42,9 @@ class MockBtaDmInterface : public BtaDmInterface { (bool start, uint8_t duration, bool low_latency_scan)); MOCK_METHOD((void), BTA_DmBleCsisObserve, (bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb)); + MOCK_METHOD((void), BTA_DmSirkSecCbRegister, (tBTA_DM_SEC_CBACK * p_cback)); + MOCK_METHOD((void), BTA_DmSirkConfirmDeviceReply, + (const RawAddress& bd_addr, bool accept)); }; /** diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 5a7e7a75fa..6088c5d24c 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -2367,6 +2367,11 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) { p_data->proc_id_addr.pairing_bda, p_data->proc_id_addr.id_addr); break; + case BTA_DM_SIRK_VERIFICATION_REQ_EVT: + GetInterfaceToProfiles()->events->invoke_le_address_associate_cb( + p_data->proc_id_addr.pairing_bda, p_data->proc_id_addr.id_addr); + break; + default: BTIF_TRACE_WARNING("%s: unhandled event (%d)", __func__, event); break; diff --git a/system/btif/src/btif_util.cc b/system/btif/src/btif_util.cc index fb24a1ab86..d8caea1bab 100644 --- a/system/btif/src/btif_util.cc +++ b/system/btif/src/btif_util.cc @@ -160,6 +160,7 @@ const char* dump_dm_event(uint16_t event) { CASE_RETURN_STR(BTA_DM_BLE_AUTH_CMPL_EVT) CASE_RETURN_STR(BTA_DM_DEV_UNPAIRED_EVT) CASE_RETURN_STR(BTA_DM_ENER_INFO_READ) + CASE_RETURN_STR(BTA_DM_SIRK_VERIFICATION_REQ_EVT) default: return "UNKNOWN DM EVENT"; diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc index 49c74d8b56..8be911b3d4 100644 --- a/system/main/shim/btm_api.cc +++ b/system/main/shim/btm_api.cc @@ -143,6 +143,10 @@ class ShimUi : public bluetooth::security::UI { if (bta_callbacks->p_le_key_callback == nullptr) { LOG_INFO("UNIMPLEMENTED %s le_key_callback", __func__); } + + if (bta_callbacks->p_sirk_verification_callback == nullptr) { + LOG_INFO("UNIMPLEMENTED %s sirk_verification_callback", __func__); + } } void DisplayPairingPrompt(const bluetooth::hci::AddressWithType& address, @@ -275,6 +279,10 @@ class ShimBondListener : public bluetooth::security::ISecurityManagerListener { if (bta_callbacks->p_le_key_callback == nullptr) { LOG_INFO("UNIMPLEMENTED %s le_key_callback", __func__); } + + if (bta_callbacks->p_sirk_verification_callback == nullptr) { + LOG_INFO("UNIMPLEMENTED %s sirk_verification_callback", __func__); + } } void OnDeviceBonded(bluetooth::hci::AddressWithType device) override { diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index c85d71cfe2..86b0f9c3e6 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -1933,6 +1933,16 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, } break; + case SMP_SIRK_VERIFICATION_REQ_EVT: + res = (*btm_cb.api.p_sirk_verification_callback)(bd_addr); + LOG_DEBUG("SMP SIRK verification result: %s", + btm_status_text(res).c_str()); + if (res != BTM_CMD_STARTED) { + return res; + } + + break; + default: BTM_TRACE_DEBUG("unknown event = %d", event); break; @@ -2045,6 +2055,37 @@ bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig, } /******************************************************************************* + * + * Function BTM_BleSirkConfirmDeviceReply + * + * Description This procedure confirms requested to validate set device. + * + * Parameter bd_addr - BD address of the peer + * res - confirmation result BTM_SUCCESS if success + * + * Returns void + * + ******************************************************************************/ +void BTM_BleSirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { + if (bluetooth::shim::is_gd_shim_enabled()) { + ASSERT_LOG(false, "This should not be invoked from code path"); + } + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); + tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_FAIL; + + if (p_dev_rec == NULL) { + LOG_ERROR("Confirmation of Unknown device"); + return; + } + + BTM_LogHistory( + kBtmLogTag, bd_addr, "SIRK confirmation", + base::StringPrintf("status:%s", smp_status_text(res_smp).c_str())); + LOG_DEBUG(""); + SMP_SirkConfirmDeviceReply(bd_addr, res_smp); +} + +/******************************************************************************* * Utility functions for LE device IR/ER generation ******************************************************************************/ /** This function is to notify application new keys have been generated. */ diff --git a/system/stack/btm/btm_client_interface.cc b/system/stack/btm/btm_client_interface.cc index f97555f896..576bd0848b 100644 --- a/system/stack/btm/btm_client_interface.cc +++ b/system/stack/btm/btm_client_interface.cc @@ -128,6 +128,7 @@ struct btm_client_interface_t btm_client_interface = { .BTM_IsEncrypted = BTM_IsEncrypted, .BTM_SecIsSecurityPending = BTM_SecIsSecurityPending, .BTM_IsLinkKeyKnown = BTM_IsLinkKeyKnown, + .BTM_BleSirkConfirmDeviceReply = BTM_BleSirkConfirmDeviceReply, }, .ble = diff --git a/system/stack/btm/btm_int_types.h b/system/stack/btm/btm_int_types.h index b61f08823d..713d4fe135 100644 --- a/system/stack/btm/btm_int_types.h +++ b/system/stack/btm/btm_int_types.h @@ -117,6 +117,7 @@ typedef struct { uint16_t psm; bool is_orig; tBTM_SEC_CALLBACK* p_callback; + tSMP_SIRK_CALLBACK* p_sirk_callback; void* p_ref_data; uint16_t rfcomm_security_requirement; tBT_TRANSPORT transport; diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 12fb5b194b..88a9abaeb4 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -939,6 +939,20 @@ uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len, ******************************************************************************/ tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void); +/******************************************************************************* + * + * Function BTM_BleSirkConfirmDeviceReply + * + * Description This procedure confirms requested to validate set device. + * + * Parameter bd_addr - BD address of the peer + * res - confirmation result BTM_SUCCESS if success + * + * Returns void + * + ******************************************************************************/ +void BTM_BleSirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res); + /** * Send remote name request, either to legacy HCI, or to GD shim Name module */ diff --git a/system/stack/include/btm_client_interface.h b/system/stack/include/btm_client_interface.h index 24669beef2..a12c1b77b7 100644 --- a/system/stack/include/btm_client_interface.h +++ b/system/stack/include/btm_client_interface.h @@ -160,6 +160,8 @@ struct btm_client_interface_t { bool (*BTM_SecIsSecurityPending)(const RawAddress& bd_addr); bool (*BTM_IsLinkKeyKnown)(const RawAddress& bd_addr, tBT_TRANSPORT transport); + void (*BTM_BleSirkConfirmDeviceReply)(const RawAddress& bd_addr, + uint8_t res); } security; struct { diff --git a/system/stack/include/security_client_callbacks.h b/system/stack/include/security_client_callbacks.h index d6070cd050..d5daf3051d 100644 --- a/system/stack/include/security_client_callbacks.h +++ b/system/stack/include/security_client_callbacks.h @@ -73,6 +73,11 @@ typedef void(tBTM_AUTH_COMPLETE_CALLBACK)(const RawAddress& bd_addr, tBTM_BD_NAME bd_name, tHCI_REASON reason); +/* Request SIRK verification for found member. Parameters are + * BD Address of remote + */ +typedef uint8_t(tBTM_SIRK_VERIFICATION_CALLBACK)(const RawAddress& bd_addr); + struct tBTM_APPL_INFO { tBTM_PIN_CALLBACK* p_pin_callback{nullptr}; tBTM_LINK_KEY_CALLBACK* p_link_key_callback{nullptr}; @@ -81,4 +86,5 @@ struct tBTM_APPL_INFO { tBTM_SP_CALLBACK* p_sp_callback{nullptr}; tBTM_LE_CALLBACK* p_le_callback{nullptr}; tBTM_LE_KEY_CALLBACK* p_le_key_callback{nullptr}; + tBTM_SIRK_VERIFICATION_CALLBACK* p_sirk_verification_callback{nullptr}; }; diff --git a/system/stack/include/smp_api.h b/system/stack/include/smp_api.h index 67b488d24d..0a56f19c91 100644 --- a/system/stack/include/smp_api.h +++ b/system/stack/include/smp_api.h @@ -200,6 +200,20 @@ bool SMP_CrLocScOobData(); ******************************************************************************/ void SMP_ClearLocScOobData(); +/******************************************************************************* + * + * Function SMP_SirkConfirmDeviceReply + * + * Description This function is called after Security Manager submitted + * verification of device with CSIP. + * + * Parameters: bd_addr - Address of the device with which verification + * was requested + * res - comparison result SMP_SUCCESS if success + * + ******************************************************************************/ +void SMP_SirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res); + // Called when LTK request is received from controller. bool smp_proc_ltk_request(const RawAddress& bda); diff --git a/system/stack/include/smp_api_types.h b/system/stack/include/smp_api_types.h index 12b64f35c9..d33cc6dc7b 100644 --- a/system/stack/include/smp_api_types.h +++ b/system/stack/include/smp_api_types.h @@ -99,8 +99,9 @@ typedef enum : uint8_t { SMP_UNUSED11 = 11, SMP_BR_KEYS_REQ_EVT = 12, /* SMP over BR keys request event */ SMP_UNUSED13 = 13, - SMP_CONSENT_REQ_EVT = 14, /* Consent request event */ - SMP_LE_ADDR_ASSOC_EVT = 15, /* Identity address association event */ + SMP_CONSENT_REQ_EVT = 14, /* Consent request event */ + SMP_LE_ADDR_ASSOC_EVT = 15, /* Identity address association event */ + SMP_SIRK_VERIFICATION_REQ_EVT = 16, /* SIRK verification request event */ } tSMP_EVT; /* Device IO capability */ @@ -243,5 +244,8 @@ typedef struct { * events occur.*/ typedef tBTM_STATUS(tSMP_CALLBACK)(tSMP_EVT event, const RawAddress& bd_addr, const tSMP_EVT_DATA* p_data); +/* Security Manager SIRK verification event - Called by the stack when Security + * Manager requires verification from CSIP.*/ +typedef tBTM_STATUS(tSMP_SIRK_CALLBACK)(const RawAddress& bd_addr); #endif // SMP_API_TYPES_H diff --git a/system/stack/include/smp_status.h b/system/stack/include/smp_status.h index 10c6e59483..d89a25467b 100644 --- a/system/stack/include/smp_status.h +++ b/system/stack/include/smp_status.h @@ -55,7 +55,8 @@ typedef enum : uint8_t { /* Unspecified failure reason */ SMP_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A), /* 0x18 */ - SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B), /* 0x19 */ + SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B), /* 0x19 */ + SMP_SIRK_DEVICE_INVALID = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0C), /* 0x1a */ } tSMP_STATUS; #ifndef CASE_RETURN_TEXT @@ -89,6 +90,7 @@ inline std::string smp_status_text(const tSMP_STATUS& status) { CASE_RETURN_TEXT(SMP_RSP_TIMEOUT); CASE_RETURN_TEXT(SMP_FAIL); CASE_RETURN_TEXT(SMP_CONN_TOUT); + CASE_RETURN_TEXT(SMP_SIRK_DEVICE_INVALID); default: return base::StringPrintf("UNKNOWN[%hhu]", status); } diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc index 5748169072..22942fc759 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -1215,6 +1215,51 @@ void smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { } /******************************************************************************* + * Function smp_sirk_verify + * Description verify if device belongs to csis group. + ******************************************************************************/ +void smp_sirk_verify(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { + tBTM_STATUS callback_rc; + LOG_DEBUG(""); + + if (p_data->status != SMP_SUCCESS) { + LOG_DEBUG( + "Cancel device verification due to invalid status (%d) while " + "bonding.", + p_data->status); + + tSMP_INT_DATA smp_int_data; + smp_int_data.status = SMP_SIRK_DEVICE_INVALID; + + BTM_LogHistory( + kBtmLogTag, p_cb->pairing_bda, "SIRK verification", + base::StringPrintf("Verification failed, smp_status:%s", + smp_status_text(smp_int_data.status).c_str())); + + smp_sm_event(p_cb, SMP_SIRK_DEVICE_VALID_EVT, &smp_int_data); + + return; + } + + if (p_cb->p_callback) { + p_cb->cb_evt = SMP_SIRK_VERIFICATION_REQ_EVT; + callback_rc = (*p_cb->p_callback)(p_cb->cb_evt, p_cb->pairing_bda, nullptr); + + /* There is no member validator callback - device is by default valid */ + if (callback_rc == BTM_SUCCESS_NO_SECURITY) { + BTM_LogHistory(kBtmLogTag, p_cb->pairing_bda, "SIRK verification", + base::StringPrintf("Device validated due to no security")); + + tSMP_INT_DATA smp_int_data; + smp_int_data.status = SMP_SUCCESS; + smp_sm_event(p_cb, SMP_SIRK_DEVICE_VALID_EVT, &smp_int_data); + } + } else { + LOG_ERROR("There are no registrated callbacks for SMP"); + } +} + +/******************************************************************************* * Function smp_check_auth_req * Description check authentication request ******************************************************************************/ diff --git a/system/stack/smp/smp_api.cc b/system/stack/smp/smp_api.cc index ace84db810..3362bc01c8 100644 --- a/system/stack/smp/smp_api.cc +++ b/system/stack/smp/smp_api.cc @@ -583,3 +583,53 @@ bool SMP_CrLocScOobData() { * ******************************************************************************/ void SMP_ClearLocScOobData() { smp_clear_local_oob_data(); } + +/******************************************************************************* + * + * Function SMP_SirkConfirmDeviceReply + * + * Description This function is called after Security Manager submitted + * verification of device with CSIP. + * + * Parameters: bd_addr - Address of the device with which verification + * was requested + * res - comparison result SMP_SUCCESS if success + * + ******************************************************************************/ +void SMP_SirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { + LOG_ASSERT(!bluetooth::shim::is_gd_shim_enabled()) + << "Legacy SMP API should not be invoked when GD Security is used"; + + tSMP_CB* p_cb = &smp_cb; + + LOG_INFO("Result: %d", res); + + /* If timeout already expired or has been canceled, ignore the reply */ + if (p_cb->cb_evt != SMP_SIRK_VERIFICATION_REQ_EVT) { + LOG_WARN("Wrong State: %d", p_cb->state); + return; + } + + if (bd_addr != p_cb->pairing_bda) { + LOG_WARN("Wrong confirmation BD Addr: %s vs expected %s", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + return; + } + + if (btm_find_dev(bd_addr) == NULL) { + LOG_ERROR("No dev CB"); + return; + } + + tSMP_INT_DATA smp_int_data; + if (res != SMP_SUCCESS) { + LOG_WARN("Verification fails"); + /* send pairing failure */ + smp_int_data.status = SMP_SIRK_DEVICE_INVALID; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); + } else { + smp_int_data.status = SMP_SUCCESS; + smp_sm_event(p_cb, SMP_SIRK_DEVICE_VALID_EVT, &smp_int_data); + } +} diff --git a/system/stack/smp/smp_int.h b/system/stack/smp/smp_int.h index 1cf316ef30..8b7a913e4f 100644 --- a/system/stack/smp/smp_int.h +++ b/system/stack/smp/smp_int.h @@ -147,7 +147,8 @@ typedef enum : uint8_t { SMP_SC_OOB_DATA_EVT = (SMP_SELF_DEF_EVT + 23), // 0x27 SMP_CR_LOC_SC_OOB_DATA_EVT = (SMP_SELF_DEF_EVT + 24), // 0x28 - SMP_MAX_EVT = SMP_CR_LOC_SC_OOB_DATA_EVT, // 0x28 + SMP_SIRK_DEVICE_VALID_EVT = (SMP_SELF_DEF_EVT + 25), // 0x29 + SMP_MAX_EVT = SMP_SIRK_DEVICE_VALID_EVT, // 0x29 } tSMP_EVENT; typedef tSMP_EVENT tSMP_BR_EVENT; @@ -357,6 +358,7 @@ void smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_proc_discard(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_pairing_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); +void smp_sirk_verify(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_proc_compare(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); void smp_check_auth_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); diff --git a/system/stack/smp/smp_main.cc b/system/stack/smp/smp_main.cc index ab30510e5b..ec6e7361e3 100644 --- a/system/stack/smp/smp_main.cc +++ b/system/stack/smp/smp_main.cc @@ -91,6 +91,7 @@ const char* const smp_event_name[] = {"PAIRING_REQ_EVT", "KEYPRESS_NOTIFICATION_EVT", "SEC_CONN_OOB_DATA_EVT", "CREATE_LOCAL_SEC_CONN_OOB_DATA_EVT", + "SIRK_DEVICE_VALID_EVT", "OUT_OF_RANGE_EVT"}; const char* smp_get_event_name(tSMP_EVENT event); @@ -137,6 +138,7 @@ enum { SMP_CHECK_AUTH_REQ, SMP_PAIR_TERMINATE, SMP_ENC_CMPL, + SMP_SIRK_VERIFY, SMP_PROC_DISCARD, SMP_CREATE_PRIVATE_KEY, SMP_USE_OOB_PRIVATE_KEY, @@ -201,6 +203,7 @@ static const tSMP_ACT smp_sm_action[] = { smp_check_auth_req, smp_pair_terminate, smp_enc_cmpl, + smp_sirk_verify, smp_proc_discard, smp_create_private_key, smp_use_oob_private_key, @@ -232,9 +235,10 @@ static const tSMP_ACT smp_sm_action[] = { /************ SMP Central FSM State/Event Indirection Table **************/ static const uint8_t smp_central_entry_map[][SMP_STATE_MAX] = { /* state name: */ - /* Idle, WaitApp Rsp, SecReq Pend, Pair ReqRsp, Wait Cfm, Confirm, Rand, - PublKey Exch, SCPhs1 Strt, Wait Cmtm, Wait Nonce, SCPhs2 Strt, Wait - DHKChk, DHKChk, Enc Pend, Bond Pend, CrLocSc OobData */ + /* Idle, WaitApp Rsp, SecReq Pend, Pair ReqRsp, Wait Cfm, + Confirm, Rand, PublKey Exch, SCPhs1 Strt, Wait Cmtm, Wait Nonce, + SCPhs2 Strt, Wait DHKChk, DHKChk, Enc Pend, Bond Pend, CrLocSc OobData + */ /* PAIR_REQ */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* PAIR_RSP */ @@ -283,7 +287,7 @@ static const uint8_t smp_central_entry_map[][SMP_STATE_MAX] = { {0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, /* AUTH_CMPL */ {4, 0x82, 0, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0}, + 0x82, 0x82, 7, 0}, /* ENC_REQ */ {0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}, /* BOND_REQ */ @@ -318,6 +322,8 @@ static const uint8_t smp_central_entry_map[][SMP_STATE_MAX] = { {0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* CR_LOC_SC_OOB_DATA */ {5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* SIRK_VERIFY */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x82, 0}, }; static const uint8_t smp_all_table[][SMP_SM_NUM_COLS] = { @@ -512,6 +518,7 @@ static const uint8_t smp_central_enc_pending_table[][SMP_SM_NUM_COLS] = { {SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, /* BOND_REQ */ {SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}}; + static const uint8_t smp_central_bond_pending_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ /* ENC_INFO */ @@ -526,7 +533,10 @@ static const uint8_t smp_central_bond_pending_table[][SMP_SM_NUM_COLS] = { {SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, /* KEY_READY */ /* LTK ready */ - {SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}}; + {SMP_SEND_ENC_INFO, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, + /* AUTH_CMPL */ + {SMP_SIRK_VERIFY, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, +}; static const uint8_t smp_central_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS] = { @@ -595,7 +605,7 @@ static const uint8_t smp_peripheral_entry_map[][SMP_STATE_MAX] = { /* ENC_REQ */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, /* BOND_REQ */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1}, /* DISCARD_SEC_REQ */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* PUBL_KEY_EXCH_REQ */ @@ -626,6 +636,8 @@ static const uint8_t smp_peripheral_entry_map[][SMP_STATE_MAX] = { {0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* CR_LOC_SC_OOB_DATA */ {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* SIRK_VERIFY */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }; static const uint8_t smp_peripheral_idle_table[][SMP_SM_NUM_COLS] = { @@ -838,6 +850,7 @@ static const uint8_t smp_peripheral_enc_pending_table[][SMP_SM_NUM_COLS] = { {SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_STATE_ENCRYPTION_PENDING}, /* BOND_REQ */ {SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}}; + static const uint8_t smp_peripheral_bond_pending_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ @@ -855,8 +868,9 @@ static const uint8_t smp_peripheral_bond_pending_table[][SMP_SM_NUM_COLS] = { /* CENTRAL_ID*/ {SMP_PROC_CENTRAL_ID, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, /* ID_ADDR */ - {SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING} - + {SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, + /* AUTH_CMPL */ + {SMP_SIRK_VERIFY, SMP_SM_NO_ACTION, SMP_STATE_BOND_PENDING}, }; static const uint8_t @@ -924,7 +938,8 @@ static const tSMP_SM_TBL smp_state_table[][2] = { /* SMP_STATE_CREATE_LOCAL_SEC_CONN_OOB_DATA */ {smp_central_create_local_sec_conn_oob_data, - smp_peripheral_create_local_sec_conn_oob_data}}; + smp_peripheral_create_local_sec_conn_oob_data}, +}; typedef const uint8_t (*tSMP_ENTRY_TBL)[SMP_STATE_MAX]; static const tSMP_ENTRY_TBL smp_entry_table[] = {smp_central_entry_map, @@ -1020,7 +1035,6 @@ bool smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, tSMP_INT_DATA* p_data) { } /* Get possible next state from state table. */ - smp_set_state(state_table[entry - 1][SMP_SME_NEXT_STATE]); /* If action is not ignore, clear param, exec action and get next state. diff --git a/system/test/mock/mock_stack_smp_api.cc b/system/test/mock/mock_stack_smp_api.cc index 62b04f834a..74232f2c9d 100644 --- a/system/test/mock/mock_stack_smp_api.cc +++ b/system/test/mock/mock_stack_smp_api.cc @@ -88,3 +88,7 @@ bool SMP_CrLocScOobData() { } void SMP_ClearLocScOobData() { inc_func_call_count(__func__); } + +void SMP_SirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { + inc_func_call_count(__func__); +} |