From a7f2384e109a7e7e6451ccbebaa3c0316ee504de Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 16:52:05 +0100 Subject: [PATCH 01/24] BLE: Add default privacy configuration --- features/FEATURE_BLE/ble/Gap.h | 6 ++++++ features/FEATURE_BLE/source/Gap.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index 17abea4441..148f36edc4 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -887,6 +887,12 @@ public: */ static const uint16_t UNIT_1_25_MS = 1250; + static const PeripheralPrivacyConfiguration_t + default_peripheral_privacy_configuration; + + static const CentralPrivacyConfiguration_t + default_central_privacy_configuration; + /** * Convert milliseconds into 1.25ms units. * diff --git a/features/FEATURE_BLE/source/Gap.cpp b/features/FEATURE_BLE/source/Gap.cpp index 7643a34733..c8650f27c7 100644 --- a/features/FEATURE_BLE/source/Gap.cpp +++ b/features/FEATURE_BLE/source/Gap.cpp @@ -36,3 +36,13 @@ ble_error_t Gap::getRandomAddressType( return BLE_ERROR_INVALID_PARAM; } } + +const Gap::PeripheralPrivacyConfiguration_t Gap::default_peripheral_privacy_configuration = { + /* use_non_resolvable_random_address */ false, + /* resolution_strategy */ PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE +}; + +const Gap::CentralPrivacyConfiguration_t Gap::default_central_privacy_configuration = { + /* use_non_resolvable_random_address */ false, + /* resolution_strategy */ CentralPrivacyConfiguration_t::DO_NOT_RESOLVE +}; From 365f3d25275c1bd4fbcc59bf5ee1e925df1362de Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 16:53:31 +0100 Subject: [PATCH 02/24] BLE: Add ah in Nordic CryptoToolbox. --- .../TARGET_NRF5/source/nRF5XCrypto.cpp | 32 +++++++++++++++++ .../TARGET_NRF5/source/nRF5xCrypto.h | 34 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp index ca875d805f..090b29db62 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp @@ -37,6 +37,8 @@ #include "cmsis.h" #include "nRF5xCrypto.h" #include "platform/mbed_assert.h" +#include "nrf_soc.h" + namespace ble { namespace pal { @@ -128,6 +130,36 @@ bool CryptoToolbox::generate_shared_secret( return err ? false : true; } +bool CryptoToolbox::ah( + const ArrayView& irk, + const ArrayView& prand, + ArrayView hash +) { + // Note copy then swap operation can be optimized. + + // Note: the encryption block works in big endian; go figure. + nrf_ecb_hal_data_t ecb_hal_data; + + memcpy(ecb_hal_data.key, irk.data(), irk.size()); + swap_endian(ecb_hal_data.key, sizeof(ecb_hal_data.key)); + + memcpy(ecb_hal_data.cleartext, prand.data(), prand.size()); + memset(ecb_hal_data.cleartext + prand.size(), 0, sizeof(ecb_hal_data.cleartext) - prand.size()); + swap_endian(ecb_hal_data.cleartext, sizeof(ecb_hal_data.cleartext)); + + uint32_t err = sd_ecb_block_encrypt(&ecb_hal_data); + + if (err) { + return false; + } + + swap_endian(ecb_hal_data.ciphertext, sizeof(ecb_hal_data.ciphertext)); + + memcpy(hash.data(), ecb_hal_data.ciphertext, hash.size()); + + return true; +} + void CryptoToolbox::load_mpi(mbedtls_mpi& dest, const ArrayView& src) { ble::public_key_coord_t src_be = src.data(); diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h index 0189e44ddc..470002c7e1 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h @@ -48,6 +48,21 @@ public: */ static const ptrdiff_t lesc_key_size_ = public_key_coord_t::size_; + /** + * Size of an IRK. + */ + static const ptrdiff_t irk_size_ = irk_t::size_; + + /** + * Size of the hash generated by ah. + */ + static const ptrdiff_t hash_size_ = 3; + + /** + * Size of prand. + */ + static const ptrdiff_t prand_size_ = 3; + /** * Create a new CryptoToolbox. */ @@ -88,6 +103,25 @@ public: ArrayView shared_secret ); + /** + * Execute the function ah. This function can be used to generate private + * resolvable addresses and resolve them. + * + * @note all parameters passed and return by this fucntion are in little + * endian. + * + * @param[in] irk The key used to create hash. + * @param[in] prand The random part from which the hash will be generated. + * @param[out] hash The hash generated. + * + * @return true in case of success and false otherwise. + */ + bool ah( + const ArrayView& irk, + const ArrayView& prand, + ArrayView hash + ); + private: void load_mpi(mbedtls_mpi& dest, const ArrayView& src); From fb680db62177a1bba223a9fba6b11af0b806edbc Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 16:57:07 +0100 Subject: [PATCH 03/24] BLE: Implement resolving list in Nordic PAL security manager --- .../source/nRF5xPalSecurityManager.cpp | 91 +++++++++++++++++-- .../source/nRF5xPalSecurityManager.h | 45 +++++++++ 2 files changed, 127 insertions(+), 9 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp index dfad1a671d..ad35e29aeb 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp @@ -89,7 +89,8 @@ nRF5xSecurityManager::nRF5xSecurityManager() _io_capability(io_capability_t::NO_INPUT_NO_OUTPUT), _min_encryption_key_size(7), _max_encryption_key_size(16), - _control_blocks(NULL) + _control_blocks(NULL), + resolving_list_entry_count(0) { } @@ -141,8 +142,7 @@ ble_error_t nRF5xSecurityManager::reset() uint8_t nRF5xSecurityManager::read_resolving_list_capacity() { - // FIXME: implement with privacy - return 0; + return MAX_RESOLVING_LIST_ENTRIES; } ble_error_t nRF5xSecurityManager::add_device_to_resolving_list( @@ -150,22 +150,95 @@ ble_error_t nRF5xSecurityManager::add_device_to_resolving_list( const address_t &peer_identity_address, const irk_t &peer_irk ) { - // FIXME: implement with privacy - return BLE_ERROR_NOT_IMPLEMENTED; + if (resolving_list_entry_count >= MAX_RESOLVING_LIST_ENTRIES) { + return BLE_ERROR_INVALID_STATE; + } + + resolving_list_entry_t& entry = resolving_list[resolving_list_entry_count]; + entry.peer_identity_address_type = peer_identity_address_type; + entry.peer_identity_address = peer_identity_address; + entry.peer_irk = peer_irk; + + ++resolving_list_entry_count; + + return BLE_ERROR_NONE; } ble_error_t nRF5xSecurityManager::remove_device_from_resolving_list( advertising_peer_address_type_t peer_identity_address_type, const address_t &peer_identity_address ) { - // FIXME: implement with privacy - return BLE_ERROR_NOT_IMPLEMENTED; + size_t entry_index; + + // first the index needs to be found + for (entry_index = 0; entry_index < resolving_list_entry_count; ++entry_index) { + resolving_list_entry_t& entry = resolving_list[entry_index]; + if (entry.peer_identity_address_type == peer_identity_address_type && + entry.peer_identity_address == peer_identity_address + ) { + break; + } + } + + if (entry_index == resolving_list_entry_count) { + return BLE_ERROR_INVALID_PARAM; + } + + // Elements after the entry can be moved in the list + for (size_t i = entry_index; i < (resolving_list_entry_count - 1); ++i) { + resolving_list[i] = resolving_list[i + 1]; + } + + --resolving_list_entry_count; + + return BLE_ERROR_NONE; } ble_error_t nRF5xSecurityManager::clear_resolving_list() { - // FIXME: implement with privacy - return BLE_ERROR_NOT_IMPLEMENTED; + resolving_list_entry_count = 0; + return BLE_ERROR_NONE; +} + +void nRF5xSecurityManager::get_resolving_list( + size_t& count, + const resolving_list_entry_t*& entries +) { + count = resolving_list_entry_count; + entries = resolving_list; +} + +bool nRF5xSecurityManager::resolve_address( + const address_t& resolvable_address, + advertising_peer_address_type_t& resolved_address_type, + address_t& resolved_address +) { + typedef byte_array_t hash_t; + + for (size_t i = 0; i < resolving_list_entry_count; ++i) { + resolving_list_entry_t& entry = resolving_list[i]; + hash_t hash_generated; + + // Compute the hash part from the random address part when the irk of + // the entry is used + _crypto.ah( + make_const_ArrayView(entry.peer_irk), + make_const_ArrayView( + resolvable_address.data() + CryptoToolbox::hash_size_ + ), + make_ArrayView(hash_generated) + ); + + // Compare hash generated with the hash present in the address passed as + // parameter. If they are equal then the IRK of the entry has been used + // to generate the resolvable address. + if (memcmp(hash_generated.data(), resolvable_address.data(), CryptoToolbox::hash_size_) == 0) { + resolved_address_type = entry.peer_identity_address_type; + resolved_address = entry.peer_identity_address; + return true; + } + } + return false; } //////////////////////////////////////////////////////////////////////////// diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h index 35de6ba86b..443fa19130 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h @@ -83,6 +83,46 @@ public: */ virtual ble_error_t clear_resolving_list(); + /** + * An entry of the resolving list stored in the SecurityManager. + */ + struct resolving_list_entry_t { + resolving_list_entry_t() : + peer_identity_address_type( + advertising_peer_address_type_t::PUBLIC_ADDRESS + ) + { } + + irk_t peer_irk; + address_t peer_identity_address; + advertising_peer_address_type_t peer_identity_address_type; + }; + + /** + * Return the IRKs present in the resolving list + * @param count The number of entries present in the resolving list. + * @param pointer to the first entry of the resolving list. + */ + void get_resolving_list( + size_t& count, + const resolving_list_entry_t*& entries + ); + + /** + * Try to resolve a private resolvable address. + * + * @param resolvable_address The address to resolve. + * @param resolved_address_type The type of the identity address resolved. + * @param resolved_address The identity address resolved. + * @return True if the address has been resolved and false otherwise. + */ + bool resolve_address( + const address_t& resolvable_address, + advertising_peer_address_type_t& resolved_address_type, + address_t& resolved_address + ); + + //////////////////////////////////////////////////////////////////////////// // Pairing // @@ -351,6 +391,11 @@ private: ble::public_key_coord_t X; ble::public_key_coord_t Y; ble::public_key_coord_t secret; + + static const size_t MAX_RESOLVING_LIST_ENTRIES = BLE_GAP_WHITELIST_IRK_MAX_COUNT; + + size_t resolving_list_entry_count; + resolving_list_entry_t resolving_list[MAX_RESOLVING_LIST_ENTRIES]; }; } // nordic From a18283d897749a776bd3763b04e06884aed1bac4 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 18:15:32 +0100 Subject: [PATCH 04/24] BLE: change nRF5xSecurityManager::get_resolving_list return It now returns a resolving list entry. --- .../TARGET_NRF5/source/nRF5xPalSecurityManager.cpp | 12 ++++++------ .../TARGET_NRF5/source/nRF5xPalSecurityManager.h | 5 +---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp index ad35e29aeb..e63345900e 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp @@ -200,12 +200,12 @@ ble_error_t nRF5xSecurityManager::clear_resolving_list() return BLE_ERROR_NONE; } -void nRF5xSecurityManager::get_resolving_list( - size_t& count, - const resolving_list_entry_t*& entries -) { - count = resolving_list_entry_count; - entries = resolving_list; +ArrayView +nRF5xSecurityManager::get_resolving_list() { + return ArrayView( + resolving_list, + resolving_list_entry_count + ); } bool nRF5xSecurityManager::resolve_address( diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h index 443fa19130..d358af79b2 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h @@ -103,10 +103,7 @@ public: * @param count The number of entries present in the resolving list. * @param pointer to the first entry of the resolving list. */ - void get_resolving_list( - size_t& count, - const resolving_list_entry_t*& entries - ); + ArrayView get_resolving_list(); /** * Try to resolve a private resolvable address. From 2a9d80c5f04f782c9b97b58b85ab559c5445c133 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 18:16:36 +0100 Subject: [PATCH 05/24] BLE: Change nRF5xSecurityManager::resolve_address signature Return the resolving list entry instead of accepting in parameters. --- .../source/nRF5xPalSecurityManager.cpp | 15 ++++++--------- .../TARGET_NRF5/source/nRF5xPalSecurityManager.h | 11 ++++------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp index e63345900e..fec4ff6885 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.cpp @@ -208,11 +208,8 @@ nRF5xSecurityManager::get_resolving_list() { ); } -bool nRF5xSecurityManager::resolve_address( - const address_t& resolvable_address, - advertising_peer_address_type_t& resolved_address_type, - address_t& resolved_address -) { +const nRF5xSecurityManager::resolving_list_entry_t* +nRF5xSecurityManager::resolve_address(const address_t& resolvable_address) { typedef byte_array_t hash_t; for (size_t i = 0; i < resolving_list_entry_count; ++i) { @@ -233,14 +230,14 @@ bool nRF5xSecurityManager::resolve_address( // parameter. If they are equal then the IRK of the entry has been used // to generate the resolvable address. if (memcmp(hash_generated.data(), resolvable_address.data(), CryptoToolbox::hash_size_) == 0) { - resolved_address_type = entry.peer_identity_address_type; - resolved_address = entry.peer_identity_address; - return true; + return &entry; } } - return false; + return NULL; } + + //////////////////////////////////////////////////////////////////////////// // Pairing // diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h index d358af79b2..bd9206b790 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xPalSecurityManager.h @@ -109,14 +109,11 @@ public: * Try to resolve a private resolvable address. * * @param resolvable_address The address to resolve. - * @param resolved_address_type The type of the identity address resolved. - * @param resolved_address The identity address resolved. - * @return True if the address has been resolved and false otherwise. + * + * @return Pointer to the entry found if any. */ - bool resolve_address( - const address_t& resolvable_address, - advertising_peer_address_type_t& resolved_address_type, - address_t& resolved_address + const resolving_list_entry_t* resolve_address( + const address_t& resolvable_address ); From b3c871c9602268ea7d581a0ef91e9dad1dee0cab Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 16 Apr 2018 18:17:17 +0100 Subject: [PATCH 06/24] BLE: Implement privacy on Nordic targets. --- .../TARGET_NRF5/source/btle/btle.cpp | 52 +-- .../TARGET_NRF5/source/nRF5xGap.cpp | 432 +++++++++++++++--- .../TARGET_NRF5/source/nRF5xGap.h | 45 +- 3 files changed, 397 insertions(+), 132 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp index 32e1e3df0c..8839fd19db 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp @@ -61,7 +61,7 @@ void app_error_handler(uint32_t error_code, uint32_t line_num, const extern "C" void SD_EVT_IRQHandler(void); // export the softdevice event handler for registration by nvic-set-vector. -static void btle_handler(ble_evt_t *p_ble_evt); +void btle_handler(ble_evt_t *p_ble_evt); static void sys_evt_dispatch(uint32_t sys_evt) { @@ -161,7 +161,7 @@ error_t btle_init(void) return btle_gap_init(); } -static void btle_handler(ble_evt_t *p_ble_evt) +void btle_handler(ble_evt_t *p_ble_evt) { using ble::pal::vendor::nordic::nRF5XGattClient; using ble::pal::vendor::nordic::nRF5xSecurityManager; @@ -189,38 +189,12 @@ static void btle_handler(ble_evt_t *p_ble_evt) /* Custom event handler */ switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: { - Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; -#if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110) - /* Only peripheral role is supported by S110 */ - Gap::Role_t role = Gap::PERIPHERAL; -#else - Gap::Role_t role = static_cast(p_ble_evt->evt.gap_evt.params.connected.role); -#endif - gap.setConnectionHandle(handle); - const Gap::ConnectionParams_t *params = reinterpret_cast(&(p_ble_evt->evt.gap_evt.params.connected.conn_params)); - const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr; -#if (NRF_SD_BLE_API_VERSION <= 2) - const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr; - - gap.processConnectionEvent(handle, - role, - static_cast(peer->addr_type), peer->addr, - static_cast(own->addr_type), own->addr, - params); -#else - Gap::AddressType_t addr_type; - Gap::Address_t own_address; - gap.getAddress(&addr_type, own_address); - - gap.processConnectionEvent(handle, - role, - static_cast(peer->addr_type), peer->addr, - addr_type, own_address, - params); -#endif + case BLE_GAP_EVT_CONNECTED: + gap.on_connection( + p_ble_evt->evt.gap_evt.conn_handle, + p_ble_evt->evt.gap_evt.params.connected + ); break; - } case BLE_GAP_EVT_DISCONNECTED: { Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; @@ -266,17 +240,9 @@ static void btle_handler(ble_evt_t *p_ble_evt) // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION)); break; - case BLE_GAP_EVT_ADV_REPORT: { - const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report; - gap.processAdvertisementReport(advReport->peer_addr.addr, - advReport->rssi, - advReport->scan_rsp, - static_cast(advReport->type), - advReport->dlen, - advReport->data, - static_cast(advReport->peer_addr.addr_type)); + case BLE_GAP_EVT_ADV_REPORT: + gap.on_advertising_packet(p_ble_evt->evt.gap_evt.params.adv_report); break; - } default: break; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp index bb38334b59..3d3c085adc 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp @@ -26,7 +26,66 @@ #include "ble_advdata.h" #include "headers/nrf_ble_hci.h" #include "ble/pal/ConnectionEventMonitor.h" +#include "nRF5XPalSecurityManager.h" +using ble::pal::vendor::nordic::nRF5xSecurityManager; +typedef nRF5xSecurityManager::resolving_list_entry_t resolving_list_entry_t; +using ble::ArrayView; +using ble::pal::advertising_peer_address_type_t; + +namespace { + +nRF5xSecurityManager& get_sm() { + return nRF5xSecurityManager::get_security_manager(); +} + +void set_private_resolvable_address() { + ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE }; + sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); +} + +void set_private_non_resolvable_address() { + ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE }; + sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr); +} + +bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) { + switch (params.getAdvertisingType()) { + case GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED: + case GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED: + return true; + default: + return false; + } +} + +bool is_identity_address(BLEProtocol::AddressType_t address_type) { + switch (address_type) { + case BLEProtocol::AddressType::PUBLIC_IDENTITY: + case BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY: + return true; + default: + return false; + } +} + +BLEProtocol::AddressType_t convert_nordic_address(uint8_t address) { + if (address == BLE_GAP_ADDR_TYPE_PUBLIC) { + return BLEProtocol::AddressType::PUBLIC; + } else { + return BLEProtocol::AddressType::RANDOM; + } +} + +BLEProtocol::AddressType_t convert_identity_address(advertising_peer_address_type_t address) { + if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) { + return BLEProtocol::AddressType::PUBLIC_IDENTITY; + } else { + return BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY; + } +} + +} // namespace void radioNotificationStaticCallback(bool param) { nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); @@ -40,7 +99,11 @@ nRF5xGap::nRF5xGap() : Gap(), whitelistAddresses(), radioNotificationCallbackParam(false), radioNotificationTimeout(), - _connection_event_handler(NULL) + _connection_event_handler(NULL), + _privacy_enabled(false), + _peripheral_privacy_configuration(default_peripheral_privacy_configuration), + _central_privacy_configuration(default_central_privacy_configuration), + _non_private_type(BLEProtocol::AddressType::RANDOM) { m_connectionHandle = BLE_CONN_HANDLE_INVALID; } @@ -204,6 +267,29 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) } } + if (_privacy_enabled) { + if (_peripheral_privacy_configuration.resolution_strategy != PeripheralPrivacyConfiguration_t::DO_NOT_RESOLVE) { + ArrayView entries = get_sm().get_resolving_list(); + + size_t limit = std::min( + entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE + ); + + for (size_t i = 0; i < limit; ++i) { + whitelistIrkPtrs[i] = (ble_gap_irk_t*) entries[i].peer_irk.data(); + } + whitelist.irk_count = limit; + } + + if (_peripheral_privacy_configuration.use_non_resolvable_random_address && + is_advertising_non_connectable(params) + ) { + set_private_non_resolvable_address(); + } else { + set_private_resolvable_address(); + } + } + adv_para.p_whitelist = &whitelist; #endif /* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */ @@ -255,6 +341,8 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) } } + // FIXME: fill the irk list once addresses are resolved by the softdevice. + scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ #else @@ -270,6 +358,14 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) scanParams.window = scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ scanParams.timeout = scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ + if (_privacy_enabled) { + if (_central_privacy_configuration.use_non_resolvable_random_address) { + set_private_non_resolvable_address(); + } else { + set_private_resolvable_address(); + } + } + if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } @@ -318,6 +414,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, const GapScanningParams *scanParamsIn) { ble_gap_addr_t addr; + ble_gap_addr_t* addr_ptr = &addr; addr.addr_type = peerAddrType; memcpy(addr.addr, peerAddr, Gap::ADDR_LEN); @@ -354,9 +451,37 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, return error; } } - scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ + + if (_privacy_enabled) { + // configure the "whitelist" with the IRK associated with the identity + // address in input. + if (is_identity_address(peerAddrType)) { + ArrayView entries = get_sm().get_resolving_list(); + + size_t i; + for (i = 0; i < entries.size(); ++i) { + const ble::address_t& entry_address = entries[i].peer_identity_address; + + // entry found; fill the whitelist and invalidate addr_ptr + if (memcmp(entry_address.data(), peerAddr, entry_address.size_) == 0) { + whitelist.pp_irks[0] = (ble_gap_irk_t*) entries[i].peer_irk.data(); + whitelist.irk_count = 1; + scanParams.selective = 1; + addr_ptr = NULL; + break; + } + } + + // Occur only if the address in input hasn't been resolved. + if (i == entries.size()) { + return BLE_ERROR_INVALID_PARAM; + } + } + + set_private_resolvable_address(); + } #else /* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */ @@ -388,7 +513,7 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr, scanParams.timeout = _scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ } - uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams); + uint32_t rc = sd_ble_gap_connect(addr_ptr, &scanParams, &connParams); if (rc == NRF_SUCCESS) { return BLE_ERROR_NONE; } @@ -543,52 +668,33 @@ uint16_t nRF5xGap::getConnectionHandle(void) /**************************************************************************/ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) { -#if (NRF_SD_BLE_API_VERSION <= 2) - uint8_t cycle_mode; -#else - ble_gap_privacy_params_t privacy_params = {0}; -#endif + using BLEProtocol::AddressType; + if (type != AddressType::PUBLIC || type != AddressType::RANDOM_STATIC) { + return BLE_ERROR_INVALID_PARAM; + } + + if (_privacy_enabled) { + return BLE_ERROR_INVALID_STATE; + } ble_gap_addr_t dev_addr; + memcpy(dev_addr.addr, address, ADDR_LEN); + if (type == AddressType::PUBLIC) { + dev_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + } else { + dev_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC; + } - /* When using Public or Static addresses, the cycle mode must be None. - When using Random Private addresses, the cycle mode must be Auto. - In auto mode, the given address is ignored. - */ - if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC)) - { - memcpy(dev_addr.addr, address, ADDR_LEN); #if (NRF_SD_BLE_API_VERSION <= 2) - cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE; + ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); #else - privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; - dev_addr.addr_type = type; + // FIXME is there any reason to use the pm ? + ble_gap_privacy_params_t privacy_params = {0}; + privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; - ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); - ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); -#endif - } - else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE)) - { -#if (NRF_SD_BLE_API_VERSION <= 2) - cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO; -#else - privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY; - privacy_params.private_addr_type = type; - - ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); -#endif - // address is ignored when in auto mode - } - else - { - return BLE_ERROR_PARAM_OUT_OF_RANGE; - } - -#if (NRF_SD_BLE_API_VERSION <= 2) - dev_addr.addr_type = type; - ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE); #endif return BLE_ERROR_NONE; @@ -597,6 +703,7 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) { ble_gap_addr_t dev_addr; + #if (NRF_SD_BLE_API_VERSION <= 2) if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) { #else @@ -606,11 +713,17 @@ ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) } if (typeP != NULL) { - *typeP = static_cast(dev_addr.addr_type); + if (dev_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC){ + *typeP = BLEProtocol::AddressType::PUBLIC; + } else { + *typeP = BLEProtocol::AddressType::RANDOM; + } } + if (address != NULL) { memcpy(address, dev_addr.addr, ADDR_LEN); } + return BLE_ERROR_NONE; } @@ -939,6 +1052,55 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const return Gap::INIT_POLICY_IGNORE_WHITELIST; } +ble_error_t nRF5xGap::enablePrivacy(bool enable) +{ + if (enable == _privacy_enabled) { + return BLE_ERROR_NONE; + } + + ble_error_t err = BLE_ERROR_UNSPECIFIED; + if (enable == false) { + err = setAddress(_non_private_type, _non_private_address); + } else { + err = getAddress(&_non_private_type, _non_private_address); + } + + if (err) { + return err; + } + + _privacy_enabled = enable; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::setPeripheralPrivacyConfiguration( + const PeripheralPrivacyConfiguration_t *configuration +) { + _peripheral_privacy_configuration = *configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::getPeripheralPrivacyConfiguration( + PeripheralPrivacyConfiguration_t *configuration +) { + *configuration = _peripheral_privacy_configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::setCentralPrivacyConfiguration( + const CentralPrivacyConfiguration_t *configuration +) { + _central_privacy_configuration = *configuration; + return BLE_ERROR_NONE; +} + +ble_error_t nRF5xGap::getCentralPrivacyConfiguration( + CentralPrivacyConfiguration_t *configuration +) { + *configuration = _central_privacy_configuration; + return BLE_ERROR_NONE; +} + #if (NRF_SD_BLE_API_VERSION <= 2) /**************************************************************************/ /*! @@ -1055,38 +1217,6 @@ void nRF5xGap::set_connection_event_handler( _connection_event_handler = connection_event_handler; } -void nRF5xGap::processConnectionEvent( - Handle_t handle, - Role_t role, - BLEProtocol::AddressType_t peerAddrType, - const BLEProtocol::AddressBytes_t peerAddr, - BLEProtocol::AddressType_t ownAddrType, - const BLEProtocol::AddressBytes_t ownAddr, - const ConnectionParams_t *connectionParams -) { - if (_connection_event_handler) { - _connection_event_handler->on_connected( - handle, - role, - peerAddrType, - peerAddr, - ownAddrType, - ownAddr, - connectionParams - ); - } - - ::Gap::processConnectionEvent( - handle, - role, - peerAddrType, - peerAddr, - ownAddrType, - ownAddr, - connectionParams - ); -} - void nRF5xGap::processDisconnectionEvent( Handle_t handle, DisconnectionReason_t reason @@ -1103,3 +1233,155 @@ void nRF5xGap::processDisconnectionEvent( reason ); } + +void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t& evt) { + using BLEProtocol::AddressType; + + // set the new connection handle as the _default_ handle in gap + setConnectionHandle(handle); + + // deal with own address + AddressType_t own_addr_type; + Address_t own_address; + const uint8_t* own_resolvable_address = NULL; + +#if (NRF_SD_BLE_API_VERSION <= 2) + if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) { + own_addr_type = AddressType::PUBLIC; + } else { + own_addr_type = AddressType::RANDOM; + } + memcpy(own_address, evt.own_addr.addr, sizeof(own_address)); +#else + gap.getAddress(&addr_type, own_address); +#endif + + if (_privacy_enabled) { + own_resolvable_address = own_address; + } + + // deal with the peer address: If privacy is enabled then the softdevice + // indicates if the address has been resolved or not. If the address has + // been resolved then the identity address should be passed to the application. + // Depending on the privacy chosen by the application, connection request + // from privacy enabled peers may trigger a disconnection, the pairing procedure + // or the authentication procedure. + AddressType_t peer_addr_type; + const uint8_t* peer_address; + const uint8_t* peer_resolvable_address; + + if (evt.irk_match) { + const resolving_list_entry_t* entry = get_sm().resolve_address( + evt.peer_addr.addr + ); + MBED_ASSERT(entry == NULL); + + peer_addr_type = convert_identity_address(entry->peer_identity_address_type); + peer_address = entry->peer_identity_address.data(); + peer_resolvable_address = evt.peer_addr.addr; + } else { + if (_privacy_enabled && + evt.role == BLE_GAP_ROLE_PERIPH && + _peripheral_privacy_configuration.resolution_strategy == PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && + get_sm().get_resolving_list().size() > 0 + ) { + // FIXME: should use BLE_HCI_AUTHENTICATION_FAILURE; not possible + // with the softdevice ... + sd_ble_gap_disconnect(handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + return; + } + + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + peer_address = evt.peer_addr.addr; + peer_resolvable_address = NULL; + } + + // notify internal event handler before applying the resolution strategy + if (_connection_event_handler) { + _connection_event_handler->on_connected( + handle, + static_cast(evt.role), + peer_addr_type, + peer_address, + own_addr_type, + own_address, + reinterpret_cast(&(evt.conn_params)) + ); + } + + // Apply authentication strategy before application notification + if (!evt.irk_match && + _privacy_enabled && + evt.role == BLE_GAP_ROLE_PERIPH && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + ) { + switch (_peripheral_privacy_configuration.resolution_strategy) { + case PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE: + nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestPairing(handle); + break; + + case PeripheralPrivacyConfiguration_t::PERFORM_AUTHENTICATION_PROCEDURE: + // FIXME: lookup secure DB to know what to do. + break; + + default: + break; + } + } + + processConnectionEvent( + handle, + static_cast(evt.role), + peer_addr_type, + peer_address, + own_addr_type, + own_address, + reinterpret_cast(&(evt.conn_params)), + peer_resolvable_address, + own_resolvable_address + ); +} + +void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) { + using BLEProtocol::AddressType; + + AddressType_t peer_addr_type; + const uint8_t* peer_address = evt.peer_addr.addr; + + if (_privacy_enabled && + evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && + _central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE + ) { + using ble::pal::vendor::nordic::nRF5xSecurityManager; + + const resolving_list_entry_t* entry = get_sm().resolve_address( + peer_address + ); + + if (entry) { + peer_address = entry->peer_identity_address.data(); + peer_addr_type = convert_identity_address(entry->peer_identity_address_type); + } else if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD) { + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + } else { + // filter out the packet. + return; + } + } else { + peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type); + } + + processAdvertisementReport( + peer_address, + evt.rssi, + evt.scan_rsp, + static_cast(evt.type), + evt.dlen, + evt.data, + peer_addr_type + ); +} + + + diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h index 9a6973331c..cb12a610f2 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h @@ -122,6 +122,24 @@ public: return BLE_ERROR_UNSPECIFIED; } + virtual ble_error_t enablePrivacy(bool enable); + + virtual ble_error_t setPeripheralPrivacyConfiguration( + const PeripheralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t getPeripheralPrivacyConfiguration( + PeripheralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t setCentralPrivacyConfiguration( + const CentralPrivacyConfiguration_t *configuration + ); + + virtual ble_error_t getCentralPrivacyConfiguration( + CentralPrivacyConfiguration_t *configuration + ); + /* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */ #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); @@ -260,23 +278,10 @@ public: /** @note Implements ConnectionEventMonitor. * @copydoc ConnectionEventMonitor::set_connection_event_handler */ - void set_connection_event_handler( + virtual void set_connection_event_handler( ConnectionEventMonitor::EventHandler* connection_event_handler ); - /** - * @copydoc ::Gap::processConnectionEvent - */ - void processConnectionEvent( - Handle_t handle, - Role_t role, - BLEProtocol::AddressType_t peerAddrType, - const BLEProtocol::AddressBytes_t peerAddr, - BLEProtocol::AddressType_t ownAddrType, - const BLEProtocol::AddressBytes_t ownAddr, - const ConnectionParams_t *connectionParams - ); - /** * @copydoc ::Gap::processDisconnectionEvent */ @@ -285,10 +290,22 @@ public: DisconnectionReason_t reason ); +private: + friend void btle_handler(ble_evt_t *p_ble_evt); + + void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt); + void on_advertising_packet(const ble_gap_evt_adv_report_t &evt); + uint16_t m_connectionHandle; ConnectionEventMonitor::EventHandler* _connection_event_handler; + bool _privacy_enabled; + PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration; + CentralPrivacyConfiguration_t _central_privacy_configuration; + AddressType_t _non_private_type; + Address_t _non_private_address; + /* * Allow instantiation from nRF5xn when required. */ From 51e1c76b4ab004b26749061f6aa550ad8fb3138d Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:03:20 +0100 Subject: [PATCH 07/24] BLE: Set default mac address to all 00. --- features/FEATURE_BLE/ble/BLETypes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/ble/BLETypes.h b/features/FEATURE_BLE/ble/BLETypes.h index 41e4c99f13..0c4c894eb3 100644 --- a/features/FEATURE_BLE/ble/BLETypes.h +++ b/features/FEATURE_BLE/ble/BLETypes.h @@ -426,10 +426,10 @@ typedef uint32_t sign_count_t; */ struct address_t : public byte_array_t<6> { /** - * Create an invalid mac address, equal to FF:FF:FF:FF:FF:FF + * Create an invalid mac address, equal to 00:00:00:00:00:00 */ address_t() { - memset(_value, 0xFF, sizeof(_value)); + memset(_value, 0x00, sizeof(_value)); } /** From dfbf383614872d0eaafd646601344aec70c91eb0 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:03:57 +0100 Subject: [PATCH 08/24] BLE: Fix const correctness of ::Gap::getRandomAddressType --- features/FEATURE_BLE/ble/Gap.h | 2 +- features/FEATURE_BLE/source/Gap.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index 148f36edc4..adaf06bc44 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -1068,7 +1068,7 @@ public: * the address in input was not identifiable as a random address. */ static ble_error_t getRandomAddressType( - BLEProtocol::AddressBytes_t address, + const BLEProtocol::AddressBytes_t address, RandomAddressType_t* addressType ); diff --git a/features/FEATURE_BLE/source/Gap.cpp b/features/FEATURE_BLE/source/Gap.cpp index c8650f27c7..425f833106 100644 --- a/features/FEATURE_BLE/source/Gap.cpp +++ b/features/FEATURE_BLE/source/Gap.cpp @@ -17,7 +17,7 @@ #include "ble/Gap.h" ble_error_t Gap::getRandomAddressType( - BLEProtocol::AddressBytes_t address, + const BLEProtocol::AddressBytes_t address, RandomAddressType_t* type ) { // see section Device address in Bluetooth Link Layer specification From 9643b571592f36b48346b874dfa4e59dec2ad1ce Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:06:00 +0100 Subject: [PATCH 09/24] BLE: Remove flag SecurityDistributionFlags_t::local_address_is_public This flag was not used and not useful. --- features/FEATURE_BLE/ble/pal/SecurityDb.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/FEATURE_BLE/ble/pal/SecurityDb.h b/features/FEATURE_BLE/ble/pal/SecurityDb.h index 62f67fb95b..2de7734546 100644 --- a/features/FEATURE_BLE/ble/pal/SecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/SecurityDb.h @@ -35,7 +35,6 @@ struct SecurityDistributionFlags_t { peer_address(), encryption_key_size(0), peer_address_is_public(false), - local_address_is_public(false), csrk_stored(false), csrk_mitm_protected(false), ltk_stored(false), @@ -50,8 +49,6 @@ struct SecurityDistributionFlags_t { uint8_t encryption_key_size; /** true if peer address is public, false if it's static random */ uint8_t peer_address_is_public:1; - /** true if local address is public, false if it's static random */ - uint8_t local_address_is_public:1; /** CSRK (Connection Signature Resolving Key) has been distributed and stored */ uint8_t csrk_stored:1; From ab6821aab86610fc471ac91af92478cf4bf733b3 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:06:47 +0100 Subject: [PATCH 10/24] BLE: Add a flag indicating if irk is stored in the distribution flags. --- features/FEATURE_BLE/ble/pal/SecurityDb.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/ble/pal/SecurityDb.h b/features/FEATURE_BLE/ble/pal/SecurityDb.h index 2de7734546..023fd0bcac 100644 --- a/features/FEATURE_BLE/ble/pal/SecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/SecurityDb.h @@ -39,7 +39,8 @@ struct SecurityDistributionFlags_t { csrk_mitm_protected(false), ltk_stored(false), ltk_mitm_protected(false), - secure_connections_paired(false) { + secure_connections_paired(false), + irk_stored(false) { } /** peer address */ @@ -60,6 +61,8 @@ struct SecurityDistributionFlags_t { uint8_t ltk_mitm_protected:1; /** the current pairing was done using Secure Connections */ uint8_t secure_connections_paired:1; + /** the security entry has been distributed and stored */ + uint8_t irk_stored:1; }; /** Long Term Key and data used to identify it */ From e8041510a63ac1d217d79f5978c00d6c1a8acb83 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:07:19 +0100 Subject: [PATCH 11/24] BLE: Add a flag that indicate if the identity address is public or not. --- features/FEATURE_BLE/ble/pal/SecurityDb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/FEATURE_BLE/ble/pal/SecurityDb.h b/features/FEATURE_BLE/ble/pal/SecurityDb.h index 023fd0bcac..653ec57dec 100644 --- a/features/FEATURE_BLE/ble/pal/SecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/SecurityDb.h @@ -81,6 +81,8 @@ struct SecurityEntryIdentity_t { address_t identity_address; /** Identity Resolving Key */ irk_t irk; + /** true if peer identity address is public, false if it's static random */ + uint8_t identity_address_is_public:1; }; /** From 15fa3bfd37a66c9decfa659701ae4becd3871a47 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:08:01 +0100 Subject: [PATCH 12/24] BLE: Add a function to retrieve a device identity. --- features/FEATURE_BLE/ble/pal/SecurityDb.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/FEATURE_BLE/ble/pal/SecurityDb.h b/features/FEATURE_BLE/ble/pal/SecurityDb.h index 653ec57dec..7c6e77637e 100644 --- a/features/FEATURE_BLE/ble/pal/SecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/SecurityDb.h @@ -105,6 +105,8 @@ public: SecurityEntryKeysDbCb_t; typedef mbed::Callback SecurityEntryCsrkDbCb_t; + typedef mbed::Callback + SecurityEntryIdentityDbCb_t; typedef mbed::Callback WhitelistDbCb_t; @@ -261,6 +263,17 @@ public: const address_t &peer_address ) = 0; + /** + * Retrieve stored identity address and IRK. + * + * @param[in] cb callback that will receive the SecurityEntryIdentity_t struct + * @param[in] db_entry handle of the entry being queried. + */ + virtual void get_entry_identity( + SecurityEntryIdentityDbCb_t cb, + entry_handle_t db_entry + ) = 0; + /** * Update peer signing key. * From 6fc74fbc4464b5a94417c8b35ea00e9fe295b1e4 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:09:00 +0100 Subject: [PATCH 13/24] BLE: Fix MemorySecurityDB constructor warning. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index eb28867734..fc80e4cc45 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -49,8 +49,9 @@ private: } public: - MemorySecurityDb() { }; - virtual ~MemorySecurityDb() { }; + MemorySecurityDb() : _local_sign_counter(0) { } + + virtual ~MemorySecurityDb() { } virtual const SecurityDistributionFlags_t* get_distribution_flags( entry_handle_t entry_handle From 06e0aa3440b6183fd57a74eb0615abf1bb9a1074 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:10:19 +0100 Subject: [PATCH 14/24] BLE: flag that irk has been stored in the security entry. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 1 + 1 file changed, 1 insertion(+) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index fc80e4cc45..f71c95aeb1 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -208,6 +208,7 @@ public: if (entry) { entry->state = ENTRY_WRITTEN; entry->peer_identity.irk = irk; + entry->flags.irk_stored; } } From a3bb18d7241a45774b3dc2e55d80bc88af2a93a0 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:11:05 +0100 Subject: [PATCH 15/24] BLE: store identity address type in DB. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 1 + 1 file changed, 1 insertion(+) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index f71c95aeb1..0ffaea970d 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -221,6 +221,7 @@ public: if (entry) { entry->state = ENTRY_WRITTEN; entry->peer_identity.identity_address = peer_address; + entry->peer_identity.identity_address_is_public = address_is_public; } } From f905d2a4d446b7312e60f43f3b3908a805e4b08b Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:14:53 +0100 Subject: [PATCH 16/24] BLE: Improve DB entry lookup. The DB entry lookup now looks at the identity address and/or connection address to find a DB entry associated to an address. If the entry has not been found in the DB and a new entry is returned then the connection address is not stored for private addresses. --- .../FEATURE_BLE/ble/pal/MemorySecurityDB.h | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index 0ffaea970d..b0c6f7088e 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -274,14 +274,46 @@ public: const address_t &peer_address ) { const bool peer_address_public = - (peer_address_type == BLEProtocol::AddressType::PUBLIC); + (peer_address_type == BLEProtocol::AddressType::PUBLIC) || + (peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY); for (size_t i = 0; i < MAX_ENTRIES; i++) { - if (_entries[i].state == ENTRY_FREE) { + entry_t& e = _entries[i]; + + if (e.state == ENTRY_FREE) { continue; - } else if (peer_address == _entries[i].peer_identity.identity_address - && _entries[i].flags.peer_address_is_public == peer_address_public) { - return &_entries[i]; + } else { + if (peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY && + e.flags.irk_stored == false + ) { + continue; + } + + // lookup for the identity address then the connection address. + if (e.flags.irk_stored && + e.peer_identity.identity_address == peer_address && + e.peer_identity.identity_address_is_public == peer_address_public + ) { + return &e; + // lookup for connection address used during bonding + } else if (e.flags.peer_address == peer_address && + e.flags.peer_address_is_public == peer_address_public + ) { + return &e; + } + } + } + + // determine if the address in input is private or not. + bool is_private_address = false; + if (peer_address_type == BLEProtocol::AddressType::RANDOM) { + ::Gap::RandomAddressType_t random_type(::Gap::RandomAddressType_t::STATIC); + ble_error_t err = ::Gap::getRandomAddressType(peer_address.data(), &random_type); + if (err) { + return NULL; + } + if (random_type != ::Gap::RandomAddressType_t::STATIC) { + is_private_address = true; } } @@ -289,8 +321,14 @@ public: for (size_t i = 0; i < MAX_ENTRIES; i++) { if (_entries[i].state == ENTRY_FREE) { _entries[i] = entry_t(); - _entries[i].flags.peer_address = peer_address; - _entries[i].flags.peer_address_is_public = peer_address_public; + // do not store private addresses in the flags; just store public + // or random static address so it can be reused latter. + if (is_private_address == false) { + _entries[i].flags.peer_address = peer_address; + _entries[i].flags.peer_address_is_public = peer_address_public; + } else { + _entries[i].flags.peer_address = address_t(); + } _entries[i].state = ENTRY_RESERVED; return &_entries[i]; } From ae8d5b4de1db4d68cc6e077879bdb9d365795bd0 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:15:28 +0100 Subject: [PATCH 17/24] BLE: Implement identity retrieval in secure DB. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index b0c6f7088e..c6c627b66b 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -17,6 +17,7 @@ #ifndef PAL_MEMORY_SECURITY_DB_H_ #define PAL_MEMORY_SECURITY_DB_H_ +#include "ble/Gap.h" #include "SecurityDB.h" namespace ble { @@ -174,6 +175,19 @@ public: cb(entry_handle, key); } + virtual void get_entry_identity( + SecurityEntryIdentityDbCb_t cb, + entry_handle_t entry_handle + ) { + entry_t *entry = as_entry(entry_handle); + if (entry && entry->flags.irk_stored) { + cb(entry_handle, &entry->peer_identity); + } else { + cb(entry_handle, NULL); + } + } + + /* set */ virtual void set_entry_peer_ltk( From 77b1903634081e3228ca20d085701db315874ef6 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 14:16:35 +0100 Subject: [PATCH 18/24] BLE: Add bonded device to resolving list at the end of bonding. --- .../ble/generic/GenericSecurityManager.h | 20 +++++----------- .../source/generic/GenericSecurityManager.cpp | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index 4ca681adae..e30e4b9114 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -400,21 +400,13 @@ private: ); /** - * Inform the security manager of a new connection. - * - * @param[in] params information about the new connection. + * Callback invoked by the secure DB when an identity entry has been + * retrieved. + * @param identity */ - void connection_callback( - const Gap::ConnectionCallbackParams_t* params - ); - - /** - * Inform the security manager that a connection ended. - * - * @param[in] params handle and reason of the disconnection. - */ - void disconnection_callback( - const Gap::DisconnectionCallbackParams_t* params + void on_security_entry_retrieved( + pal::SecurityDb::entry_handle_t entry, + const pal::SecurityEntryIdentity_t* identity ); private: diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index f73e5caccf..83e86de435 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -864,6 +864,26 @@ void GenericSecurityManager::on_disconnected( _db.sync(); } +void GenericSecurityManager::on_security_entry_retrieved( + pal::SecurityDb::entry_handle_t entry, + const pal::SecurityEntryIdentity_t* identity +) { + if (!identity) { + return; + } + + typedef advertising_peer_address_type_t address_type_t; + + _pal.add_device_to_resolving_list( + identity->identity_address_is_public ? + address_type_t::PUBLIC_ADDRESS : + address_type_t::RANDOM_ADDRESS, + identity->identity_address, + identity->irk + ); +} + + /* Implements ble::pal::SecurityManagerEventHandler */ //////////////////////////////////////////////////////////////////////////// @@ -935,6 +955,10 @@ void GenericSecurityManager::on_pairing_completed(connection_handle_t connection if (cb) { // set the distribution flags in the db _db.set_distribution_flags(cb->db_entry, *cb); + _db.get_entry_identity( + mbed::callback(this, &GenericSecurityManager::on_security_entry_retrieved), + cb->db_entry + ); } eventHandler->pairingResult( From ede3d4374335158ef93702ba235f07de88a9c128 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 15:57:30 +0100 Subject: [PATCH 19/24] BLE: Add function to querry the list of identity addresses present in the SecureDB. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 16 ++++++++++++++++ features/FEATURE_BLE/ble/pal/SecurityDb.h | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index c6c627b66b..afb63f418d 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -187,6 +187,22 @@ public: } } + virtual void get_identity_list( + IdentitylistDbCb_t cb, + ArrayView& entries + ) { + size_t count = 0; + for (size_t i = 0; i < MAX_ENTRIES && count < entries.size(); ++i) { + entry_t& e = _entries[i]; + + if (e.state == ENTRY_WRITTEN && e.flags.irk_stored) { + entries[count] = &e.peer_identity; + ++count; + } + } + + cb(entries, count); + } /* set */ diff --git a/features/FEATURE_BLE/ble/pal/SecurityDb.h b/features/FEATURE_BLE/ble/pal/SecurityDb.h index 7c6e77637e..bc790ccfb1 100644 --- a/features/FEATURE_BLE/ble/pal/SecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/SecurityDb.h @@ -107,6 +107,8 @@ public: SecurityEntryCsrkDbCb_t; typedef mbed::Callback SecurityEntryIdentityDbCb_t; + typedef mbed::Callback&, size_t count)> + IdentitylistDbCb_t; typedef mbed::Callback WhitelistDbCb_t; @@ -274,6 +276,20 @@ public: entry_handle_t db_entry ) = 0; + /** + * Asynchronously return the identity list stored in NVM through a callback. + * Function takes ownership of the memory. The identity list and the + * ownership will be returned in the callback. + * + * @param[in] cb callback that will receive the whitelist + * @param[in] identity_list preallocated identity_list that will be filled + * in. + */ + virtual void get_identity_list( + IdentitylistDbCb_t cb, + ArrayView& identity_list + ) = 0; + /** * Update peer signing key. * From 951a6be4c86dca26e7b768726554296245a7b9c2 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Tue, 17 Apr 2018 15:58:21 +0100 Subject: [PATCH 20/24] BLE: retrieve and fill resolving list at GenericSecurityManager startup. --- .../ble/generic/GenericSecurityManager.h | 14 +++++++- .../source/generic/GenericSecurityManager.cpp | 36 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index e30e4b9114..68f664f837 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -25,6 +25,7 @@ #include "ble/pal/SigningEventMonitor.h" #include "ble/generic/GenericGap.h" #include "ble/pal/PalSecurityManager.h" +#include "ble/ArrayView.h" namespace ble { namespace generic { @@ -402,13 +403,24 @@ private: /** * Callback invoked by the secure DB when an identity entry has been * retrieved. - * @param identity + * @param entry Handle of the entry. + * @param identity The identity associated with the entry; may be NULL. */ void on_security_entry_retrieved( pal::SecurityDb::entry_handle_t entry, const pal::SecurityEntryIdentity_t* identity ); + /** + * Callback invoked by the secure DB when the identity list has been + * retrieved. + * @param identity + */ + void on_identity_list_retrieved( + ble::ArrayView&, + size_t count + ); + private: struct ControlBlock_t : public pal::SecurityDistributionFlags_t { ControlBlock_t(); diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index 83e86de435..0b93ac0b7d 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -74,6 +74,22 @@ ble_error_t GenericSecurityManager::init( _signing_monitor.set_signing_event_handler(this); _pal.set_event_handler(this); + uint8_t resolving_list_capacity = _pal.read_resolving_list_capacity(); + pal::SecurityEntryIdentity_t** identity_list_p = + new (std::nothrow) pal::SecurityEntryIdentity_t*[resolving_list_capacity]; + + if (identity_list_p) { + ArrayView identity_list( + identity_list_p, + resolving_list_capacity + ); + + _db.get_identity_list( + mbed::callback(this, &GenericSecurityManager::on_identity_list_retrieved), + identity_list + ); + } + return BLE_ERROR_NONE; } @@ -883,6 +899,26 @@ void GenericSecurityManager::on_security_entry_retrieved( ); } +void GenericSecurityManager::on_identity_list_retrieved( + ble::ArrayView& identity_list, + size_t count +) { + typedef advertising_peer_address_type_t address_type_t; + + _pal.clear_resolving_list(); + for (size_t i = 0; i < count; ++i) { + _pal.add_device_to_resolving_list( + identity_list[i]->identity_address_is_public ? + address_type_t::PUBLIC_ADDRESS : + address_type_t::RANDOM_ADDRESS, + identity_list[i]->identity_address, + identity_list[i]->irk + ); + } + + delete [] identity_list.data(); +} + /* Implements ble::pal::SecurityManagerEventHandler */ From 0b923978405cee28dece81bc0e54a525271a59e7 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 20 Apr 2018 10:22:13 +0100 Subject: [PATCH 21/24] BLE: Fix flag IRK stored in Memory security DB. --- features/FEATURE_BLE/ble/pal/MemorySecurityDB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h index afb63f418d..24783f42c9 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h @@ -238,7 +238,7 @@ public: if (entry) { entry->state = ENTRY_WRITTEN; entry->peer_identity.irk = irk; - entry->flags.irk_stored; + entry->flags.irk_stored = true; } } From cbb33ea938746c3bcbf00ef760ccb460e971e82e Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 20 Apr 2018 10:22:56 +0100 Subject: [PATCH 22/24] BLE: Add comments to GenericSecurityManager::on_identity_list_retrieved. --- features/FEATURE_BLE/ble/generic/GenericSecurityManager.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index 68f664f837..c242b7cba6 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -414,10 +414,14 @@ private: /** * Callback invoked by the secure DB when the identity list has been * retrieved. - * @param identity + * + * @param identity View to the array passed to the secure DB. It contains + * identity entries retrieved. + * + * @param count Number of identities entries retrieved. */ void on_identity_list_retrieved( - ble::ArrayView&, + ble::ArrayView& identity_list, size_t count ); From 1a35f3e2174f8fd1ea3c266e2ccfda945f16f8a2 Mon Sep 17 00:00:00 2001 From: Paul Szczepanek <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Tue, 8 May 2018 17:49:22 +0100 Subject: [PATCH 23/24] fixed case in name --- .../ble/pal/{MemorySecurityDB.h => MemorySecurityDb.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename features/FEATURE_BLE/ble/pal/{MemorySecurityDB.h => MemorySecurityDb.h} (100%) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDB.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDb.h similarity index 100% rename from features/FEATURE_BLE/ble/pal/MemorySecurityDB.h rename to features/FEATURE_BLE/ble/pal/MemorySecurityDb.h From 214656a9eee59d46afd6f4133392b956a8a4cfe5 Mon Sep 17 00:00:00 2001 From: Paul Szczepanek <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Tue, 8 May 2018 17:56:38 +0100 Subject: [PATCH 24/24] fix case in #include --- features/FEATURE_BLE/ble/pal/MemorySecurityDb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/ble/pal/MemorySecurityDb.h b/features/FEATURE_BLE/ble/pal/MemorySecurityDb.h index 24783f42c9..81ef33fd6e 100644 --- a/features/FEATURE_BLE/ble/pal/MemorySecurityDb.h +++ b/features/FEATURE_BLE/ble/pal/MemorySecurityDb.h @@ -18,7 +18,7 @@ #define PAL_MEMORY_SECURITY_DB_H_ #include "ble/Gap.h" -#include "SecurityDB.h" +#include "SecurityDb.h" namespace ble { namespace pal {