Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
GenericSecurityManager.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017-2018 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 "ble/SecurityManager.h" 00018 #include "ble/pal/PalSecurityManager.h" 00019 #include "ble/generic/GenericSecurityManager.h" 00020 #include "ble/generic/MemorySecurityDb.h" 00021 #include "ble/generic/FileSecurityDb.h" 00022 00023 using ble::pal::advertising_peer_address_type_t; 00024 using ble::pal::AuthenticationMask; 00025 using ble::pal::KeyDistribution; 00026 using ble::pal::connection_peer_address_type_t; 00027 00028 namespace ble { 00029 namespace generic { 00030 00031 /* Implements SecurityManager */ 00032 00033 //////////////////////////////////////////////////////////////////////////// 00034 // SM lifecycle management 00035 // 00036 00037 ble_error_t GenericSecurityManager::init( 00038 bool bondable, 00039 bool mitm, 00040 SecurityIOCapabilities_t iocaps, 00041 const Passkey_t passkey, 00042 bool signing, 00043 const char* db_path 00044 ) { 00045 ble_error_t result = _pal.initialize(); 00046 00047 if (result != BLE_ERROR_NONE) { 00048 return result; 00049 } 00050 00051 result = init_database(db_path); 00052 00053 if (result != BLE_ERROR_NONE) { 00054 return result; 00055 } 00056 00057 _pal.set_io_capability((io_capability_t::type) iocaps); 00058 00059 if (passkey) { 00060 _pal.set_display_passkey(PasskeyAscii::to_num(passkey)); 00061 } else { 00062 _pal.set_display_passkey(0); 00063 } 00064 00065 _legacy_pairing_allowed = true; 00066 00067 bool secure_connections; 00068 _pal.get_secure_connections_support(secure_connections); 00069 00070 _default_authentication.set_bondable(bondable); 00071 _default_authentication.set_mitm(mitm); 00072 _default_authentication.set_secure_connections(secure_connections); 00073 _default_authentication.set_keypress_notification(true); 00074 00075 // FIXME: depends on BR/EDR support 00076 _default_key_distribution.set_link(false); 00077 00078 _default_key_distribution.set_signing(signing); 00079 if (signing) { 00080 init_signing(); 00081 } 00082 00083 _connection_monitor.set_connection_event_handler(this); 00084 _signing_monitor.set_signing_event_handler(this); 00085 _pal.set_event_handler(this); 00086 00087 result = init_resolving_list(); 00088 00089 if (result != BLE_ERROR_NONE) { 00090 delete _db; 00091 return result; 00092 } 00093 00094 return BLE_ERROR_NONE; 00095 } 00096 00097 ble_error_t GenericSecurityManager::setDatabaseFilepath( 00098 const char *db_path 00099 ) { 00100 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00101 00102 /* operation only allowed with no connections active */ 00103 for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { 00104 if (_control_blocks[i].connected) { 00105 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00106 } 00107 } 00108 00109 ble_error_t result = init_database(db_path); 00110 if (result != BLE_ERROR_NONE) { 00111 return result; 00112 } 00113 00114 init_resolving_list(); 00115 00116 return BLE_ERROR_NONE; 00117 } 00118 00119 ble_error_t GenericSecurityManager::reset(void) { 00120 _pal.reset(); 00121 SecurityManager::reset(); 00122 00123 return BLE_ERROR_NONE; 00124 } 00125 00126 ble_error_t GenericSecurityManager::preserveBondingStateOnReset(bool enabled) { 00127 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00128 _db->set_restore(enabled); 00129 return BLE_ERROR_NONE; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////////////// 00133 // List management 00134 // 00135 00136 ble_error_t GenericSecurityManager::purgeAllBondingState(void) { 00137 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00138 _db->clear_entries(); 00139 return BLE_ERROR_NONE; 00140 } 00141 00142 ble_error_t GenericSecurityManager::generateWhitelistFromBondTable(Gap::Whitelist_t *whitelist) const { 00143 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00144 if (eventHandler) { 00145 if (!whitelist) { 00146 return BLE_ERROR_INVALID_PARAM; 00147 } 00148 _db->generate_whitelist_from_bond_table( 00149 mbed::callback(eventHandler, &::SecurityManager::EventHandler::whitelistFromBondTable), 00150 whitelist 00151 ); 00152 } 00153 return BLE_ERROR_NONE; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////////////// 00157 // Pairing 00158 // 00159 00160 ble_error_t GenericSecurityManager::requestPairing(connection_handle_t connection) { 00161 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00162 ControlBlock_t *cb = get_control_block(connection); 00163 if (!cb) { 00164 return BLE_ERROR_INVALID_PARAM; 00165 } 00166 00167 if (!_legacy_pairing_allowed && !_default_authentication.get_secure_connections()) { 00168 return BLE_ERROR_INVALID_STATE; 00169 } 00170 00171 set_mitm_performed(connection, false); 00172 update_oob_presence(connection); 00173 00174 AuthenticationMask link_authentication(_default_authentication); 00175 00176 if (cb->mitm_requested) { 00177 link_authentication.set_mitm(true); 00178 } 00179 00180 /* by default the initiator doesn't send any keys other then identity */ 00181 KeyDistribution initiator_distribution( 00182 KeyDistribution::KEY_DISTRIBUTION_IDENTITY | 00183 _default_key_distribution.get_link() 00184 ); 00185 00186 initiator_distribution.set_signing( 00187 cb->signing_override_default ? 00188 cb->signing_requested : 00189 _default_key_distribution.get_signing() 00190 ); 00191 00192 /* if requested the initiator may send all the default keys for later 00193 * use when roles are changed */ 00194 if (_master_sends_keys) { 00195 initiator_distribution = _default_key_distribution; 00196 } 00197 00198 KeyDistribution responder_distribution(_default_key_distribution); 00199 00200 if (cb->signing_override_default) { 00201 responder_distribution.set_signing(cb->signing_requested); 00202 } 00203 00204 return _pal.send_pairing_request( 00205 connection, 00206 cb->oob_present, 00207 link_authentication, 00208 initiator_distribution, 00209 responder_distribution 00210 ); 00211 } 00212 00213 ble_error_t GenericSecurityManager::acceptPairingRequest(connection_handle_t connection) { 00214 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00215 ControlBlock_t *cb = get_control_block(connection); 00216 if (!cb) { 00217 return BLE_ERROR_INVALID_PARAM; 00218 } 00219 00220 update_oob_presence(connection); 00221 00222 AuthenticationMask link_authentication(_default_authentication); 00223 if (cb->mitm_requested) { 00224 link_authentication.set_mitm(true); 00225 } 00226 00227 KeyDistribution initiator_distribution = cb->get_initiator_key_distribution(); 00228 00229 bool master_signing = initiator_distribution.get_signing(); 00230 00231 if (_master_sends_keys) { 00232 initiator_distribution &= _default_key_distribution; 00233 } else { 00234 initiator_distribution &= KeyDistribution( 00235 KeyDistribution::KEY_DISTRIBUTION_IDENTITY | 00236 KeyDistribution::KEY_DISTRIBUTION_LINK 00237 ); 00238 } 00239 00240 /* signing has to be offered and enabled on the link */ 00241 if (master_signing) { 00242 initiator_distribution.set_signing( 00243 cb->signing_override_default ? 00244 cb->signing_requested : 00245 _default_key_distribution.get_signing() 00246 ); 00247 } 00248 00249 KeyDistribution responder_distribution(cb->get_responder_key_distribution()); 00250 00251 responder_distribution &= _default_key_distribution; 00252 00253 /* signing has to be requested and enabled on the link */ 00254 if (responder_distribution.get_signing()) { 00255 responder_distribution.set_signing( 00256 cb->signing_override_default ? 00257 cb->signing_requested : 00258 _default_key_distribution.get_signing() 00259 ); 00260 } 00261 00262 return _pal.send_pairing_response( 00263 connection, 00264 cb->oob_present, 00265 link_authentication, 00266 initiator_distribution, 00267 responder_distribution 00268 ); 00269 } 00270 00271 ble_error_t GenericSecurityManager::cancelPairingRequest(connection_handle_t connection) { 00272 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00273 return _pal.cancel_pairing(connection, pairing_failure_t::UNSPECIFIED_REASON); 00274 } 00275 00276 ble_error_t GenericSecurityManager::setPairingRequestAuthorisation(bool required) { 00277 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00278 _pairing_authorisation_required = required; 00279 return BLE_ERROR_NONE; 00280 } 00281 00282 //////////////////////////////////////////////////////////////////////////// 00283 // Feature support 00284 // 00285 00286 ble_error_t GenericSecurityManager::allowLegacyPairing(bool allow) { 00287 _legacy_pairing_allowed = allow; 00288 return BLE_ERROR_NONE; 00289 } 00290 00291 ble_error_t GenericSecurityManager::getSecureConnectionsSupport(bool *enabled) { 00292 return _pal.get_secure_connections_support(*enabled); 00293 } 00294 00295 //////////////////////////////////////////////////////////////////////////// 00296 // Security settings 00297 // 00298 00299 ble_error_t GenericSecurityManager::setIoCapability(SecurityIOCapabilities_t iocaps) { 00300 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00301 return _pal.set_io_capability((io_capability_t::type) iocaps); 00302 } 00303 00304 ble_error_t GenericSecurityManager::setDisplayPasskey(const Passkey_t passkey) { 00305 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00306 return _pal.set_display_passkey(PasskeyAscii::to_num(passkey)); 00307 } 00308 00309 ble_error_t GenericSecurityManager::setAuthenticationTimeout( 00310 connection_handle_t connection, 00311 uint32_t timeout_in_ms 00312 ) { 00313 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00314 return _pal.set_authentication_timeout(connection, timeout_in_ms / 10); 00315 } 00316 00317 ble_error_t GenericSecurityManager::getAuthenticationTimeout( 00318 connection_handle_t connection, 00319 uint32_t *timeout_in_ms 00320 ) { 00321 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00322 uint16_t timeout_in_10ms; 00323 ble_error_t status = _pal.get_authentication_timeout(connection, timeout_in_10ms); 00324 *timeout_in_ms = 10 * timeout_in_10ms; 00325 return status; 00326 } 00327 00328 ble_error_t GenericSecurityManager::setLinkSecurity( 00329 connection_handle_t connection, 00330 SecurityMode_t securityMode 00331 ) { 00332 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00333 ControlBlock_t *cb = get_control_block(connection); 00334 if (!cb) { 00335 return BLE_ERROR_INVALID_PARAM; 00336 } 00337 00338 if (cb->encryption_requested) { 00339 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00340 } 00341 00342 switch (securityMode) { 00343 case SECURITY_MODE_ENCRYPTION_OPEN_LINK: 00344 return setLinkEncryption(connection, link_encryption_t::NOT_ENCRYPTED); 00345 00346 case SECURITY_MODE_ENCRYPTION_NO_MITM: 00347 return setLinkEncryption(connection, link_encryption_t::ENCRYPTED); 00348 00349 case SECURITY_MODE_ENCRYPTION_WITH_MITM: 00350 return setLinkEncryption(connection, link_encryption_t::ENCRYPTED_WITH_MITM); 00351 00352 case SECURITY_MODE_SIGNED_NO_MITM: 00353 return getSigningKey(connection, false); 00354 00355 case SECURITY_MODE_SIGNED_WITH_MITM: 00356 return getSigningKey(connection, true); 00357 00358 default: 00359 return BLE_ERROR_INVALID_PARAM; 00360 } 00361 } 00362 00363 ble_error_t GenericSecurityManager::setKeypressNotification(bool enabled) { 00364 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00365 _default_authentication.set_keypress_notification(enabled); 00366 return BLE_ERROR_NONE; 00367 } 00368 00369 ble_error_t GenericSecurityManager::enableSigning( 00370 connection_handle_t connection, 00371 bool enabled 00372 ) { 00373 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00374 ControlBlock_t *cb = get_control_block(connection); 00375 if (!cb) { 00376 return BLE_ERROR_INVALID_PARAM; 00377 } 00378 00379 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00380 if (!flags) { 00381 return BLE_ERROR_INVALID_PARAM; 00382 } 00383 00384 cb->signing_override_default = true; 00385 00386 if (enabled && !cb->signing_requested && !_default_key_distribution.get_signing()) { 00387 cb->signing_requested = true; 00388 if (flags->csrk_stored) { 00389 /* used the stored ones when available */ 00390 _db->get_entry_peer_csrk( 00391 mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb), 00392 cb->db_entry 00393 ); 00394 } else { 00395 /* create keys if needed and exchange them */ 00396 init_signing(); 00397 if (cb->is_master) { 00398 return requestPairing(connection); 00399 } else { 00400 return slave_security_request(connection); 00401 } 00402 } 00403 } else { 00404 cb->signing_requested = enabled; 00405 } 00406 00407 return BLE_ERROR_NONE; 00408 } 00409 00410 ble_error_t GenericSecurityManager::setHintFutureRoleReversal(bool enable) { 00411 _master_sends_keys = enable; 00412 return BLE_ERROR_NONE; 00413 } 00414 00415 //////////////////////////////////////////////////////////////////////////// 00416 // Encryption 00417 // 00418 00419 ble_error_t GenericSecurityManager::getLinkEncryption( 00420 connection_handle_t connection, 00421 link_encryption_t *encryption 00422 ) { 00423 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00424 ControlBlock_t *cb = get_control_block(connection); 00425 if (!cb) { 00426 return BLE_ERROR_INVALID_PARAM; 00427 } 00428 00429 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00430 if (!flags) { 00431 return BLE_ERROR_INVALID_PARAM; 00432 } 00433 00434 if (cb->encrypted) { 00435 if (flags->ltk_mitm_protected || cb->mitm_performed) { 00436 if (flags->secure_connections_paired) { 00437 *encryption = link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM; 00438 } else { 00439 *encryption = link_encryption_t::ENCRYPTED_WITH_MITM; 00440 } 00441 } else { 00442 *encryption = link_encryption_t::ENCRYPTED; 00443 } 00444 } else if (cb->encryption_requested) { 00445 *encryption = link_encryption_t::ENCRYPTION_IN_PROGRESS; 00446 } else { 00447 *encryption = link_encryption_t::NOT_ENCRYPTED; 00448 } 00449 00450 return BLE_ERROR_NONE; 00451 } 00452 00453 ble_error_t GenericSecurityManager::setLinkEncryption( 00454 connection_handle_t connection, 00455 link_encryption_t encryption 00456 ) { 00457 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00458 ControlBlock_t *cb = get_control_block(connection); 00459 if (!cb) { 00460 return BLE_ERROR_INVALID_PARAM; 00461 } 00462 00463 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00464 if (!flags) { 00465 return BLE_ERROR_INVALID_PARAM; 00466 } 00467 00468 link_encryption_t current_encryption(link_encryption_t::NOT_ENCRYPTED); 00469 getLinkEncryption(connection, ¤t_encryption); 00470 00471 if (current_encryption == link_encryption_t::ENCRYPTION_IN_PROGRESS) { 00472 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00473 } 00474 00475 if (current_encryption == encryption) { 00476 00477 /* ignore if the link is already at required state*/ 00478 00479 } else if (encryption == link_encryption_t::NOT_ENCRYPTED) { 00480 // Fail as it is not permitted to turn down encryption 00481 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00482 } else if (encryption == link_encryption_t::ENCRYPTED) { 00483 00484 /* only change if we're not already encrypted with mitm */ 00485 if (current_encryption != link_encryption_t::ENCRYPTED_WITH_MITM || 00486 current_encryption != link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM 00487 ) { 00488 cb->encryption_requested = true; 00489 return enable_encryption(connection); 00490 } 00491 00492 } else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) { 00493 00494 if (flags->ltk_mitm_protected && !cb->encrypted) { 00495 cb->encryption_requested = true; 00496 return enable_encryption(connection); 00497 } else { 00498 cb->encryption_requested = true; 00499 return requestAuthentication(connection); 00500 } 00501 00502 } else if (encryption == link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM) { 00503 00504 if (flags->ltk_mitm_protected && 00505 flags->secure_connections_paired && 00506 !cb->encrypted 00507 ) { 00508 cb->encryption_requested = true; 00509 return enable_encryption(connection); 00510 } else { 00511 cb->encryption_requested = true; 00512 return requestAuthentication(connection); 00513 } 00514 00515 } else { 00516 return BLE_ERROR_INVALID_PARAM; 00517 } 00518 00519 eventHandler->linkEncryptionResult(connection, current_encryption); 00520 00521 return BLE_ERROR_NONE; 00522 } 00523 00524 ble_error_t GenericSecurityManager::getEncryptionKeySize( 00525 connection_handle_t connection, 00526 uint8_t *size 00527 ) { 00528 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00529 ControlBlock_t *cb = get_control_block(connection); 00530 if (!cb) { 00531 return BLE_ERROR_INVALID_PARAM; 00532 } 00533 00534 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00535 if (!flags) { 00536 return BLE_ERROR_INVALID_PARAM; 00537 } 00538 00539 *size = flags->encryption_key_size; 00540 return BLE_ERROR_NONE; 00541 } 00542 00543 ble_error_t GenericSecurityManager::setEncryptionKeyRequirements( 00544 uint8_t minimumByteSize, 00545 uint8_t maximumByteSize 00546 ) { 00547 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00548 return _pal.set_encryption_key_requirements(minimumByteSize, maximumByteSize); 00549 } 00550 00551 //////////////////////////////////////////////////////////////////////////// 00552 // Keys 00553 // 00554 00555 ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection, bool authenticated) { 00556 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00557 ControlBlock_t *cb = get_control_block(connection); 00558 if (!cb) { 00559 return BLE_ERROR_INVALID_PARAM; 00560 } 00561 00562 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00563 if (!flags) { 00564 return BLE_ERROR_INVALID_PARAM; 00565 } 00566 00567 if (flags->csrk_stored && (flags->csrk_mitm_protected || !authenticated)) { 00568 /* we have a key that is either authenticated or we don't care if it is 00569 * so retrieve it from the db now */ 00570 _db->get_entry_peer_csrk( 00571 mbed::callback(this, &GenericSecurityManager::return_csrk_cb), 00572 cb->db_entry 00573 ); 00574 return BLE_ERROR_NONE; 00575 00576 } else { 00577 /* we don't have the right key so we need to get it first 00578 * keys exchange will create the signingKey event */ 00579 if (authenticated) { 00580 return requestAuthentication(connection); 00581 } else if (cb->is_master) { 00582 return requestPairing(connection); 00583 } else { 00584 return slave_security_request(connection); 00585 } 00586 } 00587 } 00588 00589 //////////////////////////////////////////////////////////////////////////// 00590 // Privacy 00591 // 00592 00593 ble_error_t GenericSecurityManager::setPrivateAddressTimeout(uint16_t timeout_in_seconds) { 00594 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00595 return _pal.set_private_address_timeout(timeout_in_seconds); 00596 } 00597 00598 //////////////////////////////////////////////////////////////////////////// 00599 // Authentication 00600 // 00601 00602 ble_error_t GenericSecurityManager::requestAuthentication(connection_handle_t connection) { 00603 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00604 ControlBlock_t *cb = get_control_block(connection); 00605 if (!cb) { 00606 return BLE_ERROR_INVALID_PARAM; 00607 } 00608 00609 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00610 if (!flags) { 00611 return BLE_ERROR_INVALID_PARAM; 00612 } 00613 00614 if (flags->ltk_mitm_protected) { 00615 if (cb->authenticated) { 00616 return BLE_ERROR_NONE; 00617 } else { 00618 cb->encryption_requested = true; 00619 return enable_encryption(connection); 00620 } 00621 } else { 00622 cb->mitm_requested = true; 00623 if (cb->is_master) { 00624 return requestPairing(connection); 00625 } else { 00626 return slave_security_request(connection); 00627 } 00628 } 00629 } 00630 00631 //////////////////////////////////////////////////////////////////////////// 00632 // MITM 00633 // 00634 00635 ble_error_t GenericSecurityManager::generateOOB( 00636 const address_t *address 00637 ) { 00638 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00639 /* legacy pairing */ 00640 ble_error_t status = get_random_data(_oob_temporary_key.data(), 16); 00641 00642 if (status == BLE_ERROR_NONE) { 00643 _oob_temporary_key_creator_address = *address; 00644 00645 eventHandler->legacyPairingOobGenerated( 00646 &_oob_temporary_key_creator_address, 00647 &_oob_temporary_key 00648 ); 00649 } else { 00650 return status; 00651 } 00652 00653 /* Secure connections. Avoid generating if we're already waiting for it. 00654 * If a local random is set to 0 it means we're already calculating. */ 00655 if (!is_all_zeros(_oob_local_random)) { 00656 status = _pal.generate_secure_connections_oob(); 00657 00658 if (status == BLE_ERROR_NONE) { 00659 _oob_local_address = *address; 00660 /* this will be updated when calculation completes, 00661 * a value of all zeros is an invalid random value */ 00662 set_all_zeros(_oob_local_random); 00663 } else if (status != BLE_ERROR_NOT_IMPLEMENTED) { 00664 return status; 00665 } 00666 } else { 00667 return BLE_STACK_BUSY; 00668 } 00669 00670 return BLE_ERROR_NONE; 00671 } 00672 00673 ble_error_t GenericSecurityManager::setOOBDataUsage( 00674 connection_handle_t connection, 00675 bool useOOB, 00676 bool OOBProvidesMITM 00677 ) { 00678 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00679 ControlBlock_t *cb = get_control_block(connection); 00680 if (!cb) { 00681 return BLE_ERROR_INVALID_PARAM; 00682 } 00683 00684 cb->attempt_oob = useOOB; 00685 cb->oob_mitm_protection = OOBProvidesMITM; 00686 00687 if (useOOB) { 00688 return generateOOB(&cb->local_address); 00689 } else { 00690 return BLE_ERROR_NONE; 00691 } 00692 } 00693 00694 ble_error_t GenericSecurityManager::confirmationEntered( 00695 connection_handle_t connection, 00696 bool confirmation 00697 ) { 00698 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00699 return _pal.confirmation_entered(connection, confirmation); 00700 } 00701 00702 ble_error_t GenericSecurityManager::passkeyEntered( 00703 connection_handle_t connection, 00704 Passkey_t passkey 00705 ) { 00706 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00707 return _pal.passkey_request_reply( 00708 connection, 00709 PasskeyAscii::to_num(passkey) 00710 ); 00711 } 00712 00713 ble_error_t GenericSecurityManager::sendKeypressNotification( 00714 connection_handle_t connection, 00715 Keypress_t keypress 00716 ) { 00717 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00718 return _pal.send_keypress_notification(connection, keypress); 00719 } 00720 00721 ble_error_t GenericSecurityManager::legacyPairingOobReceived( 00722 const address_t *address, 00723 const oob_tk_t *tk 00724 ) { 00725 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00726 if (address && tk) { 00727 ControlBlock_t *cb = get_control_block(*address); 00728 if (!cb) { 00729 return BLE_ERROR_INVALID_PARAM; 00730 } 00731 00732 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00733 if (!flags) { 00734 return BLE_ERROR_INVALID_PARAM; 00735 } 00736 00737 _oob_temporary_key = *tk; 00738 _oob_temporary_key_creator_address = *address; 00739 00740 if (flags->peer_address == _oob_temporary_key_creator_address) { 00741 cb->attempt_oob = true; 00742 } 00743 00744 if (cb->legacy_pairing_oob_request_pending) { 00745 on_legacy_pairing_oob_request(cb->connection); 00746 /* legacy_pairing_oob_request_pending stops us from 00747 * going into a loop of asking the user for oob 00748 * so this reset needs to happen after the call above */ 00749 cb->legacy_pairing_oob_request_pending = false; 00750 } 00751 } 00752 return BLE_ERROR_NONE; 00753 } 00754 00755 ble_error_t GenericSecurityManager::oobReceived( 00756 const address_t *address, 00757 const oob_lesc_value_t *random, 00758 const oob_confirm_t *confirm 00759 ) { 00760 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00761 if (address && random && confirm) { 00762 _oob_peer_address = *address; 00763 _oob_peer_random = *random; 00764 _oob_peer_confirm = *confirm; 00765 return BLE_ERROR_NONE; 00766 } 00767 00768 return BLE_ERROR_INVALID_PARAM; 00769 } 00770 00771 //////////////////////////////////////////////////////////////////////////// 00772 // Helper functions 00773 // 00774 00775 ble_error_t GenericSecurityManager::init_database( 00776 const char *db_path 00777 ) { 00778 delete _db; 00779 00780 FILE* db_file = FileSecurityDb::open_db_file(db_path); 00781 00782 if (db_file) { 00783 _db = new (std::nothrow) FileSecurityDb(db_file); 00784 } else { 00785 _db = new (std::nothrow) MemorySecurityDb(); 00786 } 00787 00788 if (!_db) { 00789 return BLE_ERROR_NO_MEM; 00790 } 00791 00792 _db->restore(); 00793 00794 return BLE_ERROR_NONE; 00795 } 00796 00797 ble_error_t GenericSecurityManager::init_resolving_list() { 00798 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00799 00800 /* match the resolving list to the currently stored set of IRKs */ 00801 uint8_t resolving_list_capacity = _pal.read_resolving_list_capacity(); 00802 SecurityEntryIdentity_t* identity_list_p = 00803 new (std::nothrow) SecurityEntryIdentity_t[resolving_list_capacity]; 00804 00805 if (identity_list_p) { 00806 ArrayView<SecurityEntryIdentity_t> identity_list( 00807 identity_list_p, 00808 resolving_list_capacity 00809 ); 00810 00811 _db->get_identity_list( 00812 mbed::callback(this, &GenericSecurityManager::on_identity_list_retrieved), 00813 identity_list 00814 ); 00815 } else { 00816 return BLE_ERROR_NO_MEM; 00817 } 00818 00819 return BLE_ERROR_NONE; 00820 } 00821 00822 ble_error_t GenericSecurityManager::init_signing() { 00823 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00824 const csrk_t *pcsrk = _db->get_local_csrk(); 00825 sign_count_t local_sign_counter = _db->get_local_sign_counter(); 00826 00827 if (!pcsrk) { 00828 csrk_t csrk; 00829 00830 ble_error_t ret = get_random_data(csrk.data(), csrk.size()); 00831 if (ret != BLE_ERROR_NONE) { 00832 return ret; 00833 } 00834 00835 pcsrk = &csrk; 00836 _db->set_local_csrk(csrk); 00837 _db->set_local_sign_counter(local_sign_counter); 00838 } 00839 00840 return _pal.set_csrk(*pcsrk, local_sign_counter); 00841 } 00842 00843 ble_error_t GenericSecurityManager::get_random_data(uint8_t *buffer, size_t size) { 00844 byte_array_t<8> random_data; 00845 00846 while (size) { 00847 /* fill out the buffer by reading the random data in chunks 00848 * and copying it until reaching the set size */ 00849 size_t copy_size = std::max(size, random_data.size()); 00850 ble_error_t ret = _pal.get_random_data(random_data); 00851 if (ret != BLE_ERROR_NONE) { 00852 return ret; 00853 } 00854 memcpy(buffer, random_data.data(), copy_size); 00855 size -= copy_size; 00856 buffer += copy_size; 00857 } 00858 00859 return BLE_ERROR_NONE; 00860 } 00861 00862 ble_error_t GenericSecurityManager::slave_security_request(connection_handle_t connection) { 00863 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00864 ControlBlock_t *cb = get_control_block(connection); 00865 if (!cb) { 00866 return BLE_ERROR_INVALID_PARAM; 00867 } 00868 AuthenticationMask link_authentication(_default_authentication); 00869 link_authentication.set_mitm(cb->mitm_requested); 00870 return _pal.slave_security_request(connection, link_authentication); 00871 } 00872 00873 ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connection) { 00874 if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; 00875 ControlBlock_t *cb = get_control_block(connection); 00876 if (!cb) { 00877 return BLE_ERROR_INVALID_PARAM; 00878 } 00879 00880 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00881 if (!flags) { 00882 return BLE_ERROR_INVALID_PARAM; 00883 } 00884 00885 if (cb->is_master) { 00886 if (flags->ltk_stored) { 00887 _db->get_entry_peer_keys( 00888 mbed::callback(this, &GenericSecurityManager::enable_encryption_cb), 00889 cb->db_entry 00890 ); 00891 return BLE_ERROR_NONE; 00892 } else { 00893 return requestPairing(connection); 00894 } 00895 } else { 00896 return slave_security_request(connection); 00897 } 00898 } 00899 00900 void GenericSecurityManager::enable_encryption_cb( 00901 SecurityDb::entry_handle_t db_entry, 00902 const SecurityEntryKeys_t* entryKeys 00903 ) { 00904 MBED_ASSERT(_db); 00905 ControlBlock_t *cb = get_control_block(db_entry); 00906 if (!cb) { 00907 return; 00908 } 00909 00910 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00911 if (!flags) { 00912 return; 00913 } 00914 00915 if (entryKeys) { 00916 if (flags->secure_connections_paired) { 00917 _pal.enable_encryption(cb->connection, entryKeys->ltk, flags->ltk_mitm_protected); 00918 } else { 00919 _pal.enable_encryption(cb->connection, entryKeys->ltk, entryKeys->rand, entryKeys->ediv, flags->ltk_mitm_protected); 00920 } 00921 } 00922 } 00923 00924 void GenericSecurityManager::set_ltk_cb( 00925 SecurityDb::entry_handle_t db_entry, 00926 const SecurityEntryKeys_t* entryKeys 00927 ) { 00928 MBED_ASSERT(_db); 00929 ControlBlock_t *cb = get_control_block(db_entry); 00930 if (!cb) { 00931 return; 00932 } 00933 00934 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00935 if (!flags) { 00936 return; 00937 } 00938 00939 if (entryKeys) { 00940 _pal.set_ltk( 00941 cb->connection, 00942 entryKeys->ltk, 00943 flags->ltk_mitm_protected, 00944 flags->secure_connections_paired 00945 ); 00946 } else { 00947 _pal.set_ltk_not_found(cb->connection); 00948 } 00949 } 00950 00951 void GenericSecurityManager::set_peer_csrk_cb( 00952 SecurityDb::entry_handle_t db_entry, 00953 const SecurityEntrySigning_t* signing 00954 ) { 00955 ControlBlock_t *cb = get_control_block(db_entry); 00956 if (!cb || !signing) { 00957 return; 00958 } 00959 00960 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00961 if (!flags) { 00962 return; 00963 } 00964 00965 _pal.set_peer_csrk( 00966 cb->connection, 00967 signing->csrk, 00968 flags->csrk_mitm_protected, 00969 signing->counter 00970 ); 00971 } 00972 00973 void GenericSecurityManager::return_csrk_cb( 00974 SecurityDb::entry_handle_t db_entry, 00975 const SecurityEntrySigning_t *signing 00976 ) { 00977 MBED_ASSERT(_db); 00978 ControlBlock_t *cb = get_control_block(db_entry); 00979 if (!cb || !signing) { 00980 return; 00981 } 00982 00983 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 00984 if (!flags) { 00985 return; 00986 } 00987 00988 eventHandler->signingKey( 00989 cb->connection, 00990 &signing->csrk, 00991 flags->csrk_mitm_protected 00992 ); 00993 } 00994 00995 void GenericSecurityManager::update_oob_presence(connection_handle_t connection) { 00996 MBED_ASSERT(_db); 00997 ControlBlock_t *cb = get_control_block(connection); 00998 if (!cb) { 00999 return; 01000 } 01001 01002 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01003 if (!flags) { 01004 return; 01005 } 01006 01007 /* if we support secure connection we only care about secure connections oob data */ 01008 if (_default_authentication.get_secure_connections()) { 01009 cb->oob_present = (flags->peer_address == _oob_peer_address); 01010 } else { 01011 /* otherwise for legacy pairing we first set the oob based on set preference */ 01012 cb->oob_present = cb->attempt_oob; 01013 01014 /* and also turn it on if we have oob data for legacy pairing */ 01015 if (flags->peer_address == _oob_temporary_key_creator_address 01016 || cb->local_address == _oob_temporary_key_creator_address) { 01017 cb->oob_present = true; 01018 } 01019 } 01020 } 01021 01022 void GenericSecurityManager::set_mitm_performed(connection_handle_t connection, bool enable) { 01023 ControlBlock_t *cb = get_control_block(connection); 01024 if (cb) { 01025 cb->mitm_performed = enable; 01026 /* whenever we reset mitm performed we also reset pending requests 01027 * as this happens whenever a new pairing attempt happens */ 01028 if (!enable) { 01029 cb->legacy_pairing_oob_request_pending = false; 01030 } 01031 } 01032 } 01033 01034 void GenericSecurityManager::on_connected( 01035 connection_handle_t connection, 01036 Gap::Role_t role, 01037 peer_address_type_t peer_address_type, 01038 const BLEProtocol::AddressBytes_t peer_address, 01039 BLEProtocol::AddressType_t local_address_type, 01040 const BLEProtocol::AddressBytes_t local_address, 01041 const Gap::ConnectionParams_t *connection_params 01042 ) { 01043 MBED_ASSERT(_db); 01044 ControlBlock_t *cb = acquire_control_block(connection); 01045 if (!cb) { 01046 return; 01047 } 01048 01049 // setup the control block 01050 cb->local_address = local_address; 01051 cb->is_master = (role == Gap::CENTRAL); 01052 01053 // get the associated db handle and the distribution flags if any 01054 cb->db_entry = _db->open_entry(peer_address_type, peer_address); 01055 01056 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01057 01058 flags->peer_address = peer_address; 01059 flags->peer_address_is_public = 01060 (peer_address_type == peer_address_type_t::PUBLIC) || 01061 (peer_address_type == peer_address_type_t::PUBLIC_IDENTITY); 01062 01063 const bool signing = cb->signing_override_default ? 01064 cb->signing_requested : 01065 _default_key_distribution.get_signing(); 01066 01067 if (signing && flags->csrk_stored) { 01068 _db->get_entry_peer_csrk( 01069 mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb), 01070 cb->db_entry 01071 ); 01072 } 01073 } 01074 01075 void GenericSecurityManager::on_disconnected( 01076 connection_handle_t connection, 01077 Gap::DisconnectionReason_t reason 01078 ) { 01079 MBED_ASSERT(_db); 01080 ControlBlock_t *cb = get_control_block(connection); 01081 if (!cb) { 01082 return; 01083 } 01084 01085 _pal.remove_peer_csrk(connection); 01086 01087 _db->close_entry(cb->db_entry); 01088 release_control_block(cb); 01089 } 01090 01091 void GenericSecurityManager::on_security_entry_retrieved( 01092 SecurityDb::entry_handle_t entry, 01093 const SecurityEntryIdentity_t* identity 01094 ) { 01095 if (!identity) { 01096 return; 01097 } 01098 01099 typedef advertising_peer_address_type_t address_type_t; 01100 01101 _pal.add_device_to_resolving_list( 01102 identity->identity_address_is_public ? 01103 address_type_t::PUBLIC_ADDRESS : 01104 address_type_t::RANDOM_ADDRESS, 01105 identity->identity_address, 01106 identity->irk 01107 ); 01108 } 01109 01110 void GenericSecurityManager::on_identity_list_retrieved( 01111 ble::ArrayView<SecurityEntryIdentity_t>& identity_list, 01112 size_t count 01113 ) { 01114 typedef advertising_peer_address_type_t address_type_t; 01115 01116 _pal.clear_resolving_list(); 01117 for (size_t i = 0; i < count; ++i) { 01118 _pal.add_device_to_resolving_list( 01119 identity_list[i].identity_address_is_public ? 01120 address_type_t::PUBLIC_ADDRESS : 01121 address_type_t::RANDOM_ADDRESS, 01122 identity_list[i].identity_address, 01123 identity_list[i].irk 01124 ); 01125 } 01126 01127 delete [] identity_list.data(); 01128 } 01129 01130 01131 /* Implements ble::pal::SecurityManagerEventHandler */ 01132 01133 //////////////////////////////////////////////////////////////////////////// 01134 // Pairing 01135 // 01136 01137 void GenericSecurityManager::on_pairing_request( 01138 connection_handle_t connection, 01139 bool use_oob, 01140 AuthenticationMask authentication, 01141 KeyDistribution initiator_dist, 01142 KeyDistribution responder_dist 01143 ) { 01144 /* cancel pairing if secure connection paring is not possible */ 01145 if (!_legacy_pairing_allowed && !authentication.get_secure_connections()) { 01146 cancelPairingRequest(connection); 01147 return; 01148 } 01149 01150 ControlBlock_t *cb = get_control_block(connection); 01151 if (!cb) { 01152 return; 01153 } 01154 01155 cb->set_initiator_key_distribution(initiator_dist); 01156 cb->set_responder_key_distribution(responder_dist); 01157 01158 cb->mitm_performed = false; 01159 01160 if (_pairing_authorisation_required) { 01161 eventHandler->pairingRequest(connection); 01162 } else { 01163 acceptPairingRequest(connection); 01164 } 01165 } 01166 01167 void GenericSecurityManager::on_pairing_error( 01168 connection_handle_t connection, 01169 pairing_failure_t error 01170 ) { 01171 set_mitm_performed(connection, false); 01172 01173 eventHandler->pairingResult( 01174 connection, 01175 (SecurityManager::SecurityCompletionStatus_t)(error.value() | 0x80) 01176 ); 01177 01178 /* if this pairing was triggered by a failed encryption attempt 01179 * inform the application of the encryption failure */ 01180 ControlBlock_t *cb = get_control_block(connection); 01181 if (cb && cb->encryption_requested && cb->encryption_failed) { 01182 eventHandler->linkEncryptionResult( 01183 connection, 01184 link_encryption_t::NOT_ENCRYPTED 01185 ); 01186 } 01187 } 01188 01189 void GenericSecurityManager::on_pairing_timed_out(connection_handle_t connection) { 01190 set_mitm_performed(connection, false); 01191 01192 eventHandler->pairingResult( 01193 connection, 01194 SecurityManager::SEC_STATUS_TIMEOUT 01195 ); 01196 } 01197 01198 void GenericSecurityManager::on_pairing_completed(connection_handle_t connection) { 01199 MBED_ASSERT(_db); 01200 ControlBlock_t *cb = get_control_block(connection); 01201 if (cb) { 01202 _db->get_entry_identity( 01203 mbed::callback(this, &GenericSecurityManager::on_security_entry_retrieved), 01204 cb->db_entry 01205 ); 01206 } 01207 01208 eventHandler->pairingResult( 01209 connection, 01210 SecurityManager::SEC_STATUS_SUCCESS 01211 ); 01212 } 01213 01214 //////////////////////////////////////////////////////////////////////////// 01215 // Security 01216 // 01217 01218 void GenericSecurityManager::on_valid_mic_timeout(connection_handle_t connection) { 01219 (void)connection; 01220 } 01221 01222 void GenericSecurityManager::on_signed_write_received( 01223 connection_handle_t connection, 01224 sign_count_t sign_counter 01225 ) { 01226 MBED_ASSERT(_db); 01227 ControlBlock_t *cb = get_control_block(connection); 01228 if (!cb) { 01229 return; 01230 } 01231 _db->set_entry_peer_sign_counter(cb->db_entry, sign_counter); 01232 } 01233 01234 void GenericSecurityManager::on_signed_write_verification_failure( 01235 connection_handle_t connection 01236 ) { 01237 ControlBlock_t *cb = get_control_block(connection); 01238 if (!cb) { 01239 return; 01240 } 01241 01242 const bool signing = cb->signing_override_default ? 01243 cb->signing_requested : 01244 _default_key_distribution.get_signing(); 01245 01246 if (signing) { 01247 cb->csrk_failures++; 01248 if (cb->csrk_failures == 3) { 01249 cb->csrk_failures = 0; 01250 if (cb->is_master) { 01251 requestPairing(connection); 01252 } else { 01253 slave_security_request(connection); 01254 } 01255 } 01256 } 01257 } 01258 01259 void GenericSecurityManager::on_signed_write() { 01260 MBED_ASSERT(_db); 01261 _db->set_local_sign_counter(_db->get_local_sign_counter() + 1); 01262 } 01263 01264 void GenericSecurityManager::on_slave_security_request( 01265 connection_handle_t connection, 01266 AuthenticationMask authentication 01267 ) { 01268 MBED_ASSERT(_db); 01269 ControlBlock_t *cb = get_control_block(connection); 01270 if (!cb) { 01271 return; 01272 } 01273 01274 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01275 if (!flags) { 01276 return; 01277 } 01278 01279 bool pairing_required = false; 01280 01281 if (authentication.get_secure_connections() && !flags->secure_connections_paired 01282 && _default_authentication.get_secure_connections()) { 01283 pairing_required = true; 01284 } 01285 01286 if (authentication.get_mitm() && !flags->ltk_mitm_protected) { 01287 pairing_required = true; 01288 cb->mitm_requested = true; 01289 } 01290 01291 if (pairing_required) { 01292 requestPairing(connection); 01293 } else if (!cb->encryption_requested) { 01294 /* this will refresh keys if encryption is already present */ 01295 enable_encryption(connection); 01296 } 01297 } 01298 01299 //////////////////////////////////////////////////////////////////////////// 01300 // Encryption 01301 // 01302 01303 void GenericSecurityManager::on_link_encryption_result( 01304 connection_handle_t connection, 01305 link_encryption_t result 01306 ) { 01307 01308 ControlBlock_t *cb = get_control_block(connection); 01309 if (!cb) { 01310 return; 01311 } 01312 01313 if (result == link_encryption_t::ENCRYPTED) { 01314 01315 cb->encryption_requested = false; 01316 cb->encryption_failed = false; 01317 cb->encrypted = true; 01318 01319 } else if ( 01320 result == link_encryption_t::ENCRYPTED_WITH_MITM || 01321 result == link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM 01322 ) { 01323 01324 cb->encryption_requested = false; 01325 cb->encryption_failed = false; 01326 cb->authenticated = true; 01327 cb->encrypted = true; 01328 01329 } else if (result == link_encryption_t::NOT_ENCRYPTED 01330 && cb->encryption_requested 01331 && !cb->encryption_failed) { 01332 01333 /* if we failed encryption for the first time 01334 * retry repairing in case slave lost LTK */ 01335 requestPairing(cb->connection); 01336 cb->encryption_failed = true; 01337 /* don't return an event yet since we are retrying */ 01338 return; 01339 } 01340 01341 eventHandler->linkEncryptionResult(connection, result); 01342 } 01343 01344 void GenericSecurityManager::on_link_encryption_request_timed_out( 01345 connection_handle_t connection 01346 ) { 01347 eventHandler->linkEncryptionResult( 01348 connection, 01349 link_encryption_t::NOT_ENCRYPTED 01350 ); 01351 } 01352 01353 //////////////////////////////////////////////////////////////////////////// 01354 // MITM 01355 // 01356 01357 void GenericSecurityManager::on_passkey_display( 01358 connection_handle_t connection, 01359 passkey_num_t passkey 01360 ) { 01361 set_mitm_performed(connection); 01362 eventHandler->passkeyDisplay(connection, PasskeyAscii(passkey).value()); 01363 } 01364 01365 void GenericSecurityManager::on_keypress_notification( 01366 connection_handle_t connection, 01367 SecurityManager::Keypress_t keypress 01368 ) { 01369 set_mitm_performed(connection); 01370 eventHandler->keypressNotification(connection, keypress); 01371 } 01372 01373 void GenericSecurityManager::on_passkey_request(connection_handle_t connection) { 01374 set_mitm_performed(connection); 01375 eventHandler->passkeyRequest(connection); 01376 } 01377 01378 void GenericSecurityManager::on_confirmation_request(connection_handle_t connection) { 01379 set_mitm_performed(connection); 01380 eventHandler->confirmationRequest(connection); 01381 } 01382 01383 void GenericSecurityManager::on_secure_connections_oob_request(connection_handle_t connection) { 01384 set_mitm_performed(connection); 01385 01386 ControlBlock_t *cb = get_control_block(connection); 01387 if (!cb) { 01388 return; 01389 } 01390 01391 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01392 if (!flags) { 01393 return; 01394 } 01395 01396 if (flags->peer_address == _oob_peer_address) { 01397 _pal.secure_connections_oob_request_reply(connection, _oob_local_random, _oob_peer_random, _oob_peer_confirm); 01398 /* do not re-use peer OOB */ 01399 set_all_zeros(_oob_peer_address); 01400 } else { 01401 _pal.cancel_pairing(connection, pairing_failure_t::OOB_NOT_AVAILABLE); 01402 } 01403 } 01404 01405 void GenericSecurityManager::on_legacy_pairing_oob_request(connection_handle_t connection) { 01406 MBED_ASSERT(_db); 01407 ControlBlock_t *cb = get_control_block(connection); 01408 if (!cb) { 01409 return; 01410 } 01411 01412 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01413 if (!flags) { 01414 return; 01415 } 01416 01417 if (flags->peer_address == _oob_temporary_key_creator_address 01418 || cb->local_address == _oob_temporary_key_creator_address) { 01419 01420 set_mitm_performed(connection); 01421 _pal.legacy_pairing_oob_request_reply(connection, _oob_temporary_key); 01422 01423 /* do not re-use peer OOB */ 01424 if (flags->peer_address == _oob_temporary_key_creator_address) { 01425 set_all_zeros(_oob_temporary_key_creator_address); 01426 } 01427 01428 } else if (!cb->legacy_pairing_oob_request_pending) { 01429 01430 cb->legacy_pairing_oob_request_pending = true; 01431 eventHandler->legacyPairingOobRequest(connection); 01432 01433 } 01434 } 01435 01436 void GenericSecurityManager::on_secure_connections_oob_generated( 01437 const oob_lesc_value_t &random, 01438 const oob_confirm_t &confirm 01439 ) { 01440 eventHandler->oobGenerated(&_oob_local_address, &random, &confirm); 01441 _oob_local_random = random; 01442 } 01443 01444 //////////////////////////////////////////////////////////////////////////// 01445 // Keys 01446 // 01447 01448 void GenericSecurityManager::on_secure_connections_ltk_generated( 01449 connection_handle_t connection, 01450 const ltk_t <k 01451 ) { 01452 MBED_ASSERT(_db); 01453 ControlBlock_t *cb = get_control_block(connection); 01454 if (!cb) { 01455 return; 01456 } 01457 01458 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01459 if (!flags) { 01460 return; 01461 } 01462 01463 flags->ltk_mitm_protected = cb->mitm_performed; 01464 flags->secure_connections_paired = true; 01465 01466 _db->set_entry_peer_ltk(cb->db_entry, ltk); 01467 _db->set_entry_local_ltk(cb->db_entry, ltk); 01468 } 01469 01470 void GenericSecurityManager::on_keys_distributed_ltk( 01471 connection_handle_t connection, 01472 const ltk_t <k 01473 ) { 01474 MBED_ASSERT(_db); 01475 ControlBlock_t *cb = get_control_block(connection); 01476 if (!cb) { 01477 return; 01478 } 01479 01480 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01481 if (!flags) { 01482 return; 01483 } 01484 01485 flags->ltk_mitm_protected = cb->mitm_performed; 01486 01487 _db->set_entry_peer_ltk(cb->db_entry, ltk); 01488 } 01489 01490 void GenericSecurityManager::on_keys_distributed_ediv_rand( 01491 connection_handle_t connection, 01492 const ediv_t &ediv, 01493 const rand_t &rand 01494 ) { 01495 MBED_ASSERT(_db); 01496 ControlBlock_t *cb = get_control_block(connection); 01497 if (!cb) { 01498 return; 01499 } 01500 01501 _db->set_entry_peer_ediv_rand(cb->db_entry, ediv, rand); 01502 } 01503 01504 void GenericSecurityManager::on_keys_distributed_local_ltk( 01505 connection_handle_t connection, 01506 const ltk_t <k 01507 ) { 01508 MBED_ASSERT(_db); 01509 ControlBlock_t *cb = get_control_block(connection); 01510 if (!cb) { 01511 return; 01512 } 01513 01514 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01515 if (!flags) { 01516 return; 01517 } 01518 01519 _db->set_entry_local_ltk(cb->db_entry, ltk); 01520 } 01521 01522 void GenericSecurityManager::on_keys_distributed_local_ediv_rand( 01523 connection_handle_t connection, 01524 const ediv_t &ediv, 01525 const rand_t &rand 01526 ) { 01527 MBED_ASSERT(_db); 01528 ControlBlock_t *cb = get_control_block(connection); 01529 if (!cb) { 01530 return; 01531 } 01532 01533 _db->set_entry_local_ediv_rand(cb->db_entry, ediv, rand); 01534 } 01535 01536 void GenericSecurityManager::on_keys_distributed_irk( 01537 connection_handle_t connection, 01538 const irk_t &irk 01539 ) { 01540 MBED_ASSERT(_db); 01541 ControlBlock_t *cb = get_control_block(connection); 01542 if (!cb) { 01543 return; 01544 } 01545 01546 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01547 if (!flags) { 01548 return; 01549 } 01550 01551 _db->set_entry_peer_irk(cb->db_entry, irk); 01552 } 01553 01554 void GenericSecurityManager::on_keys_distributed_bdaddr( 01555 connection_handle_t connection, 01556 advertising_peer_address_type_t peer_address_type, 01557 const address_t &peer_identity_address 01558 ) { 01559 MBED_ASSERT(_db); 01560 ControlBlock_t *cb = get_control_block(connection); 01561 if (!cb) { 01562 return; 01563 } 01564 01565 _db->set_entry_peer_bdaddr( 01566 cb->db_entry, 01567 (peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS), 01568 peer_identity_address 01569 ); 01570 } 01571 01572 void GenericSecurityManager::on_keys_distributed_csrk( 01573 connection_handle_t connection, 01574 const csrk_t &csrk 01575 ) { 01576 MBED_ASSERT(_db); 01577 ControlBlock_t *cb = get_control_block(connection); 01578 if (!cb) { 01579 return; 01580 } 01581 01582 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01583 if (!flags) { 01584 return; 01585 } 01586 01587 flags->csrk_mitm_protected = cb->mitm_performed; 01588 _db->set_entry_peer_csrk(cb->db_entry, csrk); 01589 01590 eventHandler->signingKey( 01591 connection, 01592 &csrk, 01593 flags->csrk_mitm_protected 01594 ); 01595 } 01596 01597 void GenericSecurityManager::on_ltk_request( 01598 connection_handle_t connection, 01599 const ediv_t &ediv, 01600 const rand_t &rand 01601 ) { 01602 MBED_ASSERT(_db); 01603 ControlBlock_t *cb = get_control_block(connection); 01604 if (!cb) { 01605 return; 01606 } 01607 01608 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01609 if (!flags) { 01610 return; 01611 } 01612 01613 _db->get_entry_local_keys( 01614 mbed::callback(this, &GenericSecurityManager::set_ltk_cb), 01615 cb->db_entry, 01616 ediv, 01617 rand 01618 ); 01619 } 01620 01621 /* control blocks list management */ 01622 01623 GenericSecurityManager::ControlBlock_t::ControlBlock_t() : 01624 connection(0), 01625 db_entry(0), 01626 local_address(), 01627 connected(false), 01628 authenticated(false), 01629 is_master(false), 01630 encryption_requested(false), 01631 encryption_failed(false), 01632 encrypted(false), 01633 signing_requested(false), 01634 signing_override_default(false), 01635 mitm_requested(false), 01636 mitm_performed(false), 01637 attempt_oob(false), 01638 oob_mitm_protection(false), 01639 oob_present(false), 01640 legacy_pairing_oob_request_pending(false), 01641 csrk_failures(0) { } 01642 01643 void GenericSecurityManager::on_ltk_request(connection_handle_t connection) 01644 { 01645 MBED_ASSERT(_db); 01646 ControlBlock_t *cb = get_control_block(connection); 01647 if (!cb) { 01648 return; 01649 } 01650 01651 _db->get_entry_local_keys( 01652 mbed::callback(this, &GenericSecurityManager::set_ltk_cb), 01653 cb->db_entry 01654 ); 01655 } 01656 01657 GenericSecurityManager::ControlBlock_t* 01658 GenericSecurityManager::acquire_control_block(connection_handle_t connection) 01659 { 01660 /* grab the first disconnected slot*/ 01661 for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { 01662 if (!_control_blocks[i].connected) { 01663 ControlBlock_t* cb = &_control_blocks[i]; 01664 cb->connected = true; 01665 cb->connection = connection; 01666 return cb; 01667 } 01668 } 01669 01670 return NULL; 01671 } 01672 01673 GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block( 01674 connection_handle_t connection 01675 ) { 01676 for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { 01677 if (!_control_blocks[i].connected) { 01678 continue; 01679 } else if (connection == _control_blocks[i].connection) { 01680 return &_control_blocks[i]; 01681 } 01682 } 01683 return NULL; 01684 } 01685 01686 GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block( 01687 const address_t &peer_address 01688 ) { 01689 MBED_ASSERT(_db); 01690 for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { 01691 ControlBlock_t *cb = &_control_blocks[i]; 01692 if (cb->connected) { 01693 SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry); 01694 if (flags && (flags->peer_address == peer_address)) { 01695 return cb; 01696 } 01697 } 01698 } 01699 return NULL; 01700 } 01701 01702 GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_block( 01703 SecurityDb::entry_handle_t db_entry 01704 ) { 01705 for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { 01706 if (!_control_blocks[i].connected) { 01707 continue; 01708 } else if (db_entry == _control_blocks[i].db_entry) { 01709 return &_control_blocks[i]; 01710 } 01711 } 01712 return NULL; 01713 } 01714 01715 void GenericSecurityManager::release_control_block(ControlBlock_t* cb) 01716 { 01717 *cb = ControlBlock_t(); 01718 } 01719 01720 } /* namespace generic */ 01721 } /* namespace ble */
Generated on Tue Aug 9 2022 00:37:08 by
1.7.2