mirror of https://github.com/ARMmbed/mbed-os.git
Removed deprecated Security Manager
parent
7b6b02a746
commit
713ab14d22
|
@ -38,11 +38,9 @@
|
|||
extern "C" {
|
||||
#if (IS_LEGACY_DEVICE_MANAGER_ENABLED)
|
||||
#include "pstorage.h"
|
||||
#include "device_manager.h"
|
||||
#else
|
||||
#include "fstorage.h"
|
||||
#include "fds.h"
|
||||
#include "peer_manager.h"
|
||||
#include "ble_conn_state.h"
|
||||
#endif
|
||||
|
||||
|
@ -145,9 +143,6 @@ error_t btle_init(void)
|
|||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Peer Manger must been initialised prior any other call to its API (this file and btle_security_pm.cpp)
|
||||
pm_init();
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
ble_gap_addr_t addr;
|
||||
if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
|
||||
|
@ -157,9 +152,7 @@ error_t btle_init(void)
|
|||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
#else
|
||||
ble_gap_privacy_params_t privacy_params = {0};
|
||||
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
|
||||
pm_privacy_set(&privacy_params);
|
||||
|
||||
#endif
|
||||
|
||||
ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
|
||||
|
@ -179,14 +172,10 @@ static void btle_handler(ble_evt_t *p_ble_evt)
|
|||
#endif
|
||||
|
||||
#if (IS_LEGACY_DEVICE_MANAGER_ENABLED)
|
||||
dm_ble_evt_handler(p_ble_evt);
|
||||
#else
|
||||
// Forward BLE events to the Connection State module.
|
||||
// This must be called before any event handler that uses this module.
|
||||
ble_conn_state_on_ble_evt(p_ble_evt);
|
||||
|
||||
// Forward BLE events to the Peer Manager
|
||||
pm_on_ble_evt(p_ble_evt);
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
|
|
|
@ -1,326 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if defined(S110)
|
||||
#include "btle.h"
|
||||
|
||||
#include "nRF5xn.h"
|
||||
|
||||
extern "C" {
|
||||
#include "pstorage.h"
|
||||
#include "device_manager.h"
|
||||
#include "id_manager.h"
|
||||
}
|
||||
|
||||
#include "btle_security.h"
|
||||
|
||||
static dm_application_instance_t applicationInstance;
|
||||
static bool initialized = false;
|
||||
static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result);
|
||||
|
||||
// default security parameters. Avoid "holes" between member assigments in order to compile by gcc++11.
|
||||
static ble_gap_sec_params_t securityParameters = {
|
||||
.bond = true, /**< Perform bonding. */
|
||||
.mitm = true, /**< Man In The Middle protection required. */
|
||||
.lesc = false, /**< Enable LE Secure Connection pairing. */
|
||||
.keypress = false, /**< Enable generation of keypress notifications. */
|
||||
.io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
|
||||
.oob = 0, /**< Out Of Band data available. */
|
||||
.min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
|
||||
.max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
|
||||
.kdist_own = {
|
||||
.enc = 0, /**< Long Term Key and Master Identification. */
|
||||
.id = 0, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
}, /**< Key distribution bitmap: keys that the local device will distribute. */
|
||||
.kdist_peer = {
|
||||
.enc = 1, /**< Long Term Key and Master Identification. */
|
||||
.id = 1, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 1, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
} /**< Key distribution bitmap: keys that the peripheral device will distribute. */
|
||||
};
|
||||
|
||||
bool
|
||||
btle_hasInitializedSecurity(void)
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_initializeSecurity(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps,
|
||||
const SecurityManager::Passkey_t passkey)
|
||||
{
|
||||
/* guard against multiple initializations */
|
||||
if (initialized) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
if (pstorage_init() != NRF_SUCCESS) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
ret_code_t rc;
|
||||
if (passkey) {
|
||||
ble_opt_t opts;
|
||||
opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
|
||||
if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
default:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_BUSY:
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dm_init_param_t dm_init_param = {
|
||||
.clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
|
||||
};
|
||||
if (dm_init(&dm_init_param) != NRF_SUCCESS) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
// update default security parameters with function call parameters
|
||||
securityParameters.bond = enableBonding;
|
||||
securityParameters.mitm = requireMITM;
|
||||
securityParameters.io_caps = iocaps;
|
||||
|
||||
const dm_application_param_t dm_param = {
|
||||
.evt_handler = dm_handler,
|
||||
.service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
|
||||
.sec_param = securityParameters
|
||||
};
|
||||
|
||||
if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_purgeAllBondingState(void)
|
||||
{
|
||||
ret_code_t rc;
|
||||
if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
|
||||
{
|
||||
ret_code_t rc;
|
||||
dm_handle_t dmHandle = {
|
||||
.appl_id = applicationInstance,
|
||||
};
|
||||
if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
|
||||
if (rc == NRF_ERROR_NOT_FOUND) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
} else {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
|
||||
{
|
||||
// use default and updated parameters as starting point
|
||||
// and modify structure based on security mode.
|
||||
ble_gap_sec_params_t params = securityParameters;
|
||||
|
||||
switch (securityMode) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
|
||||
/**< Require no protection, open link. */
|
||||
securityParameters.bond = false;
|
||||
securityParameters.mitm = false;
|
||||
break;
|
||||
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
|
||||
/**< Require encryption, but no MITM protection. */
|
||||
securityParameters.bond = true;
|
||||
securityParameters.mitm = false;
|
||||
break;
|
||||
|
||||
// not yet implemented security modes
|
||||
case SecurityManager::SECURITY_MODE_NO_ACCESS:
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
|
||||
/**< Require encryption and MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
|
||||
/**< Require signing or encryption, but no MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
|
||||
/**< Require signing or encryption, and MITM protection. */
|
||||
default:
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// update security settings for given connection
|
||||
uint32_t result = sd_ble_gap_authenticate(connectionHandle, ¶ms);
|
||||
|
||||
if (result == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ret_code_t
|
||||
dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
|
||||
{
|
||||
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
|
||||
|
||||
switch (p_event->event_id) {
|
||||
case DM_EVT_SECURITY_SETUP: /* started */ {
|
||||
const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
|
||||
securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
|
||||
peerParams->bond,
|
||||
peerParams->mitm,
|
||||
(SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
|
||||
break;
|
||||
}
|
||||
case DM_EVT_SECURITY_SETUP_COMPLETE:
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
|
||||
(SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
|
||||
break;
|
||||
case DM_EVT_LINK_SECURED: {
|
||||
unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
|
||||
unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
|
||||
SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
|
||||
switch (securityMode) {
|
||||
case 1:
|
||||
switch (level) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
|
||||
break;
|
||||
case 3:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (level) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
|
||||
break;
|
||||
}
|
||||
case DM_EVT_DEVICE_CONTEXT_STORED:
|
||||
securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
|
||||
{
|
||||
if (!btle_hasInitializedSecurity()) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
ret_code_t err = dm_whitelist_create(&applicationInstance, p_whitelist);
|
||||
if (err == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else if (err == NRF_ERROR_NULL) {
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
} else {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
|
||||
{
|
||||
/*
|
||||
* Use a helper function from the Nordic SDK to test whether the BLE
|
||||
* address can be generated using the IRK.
|
||||
*/
|
||||
return im_address_resolve(p_addr, p_irk);
|
||||
}
|
||||
|
||||
void
|
||||
btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address)
|
||||
{
|
||||
/* Set type to resolvable */
|
||||
address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
||||
|
||||
/*
|
||||
* Assign a random number to the most significant 3 bytes
|
||||
* of the address.
|
||||
*/
|
||||
address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C;
|
||||
|
||||
/* Calculate the hash and store it in the top half of the address */
|
||||
ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr);
|
||||
}
|
||||
#endif
|
|
@ -1,146 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _BTLE_SECURITY_H_
|
||||
#define _BTLE_SECURITY_H_
|
||||
|
||||
#include "ble/Gap.h"
|
||||
#include "ble/SecurityManager.h"
|
||||
|
||||
/**
|
||||
* Function to test whether the SecurityManager has been initialized.
|
||||
* Possible by a call to @ref btle_initializeSecurity().
|
||||
*
|
||||
* @return True if the SecurityManager was previously initialized, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool btle_hasInitializedSecurity(void);
|
||||
|
||||
/**
|
||||
* Enable Nordic's Device Manager, which brings in functionality from the
|
||||
* stack's Security Manager. The Security Manager implements the actual
|
||||
* cryptographic algorithms and protocol exchanges that allow two devices to
|
||||
* securely exchange data and privately detect each other.
|
||||
*
|
||||
* @param[in] enableBonding Allow for bonding.
|
||||
* @param[in] requireMITM Require protection for man-in-the-middle attacks.
|
||||
* @param[in] iocaps To specify IO capabilities of this peripheral,
|
||||
* such as availability of a display or keyboard to
|
||||
* support out-of-band exchanges of security data.
|
||||
* @param[in] passkey To specify a static passkey.
|
||||
*
|
||||
* @return BLE_ERROR_NONE on success.
|
||||
*/
|
||||
ble_error_t btle_initializeSecurity(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE,
|
||||
const SecurityManager::Passkey_t passkey = NULL);
|
||||
|
||||
/**
|
||||
* Get the security status of a link.
|
||||
*
|
||||
* @param[in] connectionHandle
|
||||
* Handle to identify the connection.
|
||||
* @param[out] securityStatusP
|
||||
* security status.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP);
|
||||
|
||||
/**
|
||||
* Set the security mode on a connection. Useful for elevating the security mode
|
||||
* once certain conditions are met, e.g., a particular service is found.
|
||||
*
|
||||
* @param[in] connectionHandle
|
||||
* Handle to identify the connection.
|
||||
* @param[in] securityMode
|
||||
* security mode.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode);
|
||||
|
||||
/**
|
||||
* Function for deleting all peer device context and all related bonding
|
||||
* information from the database.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
|
||||
* @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
||||
* application registration.
|
||||
*/
|
||||
ble_error_t btle_purgeAllBondingState(void);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/**
|
||||
* Query the SoftDevice bond table to extract a whitelist containing the BLE
|
||||
* addresses and IRKs of bonded devices.
|
||||
*
|
||||
* @param[in/out] p_whitelist
|
||||
* (on input) p_whitelist->addr_count and
|
||||
* p_whitelist->irk_count specify the maximum number of
|
||||
* addresses and IRKs added to the whitelist structure.
|
||||
* (on output) *p_whitelist is a whitelist containing the
|
||||
* addresses and IRKs of the bonded devices.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function to test whether a BLE address is generated using an IRK.
|
||||
*
|
||||
* @param[in] p_addr
|
||||
* Pointer to a BLE address.
|
||||
* @param[in] p_irk
|
||||
* Pointer to an IRK.
|
||||
*
|
||||
* @return True if p_addr can be generated using p_irk, false otherwise.
|
||||
*/
|
||||
bool btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
|
||||
|
||||
/**
|
||||
* Function to generate a private resolvable BLE address.
|
||||
*
|
||||
* @param[out] p_addr
|
||||
* The output address.
|
||||
* @param[in] p_irk
|
||||
* A reference to a IRK.
|
||||
*
|
||||
* @note This function does not generate a secure address since the prand number in the
|
||||
* resolvable address is not truly random. Therefore, the output of this function
|
||||
* is only meant to be used by the application internally but never exported.
|
||||
*/
|
||||
void btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE if successful.
|
||||
* @retval BLE_ERROR_UNSPECIFIED Bond data could not be found in flash or is inconsistent.
|
||||
*/
|
||||
ble_error_t btle_getAddressesFromBondTable(Gap::Whitelist_t &addrList);
|
||||
#endif
|
||||
|
||||
#endif /* _BTLE_SECURITY_H_ */
|
|
@ -1,488 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(S130) || defined(S132) || defined(S140)
|
||||
#include "btle.h"
|
||||
|
||||
#include "nRF5xn.h"
|
||||
|
||||
extern "C" {
|
||||
#include "peer_manager.h"
|
||||
#include "id_manager.h"
|
||||
#include "fds.h"
|
||||
}
|
||||
|
||||
#include "btle_security.h"
|
||||
#if 0
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
static void pm_handler(pm_evt_t const *p_event);
|
||||
static bool _enc_in_progress = false; // helper flag for distinguish between state of link connected and link connected in progres of encryption establishing.
|
||||
volatile static uint32_t async_ret_code; // busy loop support variable for asyncronous API.
|
||||
|
||||
// default security parameters. Avoid "holes" between member assigments in order to compile by gcc++11.
|
||||
static ble_gap_sec_params_t securityParameters = {
|
||||
.bond = true, /**< Perform bonding. */
|
||||
.mitm = true, /**< Man In The Middle protection required. */
|
||||
.lesc = false, /**< Enable LE Secure Connection pairing. */
|
||||
.keypress = false, /**< Enable generation of keypress notifications. */
|
||||
.io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
|
||||
.oob = 0, /**< Out Of Band data available. */
|
||||
.min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
|
||||
.max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
|
||||
.kdist_own = {
|
||||
.enc = 0, /**< Long Term Key and Master Identification. */
|
||||
.id = 0, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
}, /**< Key distribution bitmap: keys that the local device will distribute. */
|
||||
.kdist_peer = {
|
||||
.enc = 1, /**< Long Term Key and Master Identification. */
|
||||
.id = 1, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
} /**< Key distribution bitmap: keys that the peripheral device will distribute. */
|
||||
};
|
||||
|
||||
bool
|
||||
btle_hasInitializedSecurity(void)
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
ble_error_t
|
||||
btle_initializeSecurity(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps,
|
||||
const SecurityManager::Passkey_t passkey)
|
||||
{
|
||||
/* guard against multiple initializations */
|
||||
if (initialized) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ret_code_t rc;
|
||||
if (passkey) {
|
||||
ble_opt_t opts;
|
||||
opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
|
||||
if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
default:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_BUSY:
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update default security parameters with function call parameters
|
||||
securityParameters.bond = enableBonding;
|
||||
securityParameters.mitm = requireMITM;
|
||||
securityParameters.io_caps = iocaps;
|
||||
|
||||
if (enableBonding) {
|
||||
securityParameters.kdist_own.enc = 1;
|
||||
securityParameters.kdist_own.id = 1;
|
||||
} else {
|
||||
securityParameters.kdist_own.enc = 0;
|
||||
securityParameters.kdist_own.id = 0;
|
||||
}
|
||||
rc = pm_sec_params_set(&securityParameters);
|
||||
|
||||
if (rc == NRF_SUCCESS) {
|
||||
rc = pm_register(pm_handler);
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_purgeAllBondingState(void)
|
||||
{
|
||||
ret_code_t rc;
|
||||
|
||||
async_ret_code = NRF_ERROR_BUSY;
|
||||
|
||||
rc = pm_peers_delete(); // it is asynhronous API
|
||||
|
||||
if (rc == NRF_SUCCESS)
|
||||
{
|
||||
// waiting for respond from pm_handler
|
||||
while (async_ret_code == NRF_ERROR_BUSY) {
|
||||
// busy-loop
|
||||
}
|
||||
|
||||
rc = async_ret_code;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
|
||||
{
|
||||
ret_code_t rc;
|
||||
pm_conn_sec_status_t conn_sec_status;
|
||||
|
||||
rc = pm_conn_sec_status_get(connectionHandle, &conn_sec_status);
|
||||
|
||||
if (rc == NRF_SUCCESS)
|
||||
{
|
||||
if (conn_sec_status.encrypted) {
|
||||
*securityStatusP = SecurityManager::ENCRYPTED;
|
||||
}
|
||||
else if (conn_sec_status.connected) {
|
||||
if (_enc_in_progress) {
|
||||
*securityStatusP = SecurityManager::ENCRYPTION_IN_PROGRESS;
|
||||
}
|
||||
else {
|
||||
*securityStatusP = SecurityManager::NOT_ENCRYPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
|
||||
{
|
||||
// use default and updated parameters as starting point
|
||||
// and modify structure based on security mode.
|
||||
ret_code_t rc;
|
||||
|
||||
switch (securityMode) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
|
||||
/**< Require no protection, open link. */
|
||||
securityParameters.bond = false;
|
||||
securityParameters.mitm = false;
|
||||
securityParameters.kdist_own.enc = 0;
|
||||
break;
|
||||
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
|
||||
/**< Require encryption, but no MITM protection. */
|
||||
securityParameters.bond = true;
|
||||
securityParameters.mitm = false;
|
||||
securityParameters.kdist_own.enc = 1;
|
||||
break;
|
||||
|
||||
// not yet implemented security modes
|
||||
case SecurityManager::SECURITY_MODE_NO_ACCESS:
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
|
||||
/**< Require encryption and MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
|
||||
/**< Require signing or encryption, but no MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
|
||||
/**< Require signing or encryption, and MITM protection. */
|
||||
default:
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// update security settings for given connection
|
||||
|
||||
rc = pm_sec_params_set(&securityParameters);
|
||||
|
||||
if (rc == NRF_SUCCESS) {
|
||||
rc = pm_conn_secure(connectionHandle, false);
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pm_handler(pm_evt_t const *p_event)
|
||||
{
|
||||
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
|
||||
ret_code_t err_code;
|
||||
SecurityManager::SecurityMode_t resolvedSecurityMode;
|
||||
|
||||
switch (p_event->evt_id) {
|
||||
case PM_EVT_CONN_SEC_START: /* started */ {
|
||||
const ble_gap_sec_params_t *peerParams = &securityParameters;
|
||||
securityManager.processSecuritySetupInitiatedEvent(p_event->conn_handle,
|
||||
peerParams->bond,
|
||||
peerParams->mitm,
|
||||
(SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
|
||||
_enc_in_progress = true;
|
||||
break;
|
||||
}
|
||||
case PM_EVT_CONN_SEC_SUCCEEDED:
|
||||
// Update the rank of the peer.
|
||||
if (p_event->params.conn_sec_succeeded.procedure == PM_LINK_SECURED_PROCEDURE_BONDING)
|
||||
{
|
||||
err_code = pm_peer_rank_highest(p_event->peer_id);
|
||||
}
|
||||
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->conn_handle,
|
||||
SecurityManager::SEC_STATUS_SUCCESS);// SEC_STATUS_SUCCESS of SecurityCompletionStatus_t
|
||||
|
||||
ble_gap_conn_sec_t conn_sec;
|
||||
sd_ble_gap_conn_sec_get(p_event->conn_handle, &conn_sec);
|
||||
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
|
||||
|
||||
switch (conn_sec.sec_mode.sm) {
|
||||
case 1:
|
||||
switch (conn_sec.sec_mode.lv) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
|
||||
break;
|
||||
case 3:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (conn_sec.sec_mode.lv) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
securityManager.processLinkSecuredEvent(p_event->conn_handle, resolvedSecurityMode);
|
||||
|
||||
_enc_in_progress = false;
|
||||
break;
|
||||
|
||||
case PM_EVT_CONN_SEC_FAILED:
|
||||
SecurityManager::SecurityCompletionStatus_t securityCompletionStatus;
|
||||
|
||||
if ((uint32_t)p_event->params.conn_sec_failed.error >= PM_CONN_SEC_ERROR_BASE ) {
|
||||
securityCompletionStatus = SecurityManager::SEC_STATUS_UNSPECIFIED;
|
||||
} else {
|
||||
securityCompletionStatus =
|
||||
(SecurityManager::SecurityCompletionStatus_t)p_event->params.conn_sec_failed.error;
|
||||
}
|
||||
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->conn_handle, securityCompletionStatus);
|
||||
|
||||
_enc_in_progress = false;
|
||||
break;
|
||||
|
||||
case PM_EVT_BONDED_PEER_CONNECTED:
|
||||
pm_peer_rank_highest(p_event->peer_id);
|
||||
break;
|
||||
|
||||
case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
|
||||
if (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
|
||||
{
|
||||
securityManager.processSecurityContextStoredEvent(p_event->conn_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case PM_EVT_PEER_DATA_UPDATE_FAILED:
|
||||
break;
|
||||
|
||||
case PM_EVT_PEERS_DELETE_SUCCEEDED:
|
||||
async_ret_code = NRF_SUCCESS; // respond SUCCESS to the busy-loop in f. btle_purgeAllBondingState
|
||||
break;
|
||||
|
||||
case PM_EVT_PEERS_DELETE_FAILED:
|
||||
async_ret_code = NRF_ERROR_INTERNAL; // respond FAILURE to the busy-loop in f. btle_purgeAllBondingState
|
||||
break;
|
||||
|
||||
case PM_EVT_STORAGE_FULL:
|
||||
// Run garbage collection on the flash.
|
||||
err_code = fds_gc();
|
||||
if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
|
||||
{
|
||||
// Retry.
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
break;//PM_EVT_STORAGE_FULL
|
||||
|
||||
case PM_EVT_CONN_SEC_CONFIG_REQ:{
|
||||
// A connected peer (central) is trying to pair, but the Peer Manager already has a bond
|
||||
// for that peer. Setting allow_repairing to false rejects the pairing request.
|
||||
// If this event is ignored (pm_conn_sec_config_reply is not called in the event
|
||||
// handler), the Peer Manager assumes allow_repairing to be false.
|
||||
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
|
||||
pm_conn_sec_config_reply(p_event->conn_handle, &conn_sec_config);
|
||||
}
|
||||
break;//PM_EVT_CONN_SEC_CONFIG_REQ
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
ble_error_t
|
||||
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
|
||||
{
|
||||
if (!btle_hasInitializedSecurity()) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
ret_code_t err = pm_whitelist_create( NULL, BLE_GAP_WHITELIST_ADDR_MAX_COUNT, p_whitelist);
|
||||
if (err == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else if (err == NRF_ERROR_NULL) {
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
} else {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool
|
||||
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
|
||||
{
|
||||
/*
|
||||
* Use a helper function from the Nordic SDK to test whether the BLE
|
||||
* address can be generated using the IRK.
|
||||
*/
|
||||
return im_address_resolve(p_addr, p_irk);
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address)
|
||||
{
|
||||
/* Set type to resolvable */
|
||||
address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
||||
|
||||
/*
|
||||
* Assign a random number to the most significant 3 bytes
|
||||
* of the address.
|
||||
*/
|
||||
address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C;
|
||||
|
||||
/* Calculate the hash and store it in the top half of the address */
|
||||
ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr);
|
||||
}
|
||||
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
ble_error_t btle_getAddressesFromBondTable(Gap::Whitelist_t &addrList)
|
||||
{
|
||||
pm_peer_id_t peer_id;
|
||||
ret_code_t ret;
|
||||
pm_peer_data_bonding_t bond_data;
|
||||
|
||||
addrList.size = 0;
|
||||
peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
|
||||
|
||||
/**
|
||||
* Fill addresses list:
|
||||
* Copy addresses from bond table, or
|
||||
* for every private resolvable address in the bond table generate the resolvable address.
|
||||
*/
|
||||
while ((peer_id != PM_PEER_ID_INVALID) && (addrList.capacity > addrList.size)) {
|
||||
memset(&bond_data, 0x00, sizeof(bond_data));
|
||||
|
||||
// Read peer data from flash.
|
||||
ret = pm_peer_data_bonding_load(peer_id, &bond_data);
|
||||
|
||||
if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) {
|
||||
// Peer data could not be found in flash or peer ID is not valid.
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (bond_data.peer_ble_id.id_addr_info.addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) {
|
||||
btle_generateResolvableAddress(bond_data.peer_ble_id.id_info,
|
||||
(ble_gap_addr_t &) addrList.addresses[addrList.size].address);
|
||||
} else {
|
||||
memcpy(&addrList.addresses[addrList.size].address,
|
||||
&bond_data.peer_ble_id.id_addr_info.addr,
|
||||
sizeof(addrList.addresses[0].address));
|
||||
}
|
||||
|
||||
addrList.addresses[addrList.size].type = static_cast<BLEProtocol::AddressType_t> (bond_data.peer_ble_id.id_addr_info.addr_type);
|
||||
|
||||
addrList.size++;
|
||||
|
||||
// get next peer id
|
||||
peer_id = pm_next_peer_id_get(peer_id);
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(S130) || defined(S132) || defined(S140)
|
||||
#endif
|
|
@ -26,11 +26,6 @@
|
|||
#include "ble_advdata.h"
|
||||
#include "headers/nrf_ble_hci.h"
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
#include "peer_manager.h"
|
||||
#include "peer_data_storage.h"
|
||||
#endif
|
||||
|
||||
|
||||
void radioNotificationStaticCallback(bool param) {
|
||||
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
|
||||
|
@ -962,75 +957,7 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const
|
|||
/**************************************************************************/
|
||||
ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
|
||||
{
|
||||
ble_gap_whitelist_t whitelistFromBondTable;
|
||||
ble_gap_addr_t *addressPtr[1];
|
||||
ble_gap_irk_t *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager();
|
||||
|
||||
if (securityManager.hasInitialized()) {
|
||||
/* We do not care about the addresses, set the count to 0 */
|
||||
whitelistFromBondTable.addr_count = 0;
|
||||
/* The Nordic SDK will return a failure if we set pp_addr to NULL */
|
||||
whitelistFromBondTable.pp_addrs = addressPtr;
|
||||
/* We want all the IRKs we can get because we do not know which ones match the addresses */
|
||||
whitelistFromBondTable.irk_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
|
||||
whitelistFromBondTable.pp_irks = irkPtr;
|
||||
|
||||
/* Use the security manager to get the IRKs from the bond table */
|
||||
ble_error_t error = securityManager.createWhitelistFromBondTable(whitelistFromBondTable);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* If there is no security manager then we cannot access the bond table,
|
||||
* so disable IRK matching
|
||||
*/
|
||||
whitelistFromBondTable.addr_count = 0;
|
||||
whitelistFromBondTable.irk_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* For every private resolvable address in the local whitelist check if
|
||||
* there is an IRK for said address in the bond table and add it to the
|
||||
* local IRK list.
|
||||
*/
|
||||
whitelist.irk_count = 0;
|
||||
whitelist.addr_count = 0;
|
||||
for (uint8_t i = 0; i < whitelistAddressesSize; ++i) {
|
||||
if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) {
|
||||
/* Test if there is a matching IRK for this private resolvable address */
|
||||
for (uint8_t j = 0; j < whitelistFromBondTable.irk_count; ++j) {
|
||||
if (securityManager.matchAddressAndIrk(&whitelistAddresses[i], whitelistFromBondTable.pp_irks[j])) {
|
||||
/* Found the corresponding IRK, add it to our local whitelist */
|
||||
whitelist.pp_irks[whitelist.irk_count] = whitelistFromBondTable.pp_irks[j];
|
||||
whitelist.irk_count++;
|
||||
/* Make sure we do not look at this IRK again */
|
||||
if (j != whitelistFromBondTable.irk_count - 1) {
|
||||
/**
|
||||
* This is not the last IRK, so replace the pointer
|
||||
* with the last pointer in the array
|
||||
*/
|
||||
whitelistFromBondTable.pp_irks[j] =
|
||||
whitelistFromBondTable.pp_irks[whitelistFromBondTable.irk_count - 1];
|
||||
}
|
||||
/**
|
||||
* If the IRK is the last pointer in the array simply
|
||||
* decrement the total IRK count
|
||||
*/
|
||||
whitelistFromBondTable.irk_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Include the address into the whitelist */
|
||||
whitelist.pp_addrs[whitelist.addr_count] = &whitelistAddresses[i];
|
||||
whitelist.addr_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1049,88 +976,7 @@ ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
|
|||
|
||||
ble_error_t nRF5xGap::getStackWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper)
|
||||
{
|
||||
using ble::pal::vendor::nordic::nRF5xSecurityManager;
|
||||
|
||||
pm_peer_id_t peer_id;
|
||||
|
||||
ret_code_t ret;
|
||||
|
||||
pm_peer_data_bonding_t bond_data;
|
||||
|
||||
uint8_t irk_found[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
|
||||
memset(irk_found, 0x00, sizeof(irk_found));
|
||||
|
||||
|
||||
gapAdrHelper.identities_cnt = 0;
|
||||
|
||||
|
||||
peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
|
||||
|
||||
nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager();
|
||||
|
||||
/**
|
||||
* Build identities list:
|
||||
* For every private resolvable address in the bond table check if
|
||||
* there is maching address in th provided whitelist.
|
||||
*/
|
||||
while (peer_id != PM_PEER_ID_INVALID)
|
||||
{
|
||||
memset(&bond_data, 0x00, sizeof(bond_data));
|
||||
|
||||
// Read peer data from flash.
|
||||
ret = pm_peer_data_bonding_load(peer_id, &bond_data);
|
||||
|
||||
|
||||
if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM))
|
||||
{
|
||||
// Peer data could not be found in flash or peer ID is not valid.
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if ( bond_data.peer_ble_id.id_addr_info.addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE)
|
||||
{
|
||||
for (uint8_t i = 0; i < whitelistAddressesSize; ++i)
|
||||
{
|
||||
if (!irk_found[i])
|
||||
{
|
||||
if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE)
|
||||
{
|
||||
|
||||
//ble_gap_irk_t *p_dfg = &bond_data.peer_ble_id.id_info;
|
||||
if (btle_matchAddressAndIrk(address, irk))
|
||||
{
|
||||
// Copy data to the buffer.
|
||||
memcpy(&gapAdrHelper.identities[i], &bond_data.peer_ble_id, sizeof(ble_gap_id_key_t));
|
||||
gapAdrHelper.identities_cnt++;
|
||||
|
||||
irk_found[i] = 1; // don't look at this address again
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get next peer id
|
||||
peer_id = pm_next_peer_id_get(peer_id);
|
||||
}
|
||||
|
||||
gapAdrHelper.addrs_cnt = 0;
|
||||
|
||||
/**
|
||||
* Build whitelist from the rest of addresses (explicit addresses)
|
||||
*/
|
||||
for (uint8_t i = 0; i < whitelistAddressesSize; ++i)
|
||||
{
|
||||
if (!irk_found[i])
|
||||
{
|
||||
memcpy(&gapAdrHelper.addrs[i], &whitelistAddresses[i], sizeof(ble_gap_addr_t));
|
||||
gapAdrHelper.addrs[i].addr_id_peer = 0;
|
||||
gapAdrHelper.addrs_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::applyWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper)
|
||||
|
|
|
@ -167,12 +167,13 @@ ble_error_t nRF5xSecurityManager::slave_security_request(
|
|||
//
|
||||
|
||||
ble_error_t nRF5xSecurityManager::enable_encryption(
|
||||
connection_handle_t connection,
|
||||
const ltk_t <k,
|
||||
const rand_t &rand,
|
||||
const ediv_t &ediv,
|
||||
bool mitm
|
||||
) {
|
||||
connection_handle_t connection,
|
||||
const ltk_t <k,
|
||||
const rand_t &rand,
|
||||
const ediv_t &ediv,
|
||||
bool mitm
|
||||
)
|
||||
{
|
||||
ble_gap_master_id_t master_id;
|
||||
ble_gap_enc_info_t enc_info;
|
||||
|
||||
|
@ -180,7 +181,30 @@ ble_error_t nRF5xSecurityManager::enable_encryption(
|
|||
memcpy(&master_id.ediv, ediv.data(), ediv.size());
|
||||
|
||||
memcpy(enc_info.ltk, ltk.data(), ltk.size());
|
||||
enc_info.lesc = _use_secure_connections;
|
||||
enc_info.lesc = false;
|
||||
enc_info.auth = mitm;
|
||||
enc_info.ltk_len = ltk.size();
|
||||
|
||||
uint32_t err = sd_ble_gap_encrypt(
|
||||
connection,
|
||||
&master_id,
|
||||
&enc_info
|
||||
);
|
||||
|
||||
return convert_sd_error(err);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xSecurityManager::enable_encryption(
|
||||
connection_handle_t connection,
|
||||
const ltk_t <k,
|
||||
bool mitm
|
||||
)
|
||||
{
|
||||
ble_gap_master_id_t master_id = {0};
|
||||
ble_gap_enc_info_t enc_info;
|
||||
|
||||
memcpy(enc_info.ltk, ltk.data(), ltk.size());
|
||||
enc_info.lesc = true;
|
||||
enc_info.auth = mitm;
|
||||
enc_info.ltk_len = ltk.size();
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
connection_handle_t connection,
|
||||
const ltk_t <k,
|
||||
bool mitm
|
||||
);
|
||||
) ;
|
||||
|
||||
/**
|
||||
* @see ::ble::pal::SecurityManager::encrypt_data
|
||||
|
|
|
@ -1,194 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __NRF51822_SECURITY_MANAGER_H__
|
||||
#define __NRF51822_SECURITY_MANAGER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "nRF5xGap.h"
|
||||
#include "ble/SecurityManager.h"
|
||||
#include "btle_security.h"
|
||||
|
||||
class nRF5xSecurityManager : public SecurityManager
|
||||
{
|
||||
public:
|
||||
/* Functions that must be implemented from SecurityManager */
|
||||
virtual ble_error_t init(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityIOCapabilities_t iocaps,
|
||||
const Passkey_t passkey) {
|
||||
return btle_initializeSecurity(enableBonding, requireMITM, iocaps, passkey);
|
||||
}
|
||||
|
||||
virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
|
||||
return btle_getLinkSecurity(connectionHandle, securityStatusP);
|
||||
}
|
||||
|
||||
virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) {
|
||||
return btle_setLinkSecurity(connectionHandle, securityMode);
|
||||
}
|
||||
|
||||
virtual ble_error_t purgeAllBondingState(void) {
|
||||
return btle_purgeAllBondingState();
|
||||
}
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @return
|
||||
* BLE_ERROR_NONE if successful.
|
||||
*/
|
||||
virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
|
||||
uint8_t i;
|
||||
|
||||
ble_gap_whitelist_t whitelistFromBondTable;
|
||||
ble_gap_addr_t *addressPtr[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
ble_gap_irk_t *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
/* Initialize the structure so that we get as many addreses as the whitelist can hold */
|
||||
whitelistFromBondTable.addr_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
|
||||
whitelistFromBondTable.pp_addrs = addressPtr;
|
||||
whitelistFromBondTable.irk_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
|
||||
whitelistFromBondTable.pp_irks = irkPtr;
|
||||
|
||||
ble_error_t error = createWhitelistFromBondTable(whitelistFromBondTable);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
addresses.size = 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Put all the addresses in the structure */
|
||||
for (i = 0; i < whitelistFromBondTable.addr_count; ++i) {
|
||||
if (i >= addresses.capacity) {
|
||||
/* Ran out of space in the output Gap::Whitelist_t */
|
||||
addresses.size = i;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
memcpy(&addresses.addresses[i], whitelistFromBondTable.pp_addrs[i], sizeof(BLEProtocol::Address_t));
|
||||
}
|
||||
|
||||
/* Update the current address count */
|
||||
addresses.size = i;
|
||||
|
||||
/* The assumption here is that the underlying implementation of
|
||||
* createWhitelistFromBondTable() will not return the private resolvable
|
||||
* addresses (which is the case in the SoftDevice). Rather it returns the
|
||||
* IRKs, so we need to generate the private resolvable address by ourselves.
|
||||
*/
|
||||
for (i = 0; i < whitelistFromBondTable.irk_count; ++i) {
|
||||
if (i + addresses.size >= addresses.capacity) {
|
||||
/* Ran out of space in the output Gap::Whitelist_t */
|
||||
addresses.size += i;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
btle_generateResolvableAddress(
|
||||
*whitelistFromBondTable.pp_irks[i],
|
||||
(ble_gap_addr_t &) addresses.addresses[i + addresses.size]
|
||||
);
|
||||
}
|
||||
|
||||
/* Update the current address count */
|
||||
addresses.size += i;
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
#else // -> NRF_SD_BLE_API_VERSION >= 3
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE if successful.
|
||||
* @retval BLE_ERROR_UNSPECIFIED Bond data could not be found in flash or is inconsistent.
|
||||
*/
|
||||
virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
|
||||
return btle_getAddressesFromBondTable(addresses);
|
||||
}
|
||||
#endif // #if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear nRF5xSecurityManager's state.
|
||||
*
|
||||
* @return
|
||||
* BLE_ERROR_NONE if successful.
|
||||
*/
|
||||
virtual ble_error_t reset(void)
|
||||
{
|
||||
if (SecurityManager::reset() != BLE_ERROR_NONE) {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool hasInitialized(void) const {
|
||||
return btle_hasInitializedSecurity();
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
* Allow instantiation from nRF5xn when required.
|
||||
*/
|
||||
friend class nRF5xn;
|
||||
|
||||
nRF5xSecurityManager() {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
private:
|
||||
nRF5xSecurityManager(const nRF5xSecurityManager &);
|
||||
const nRF5xSecurityManager& operator=(const nRF5xSecurityManager &);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/*
|
||||
* Expose an interface that allows us to query the SoftDevice bond table
|
||||
* and extract a whitelist.
|
||||
*/
|
||||
ble_error_t createWhitelistFromBondTable(ble_gap_whitelist_t &whitelistFromBondTable) const {
|
||||
return btle_createWhitelistFromBondTable(&whitelistFromBondTable);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Given a BLE address and a IRK this function check whether the address
|
||||
* can be generated from the IRK. To do so, this function uses the hash
|
||||
* function and algorithm described in the Bluetooth low Energy
|
||||
* Specification. Internally, Nordic SDK functions are used.
|
||||
*/
|
||||
bool matchAddressAndIrk(ble_gap_addr_t *address, ble_gap_irk_t *irk) const {
|
||||
return btle_matchAddressAndIrk(address, irk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give nRF5xGap access to createWhitelistFromBondTable() and
|
||||
* matchAddressAndIrk()
|
||||
*/
|
||||
friend class nRF5xGap;
|
||||
};
|
||||
|
||||
#endif // ifndef __NRF51822_SECURITY_MANAGER_H__
|
Loading…
Reference in New Issue