nordic

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:13 2016 +0000
Revision:
559:c4b56f9d6f3b
Parent:
550:3f782c64d014
Child:
566:cf03471a4ec4
Synchronized with git rev b2cb5663
Author: Marcus Chang
Added SecurityManager::setLinkSecurity call for elevating security settings on a particular connection.

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 542:884f95bf5351 19 #include "nRF5xGap.h"
vcoubard 542:884f95bf5351 20 #include "nRF5xSecurityManager.h"
vcoubard 542:884f95bf5351 21
vcoubard 550:3f782c64d014 22 extern "C" {
vcoubard 550:3f782c64d014 23 #include "pstorage.h"
vcoubard 542:884f95bf5351 24 #include "device_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 542:884f95bf5351 30 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 31
vcoubard 559:c4b56f9d6f3b 32 // default security parameters
vcoubard 559:c4b56f9d6f3b 33 static ble_gap_sec_params_t securityParameters = {
vcoubard 559:c4b56f9d6f3b 34 .bond = true, /**< Perform bonding. */
vcoubard 559:c4b56f9d6f3b 35 .mitm = true, /**< Man In The Middle protection required. */
vcoubard 559:c4b56f9d6f3b 36 .io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
vcoubard 559:c4b56f9d6f3b 37 .oob = 0, /**< Out Of Band data available. */
vcoubard 559:c4b56f9d6f3b 38 .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 39 .max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
vcoubard 559:c4b56f9d6f3b 40 .kdist_periph = {
vcoubard 559:c4b56f9d6f3b 41 .enc = 1, /**< Long Term Key and Master Identification. */
vcoubard 559:c4b56f9d6f3b 42 .id = 1, /**< Identity Resolving Key and Identity Address Information. */
vcoubard 559:c4b56f9d6f3b 43 .sign = 1, /**< Connection Signature Resolving Key. */
vcoubard 559:c4b56f9d6f3b 44 }, /**< Key distribution bitmap: keys that the peripheral device will distribute. */
vcoubard 559:c4b56f9d6f3b 45 };
vcoubard 559:c4b56f9d6f3b 46
vcoubard 542:884f95bf5351 47 ble_error_t
vcoubard 542:884f95bf5351 48 btle_initializeSecurity(bool enableBonding,
vcoubard 542:884f95bf5351 49 bool requireMITM,
vcoubard 542:884f95bf5351 50 SecurityManager::SecurityIOCapabilities_t iocaps,
vcoubard 542:884f95bf5351 51 const SecurityManager::Passkey_t passkey)
vcoubard 542:884f95bf5351 52 {
vcoubard 542:884f95bf5351 53 /* guard against multiple initializations */
vcoubard 542:884f95bf5351 54 static bool initialized = false;
vcoubard 542:884f95bf5351 55 if (initialized) {
vcoubard 542:884f95bf5351 56 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 57 }
vcoubard 542:884f95bf5351 58
vcoubard 542:884f95bf5351 59 if (pstorage_init() != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 60 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 61 }
vcoubard 542:884f95bf5351 62
vcoubard 542:884f95bf5351 63 ret_code_t rc;
vcoubard 542:884f95bf5351 64 if (passkey) {
vcoubard 542:884f95bf5351 65 ble_opt_t opts;
vcoubard 542:884f95bf5351 66 opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
vcoubard 542:884f95bf5351 67 if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 68 switch (rc) {
vcoubard 542:884f95bf5351 69 case BLE_ERROR_INVALID_CONN_HANDLE:
vcoubard 542:884f95bf5351 70 case NRF_ERROR_INVALID_ADDR:
vcoubard 542:884f95bf5351 71 case NRF_ERROR_INVALID_PARAM:
vcoubard 542:884f95bf5351 72 default:
vcoubard 542:884f95bf5351 73 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:884f95bf5351 74 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 75 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 76 case NRF_ERROR_BUSY:
vcoubard 542:884f95bf5351 77 return BLE_STACK_BUSY;
vcoubard 542:884f95bf5351 78 }
vcoubard 542:884f95bf5351 79 }
vcoubard 542:884f95bf5351 80 }
vcoubard 542:884f95bf5351 81
vcoubard 542:884f95bf5351 82 dm_init_param_t dm_init_param = {
vcoubard 542:884f95bf5351 83 .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
vcoubard 542:884f95bf5351 84 };
vcoubard 542:884f95bf5351 85 if (dm_init(&dm_init_param) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 86 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 87 }
vcoubard 542:884f95bf5351 88
vcoubard 559:c4b56f9d6f3b 89 // update default security parameters with function call parameters
vcoubard 559:c4b56f9d6f3b 90 securityParameters.bond = enableBonding;
vcoubard 559:c4b56f9d6f3b 91 securityParameters.mitm = requireMITM;
vcoubard 559:c4b56f9d6f3b 92 securityParameters.io_caps = iocaps;
vcoubard 559:c4b56f9d6f3b 93
vcoubard 542:884f95bf5351 94 const dm_application_param_t dm_param = {
vcoubard 542:884f95bf5351 95 .evt_handler = dm_handler,
vcoubard 542:884f95bf5351 96 .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
vcoubard 559:c4b56f9d6f3b 97 .sec_param = securityParameters
vcoubard 542:884f95bf5351 98 };
vcoubard 542:884f95bf5351 99
vcoubard 542:884f95bf5351 100 if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 101 switch (rc) {
vcoubard 542:884f95bf5351 102 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 103 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 104 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 105 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 106 default:
vcoubard 542:884f95bf5351 107 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 108 }
vcoubard 542:884f95bf5351 109 }
vcoubard 542:884f95bf5351 110
vcoubard 542:884f95bf5351 111 initialized = true;
vcoubard 542:884f95bf5351 112 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 113 }
vcoubard 542:884f95bf5351 114
vcoubard 542:884f95bf5351 115 ble_error_t
vcoubard 542:884f95bf5351 116 btle_purgeAllBondingState(void)
vcoubard 542:884f95bf5351 117 {
vcoubard 542:884f95bf5351 118 ret_code_t rc;
vcoubard 542:884f95bf5351 119 if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
vcoubard 542:884f95bf5351 120 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 121 }
vcoubard 542:884f95bf5351 122
vcoubard 542:884f95bf5351 123 switch (rc) {
vcoubard 542:884f95bf5351 124 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 125 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 126 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 127 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 128 default:
vcoubard 542:884f95bf5351 129 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 130 }
vcoubard 542:884f95bf5351 131 }
vcoubard 542:884f95bf5351 132
vcoubard 542:884f95bf5351 133 ble_error_t
vcoubard 542:884f95bf5351 134 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
vcoubard 542:884f95bf5351 135 {
vcoubard 542:884f95bf5351 136 ret_code_t rc;
vcoubard 542:884f95bf5351 137 dm_handle_t dmHandle = {
vcoubard 542:884f95bf5351 138 .appl_id = applicationInstance,
vcoubard 542:884f95bf5351 139 };
vcoubard 542:884f95bf5351 140 if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 141 if (rc == NRF_ERROR_NOT_FOUND) {
vcoubard 542:884f95bf5351 142 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:884f95bf5351 143 } else {
vcoubard 542:884f95bf5351 144 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 145 }
vcoubard 542:884f95bf5351 146 }
vcoubard 542:884f95bf5351 147
vcoubard 542:884f95bf5351 148 if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
vcoubard 542:884f95bf5351 149 switch (rc) {
vcoubard 542:884f95bf5351 150 case NRF_ERROR_INVALID_STATE:
vcoubard 542:884f95bf5351 151 return BLE_ERROR_INVALID_STATE;
vcoubard 542:884f95bf5351 152 case NRF_ERROR_NO_MEM:
vcoubard 542:884f95bf5351 153 return BLE_ERROR_NO_MEM;
vcoubard 542:884f95bf5351 154 default:
vcoubard 542:884f95bf5351 155 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:884f95bf5351 156 }
vcoubard 542:884f95bf5351 157 }
vcoubard 542:884f95bf5351 158
vcoubard 542:884f95bf5351 159 return BLE_ERROR_NONE;
vcoubard 542:884f95bf5351 160 }
vcoubard 542:884f95bf5351 161
vcoubard 559:c4b56f9d6f3b 162 ble_error_t
vcoubard 559:c4b56f9d6f3b 163 btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
vcoubard 559:c4b56f9d6f3b 164 {
vcoubard 559:c4b56f9d6f3b 165 // use default and updated parameters as starting point
vcoubard 559:c4b56f9d6f3b 166 // and modify structure based on security mode.
vcoubard 559:c4b56f9d6f3b 167 ble_gap_sec_params_t params = securityParameters;
vcoubard 559:c4b56f9d6f3b 168
vcoubard 559:c4b56f9d6f3b 169 switch (securityMode) {
vcoubard 559:c4b56f9d6f3b 170 case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
vcoubard 559:c4b56f9d6f3b 171 /**< Require no protection, open link. */
vcoubard 559:c4b56f9d6f3b 172 securityParameters.bond = false;
vcoubard 559:c4b56f9d6f3b 173 securityParameters.mitm = false;
vcoubard 559:c4b56f9d6f3b 174 break;
vcoubard 559:c4b56f9d6f3b 175
vcoubard 559:c4b56f9d6f3b 176 case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
vcoubard 559:c4b56f9d6f3b 177 /**< Require encryption, but no MITM protection. */
vcoubard 559:c4b56f9d6f3b 178 securityParameters.bond = true;
vcoubard 559:c4b56f9d6f3b 179 securityParameters.mitm = false;
vcoubard 559:c4b56f9d6f3b 180 break;
vcoubard 559:c4b56f9d6f3b 181
vcoubard 559:c4b56f9d6f3b 182 // not yet implemented security modes
vcoubard 559:c4b56f9d6f3b 183 case SecurityManager::SECURITY_MODE_NO_ACCESS:
vcoubard 559:c4b56f9d6f3b 184 case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
vcoubard 559:c4b56f9d6f3b 185 /**< Require encryption and MITM protection. */
vcoubard 559:c4b56f9d6f3b 186 case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
vcoubard 559:c4b56f9d6f3b 187 /**< Require signing or encryption, but no MITM protection. */
vcoubard 559:c4b56f9d6f3b 188 case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
vcoubard 559:c4b56f9d6f3b 189 /**< Require signing or encryption, and MITM protection. */
vcoubard 559:c4b56f9d6f3b 190 default:
vcoubard 559:c4b56f9d6f3b 191 return BLE_ERROR_NOT_IMPLEMENTED;
vcoubard 559:c4b56f9d6f3b 192 }
vcoubard 559:c4b56f9d6f3b 193
vcoubard 559:c4b56f9d6f3b 194 // update security settings for given connection
vcoubard 559:c4b56f9d6f3b 195 uint32_t result = sd_ble_gap_authenticate(connectionHandle, &params);
vcoubard 559:c4b56f9d6f3b 196
vcoubard 559:c4b56f9d6f3b 197 if (result == NRF_SUCCESS) {
vcoubard 559:c4b56f9d6f3b 198 return BLE_ERROR_NONE;
vcoubard 559:c4b56f9d6f3b 199 } else {
vcoubard 559:c4b56f9d6f3b 200 return BLE_ERROR_UNSPECIFIED;
vcoubard 559:c4b56f9d6f3b 201 }
vcoubard 559:c4b56f9d6f3b 202 }
vcoubard 559:c4b56f9d6f3b 203
vcoubard 542:884f95bf5351 204 ret_code_t
vcoubard 542:884f95bf5351 205 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
vcoubard 542:884f95bf5351 206 {
vcoubard 542:884f95bf5351 207 switch (p_event->event_id) {
vcoubard 542:884f95bf5351 208 case DM_EVT_SECURITY_SETUP: /* started */ {
vcoubard 542:884f95bf5351 209 const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
vcoubard 542:884f95bf5351 210 nRF5xSecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 542:884f95bf5351 211 peerParams->bond,
vcoubard 542:884f95bf5351 212 peerParams->mitm,
vcoubard 542:884f95bf5351 213 (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
vcoubard 542:884f95bf5351 214 break;
vcoubard 542:884f95bf5351 215 }
vcoubard 542:884f95bf5351 216 case DM_EVT_SECURITY_SETUP_COMPLETE:
vcoubard 542:884f95bf5351 217 nRF5xSecurityManager::getInstance().
vcoubard 542:884f95bf5351 218 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 542:884f95bf5351 219 (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
vcoubard 542:884f95bf5351 220 break;
vcoubard 542:884f95bf5351 221 case DM_EVT_LINK_SECURED: {
vcoubard 542:884f95bf5351 222 unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
vcoubard 542:884f95bf5351 223 unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
vcoubard 542:884f95bf5351 224 SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
vcoubard 542:884f95bf5351 225 switch (securityMode) {
vcoubard 542:884f95bf5351 226 case 1:
vcoubard 542:884f95bf5351 227 switch (level) {
vcoubard 542:884f95bf5351 228 case 1:
vcoubard 542:884f95bf5351 229 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
vcoubard 542:884f95bf5351 230 break;
vcoubard 542:884f95bf5351 231 case 2:
vcoubard 542:884f95bf5351 232 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
vcoubard 542:884f95bf5351 233 break;
vcoubard 542:884f95bf5351 234 case 3:
vcoubard 542:884f95bf5351 235 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
vcoubard 542:884f95bf5351 236 break;
vcoubard 542:884f95bf5351 237 }
vcoubard 542:884f95bf5351 238 break;
vcoubard 542:884f95bf5351 239 case 2:
vcoubard 542:884f95bf5351 240 switch (level) {
vcoubard 542:884f95bf5351 241 case 1:
vcoubard 542:884f95bf5351 242 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
vcoubard 542:884f95bf5351 243 break;
vcoubard 542:884f95bf5351 244 case 2:
vcoubard 542:884f95bf5351 245 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
vcoubard 542:884f95bf5351 246 break;
vcoubard 542:884f95bf5351 247 }
vcoubard 542:884f95bf5351 248 break;
vcoubard 542:884f95bf5351 249 }
vcoubard 542:884f95bf5351 250
vcoubard 542:884f95bf5351 251 nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
vcoubard 542:884f95bf5351 252 break;
vcoubard 542:884f95bf5351 253 }
vcoubard 542:884f95bf5351 254 case DM_EVT_DEVICE_CONTEXT_STORED:
vcoubard 542:884f95bf5351 255 nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
vcoubard 542:884f95bf5351 256 break;
vcoubard 542:884f95bf5351 257 default:
vcoubard 542:884f95bf5351 258 break;
vcoubard 542:884f95bf5351 259 }
vcoubard 542:884f95bf5351 260
vcoubard 542:884f95bf5351 261 return NRF_SUCCESS;
rgrover1 134:74079098b3c9 262 }