Nordic stack and drivers for the mbed BLE API. Version to work around build bug.
Dependents: microbit_rubber_ducky microbit_mouse_BLE microbit_mouse_BLE_daybreak_version microbit_presenter
Fork of nRF51822 by
btle_security.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "btle.h" 00018 00019 #include "nRF5xn.h" 00020 00021 extern "C" { 00022 #include "pstorage.h " 00023 #include "device_manager.h " 00024 #include "id_manager.h" 00025 } 00026 00027 #include "btle_security.h" 00028 00029 static dm_application_instance_t applicationInstance; 00030 static bool initialized = false; 00031 static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result); 00032 00033 // default security parameters 00034 static ble_gap_sec_params_t securityParameters = { 00035 .bond = true, /**< Perform bonding. */ 00036 .mitm = true, /**< Man In The Middle protection required. */ 00037 .io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ 00038 .oob = 0, /**< Out Of Band data available. */ 00039 .min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ 00040 .max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */ 00041 .kdist_periph = { 00042 .enc = 1, /**< Long Term Key and Master Identification. */ 00043 .id = 1, /**< Identity Resolving Key and Identity Address Information. */ 00044 .sign = 1, /**< Connection Signature Resolving Key. */ 00045 }, /**< Key distribution bitmap: keys that the peripheral device will distribute. */ 00046 }; 00047 00048 bool 00049 btle_hasInitializedSecurity(void) 00050 { 00051 return initialized; 00052 } 00053 00054 ble_error_t 00055 btle_initializeSecurity(bool enableBonding, 00056 bool requireMITM, 00057 SecurityManager::SecurityIOCapabilities_t iocaps, 00058 const SecurityManager::Passkey_t passkey) 00059 { 00060 /* guard against multiple initializations */ 00061 if (initialized) { 00062 return BLE_ERROR_NONE; 00063 } 00064 00065 if (pstorage_init() != NRF_SUCCESS) { 00066 return BLE_ERROR_UNSPECIFIED; 00067 } 00068 00069 ret_code_t rc; 00070 if (passkey) { 00071 ble_opt_t opts; 00072 opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey); 00073 if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) { 00074 switch (rc) { 00075 case BLE_ERROR_INVALID_CONN_HANDLE: 00076 case NRF_ERROR_INVALID_ADDR: 00077 case NRF_ERROR_INVALID_PARAM: 00078 default: 00079 return BLE_ERROR_INVALID_PARAM; 00080 case NRF_ERROR_INVALID_STATE: 00081 return BLE_ERROR_INVALID_STATE; 00082 case NRF_ERROR_BUSY: 00083 return BLE_STACK_BUSY; 00084 } 00085 } 00086 } 00087 00088 dm_init_param_t dm_init_param = { 00089 .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */ 00090 }; 00091 if (dm_init(&dm_init_param) != NRF_SUCCESS) { 00092 return BLE_ERROR_UNSPECIFIED; 00093 } 00094 00095 // update default security parameters with function call parameters 00096 securityParameters.bond = enableBonding; 00097 securityParameters.mitm = requireMITM; 00098 securityParameters.io_caps = iocaps; 00099 00100 const dm_application_param_t dm_param = { 00101 .evt_handler = dm_handler, 00102 .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID, 00103 .sec_param = securityParameters 00104 }; 00105 00106 if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) { 00107 switch (rc) { 00108 case NRF_ERROR_INVALID_STATE: 00109 return BLE_ERROR_INVALID_STATE; 00110 case NRF_ERROR_NO_MEM: 00111 return BLE_ERROR_NO_MEM; 00112 default: 00113 return BLE_ERROR_UNSPECIFIED; 00114 } 00115 } 00116 00117 initialized = true; 00118 return BLE_ERROR_NONE; 00119 } 00120 00121 ble_error_t 00122 btle_purgeAllBondingState(void) 00123 { 00124 ret_code_t rc; 00125 if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) { 00126 return BLE_ERROR_NONE; 00127 } 00128 00129 switch (rc) { 00130 case NRF_ERROR_INVALID_STATE: 00131 return BLE_ERROR_INVALID_STATE; 00132 case NRF_ERROR_NO_MEM: 00133 return BLE_ERROR_NO_MEM; 00134 default: 00135 return BLE_ERROR_UNSPECIFIED; 00136 } 00137 } 00138 00139 ble_error_t 00140 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) 00141 { 00142 ret_code_t rc; 00143 dm_handle_t dmHandle = { 00144 .appl_id = applicationInstance, 00145 }; 00146 if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) { 00147 if (rc == NRF_ERROR_NOT_FOUND) { 00148 return BLE_ERROR_INVALID_PARAM; 00149 } else { 00150 return BLE_ERROR_UNSPECIFIED; 00151 } 00152 } 00153 00154 if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) { 00155 switch (rc) { 00156 case NRF_ERROR_INVALID_STATE: 00157 return BLE_ERROR_INVALID_STATE; 00158 case NRF_ERROR_NO_MEM: 00159 return BLE_ERROR_NO_MEM; 00160 default: 00161 return BLE_ERROR_UNSPECIFIED; 00162 } 00163 } 00164 00165 return BLE_ERROR_NONE; 00166 } 00167 00168 ble_error_t 00169 btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode) 00170 { 00171 // use default and updated parameters as starting point 00172 // and modify structure based on security mode. 00173 ble_gap_sec_params_t params = securityParameters; 00174 00175 switch (securityMode) { 00176 case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK: 00177 /**< Require no protection, open link. */ 00178 securityParameters.bond = false; 00179 securityParameters.mitm = false; 00180 break; 00181 00182 case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM: 00183 /**< Require encryption, but no MITM protection. */ 00184 securityParameters.bond = true; 00185 securityParameters.mitm = false; 00186 break; 00187 00188 // not yet implemented security modes 00189 case SecurityManager::SECURITY_MODE_NO_ACCESS: 00190 case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM: 00191 /**< Require encryption and MITM protection. */ 00192 case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM: 00193 /**< Require signing or encryption, but no MITM protection. */ 00194 case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM: 00195 /**< Require signing or encryption, and MITM protection. */ 00196 default: 00197 return BLE_ERROR_NOT_IMPLEMENTED; 00198 } 00199 00200 // update security settings for given connection 00201 uint32_t result = sd_ble_gap_authenticate(connectionHandle, ¶ms); 00202 00203 if (result == NRF_SUCCESS) { 00204 return BLE_ERROR_NONE; 00205 } else { 00206 return BLE_ERROR_UNSPECIFIED; 00207 } 00208 } 00209 00210 ret_code_t 00211 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result) 00212 { 00213 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); 00214 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager(); 00215 00216 switch (p_event->event_id) { 00217 case DM_EVT_SECURITY_SETUP: /* started */ { 00218 const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params; 00219 securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle, 00220 peerParams->bond, 00221 peerParams->mitm, 00222 (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps); 00223 break; 00224 } 00225 case DM_EVT_SECURITY_SETUP_COMPLETE: 00226 securityManager. 00227 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle, 00228 (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status)); 00229 break; 00230 case DM_EVT_LINK_SECURED: { 00231 unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm; 00232 unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv; 00233 SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS; 00234 switch (securityMode) { 00235 case 1: 00236 switch (level) { 00237 case 1: 00238 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK; 00239 break; 00240 case 2: 00241 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM; 00242 break; 00243 case 3: 00244 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM; 00245 break; 00246 } 00247 break; 00248 case 2: 00249 switch (level) { 00250 case 1: 00251 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM; 00252 break; 00253 case 2: 00254 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM; 00255 break; 00256 } 00257 break; 00258 } 00259 00260 securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode); 00261 break; 00262 } 00263 case DM_EVT_DEVICE_CONTEXT_STORED: 00264 securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle); 00265 break; 00266 default: 00267 break; 00268 } 00269 00270 return NRF_SUCCESS; 00271 } 00272 00273 ble_error_t 00274 btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist) 00275 { 00276 if (!btle_hasInitializedSecurity()) { 00277 return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00278 } 00279 ret_code_t err = dm_whitelist_create(&applicationInstance, p_whitelist); 00280 if (err == NRF_SUCCESS) { 00281 return BLE_ERROR_NONE; 00282 } else if (err == NRF_ERROR_NULL) { 00283 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00284 } else { 00285 return BLE_ERROR_INVALID_STATE; 00286 } 00287 } 00288 00289 00290 bool 00291 btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk) 00292 { 00293 /* 00294 * Use a helper function from the Nordic SDK to test whether the BLE 00295 * address can be generated using the IRK. 00296 */ 00297 return im_address_resolve(p_addr, p_irk); 00298 } 00299 00300 void 00301 btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address) 00302 { 00303 /* Set type to resolvable */ 00304 address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; 00305 00306 /* 00307 * Assign a random number to the most significant 3 bytes 00308 * of the address. 00309 */ 00310 address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E; 00311 address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F; 00312 address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C; 00313 00314 /* Calculate the hash and store it in the top half of the address */ 00315 ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr); 00316 }
Generated on Tue Jul 12 2022 19:52:03 by 1.7.2