Skip to content

Commit 2466411

Browse files
authored
Merge pull request #13037 from paul-szczepanek-arm/ble-sm-fix
BLE: Fix privacy and signing handling in Security Manager
2 parents 6a431ff + 9d54c56 commit 2466411

File tree

11 files changed

+236
-15
lines changed

11 files changed

+236
-15
lines changed

features/FEATURE_BLE/ble/SecurityManager.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,22 @@ class SecurityManager {
285285
(void)result;
286286
}
287287

288+
/**
289+
* Indicate that a peer address has been saved by the security manager or if we are
290+
* bonded to the peer the identity has been retrieved from the database on connection.
291+
*
292+
* @param[in] connectionHandle Connection handle.
293+
* @param[in] peer_address Peer address that has been saved by the security database, NULL it not found.
294+
* @param[in] address_is_public Address type, true if public. Invalid if peer_address NULL.
295+
*/
296+
virtual void peerIdentity(ble::connection_handle_t connectionHandle,
297+
const address_t *peer_address,
298+
bool address_is_public) {
299+
(void)connectionHandle;
300+
(void)peer_address;
301+
(void)address_is_public;
302+
}
303+
288304
////////////////////////////////////////////////////////////////////////////
289305
// Security
290306
//
@@ -561,6 +577,14 @@ class SecurityManager {
561577
*/
562578
ble_error_t setPairingRequestAuthorisation(bool required = true);
563579

580+
/**
581+
* Retrieve identity address for the peer on the given connection.
582+
*
583+
* @param[in] connectionHandle Handle to identify the connection.
584+
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
585+
*/
586+
ble_error_t getPeerIdentity(ble::connection_handle_t connectionHandle);
587+
564588
////////////////////////////////////////////////////////////////////////////
565589
// Feature support
566590
//
@@ -899,6 +923,10 @@ class SecurityManager {
899923
ble::connection_handle_t connectionHandle
900924
);
901925

926+
ble_error_t getPeerIdentity_(
927+
ble::connection_handle_t connectionHandle
928+
);
929+
902930
ble_error_t setPairingRequestAuthorisation_(
903931
bool required
904932
);

features/FEATURE_BLE/ble/generic/FileSecurityDb.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ class FileSecurityDb : public SecurityDb {
3434
size_t file_offset;
3535
};
3636

37-
static const size_t MAX_ENTRIES = 5;
38-
3937
static entry_t* as_entry(entry_handle_t db_handle) {
4038
return reinterpret_cast<entry_t*>(db_handle);
4139
}
@@ -118,6 +116,21 @@ class FileSecurityDb : public SecurityDb {
118116
sign_count_t sign_counter
119117
);
120118

119+
/* local csrk and identity */
120+
121+
virtual void set_local_csrk(
122+
const csrk_t &csrk
123+
);
124+
125+
virtual void set_local_identity(
126+
const irk_t &irk,
127+
const address_t &identity_address,
128+
bool public_address
129+
);
130+
131+
/* I am not overriding set_local_sign_counter to avoid constant filesystem writes,
132+
* instead this is synced by sync (which is called on disconnection) */
133+
121134
/* saving and loading from nvm */
122135

123136
virtual void restore();
@@ -146,7 +159,7 @@ class FileSecurityDb : public SecurityDb {
146159
static FILE* erase_db_file(FILE* db_file);
147160

148161
private:
149-
entry_t _entries[MAX_ENTRIES];
162+
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
150163
FILE *_db_file;
151164
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
152165
};

features/FEATURE_BLE/ble/generic/GenericSecurityManager.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ class GenericSecurityManager :
124124
bool required = true
125125
);
126126

127+
ble_error_t getPeerIdentity_(
128+
connection_handle_t connection
129+
);
130+
127131
////////////////////////////////////////////////////////////////////////////
128132
// Feature support
129133
//
@@ -321,6 +325,13 @@ class GenericSecurityManager :
321325
*/
322326
ble_error_t init_signing();
323327

328+
/**
329+
* Generate the IRK if needed.
330+
*
331+
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
332+
*/
333+
ble_error_t init_identity();
334+
324335
/**
325336
* Fills the buffer with the specified number of bytes of random data
326337
* produced by the link controller

features/FEATURE_BLE/ble/generic/MemorySecurityDb.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ class MemorySecurityDb : public SecurityDb {
3434
SecurityEntrySigning_t peer_signing;
3535
};
3636

37-
static const size_t MAX_ENTRIES = 5;
38-
3937
static entry_t* as_entry(entry_handle_t db_handle)
4038
{
4139
return reinterpret_cast<entry_t*>(db_handle);
@@ -150,11 +148,11 @@ class MemorySecurityDb : public SecurityDb {
150148

151149
private:
152150
virtual uint8_t get_entry_count() {
153-
return MAX_ENTRIES;
151+
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
154152
}
155153

156154
virtual SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) {
157-
if (index < MAX_ENTRIES) {
155+
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
158156
return &_entries[index].flags;
159157
} else {
160158
return NULL;
@@ -187,7 +185,7 @@ class MemorySecurityDb : public SecurityDb {
187185
};
188186

189187
private:
190-
entry_t _entries[MAX_ENTRIES];
188+
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
191189
};
192190

193191
} /* namespace pal */

features/FEATURE_BLE/ble/generic/SecurityDb.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,31 @@ class SecurityDb {
425425
_local_sign_counter = sign_counter;
426426
}
427427

428+
/* local identity */
429+
/**
430+
* Update the local identity.
431+
*
432+
* @param[in] csrk new CSRK value
433+
*/
434+
virtual void set_local_identity(
435+
const irk_t &irk,
436+
const address_t &identity_address,
437+
bool public_address
438+
) {
439+
_local_identity.irk = irk;
440+
_local_identity.identity_address = identity_address;
441+
_local_identity.identity_address_is_public = public_address;
442+
}
443+
444+
/**
445+
* Return local irk.
446+
*
447+
* @return irk
448+
*/
449+
virtual irk_t get_local_irk() {
450+
return _local_identity.irk;
451+
}
452+
428453
/* list management */
429454

430455
/**
@@ -592,6 +617,21 @@ class SecurityDb {
592617
continue;
593618
}
594619

620+
// Add the connection address
621+
whitelist->addresses[whitelist->size].address = flags->peer_address.data();
622+
623+
if (flags->peer_address_is_public) {
624+
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC;
625+
} else {
626+
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM;
627+
}
628+
629+
whitelist->size++;
630+
if (whitelist->size == whitelist->capacity) {
631+
break;
632+
}
633+
634+
// Add the identity address
595635
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
596636
if (!identity) {
597637
continue;

features/FEATURE_BLE/ble/pal/PalSecurityManager.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,23 @@ class SecurityManager : private mbed::NonCopyable<SecurityManager<Impl, EventHan
964964
ble_error_t set_private_address_timeout(
965965
uint16_t timeout_in_seconds
966966
) {
967-
return impl()->set_private_address_timeout(timeout_in_seconds);
967+
return impl()->set_private_address_timeout_(timeout_in_seconds);
968+
}
969+
970+
/**
971+
* Retrieve the identity address used by the controller
972+
*
973+
* @param address Will contain the address retrieved.
974+
* @param public_address will be true if the address is public and false
975+
* otherwise.
976+
* @return BLE_ERROR_NONE On success, else an error code indicating the reason
977+
* of the failure
978+
*/
979+
ble_error_t get_identity_address(
980+
address_t& address,
981+
bool& public_address
982+
) {
983+
return impl()->get_identity_address_(address, public_address);
968984
}
969985

970986
////////////////////////////////////////////////////////////////////////////

features/FEATURE_BLE/mbed_lib.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@
7171
"help": "Include periodic advertising support, depends on the extended advertising feature.",
7272
"value": true,
7373
"macro_name": "BLE_FEATURE_PERIODIC_ADVERTISING"
74+
},
75+
"ble-security-database-max-entries": {
76+
"help": "How many entries can be stored in the db, depends on security manager.",
77+
"value": 5,
78+
"macro_name": "BLE_SECURITY_DATABASE_MAX_ENTRIES"
7479
}
7580
}
7681
}

features/FEATURE_BLE/source/generic/FileSecurityDb.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t DB_VERSION = 1;
5454
)
5555

5656
#define DB_SIZE_STORES \
57-
(FileSecurityDb::MAX_ENTRIES * DB_SIZE_STORE)
57+
(BLE_SECURITY_DATABASE_MAX_ENTRIES * DB_SIZE_STORE)
5858

5959
#define DB_OFFSET_VERSION (0)
6060
#define DB_OFFSET_RESTORE (DB_OFFSET_VERSION + sizeof(DB_VERSION))
@@ -265,6 +265,22 @@ void FileSecurityDb::set_entry_peer_sign_counter(
265265
}
266266
}
267267

268+
void FileSecurityDb::set_local_csrk(
269+
const csrk_t &csrk
270+
) {
271+
this->SecurityDb::set_local_csrk(csrk);
272+
db_write(&_local_csrk, DB_OFFSET_LOCAL_CSRK);
273+
}
274+
275+
void FileSecurityDb::set_local_identity(
276+
const irk_t &irk,
277+
const address_t &identity_address,
278+
bool public_address
279+
) {
280+
this->SecurityDb::set_local_identity(irk, identity_address, public_address);
281+
db_write(&_local_identity, DB_OFFSET_LOCAL_IDENTITY);
282+
}
283+
268284
/* saving and loading from nvm */
269285

270286
void FileSecurityDb::restore() {
@@ -299,6 +315,7 @@ void FileSecurityDb::sync(entry_handle_t db_handle) {
299315

300316
db_write(&entry->peer_sign_counter, entry->file_offset + DB_STORE_OFFSET_PEER_SIGNING_COUNT);
301317
db_write(&entry->flags, entry->file_offset + DB_STORE_OFFSET_FLAGS);
318+
db_write(&_local_sign_counter, DB_OFFSET_LOCAL_SIGN_COUNT);
302319
}
303320

304321
void FileSecurityDb::set_restore(bool reload) {
@@ -308,11 +325,11 @@ void FileSecurityDb::set_restore(bool reload) {
308325
/* helper functions */
309326

310327
uint8_t FileSecurityDb::get_entry_count() {
311-
return MAX_ENTRIES;
328+
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
312329
}
313330

314331
SecurityDistributionFlags_t* FileSecurityDb::get_entry_handle_by_index(uint8_t index) {
315-
if (index < MAX_ENTRIES) {
332+
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
316333
return &_entries[index].flags;
317334
} else {
318335
return NULL;

0 commit comments

Comments
 (0)