Loading system/stack/smp/smp_act.cc +18 −1 Original line number Diff line number Diff line Loading @@ -1457,7 +1457,13 @@ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { return; } if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { // If we are doing SMP_MODEL_SEC_CONN_OOB we don't need to request OOB data // locally if loc_oob_flag == 0x00 b/c there is no OOB data to give. In the // event the loc_oob_flag is another value, we should request the OOB data // locally. Which seems to cause it to make a TK REQUEST which is used for // the legacy flow which requires both sides to have OOB data. if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag != 0x00) { if (smp_request_oob_data(p_cb)) return; } Loading Loading @@ -1948,10 +1954,21 @@ void smp_set_local_oob_random_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->sc_oob_data.loc_oob_data.publ_key_used.x, p_cb->sc_oob_data.loc_oob_data.randomizer, 0); p_cb->sc_oob_data.loc_oob_data.present = true; /* pass created OOB data up */ p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT; smp_send_app_cback(p_cb, NULL); // Store the data for later use when we are paired with // Event though the doc above says to pass up for safe keeping it never gets // kept safe. Additionally, when we need the data to make a decision we // wouldn't have it. This will save the sc_oob_data in the smp_keys.cc such // that when we receive a request to create new keys we check to see if the // sc_oob_data exists and utilize the keys that are stored there otherwise the // connector will fail commitment check and dhkey exchange. smp_save_local_oob_data(p_cb); smp_cb_cleanup(p_cb); } Loading system/stack/smp/smp_api.cc +0 −3 Original line number Diff line number Diff line Loading @@ -567,9 +567,6 @@ void SMP_CrLocScOobData( const std::array<unsigned char, 16>&, const std::array<unsigned char, 16>&)> callback) { smp_cb.local_random = bluetooth::os::GenerateRandom<16>(); smp_cb.selected_association_model = SMP_MODEL_SEC_CONN_OOB; tSMP_INT_DATA smp_int_data; smp_sm_event(&smp_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, &smp_int_data); } system/stack/smp/smp_int.h +4 −0 Original line number Diff line number Diff line Loading @@ -461,4 +461,8 @@ extern bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb); extern void print128(const Octet16& x, const uint8_t* key_name); extern void smp_xor_128(Octet16* a, const Octet16& b); /* Save the p_cb->sc_oob_data.loc_oob_data for later, since the p_cb gets * cleaned up */ extern void smp_save_local_oob_data(tSMP_CB* p_cb); #endif /* SMP_INT_H */ system/stack/smp/smp_keys.cc +36 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,19 @@ static void smp_process_private_key(tSMP_CB* p_cb); #define SMP_PASSKEY_MASK 0xfff00000 // If there is data saved here, then use its info instead // This needs to be cleared on a successfult pairing using the oob data static tSMP_LOC_OOB_DATA saved_local_oob_data = {}; void smp_save_local_oob_data(tSMP_CB* p_cb) { saved_local_oob_data = p_cb->sc_oob_data.loc_oob_data; } static bool is_empty(tSMP_LOC_OOB_DATA* data) { tSMP_LOC_OOB_DATA empty_data = {}; return memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0; } void smp_debug_print_nbyte_little_endian(uint8_t* p, const char* key_name, uint8_t len) { } Loading Loading @@ -574,6 +587,29 @@ Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb) { void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { SMP_TRACE_DEBUG("%s", __func__); // Only use the stored OOB data if we are in an oob association model if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { LOG_WARN("OOB Association Model"); // Make sure our data isn't empty, otherwise we generate new and eventually // pairing will fail Not much we can do about it at this point, just have to // generate new data The data will be cleared after the advertiser times // out, so if the advertiser times out we want the pairing to fail anyway. if (!is_empty(&saved_local_oob_data)) { LOG_WARN("Found OOB data, loading keys"); memcpy(p_cb->private_key, saved_local_oob_data.private_key_used, BT_OCTET32_LEN); memcpy(p_cb->loc_publ_key.x, saved_local_oob_data.publ_key_used.x, BT_OCTET32_LEN); memcpy(p_cb->loc_publ_key.y, saved_local_oob_data.publ_key_used.y, BT_OCTET32_LEN); p_cb->sc_oob_data.loc_oob_data = saved_local_oob_data; p_cb->local_random = saved_local_oob_data.randomizer; smp_process_private_key(p_cb); return; } LOG_WARN("OOB Association Model with no saved data present"); } btsnd_hcic_ble_rand(Bind( [](tSMP_CB* p_cb, BT_OCTET8 rand) { memcpy((void*)p_cb->private_key, rand, BT_OCTET8_LEN); Loading Loading
system/stack/smp/smp_act.cc +18 −1 Original line number Diff line number Diff line Loading @@ -1457,7 +1457,13 @@ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { return; } if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { // If we are doing SMP_MODEL_SEC_CONN_OOB we don't need to request OOB data // locally if loc_oob_flag == 0x00 b/c there is no OOB data to give. In the // event the loc_oob_flag is another value, we should request the OOB data // locally. Which seems to cause it to make a TK REQUEST which is used for // the legacy flow which requires both sides to have OOB data. if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag != 0x00) { if (smp_request_oob_data(p_cb)) return; } Loading Loading @@ -1948,10 +1954,21 @@ void smp_set_local_oob_random_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->sc_oob_data.loc_oob_data.publ_key_used.x, p_cb->sc_oob_data.loc_oob_data.randomizer, 0); p_cb->sc_oob_data.loc_oob_data.present = true; /* pass created OOB data up */ p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT; smp_send_app_cback(p_cb, NULL); // Store the data for later use when we are paired with // Event though the doc above says to pass up for safe keeping it never gets // kept safe. Additionally, when we need the data to make a decision we // wouldn't have it. This will save the sc_oob_data in the smp_keys.cc such // that when we receive a request to create new keys we check to see if the // sc_oob_data exists and utilize the keys that are stored there otherwise the // connector will fail commitment check and dhkey exchange. smp_save_local_oob_data(p_cb); smp_cb_cleanup(p_cb); } Loading
system/stack/smp/smp_api.cc +0 −3 Original line number Diff line number Diff line Loading @@ -567,9 +567,6 @@ void SMP_CrLocScOobData( const std::array<unsigned char, 16>&, const std::array<unsigned char, 16>&)> callback) { smp_cb.local_random = bluetooth::os::GenerateRandom<16>(); smp_cb.selected_association_model = SMP_MODEL_SEC_CONN_OOB; tSMP_INT_DATA smp_int_data; smp_sm_event(&smp_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, &smp_int_data); }
system/stack/smp/smp_int.h +4 −0 Original line number Diff line number Diff line Loading @@ -461,4 +461,8 @@ extern bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb); extern void print128(const Octet16& x, const uint8_t* key_name); extern void smp_xor_128(Octet16* a, const Octet16& b); /* Save the p_cb->sc_oob_data.loc_oob_data for later, since the p_cb gets * cleaned up */ extern void smp_save_local_oob_data(tSMP_CB* p_cb); #endif /* SMP_INT_H */
system/stack/smp/smp_keys.cc +36 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,19 @@ static void smp_process_private_key(tSMP_CB* p_cb); #define SMP_PASSKEY_MASK 0xfff00000 // If there is data saved here, then use its info instead // This needs to be cleared on a successfult pairing using the oob data static tSMP_LOC_OOB_DATA saved_local_oob_data = {}; void smp_save_local_oob_data(tSMP_CB* p_cb) { saved_local_oob_data = p_cb->sc_oob_data.loc_oob_data; } static bool is_empty(tSMP_LOC_OOB_DATA* data) { tSMP_LOC_OOB_DATA empty_data = {}; return memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0; } void smp_debug_print_nbyte_little_endian(uint8_t* p, const char* key_name, uint8_t len) { } Loading Loading @@ -574,6 +587,29 @@ Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb) { void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { SMP_TRACE_DEBUG("%s", __func__); // Only use the stored OOB data if we are in an oob association model if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { LOG_WARN("OOB Association Model"); // Make sure our data isn't empty, otherwise we generate new and eventually // pairing will fail Not much we can do about it at this point, just have to // generate new data The data will be cleared after the advertiser times // out, so if the advertiser times out we want the pairing to fail anyway. if (!is_empty(&saved_local_oob_data)) { LOG_WARN("Found OOB data, loading keys"); memcpy(p_cb->private_key, saved_local_oob_data.private_key_used, BT_OCTET32_LEN); memcpy(p_cb->loc_publ_key.x, saved_local_oob_data.publ_key_used.x, BT_OCTET32_LEN); memcpy(p_cb->loc_publ_key.y, saved_local_oob_data.publ_key_used.y, BT_OCTET32_LEN); p_cb->sc_oob_data.loc_oob_data = saved_local_oob_data; p_cb->local_random = saved_local_oob_data.randomizer; smp_process_private_key(p_cb); return; } LOG_WARN("OOB Association Model with no saved data present"); } btsnd_hcic_ble_rand(Bind( [](tSMP_CB* p_cb, BT_OCTET8 rand) { memcpy((void*)p_cb->private_key, rand, BT_OCTET8_LEN); Loading