nordic

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:36 2016 +0000
Revision:
600:3e66e1eb264d
Parent:
599:814c1ce92947
Child:
614:cbc548e9df98
Synchronized with git rev 2ebbcb08
Author: Andres Amaya Garcia
Add documentation and fix style of SecurityManager

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 542:884f95bf5351 1 /* mbed Microcontroller Library
vcoubard 542:884f95bf5351 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 542:884f95bf5351 3 *
vcoubard 542:884f95bf5351 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 542:884f95bf5351 5 * you may not use this file except in compliance with the License.
vcoubard 542:884f95bf5351 6 * You may obtain a copy of the License at
vcoubard 542:884f95bf5351 7 *
vcoubard 542:884f95bf5351 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 542:884f95bf5351 9 *
vcoubard 542:884f95bf5351 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 542:884f95bf5351 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 542:884f95bf5351 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 542:884f95bf5351 13 * See the License for the specific language governing permissions and
vcoubard 542:884f95bf5351 14 * limitations under the License.
vcoubard 542:884f95bf5351 15 */
vcoubard 542:884f95bf5351 16
vcoubard 542:884f95bf5351 17 #include "btle.h"
vcoubard 542:884f95bf5351 18
vcoubard 576:7023a8204a1b 19 #include "nRF5xn.h"
vcoubard 542:884f95bf5351 20
vcoubard 550:3f782c64d014 21 extern "C" {
vcoubard 550:3f782c64d014 22 #include "pstorage.h"
vcoubard 542:884f95bf5351 23 #include "device_manager.h"
vcoubard 599:814c1ce92947 24 #include "id_manager.h"
vcoubard 550:3f782c64d014 25 }
vcoubard 550:3f782c64d014 26
vcoubard 542:884f95bf5351 27 #include "btle_security.h"
vcoubard 542:884f95bf5351 28
vcoubard 542:884f95bf5351 29 static dm_application_instance_t applicationInstance;
vcoubard 599:814c1ce92947 30 static bool initialized = false;
vcoubard 542:884f95bf5351 31 static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result);
vcoubard 542:884f95bf5351 32
vcoubard 559:c4b56f9d6f3b 33 // default security parameters
vcoubard 559:c4b56f9d6f3b 34 static ble_gap_sec_params_t securityParameters = {
vcoubard 559:c4b56f9d6f3b 35 .bond = true, /**< Perform bonding. */
vcoubard 559:c4b56f9d6f3b 36 .mitm = true, /**< Man In The Middle protection required. */
vcoubard 559:c4b56f9d6f3b 37 .io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
vcoubard 559:c4b56f9d6f3b 38 .oob = 0, /**< Out Of Band data available. */
vcoubard 559:c4b56f9d6f3b 39 .min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
vcoubard 559:c4b56f9d6f3b 40 .max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
vcoubard 559:c4b56f9d6f3b 41 .kdist_periph = {
vcoubard 559:c4b56f9d6f3b 42 .enc = 1, /**< Long Term Key and Master Identification. */
vcoubard 559:c4b56f9d6f3b 43 .id = 1, /**< Identity Resolving Key and Identity Address Information. */
vcoubard 559:c4b56f9d6f3b 44 .sign = 1, /**< Connection Signature Resolving Key. */
vcoubard 559:c4b56f9d6f3b 45 }, /**< Key distribution bitmap: keys that the peripheral device will distribute. */
vcoubard 559:c4b56f9d6f3b 46 };
vcoubard 559:c4b56f9d6f3b 47
vcoubard 600:3e66e1eb264d 48 bool
vcoubard 600:3e66e1eb264d 49 btle_hasInitializedSecurity(void)
vcoubard 599:814c1ce92947 50 {
vcoubard 599:814c1ce92947 51 return initialized;
vcoubard 599:814c1ce92947 52 }
vcoubard 599:814c1ce92947 53
vcoubard 542:884f95bf5351 54 ble_error_t
vcoubard 542:884f95bf5351 55 btle_initializeSecurity(bool enableBonding,
vcoubard 542:884f95bf5351 56 bool requireMITM,
vcoubard 542:884f95bf5351 57 SecurityManager::SecurityIOCapabilities_t iocaps,
vcoubard 542:884f95bf5351 58 const SecurityManager::Passkey_t passkey)
vcoubard 542:884f95bf5351 59 {
vcoubard 542:884f95bf5351 60 /* guard against multiple initializations */
vcoubard 542:884f95bf5351 61 if (initialized) {
vcoubard 542:884f95bf5351 62 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 63 }
vcoubard 542:884f95bf5351 64
vcoubard 542:884f95bf5351 65 if (pstorage_init() != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 66 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 67 }
vcoubard 542:884f95bf5351 68
vcoubard 542:884f95bf5351 69 ret_code_t rc;
vcoubard 542:884f95bf5351 70 if (passkey) {
vcoubard 542:884f95bf5351 71 ble_opt_t opts;
vcoubard 542:884f95bf5351 72 opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
vcoubard 542:884f95bf5351 73 if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 74 switch (rc) {
vcoubard 542:884f95bf5351 75 case BLE_ERROR_INVALID_CONN_HANDLE:
vcoubard 542:884f95bf5351 76 case NRF_ERROR_INVALID_ADDR:
vcoubard 542:884f95bf5351 77 case NRF_ERROR_INVALID_PARAM:
vcoubard 542:884f95bf5351 78 default:
vcoubard 542:884f95bf5351 79 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:884f95bf5351 80 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 81 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 82 case NRF_ERROR_BUSY:
vcoubard 542:884f95bf5351 83 return BLE_STACK_BUSY;
vcoubard 542:884f95bf5351 84 }
vcoubard 542:884f95bf5351 85 }
vcoubard 542:884f95bf5351 86 }
vcoubard 542:884f95bf5351 87
vcoubard 542:884f95bf5351 88 dm_init_param_t dm_init_param = {
vcoubard 542:884f95bf5351 89 .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
vcoubard 542:884f95bf5351 90 };
vcoubard 542:884f95bf5351 91 if (dm_init(&dm_init_param) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 92 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 93 }
vcoubard 542:884f95bf5351 94
vcoubard 559:c4b56f9d6f3b 95 // update default security parameters with function call parameters
vcoubard 559:c4b56f9d6f3b 96 securityParameters.bond = enableBonding;
vcoubard 559:c4b56f9d6f3b 97 securityParameters.mitm = requireMITM;
vcoubard 559:c4b56f9d6f3b 98 securityParameters.io_caps = iocaps;
vcoubard 559:c4b56f9d6f3b 99
vcoubard 542:884f95bf5351 100 const dm_application_param_t dm_param = {
vcoubard 542:884f95bf5351 101 .evt_handler = dm_handler,
vcoubard 542:884f95bf5351 102 .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
vcoubard 559:c4b56f9d6f3b 103 .sec_param = securityParameters
vcoubard 542:884f95bf5351 104 };
vcoubard 542:884f95bf5351 105
vcoubard 542:884f95bf5351 106 if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 107 switch (rc) {
vcoubard 542:884f95bf5351 108 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 109 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 110 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 111 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 112 default:
vcoubard 542:884f95bf5351 113 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 114 }
vcoubard 542:884f95bf5351 115 }
vcoubard 542:884f95bf5351 116
vcoubard 542:884f95bf5351 117 initialized = true;
vcoubard 542:884f95bf5351 118 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 119 }
vcoubard 542:884f95bf5351 120
vcoubard 542:884f95bf5351 121 ble_error_t
vcoubard 542:884f95bf5351 122 btle_purgeAllBondingState(void)
vcoubard 542:884f95bf5351 123 {
vcoubard 542:884f95bf5351 124 ret_code_t rc;
vcoubard 542:884f95bf5351 125 if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
vcoubard 542:884f95bf5351 126 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 127 }
vcoubard 542:884f95bf5351 128
vcoubard 542:884f95bf5351 129 switch (rc) {
vcoubard 542:884f95bf5351 130 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 131 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 132 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 133 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 134 default:
vcoubard 542:884f95bf5351 135 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 136 }
vcoubard 542:884f95bf5351 137 }
vcoubard 542:884f95bf5351 138
vcoubard 542:884f95bf5351 139 ble_error_t
vcoubard 542:884f95bf5351 140 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
vcoubard 542:884f95bf5351 141 {
vcoubard 542:884f95bf5351 142 ret_code_t rc;
vcoubard 542:884f95bf5351 143 dm_handle_t dmHandle = {
vcoubard 542:884f95bf5351 144 .appl_id = applicationInstance,
vcoubard 542:884f95bf5351 145 };
vcoubard 542:884f95bf5351 146 if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 147 if (rc == NRF_ERROR_NOT_FOUND) {
vcoubard 542:884f95bf5351 148 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:884f95bf5351 149 } else {
vcoubard 542:884f95bf5351 150 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 151 }
vcoubard 542:884f95bf5351 152 }
vcoubard 542:884f95bf5351 153
vcoubard 542:884f95bf5351 154 if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 155 switch (rc) {
vcoubard 542:884f95bf5351 156 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 157 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 158 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 159 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 160 default:
vcoubard 542:884f95bf5351 161 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 162 }
vcoubard 542:884f95bf5351 163 }
vcoubard 542:884f95bf5351 164
vcoubard 542:884f95bf5351 165 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 166 }
vcoubard 542:884f95bf5351 167
vcoubard 559:c4b56f9d6f3b 168 ble_error_t
vcoubard 559:c4b56f9d6f3b 169 btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
vcoubard 559:c4b56f9d6f3b 170 {
vcoubard 559:c4b56f9d6f3b 171 // use default and updated parameters as starting point
vcoubard 559:c4b56f9d6f3b 172 // and modify structure based on security mode.
vcoubard 559:c4b56f9d6f3b 173 ble_gap_sec_params_t params = securityParameters;
vcoubard 559:c4b56f9d6f3b 174
vcoubard 559:c4b56f9d6f3b 175 switch (securityMode) {
vcoubard 559:c4b56f9d6f3b 176 case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
vcoubard 559:c4b56f9d6f3b 177 /**< Require no protection, open link. */
vcoubard 559:c4b56f9d6f3b 178 securityParameters.bond = false;
vcoubard 559:c4b56f9d6f3b 179 securityParameters.mitm = false;
vcoubard 559:c4b56f9d6f3b 180 break;
vcoubard 559:c4b56f9d6f3b 181
vcoubard 559:c4b56f9d6f3b 182 case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
vcoubard 559:c4b56f9d6f3b 183 /**< Require encryption, but no MITM protection. */
vcoubard 559:c4b56f9d6f3b 184 securityParameters.bond = true;
vcoubard 559:c4b56f9d6f3b 185 securityParameters.mitm = false;
vcoubard 559:c4b56f9d6f3b 186 break;
vcoubard 559:c4b56f9d6f3b 187
vcoubard 559:c4b56f9d6f3b 188 // not yet implemented security modes
vcoubard 559:c4b56f9d6f3b 189 case SecurityManager::SECURITY_MODE_NO_ACCESS:
vcoubard 559:c4b56f9d6f3b 190 case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
vcoubard 559:c4b56f9d6f3b 191 /**< Require encryption and MITM protection. */
vcoubard 559:c4b56f9d6f3b 192 case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
vcoubard 559:c4b56f9d6f3b 193 /**< Require signing or encryption, but no MITM protection. */
vcoubard 559:c4b56f9d6f3b 194 case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
vcoubard 559:c4b56f9d6f3b 195 /**< Require signing or encryption, and MITM protection. */
vcoubard 559:c4b56f9d6f3b 196 default:
vcoubard 559:c4b56f9d6f3b 197 return BLE_ERROR_NOT_IMPLEMENTED;
vcoubard 559:c4b56f9d6f3b 198 }
vcoubard 559:c4b56f9d6f3b 199
vcoubard 559:c4b56f9d6f3b 200 // update security settings for given connection
vcoubard 559:c4b56f9d6f3b 201 uint32_t result = sd_ble_gap_authenticate(connectionHandle, &params);
vcoubard 559:c4b56f9d6f3b 202
vcoubard 559:c4b56f9d6f3b 203 if (result == NRF_SUCCESS) {
vcoubard 559:c4b56f9d6f3b 204 return BLE_ERROR_NONE;
vcoubard 559:c4b56f9d6f3b 205 } else {
vcoubard 559:c4b56f9d6f3b 206 return BLE_ERROR_UNSPECIFIED;
vcoubard 559:c4b56f9d6f3b 207 }
vcoubard 559:c4b56f9d6f3b 208 }
vcoubard 559:c4b56f9d6f3b 209
vcoubard 542:884f95bf5351 210 ret_code_t
vcoubard 542:884f95bf5351 211 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
vcoubard 542:884f95bf5351 212 {
vcoubard 576:7023a8204a1b 213 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
vcoubard 576:7023a8204a1b 214 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
vcoubard 576:7023a8204a1b 215
vcoubard 542:884f95bf5351 216 switch (p_event->event_id) {
vcoubard 542:884f95bf5351 217 case DM_EVT_SECURITY_SETUP: /* started */ {
vcoubard 542:884f95bf5351 218 const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
vcoubard 576:7023a8204a1b 219 securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 542:884f95bf5351 220 peerParams->bond,
vcoubard 542:884f95bf5351 221 peerParams->mitm,
vcoubard 542:884f95bf5351 222 (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
vcoubard 542:884f95bf5351 223 break;
vcoubard 542:884f95bf5351 224 }
vcoubard 542:884f95bf5351 225 case DM_EVT_SECURITY_SETUP_COMPLETE:
vcoubard 576:7023a8204a1b 226 securityManager.
vcoubard 542:884f95bf5351 227 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 542:884f95bf5351 228 (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
vcoubard 542:884f95bf5351 229 break;
vcoubard 542:884f95bf5351 230 case DM_EVT_LINK_SECURED: {
vcoubard 542:884f95bf5351 231 unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
vcoubard 542:884f95bf5351 232 unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
vcoubard 542:884f95bf5351 233 SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
vcoubard 542:884f95bf5351 234 switch (securityMode) {
vcoubard 542:884f95bf5351 235 case 1:
vcoubard 542:884f95bf5351 236 switch (level) {
vcoubard 542:884f95bf5351 237 case 1:
vcoubard 542:884f95bf5351 238 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
vcoubard 542:884f95bf5351 239 break;
vcoubard 542:884f95bf5351 240 case 2:
vcoubard 542:884f95bf5351 241 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
vcoubard 542:884f95bf5351 242 break;
vcoubard 542:884f95bf5351 243 case 3:
vcoubard 542:884f95bf5351 244 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
vcoubard 542:884f95bf5351 245 break;
vcoubard 542:884f95bf5351 246 }
vcoubard 542:884f95bf5351 247 break;
vcoubard 542:884f95bf5351 248 case 2:
vcoubard 542:884f95bf5351 249 switch (level) {
vcoubard 542:884f95bf5351 250 case 1:
vcoubard 542:884f95bf5351 251 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
vcoubard 542:884f95bf5351 252 break;
vcoubard 542:884f95bf5351 253 case 2:
vcoubard 542:884f95bf5351 254 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
vcoubard 542:884f95bf5351 255 break;
vcoubard 542:884f95bf5351 256 }
vcoubard 542:884f95bf5351 257 break;
vcoubard 542:884f95bf5351 258 }
vcoubard 542:884f95bf5351 259
vcoubard 576:7023a8204a1b 260 securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
vcoubard 542:884f95bf5351 261 break;
vcoubard 542:884f95bf5351 262 }
vcoubard 542:884f95bf5351 263 case DM_EVT_DEVICE_CONTEXT_STORED:
vcoubard 576:7023a8204a1b 264 securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
vcoubard 542:884f95bf5351 265 break;
vcoubard 542:884f95bf5351 266 default:
vcoubard 542:884f95bf5351 267 break;
vcoubard 542:884f95bf5351 268 }
vcoubard 542:884f95bf5351 269
vcoubard 542:884f95bf5351 270 return NRF_SUCCESS;
vcoubard 599:814c1ce92947 271 }
vcoubard 599:814c1ce92947 272
vcoubard 600:3e66e1eb264d 273 ble_error_t
vcoubard 600:3e66e1eb264d 274 btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
vcoubard 599:814c1ce92947 275 {
vcoubard 600:3e66e1eb264d 276 ret_code_t err = dm_whitelist_create(&applicationInstance, p_whitelist);
vcoubard 600:3e66e1eb264d 277 if (err == NRF_SUCCESS) {
vcoubard 600:3e66e1eb264d 278 return BLE_ERROR_NONE;
vcoubard 600:3e66e1eb264d 279 } else if (err == NRF_ERROR_NULL) {
vcoubard 600:3e66e1eb264d 280 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 600:3e66e1eb264d 281 } else {
vcoubard 600:3e66e1eb264d 282 return BLE_ERROR_INVALID_STATE;
vcoubard 600:3e66e1eb264d 283 }
vcoubard 600:3e66e1eb264d 284 }
vcoubard 600:3e66e1eb264d 285
vcoubard 600:3e66e1eb264d 286
vcoubard 600:3e66e1eb264d 287 bool
vcoubard 600:3e66e1eb264d 288 btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
vcoubard 600:3e66e1eb264d 289 {
vcoubard 600:3e66e1eb264d 290 /*
vcoubard 600:3e66e1eb264d 291 * Use a helper function from the Nordic SDK to test whether the BLE
vcoubard 600:3e66e1eb264d 292 * address can be generated using the IRK.
vcoubard 600:3e66e1eb264d 293 */
vcoubard 599:814c1ce92947 294 return im_address_resolve(p_addr, p_irk);
rgrover1 134:74079098b3c9 295 }