mirror of https://github.com/ARMmbed/mbed-os.git
Nordic: Port privacy to softdevice v4.
Many things have changed; the identity list isn't shared anymore with the whitelist and resolution is handled by the stack itself.pull/6932/head
parent
6c44a78166
commit
37c036ca6b
|
@ -28,7 +28,6 @@
|
|||
#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;
|
||||
|
||||
|
@ -316,6 +315,20 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms)
|
|||
}
|
||||
}
|
||||
adv_para.p_whitelist = &whitelist;
|
||||
#else
|
||||
if (_privacy_enabled) {
|
||||
bool enable_resolution =
|
||||
_peripheral_privacy_configuration.resolution_strategy != PeripheralPrivacyConfiguration_t::DO_NOT_RESOLVE;
|
||||
update_identities_list(enable_resolution);
|
||||
|
||||
if (_peripheral_privacy_configuration.use_non_resolvable_random_address &&
|
||||
is_advertising_non_connectable(params)
|
||||
) {
|
||||
set_private_non_resolvable_address();
|
||||
} else {
|
||||
set_private_resolvable_address();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
|
||||
|
||||
|
@ -384,7 +397,13 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
|
|||
scanParams.interval = scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
|
||||
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) {
|
||||
bool enable_resolution =
|
||||
_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE;
|
||||
|
||||
update_identities_list(enable_resolution);
|
||||
|
||||
if (_central_privacy_configuration.use_non_resolvable_random_address) {
|
||||
set_private_non_resolvable_address();
|
||||
} else {
|
||||
|
@ -524,7 +543,15 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
|
|||
} else {
|
||||
addr.addr_id_peer = 0;
|
||||
}
|
||||
|
||||
|
||||
if (_privacy_enabled) {
|
||||
bool enable_resolution =
|
||||
_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE;
|
||||
|
||||
update_identities_list(enable_resolution);
|
||||
set_private_resolvable_address();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (scanParamsIn != NULL) {
|
||||
|
@ -1201,6 +1228,37 @@ void nRF5xGap::processDisconnectionEvent(
|
|||
);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::update_identities_list(bool resolution_enabled)
|
||||
{
|
||||
uint32_t err;
|
||||
|
||||
if (resolution_enabled) {
|
||||
ArrayView<ble_gap_id_key_t> entries = get_sm().get_resolving_list();
|
||||
size_t limit = std::min(
|
||||
entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE
|
||||
);
|
||||
ble_gap_id_key_t* id_keys_pp[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
id_keys_pp[i] = &entries[i];
|
||||
}
|
||||
|
||||
err = sd_ble_gap_device_identities_set(
|
||||
limit ? id_keys_pp : NULL,
|
||||
/* use the local IRK for all devices */ NULL,
|
||||
limit
|
||||
);
|
||||
} else {
|
||||
err = sd_ble_gap_device_identities_set(
|
||||
NULL,
|
||||
/* use the local IRK for all devices */ NULL,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
return err ? BLE_ERROR_INVALID_STATE : BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t& evt) {
|
||||
using BLEProtocol::AddressType;
|
||||
|
||||
|
@ -1246,14 +1304,8 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
|
||||
|
||||
if (private_peer_known) {
|
||||
// FIXME: Is this correct for SD > 2 ?
|
||||
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_addr_type = convert_nordic_address(evt.peer_addr.addr_type);;
|
||||
peer_address = evt.peer_addr.addr;
|
||||
peer_resolvable_address = evt.peer_addr.addr;
|
||||
} else {
|
||||
if (_privacy_enabled &&
|
||||
|
@ -1294,7 +1346,7 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
) {
|
||||
switch (_peripheral_privacy_configuration.resolution_strategy) {
|
||||
case PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE:
|
||||
nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestPairing(handle);
|
||||
nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestAuthentication(handle);
|
||||
break;
|
||||
|
||||
case PeripheralPrivacyConfiguration_t::PERFORM_AUTHENTICATION_PROCEDURE:
|
||||
|
@ -1322,32 +1374,16 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
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
|
||||
evt.peer_addr.addr_id_peer == 0 &&
|
||||
_central_privacy_configuration.resolution_strategy == CentralPrivacyConfiguration_t::RESOLVE_AND_FILTER
|
||||
) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
AddressType_t peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type);
|
||||
const uint8_t* peer_address = evt.peer_addr.addr;
|
||||
|
||||
processAdvertisementReport(
|
||||
peer_address,
|
||||
evt.rssi,
|
||||
|
|
|
@ -267,6 +267,7 @@ private:
|
|||
friend void btle_handler(const ble_evt_t *p_ble_evt);
|
||||
friend void btle_handler(const ble_evt_t *p_ble_evt, void *p_context);
|
||||
|
||||
ble_error_t update_identities_list(bool resolution_enabled);
|
||||
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;
|
||||
|
|
|
@ -158,10 +158,18 @@ ble_error_t nRF5xSecurityManager::add_device_to_resolving_list(
|
|||
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;
|
||||
ble_gap_id_key_t& entry = resolving_list[resolving_list_entry_count];
|
||||
entry.id_addr_info.addr_type = peer_identity_address_type.value();
|
||||
memcpy(
|
||||
entry.id_addr_info.addr,
|
||||
peer_identity_address.data(),
|
||||
peer_identity_address.size()
|
||||
);
|
||||
memcpy(
|
||||
entry.id_info.irk,
|
||||
peer_irk.data(),
|
||||
peer_irk.size()
|
||||
);
|
||||
|
||||
++resolving_list_entry_count;
|
||||
|
||||
|
@ -176,9 +184,9 @@ ble_error_t nRF5xSecurityManager::remove_device_from_resolving_list(
|
|||
|
||||
// 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
|
||||
ble_gap_id_key_t& entry = resolving_list[entry_index];
|
||||
if (entry.id_addr_info.addr_type == peer_identity_address_type.value() &&
|
||||
entry.id_addr_info.addr == peer_identity_address
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
@ -204,46 +212,13 @@ ble_error_t nRF5xSecurityManager::clear_resolving_list()
|
|||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ArrayView<nRF5xSecurityManager::resolving_list_entry_t>
|
||||
nRF5xSecurityManager::get_resolving_list() {
|
||||
return ArrayView<nRF5xSecurityManager::resolving_list_entry_t>(
|
||||
ArrayView<ble_gap_id_key_t> nRF5xSecurityManager::get_resolving_list() {
|
||||
return ArrayView<ble_gap_id_key_t>(
|
||||
resolving_list,
|
||||
resolving_list_entry_count
|
||||
);
|
||||
}
|
||||
|
||||
const nRF5xSecurityManager::resolving_list_entry_t*
|
||||
nRF5xSecurityManager::resolve_address(const address_t& resolvable_address) {
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
typedef byte_array_t<CryptoToolbox::hash_size_> 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<CryptoToolbox::irk_size_>(entry.peer_irk),
|
||||
make_const_ArrayView<CryptoToolbox::prand_size_>(
|
||||
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) {
|
||||
return &entry;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Pairing
|
||||
//
|
||||
|
|
|
@ -84,39 +84,12 @@ 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.
|
||||
*/
|
||||
ArrayView<resolving_list_entry_t> get_resolving_list();
|
||||
|
||||
/**
|
||||
* Try to resolve a private resolvable address.
|
||||
*
|
||||
* @param resolvable_address The address to resolve.
|
||||
*
|
||||
* @return Pointer to the entry found if any.
|
||||
*/
|
||||
const resolving_list_entry_t* resolve_address(
|
||||
const address_t& resolvable_address
|
||||
);
|
||||
|
||||
ArrayView<ble_gap_id_key_t> get_resolving_list();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Pairing
|
||||
|
@ -396,7 +369,7 @@ private:
|
|||
static const size_t MAX_RESOLVING_LIST_ENTRIES = BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT;
|
||||
|
||||
size_t resolving_list_entry_count;
|
||||
resolving_list_entry_t resolving_list[MAX_RESOLVING_LIST_ENTRIES];
|
||||
ble_gap_id_key_t resolving_list[MAX_RESOLVING_LIST_ENTRIES];
|
||||
};
|
||||
|
||||
} // nordic
|
||||
|
|
Loading…
Reference in New Issue