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.
Dependencies: nRF51_Vdd TextLCD BME280
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 Jul 12 2022 15:15:46 by
