BLE: Update security manager to use the PrivateAddressController

Resolution list has been removed from the pal as this is handled by the PrivateAddressController.
pull/13759/head
Vincent Coubard 2020-09-04 17:42:42 +01:00
parent 44681ee982
commit 237278be24
7 changed files with 43 additions and 399 deletions

View File

@ -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<const ble::SecurityManager &>(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;

View File

@ -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
/**

View File

@ -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) {

View File

@ -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];

View File

@ -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,

View File

@ -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;

View File

@ -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
//