Skip to content

Commit a1d055c

Browse files
add local idenitty and and csrk to security database
1 parent c7759fe commit a1d055c

File tree

10 files changed

+240
-8
lines changed

10 files changed

+240
-8
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: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ class FileSecurityDb : public SecurityDb {
118118
sign_count_t sign_counter
119119
);
120120

121+
/* local csrk and identity */
122+
123+
virtual void set_local_csrk(
124+
const csrk_t &csrk
125+
);
126+
127+
virtual void set_local_sign_counter(
128+
sign_count_t sign_counter
129+
);
130+
131+
virtual void set_local_identity(
132+
const irk_t &irk,
133+
const address_t &identity_address,
134+
bool public_address
135+
);
136+
121137
/* saving and loading from nvm */
122138

123139
virtual void restore();
@@ -146,7 +162,7 @@ class FileSecurityDb : public SecurityDb {
146162
static FILE* erase_db_file(FILE* db_file);
147163

148164
private:
149-
entry_t _entries[MAX_ENTRIES];
165+
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
150166
FILE *_db_file;
151167
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
152168
};

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/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: 26 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,29 @@ 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_sign_counter(
276+
sign_count_t sign_counter
277+
) {
278+
this->SecurityDb::set_local_sign_counter(sign_counter);
279+
db_write(&_local_sign_counter, DB_OFFSET_LOCAL_SIGN_COUNT);
280+
}
281+
282+
void FileSecurityDb::set_local_identity(
283+
const irk_t &irk,
284+
const address_t &identity_address,
285+
bool public_address
286+
) {
287+
this->SecurityDb::set_local_identity(irk, identity_address, public_address);
288+
db_write(&_local_identity, DB_OFFSET_LOCAL_IDENTITY);
289+
}
290+
268291
/* saving and loading from nvm */
269292

270293
void FileSecurityDb::restore() {
@@ -308,11 +331,11 @@ void FileSecurityDb::set_restore(bool reload) {
308331
/* helper functions */
309332

310333
uint8_t FileSecurityDb::get_entry_count() {
311-
return MAX_ENTRIES;
334+
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
312335
}
313336

314337
SecurityDistributionFlags_t* FileSecurityDb::get_entry_handle_by_index(uint8_t index) {
315-
if (index < MAX_ENTRIES) {
338+
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
316339
return &_entries[index].flags;
317340
} else {
318341
return NULL;

features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,19 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_(
102102
result = init_resolving_list();
103103
#endif
104104

105+
#if BLE_FEATURE_PRIVACY
106+
// set the local identity address and irk
107+
if (result != BLE_ERROR_NONE) {
108+
result = init_identity();
109+
}
110+
#endif // BLE_FEATURE_PRIVACY
111+
105112
if (result != BLE_ERROR_NONE) {
106113
delete _db;
107114
_db = NULL;
108-
return result;
109115
}
110116

111-
return BLE_ERROR_NONE;
117+
return result;
112118
}
113119

114120
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
@@ -161,7 +167,21 @@ template<template<class> class TPalSecurityManager, template<class> class Signin
161167
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::purgeAllBondingState_(void) {
162168
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
163169
_db->clear_entries();
164-
return BLE_ERROR_NONE;
170+
171+
ble_error_t ret = BLE_ERROR_NONE;
172+
173+
#if BLE_FEATURE_SIGNING
174+
// generate new csrk and irk
175+
ret = init_signing();
176+
if (ret) {
177+
return ret;
178+
}
179+
#endif // BLE_FEATURE_SIGNING
180+
#if BLE_FEATURE_PRIVACY
181+
ret = init_identity();
182+
#endif // BLE_FEATURE_PRIVACY
183+
184+
return ret;
165185
}
166186

167187
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
@@ -309,6 +329,33 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::setPair
309329
return BLE_ERROR_NONE;
310330
}
311331

332+
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
333+
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::getPeerIdentity_(connection_handle_t connection) {
334+
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
335+
if (eventHandler) {
336+
ControlBlock_t *cb = get_control_block(connection);
337+
if (!cb) {
338+
return BLE_ERROR_INVALID_PARAM;
339+
}
340+
341+
_db->get_entry_identity(
342+
[connection,this](SecurityDb::entry_handle_t handle, const SecurityEntryIdentity_t* identity) {
343+
if (eventHandler) {
344+
eventHandler->peerIdentity(
345+
connection,
346+
identity ? &identity->identity_address : nullptr,
347+
identity ? identity->identity_address_is_public : false
348+
);
349+
}
350+
},
351+
cb->db_entry
352+
);
353+
return BLE_ERROR_NONE;
354+
} else {
355+
return BLE_ERROR_INVALID_STATE;
356+
}
357+
}
358+
312359
////////////////////////////////////////////////////////////////////////////
313360
// Feature support
314361
//
@@ -901,6 +948,33 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_si
901948
return _pal.set_csrk(*pcsrk, local_sign_counter);
902949
}
903950

951+
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
952+
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_identity() {
953+
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
954+
const irk_t *pirk = nullptr;
955+
956+
irk_t irk = _db->get_local_irk();
957+
if (irk != irk_t()) {
958+
pirk = &irk;
959+
} else {
960+
ble_error_t ret = get_random_data(irk.data(), irk.size());
961+
if (ret != BLE_ERROR_NONE) {
962+
return ret;
963+
}
964+
965+
pirk = &irk;
966+
address_t identity_address;
967+
bool public_address;
968+
ret = _pal.get_identity_address(identity_address, public_address);
969+
if (ret != BLE_ERROR_NONE) {
970+
return ret;
971+
}
972+
_db->set_local_identity(irk, identity_address, public_address);
973+
}
974+
975+
return _pal.set_irk(*pirk);
976+
}
977+
904978
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
905979
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::get_random_data(uint8_t *buffer, size_t size) {
906980
byte_array_t<8> random_data;

features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalSecurityManager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ class CordioSecurityManager : public ::ble::pal::SecurityManager<CordioSecurityM
212212
*/
213213
ble_error_t set_private_address_timeout_(uint16_t timeout_in_seconds);
214214

215+
/**
216+
* @see ::ble::pal::SecurityManager::get_identity_address
217+
*/
218+
ble_error_t get_identity_address_(address_t& address, bool& public_address);
219+
215220
////////////////////////////////////////////////////////////////////////////
216221
// Keys
217222
//

features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioPalSecurityManager.tpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,20 @@ ble_error_t CordioSecurityManager<EventHandler>::set_private_address_timeout_(
279279
return BLE_ERROR_NONE;
280280
}
281281

282+
/**
283+
* @see ::ble::pal::SecurityManager::get_identity_address
284+
*/
285+
template <class EventHandler>
286+
ble_error_t CordioSecurityManager<EventHandler>::get_identity_address_(
287+
address_t& address,
288+
bool& public_address
289+
) {
290+
// On cordio, the public address is hardcoded as the identity address.
291+
address = address_t(HciGetBdAddr());
292+
public_address = true;
293+
return BLE_ERROR_NONE;
294+
}
295+
282296
////////////////////////////////////////////////////////////////////////////
283297
// Keys
284298
//

0 commit comments

Comments
 (0)