From 237278be241e781deb8f5fe595477353d9a307fe Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 4 Sep 2020 17:42:42 +0100 Subject: [PATCH] BLE: Update security manager to use the PrivateAddressController Resolution list has been removed from the pal as this is handled by the PrivateAddressController. --- .../cordio/source/BLEInstanceBaseImpl.cpp | 22 +- .../cordio/source/BLEInstanceBaseImpl.h | 6 + .../cordio/source/PalSecurityManagerImpl.cpp | 274 ------------------ .../cordio/source/PalSecurityManagerImpl.h | 65 ----- .../source/generic/SecurityManagerImpl.cpp | 18 +- .../source/generic/SecurityManagerImpl.h | 7 +- .../source/pal/PalSecurityManager.h | 50 ---- 7 files changed, 43 insertions(+), 399 deletions(-) diff --git a/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.cpp index 48df9f9b1c..f048ba01f6 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.cpp @@ -285,7 +285,8 @@ ble::impl::SecurityManager &BLEInstanceBase::getSecurityManagerImpl() static ble::impl::SecurityManager m_instance( ble::impl::PalSecurityManager::get_security_manager(), getGapImpl(), - signing_event_monitor + signing_event_monitor, + getPrivateAddressRegistry() ); return m_instance; @@ -303,6 +304,18 @@ const ble::SecurityManager &BLEInstanceBase::getSecurityManager() const return const_cast(self.getSecurityManager()); } +#if BLE_FEATURE_PRIVACY +ble::PrivateAddressController &BLEInstanceBase::getPrivateAddressRegistry() +{ + static ble::PrivateAddressController registry( + impl::PalPrivateAddressController::instance(), + _event_queue, + ble::resolvable_address_timeout_t{} + ); + return registry; +} +#endif + #endif // BLE_FEATURE_SECURITY void BLEInstanceBase::waitForEvent() @@ -337,6 +350,12 @@ void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg) if (ble::impl::PalSecurityManager::get_security_manager().sm_handler(msg)) { return; } + +#if BLE_FEATURE_PRIVACY + if (impl::PalPrivateAddressController::instance().cordio_handler(msg)) { + return; + } +#endif #endif // BLE_FEATURE_SECURITY switch (msg->event) { @@ -365,6 +384,7 @@ void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg) #if BLE_FEATURE_GATT_SERVER deviceInstance().getGattServerImpl().initialize(); #endif + deviceInstance().initialization_status = INITIALIZED; _init_callback.call(&context); } break; diff --git a/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.h b/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.h index b91e9e30e0..ceb727a416 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.h +++ b/connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.h @@ -42,6 +42,8 @@ #include "source/generic/SecurityManagerImpl.h" #include "source/GattServerImpl.h" #include "source/PalEventQueueImpl.h" +#include "source/PalPrivateAddressControllerImpl.h" +#include "source/generic/PrivateAddressController.h" #include "drivers/LowPowerTimer.h" @@ -157,6 +159,10 @@ public: */ const ble::SecurityManager &getSecurityManager() const final; +#if BLE_FEATURE_PRIVACY + ble::PrivateAddressController &getPrivateAddressRegistry(); +#endif + #endif // BLE_FEATURE_SECURITY /** diff --git a/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.cpp index 83094d06e9..772f7fa3a2 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.cpp @@ -37,17 +37,12 @@ PalSecurityManager::PalSecurityManager() : _default_passkey(0), _lesc_keys_generated(false), _public_key_x(), - _pending_privacy_control_blocks(nullptr), - _processing_privacy_control_block(false), _peer_csrks() { } PalSecurityManager::~PalSecurityManager() { -#if BLE_FEATURE_PRIVACY - clear_privacy_control_blocks(); -#endif } //////////////////////////////////////////////////////////////////////////// @@ -93,68 +88,6 @@ ble_error_t PalSecurityManager::reset() return BLE_ERROR_NONE; } -//////////////////////////////////////////////////////////////////////////// -// Resolving list management -// - - -uint8_t PalSecurityManager::read_resolving_list_capacity() -{ - // The Cordio stack requests this from the controller during initialization - return hciCoreCb.resListSize; -} - -// As the Cordio stack can only handle one of these methods at a time, we need to create a list of control blocks -// that are dequeued one after the other on completion of the previous one - -ble_error_t PalSecurityManager::add_device_to_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk -) -{ - if (read_resolving_list_capacity() == 0) { - // If 0 is returned as capacity, it means the controller does not support resolving addresses - return BLE_ERROR_NOT_IMPLEMENTED; - } - - // Queue control block - queue_add_device_to_resolving_list(peer_identity_address_type, peer_identity_address, peer_irk); - - return BLE_ERROR_NONE; -} - - -ble_error_t PalSecurityManager::remove_device_from_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address -) -{ - if (read_resolving_list_capacity() == 0) { - // If 0 is returned as capacity, it means the controller does not support resolving addresses - return BLE_ERROR_NOT_IMPLEMENTED; - } - - // Queue control block - queue_remove_device_from_resolving_list(peer_identity_address_type, peer_identity_address); - - return BLE_ERROR_NONE; -} - - -ble_error_t PalSecurityManager::clear_resolving_list() -{ - if (read_resolving_list_capacity() == 0) { - // If 0 is returned as capacity, it means the controller does not support resolving addresses - return BLE_ERROR_NOT_IMPLEMENTED; - } - - // Queue control block - queue_clear_resolving_list(); - - return BLE_ERROR_NONE; -} - //////////////////////////////////////////////////////////////////////////// // Feature support // @@ -841,220 +774,13 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg) return true; } -#if BLE_FEATURE_PRIVACY - // Privacy - case DM_PRIV_ADD_DEV_TO_RES_LIST_IND: // Device added to resolving list - case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: // Device removed from resolving list - case DM_PRIV_CLEAR_RES_LIST_IND: // Resolving list cleared - { - // Previous command completed, we can move to the next control block - self.process_privacy_control_blocks(true); - return true; - } -#endif // BLE_FEATURE_PRIVACY default: return false; } } - -struct PalSecurityManager::PrivacyControlBlock { - PrivacyControlBlock() : _next(nullptr) - { - } - - virtual ~PrivacyControlBlock() = default; - - virtual void execute() = 0; - - void set_next(PrivacyControlBlock *next) - { - _next = next; - } - - PrivacyControlBlock *next() const - { - return _next; - } - -private: - PrivacyControlBlock *_next; -}; - - -struct PalSecurityManager::PrivacyClearResListControlBlock final : PalSecurityManager::PrivacyControlBlock { - PrivacyClearResListControlBlock() : PrivacyControlBlock() - { - } - - void execute() final - { - // Execute command - DmPrivClearResList(); - } -}; - - -struct PalSecurityManager::PrivacyAddDevToResListControlBlock final : PalSecurityManager::PrivacyControlBlock { - PrivacyAddDevToResListControlBlock( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk - ) : PrivacyControlBlock(), - _peer_identity_address_type(peer_identity_address_type), - _peer_identity_address(peer_identity_address), - _peer_irk(peer_irk) - { - } - - void execute() final - { - // Execute command - DmPrivAddDevToResList( - _peer_identity_address_type.value(), - _peer_identity_address.data(), - _peer_irk.data(), - DmSecGetLocalIrk(), - false, - 0 - ); - } - -private: - advertising_peer_address_type_t _peer_identity_address_type; - address_t _peer_identity_address; - irk_t _peer_irk; -}; - - -struct PalSecurityManager::PrivacyRemoveDevFromResListControlBlock final : PalSecurityManager::PrivacyControlBlock { - PrivacyRemoveDevFromResListControlBlock( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address - ) : PrivacyControlBlock(), - _peer_identity_address_type(peer_identity_address_type), - _peer_identity_address(peer_identity_address) - { - - } - - void execute() final - { - // Execute command - DmPrivRemDevFromResList(_peer_identity_address_type.value(), _peer_identity_address.data(), 0); - } - -private: - advertising_peer_address_type_t _peer_identity_address_type; - address_t _peer_identity_address; -}; - // Helper functions for privacy -void PalSecurityManager::queue_add_device_to_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk -) -{ - auto *cb = new(std::nothrow) PrivacyAddDevToResListControlBlock( - peer_identity_address_type, - peer_identity_address, - peer_irk - ); - if (cb == nullptr) { - // Cannot go further - return; - } - - queue_privacy_control_block(cb); -} - - -void PalSecurityManager::queue_remove_device_from_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address -) -{ - auto *cb = new(std::nothrow) PrivacyRemoveDevFromResListControlBlock( - peer_identity_address_type, - peer_identity_address - ); - if (cb == nullptr) { - // Cannot go further - return; - } - - queue_privacy_control_block(cb); -} - - -void PalSecurityManager::queue_clear_resolving_list() -{ - // Remove any pending control blocks, there's no point executing them as we're about to queue the list - clear_privacy_control_blocks(); - - auto *cb = new(std::nothrow) PrivacyClearResListControlBlock(); - if (cb == nullptr) { - // Cannot go further - return; - } - - queue_privacy_control_block(cb); -} - - -void PalSecurityManager::clear_privacy_control_blocks() -{ - while (_pending_privacy_control_blocks != nullptr) { - PrivacyControlBlock *next = _pending_privacy_control_blocks->next(); - delete _pending_privacy_control_blocks; - _pending_privacy_control_blocks = next; - } -} - - -void PalSecurityManager::queue_privacy_control_block(PrivacyControlBlock *block) -{ - if (_pending_privacy_control_blocks == nullptr) { - _pending_privacy_control_blocks = block; - } else { - PrivacyControlBlock *node = _pending_privacy_control_blocks; - while (node->next() != nullptr) { - node = node->next(); - } - node->set_next(block); - } - - process_privacy_control_blocks(false); -} - -// If cb_completed is set to true, it means the previous control block has completed - -void PalSecurityManager::process_privacy_control_blocks(bool cb_completed) -{ - if ((_processing_privacy_control_block == true) && !cb_completed) { - // Busy, cannot process next control block for now - return; - } - - PrivacyControlBlock *cb = _pending_privacy_control_blocks; - if (cb == nullptr) { - // All control blocks processed - _processing_privacy_control_block = false; - return; - } - - // Process next block and free it - _processing_privacy_control_block = true; - - PrivacyControlBlock *next = cb->next(); - cb->execute(); - delete cb; - _pending_privacy_control_blocks = next; -} - - void PalSecurityManager::cleanup_peer_csrks() { for (auto & peer_csrk : _peer_csrks) { diff --git a/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.h b/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.h index 95cca71034..ec955653f6 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.h +++ b/connectivity/FEATURE_BLE/source/cordio/source/PalSecurityManagerImpl.h @@ -59,37 +59,6 @@ public: */ ble_error_t reset() final; - //////////////////////////////////////////////////////////////////////////// - // Resolving list management - // - - /** - * @see ::ble::PalSecurityManager::read_resolving_list_capacity - */ - uint8_t read_resolving_list_capacity() final; - - /** - * @see ::ble::PalSecurityManager::add_device_to_resolving_list - */ - ble_error_t add_device_to_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk - ) final; - - /** - * @see ::ble::PalSecurityManager::remove_device_from_resolving_list - */ - ble_error_t remove_device_from_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address - ) final; - - /** - * @see ::ble::PalSecurityManager::clear_resolving_list - */ - ble_error_t clear_resolving_list() final; - //////////////////////////////////////////////////////////////////////////// // Pairing // @@ -347,37 +316,6 @@ public: private: - struct PrivacyControlBlock; - struct PrivacyClearResListControlBlock; - struct PrivacyAddDevToResListControlBlock; - struct PrivacyRemoveDevFromResListControlBlock; - - // Queue control block to add device to resolving list - void queue_add_device_to_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk - ); - - // Queue control block to remove device from resolving list - void queue_remove_device_from_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address - ); - - // Queue control block to clear resolving list - void queue_clear_resolving_list(); - - // Clear all control blocks - void clear_privacy_control_blocks(); - - // Queue a control block - void queue_privacy_control_block(PrivacyControlBlock *block); - - // Try to dequeue and process the next control block - // cb_completed is set when the previous block has completed - void process_privacy_control_blocks(bool cb_completed); - void cleanup_peer_csrks(); PalSecurityManagerEventHandler *_pal_event_handler; @@ -386,9 +324,6 @@ private: passkey_num_t _default_passkey; bool _lesc_keys_generated; uint8_t _public_key_x[SEC_ECC_KEY_LEN]; - - PrivacyControlBlock *_pending_privacy_control_blocks; - bool _processing_privacy_control_block; irk_t _irk; csrk_t _csrk; csrk_t *_peer_csrks[DM_CONN_MAX]; diff --git a/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.cpp b/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.cpp index 75b4fabdfd..ef56f3f70d 100644 --- a/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.cpp @@ -134,9 +134,9 @@ ble_error_t SecurityManager::init( #if BLE_FEATURE_PRIVACY // set the local identity address and irk - if (result != BLE_ERROR_NONE) { + if (result == BLE_ERROR_NONE) { result = init_identity(); - } + } #endif // BLE_FEATURE_PRIVACY if (result != BLE_ERROR_NONE) { @@ -983,7 +983,7 @@ ble_error_t SecurityManager::init_resolving_list() if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; /* match the resolving list to the currently stored set of IRKs */ - uint8_t resolving_list_capacity = _pal.read_resolving_list_capacity(); + uint8_t resolving_list_capacity = _private_address_controller.read_resolving_list_capacity(); auto* identity_list_p = new (std::nothrow) SecurityEntryIdentity_t[resolving_list_capacity]; @@ -1051,7 +1051,11 @@ ble_error_t SecurityManager::init_identity() _db->set_local_identity(irk, identity_address, public_address); } - return _pal.set_irk(*pirk); + auto err = _pal.set_irk(*pirk); + if (!err) { + _private_address_controller.set_local_irk(*pirk); + } + return err; } @@ -1342,7 +1346,7 @@ void SecurityManager::on_security_entry_retrieved( typedef advertising_peer_address_type_t address_type_t; #if BLE_FEATURE_PRIVACY - _pal.add_device_to_resolving_list( + _private_address_controller.add_device_to_resolving_list( identity->identity_address_is_public ? address_type_t::PUBLIC : address_type_t::RANDOM, @@ -1360,9 +1364,9 @@ void SecurityManager::on_identity_list_retrieved( { typedef advertising_peer_address_type_t address_type_t; - _pal.clear_resolving_list(); + _private_address_controller.clear_resolving_list(); for (size_t i = 0; i < count; ++i) { - _pal.add_device_to_resolving_list( + _private_address_controller.add_device_to_resolving_list( identity_list[i].identity_address_is_public ? address_type_t::PUBLIC : address_type_t::RANDOM, diff --git a/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.h b/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.h index d159880f89..576fd6ae92 100644 --- a/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.h +++ b/connectivity/FEATURE_BLE/source/generic/SecurityManagerImpl.h @@ -37,7 +37,7 @@ #include "source/pal/PalSecurityManager.h" #include "source/generic/SecurityDb.h" - +#include "source/generic/PrivateAddressController.h" namespace ble { class PalGenericAccessService; @@ -451,12 +451,14 @@ public: SecurityManager( ble::PalSecurityManager &palImpl, ble::PalConnectionMonitor &connMonitorImpl, - ble::PalSigningMonitor &signingMonitorImpl + ble::PalSigningMonitor &signingMonitorImpl, + PrivateAddressController &privateAddressController ) : eventHandler(nullptr), _pal(palImpl), _connection_monitor(connMonitorImpl), _signing_monitor(signingMonitorImpl), _db(nullptr), + _private_address_controller(privateAddressController), _default_authentication(0), _default_key_distribution(KeyDistribution::KEY_DISTRIBUTION_ALL), _pairing_authorisation_required(false), @@ -639,6 +641,7 @@ private: PalSigningMonitor &_signing_monitor; SecurityDb *_db; + PrivateAddressController &_private_address_controller; /* OOB data */ address_t _oob_local_address; diff --git a/connectivity/FEATURE_BLE/source/pal/PalSecurityManager.h b/connectivity/FEATURE_BLE/source/pal/PalSecurityManager.h index 4a1906ee72..5a4e09cb8c 100644 --- a/connectivity/FEATURE_BLE/source/pal/PalSecurityManager.h +++ b/connectivity/FEATURE_BLE/source/pal/PalSecurityManager.h @@ -559,56 +559,6 @@ public: */ virtual ble_error_t reset() = 0; - //////////////////////////////////////////////////////////////////////////// - // Resolving list management - // - /** - * Return the number of address translation entries that can be stored by the - * subsystem. - * - * @warning: The number of entries is considered fixed. - * - * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.41 - * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure - */ - virtual uint8_t read_resolving_list_capacity() = 0; - - /** - * Add a device definition into the resolving list of the LE subsystem. - * - * @param[in] peer_identity_address_type public/private indicator - * @param[in] peer_identity_address address of the device whose entry is to be added - * @param[in] peer_irk peer identity resolving key - * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.38 - * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure - */ - virtual ble_error_t add_device_to_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address, - const irk_t &peer_irk - ) = 0; - - /** - * Add a device definition from the resolving list of the LE subsystem. - * - * @param[in] peer_identity_address_type public/private indicator - * @param[in] peer_identity_address address of the device whose entry is to be removed - * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.39 - * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure - */ - virtual ble_error_t remove_device_from_resolving_list( - advertising_peer_address_type_t peer_identity_address_type, - const address_t &peer_identity_address - ) = 0; - - /** - * Remove all devices from the resolving list. - * - * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.40 - * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure - */ - virtual ble_error_t clear_resolving_list() = 0; - //////////////////////////////////////////////////////////////////////////// // Pairing //