Skip to content

Commit 3ac37dc

Browse files
authored
Merge pull request #13660 from pan-/host-privacy-fixes
BLE: Retrieve correct DB entry when RPA used
2 parents 734f238 + 531ed63 commit 3ac37dc

File tree

4 files changed

+106
-51
lines changed

4 files changed

+106
-51
lines changed

connectivity/FEATURE_BLE/source/generic/GapImpl.cpp

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,43 +1260,24 @@ void Gap::on_connection_complete(const GapConnectionCompleteEvent &e)
12601260
}
12611261
#endif // BLE_ROLE_PERIPHERAL
12621262

1263-
ble::address_t address;
1264-
if (_address_type == own_address_type_t::PUBLIC) {
1265-
address = _pal_gap.get_device_address();
1266-
} else {
1267-
address = _pal_gap.get_random_address();
1268-
}
1269-
1270-
// signal internal stack
1271-
if (_connection_event_handler) {
1272-
_connection_event_handler->on_connected(
1273-
e.connection_handle,
1274-
e.role,
1275-
e.peer_address_type,
1276-
e.peer_address,
1277-
_address_type,
1278-
address
1279-
);
1280-
}
1263+
ConnectionCompleteEvent event(
1264+
BLE_ERROR_NONE,
1265+
e.connection_handle,
1266+
e.role,
1267+
e.peer_address_type,
1268+
e.peer_address,
1269+
e.local_resolvable_private_address,
1270+
e.peer_resolvable_private_address,
1271+
conn_interval_t(e.connection_interval),
1272+
e.connection_latency,
1273+
supervision_timeout_t(e.supervision_timeout),
1274+
/* default master clock accuracy */ ble::clock_accuracy_t::PPM_500
1275+
);
12811276

1282-
// signal application
12831277
if (_event_handler) {
1284-
ConnectionCompleteEvent event(
1285-
BLE_ERROR_NONE,
1286-
e.connection_handle,
1287-
e.role,
1288-
e.peer_address_type,
1289-
e.peer_address,
1290-
e.local_resolvable_private_address,
1291-
e.peer_resolvable_private_address,
1292-
conn_interval_t(e.connection_interval),
1293-
e.connection_latency,
1294-
supervision_timeout_t(e.supervision_timeout),
1295-
/* default master clock accuracy */ ble::clock_accuracy_t::PPM_500
1296-
);
1297-
signal_connection_complete(
1298-
event
1299-
);
1278+
signal_connection_complete(event);
1279+
} else {
1280+
report_internal_connection_complete(event);
13001281
}
13011282
}
13021283

@@ -2204,6 +2185,30 @@ void Gap::on_extended_advertising_report(
22042185
}
22052186

22062187
#if BLE_FEATURE_CONNECTABLE
2188+
void Gap::report_internal_connection_complete(const ConnectionCompleteEvent& event)
2189+
{
2190+
if (!_connection_event_handler || event.getStatus() != BLE_ERROR_NONE) {
2191+
return;
2192+
}
2193+
2194+
ble::address_t address;
2195+
if (_address_type == own_address_type_t::PUBLIC) {
2196+
address = _pal_gap.get_device_address();
2197+
} else {
2198+
address = _pal_gap.get_random_address();
2199+
}
2200+
2201+
_connection_event_handler->on_connected(
2202+
event.getConnectionHandle(),
2203+
event.getOwnRole(),
2204+
event.getPeerAddressType(),
2205+
event.getPeerAddress(),
2206+
_address_type,
2207+
address
2208+
);
2209+
}
2210+
2211+
22072212
void Gap::signal_connection_complete(
22082213
ConnectionCompleteEvent& event
22092214
)
@@ -2259,9 +2264,8 @@ void Gap::signal_connection_complete(
22592264

22602265
/* if successful then proceed to call the handler immediately same as for when privacy is disabled */
22612266
if (address_resolved) {
2262-
_event_handler->onConnectionComplete(
2263-
event
2264-
);
2267+
report_internal_connection_complete(event);
2268+
_event_handler->onConnectionComplete(event);
22652269
} else {
22662270
bool resolution_pending = false;
22672271
ble_error_t ret = _address_registry.queue_resolve_address(event.getPeerAddress());
@@ -2287,9 +2291,8 @@ void Gap::signal_connection_complete(
22872291
}
22882292
}
22892293
#else
2290-
_event_handler->onConnectionComplete(
2291-
event
2292-
);
2294+
report_internal_connection_complete(event);
2295+
_event_handler->onConnectionComplete(event);
22932296
#endif // BLE_FEATURE_PRIVACY
22942297
}
22952298

@@ -2329,9 +2332,8 @@ void Gap::conclude_signal_connection_complete_after_address_resolution(
23292332
}
23302333
#endif // BLE_ROLE_PERIPHERAL
23312334

2332-
_event_handler->onConnectionComplete(
2333-
event
2334-
);
2335+
report_internal_connection_complete(event);
2336+
_event_handler->onConnectionComplete(event);
23352337
#if BLE_ROLE_PERIPHERAL
23362338
#if BLE_FEATURE_SECURITY
23372339
if (resolvable_address_not_known) {

connectivity/FEATURE_BLE/source/generic/GapImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,13 @@ class Gap :
597597
ble_error_t prepare_legacy_advertising_set(const AdvertisingParameters& parameters);
598598

599599
#if BLE_FEATURE_CONNECTABLE
600+
/** Call the internal handlers that report to the security manager and GATT
601+
* that a connection has been established.
602+
*
603+
* @param report Connection event
604+
*/
605+
void report_internal_connection_complete(const ConnectionCompleteEvent& report);
606+
600607
/** Pass the connection complete event to the application. This may involve privacy resolution.
601608
*
602609
* @param report Event to be passed to the user application.

connectivity/FEATURE_BLE/source/generic/SecurityDb.h

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,26 @@ class SecurityDb {
168168
*/
169169
virtual void get_entry_local_keys(
170170
SecurityEntryKeysDbCb_t cb,
171-
entry_handle_t db_handle,
171+
entry_handle_t* db_handle,
172172
const ediv_t &ediv,
173173
const rand_t &rand
174174
) {
175-
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
175+
SecurityEntryKeys_t* keys = read_in_entry_local_keys(*db_handle);
176176
/* validate we have the correct key */
177177
if (keys && ediv == keys->ediv && rand == keys->rand) {
178-
cb(db_handle, keys);
178+
cb(*db_handle, keys);
179179
} else {
180-
cb(db_handle, NULL);
180+
// Maybe this isn't the correct entry, try to find one that matches
181+
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
182+
if (!correct_handle) {
183+
cb(*db_handle, NULL);
184+
}
185+
// Note: keys should never be null as a matching entry has been retrieved
186+
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
187+
MBED_ASSERT(keys);
188+
close_entry(*db_handle, false);
189+
*db_handle = correct_handle;
190+
cb(*db_handle, keys);
181191
}
182192
}
183193

@@ -552,17 +562,53 @@ class SecurityDb {
552562
return nullptr;
553563
}
554564

565+
/**
566+
* Find a database entry based on ediv and rand.
567+
*
568+
* @param[in] ediv E diversifier
569+
* @param[in] rand random part
570+
*
571+
* @return A handle to the entry.
572+
*/
573+
virtual entry_handle_t find_entry_by_peer_ediv_rand(
574+
const ediv_t &ediv,
575+
const rand_t &rand
576+
) {
577+
for (size_t i = 0; i < get_entry_count(); i++) {
578+
entry_handle_t db_handle = get_entry_handle_by_index(i);
579+
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
580+
581+
if (!flags || flags->connected) {
582+
continue;
583+
}
584+
585+
SecurityEntryKeys_t* keys = read_in_entry_local_keys(db_handle);
586+
if (!keys) {
587+
continue;
588+
}
589+
590+
if (keys->ediv == ediv && keys->rand == rand) {
591+
return db_handle;
592+
}
593+
}
594+
595+
return nullptr;
596+
}
597+
598+
555599
/**
556600
* Close a connection entry.
557601
*
558602
* @param[in] db_handle this handle will be freed up from the security db.
559603
*/
560-
virtual void close_entry(entry_handle_t db_handle) {
604+
virtual void close_entry(entry_handle_t db_handle, bool require_sync = true) {
561605
SecurityDistributionFlags_t* flags = get_distribution_flags(db_handle);
562606
if (flags) {
563607
flags->connected = false;
564608
}
565-
sync(db_handle);
609+
if (require_sync) {
610+
sync(db_handle);
611+
}
566612
}
567613

568614
/**

connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1935,7 +1935,7 @@ void SecurityManager::on_ltk_request(
19351935

19361936
_db->get_entry_local_keys(
19371937
mbed::callback(this, &SecurityManager::set_ltk_cb),
1938-
cb->db_entry,
1938+
&cb->db_entry,
19391939
ediv,
19401940
rand
19411941
);

0 commit comments

Comments
 (0)