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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
PalSecurityManager.h
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 #ifndef MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_ 00018 #define MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_ 00019 00020 #include "ble/common/StaticInterface.h" 00021 #include "platform/Callback.h" 00022 #include "platform/NonCopyable.h" 00023 #include "ble/BLETypes.h" 00024 #include "ble/BLEProtocol.h" 00025 #include "ble/SecurityManager.h" 00026 #include "ble/pal/GapTypes.h" 00027 00028 namespace ble { 00029 namespace pal { 00030 00031 typedef ::SecurityManager::SecurityCompletionStatus_t SecurityCompletionStatus_t; 00032 typedef ::SecurityManager::SecurityMode_t SecurityMode_t; 00033 typedef ::SecurityManager::LinkSecurityStatus_t LinkSecurityStatus_t; 00034 typedef ::SecurityManager::Keypress_t Keypress_t; 00035 00036 /** 00037 * Key distribution as required by the SMP with convenient setters and getters, 00038 * use value() to get the octet you can use directly in the PDU. 00039 */ 00040 class KeyDistribution { 00041 public: 00042 enum KeyDistributionFlags_t { 00043 KEY_DISTRIBUTION_NONE = 0x00, 00044 KEY_DISTRIBUTION_ENCRYPTION = 0x01, 00045 KEY_DISTRIBUTION_IDENTITY = 0x02, 00046 KEY_DISTRIBUTION_SIGNING = 0x04, 00047 KEY_DISTRIBUTION_LINK = 0x08, 00048 KEY_DISTRIBUTION_ALL = 0x0F 00049 }; 00050 00051 KeyDistribution() : _value(0) { } 00052 KeyDistribution(uint8_t value) : _value(value) { } 00053 KeyDistribution(bool encryption, 00054 bool identity, 00055 bool signing, 00056 bool link) : _value(0) { 00057 set_encryption(encryption); 00058 set_identity(identity); 00059 set_signing(signing); 00060 set_link(link); 00061 } 00062 00063 bool get_encryption() const { 00064 return _value & KEY_DISTRIBUTION_ENCRYPTION; 00065 } 00066 bool get_identity() const { 00067 return _value & KEY_DISTRIBUTION_IDENTITY; 00068 } 00069 bool get_signing() const { 00070 return _value & KEY_DISTRIBUTION_SIGNING; 00071 } 00072 bool get_link() const { 00073 return _value & KEY_DISTRIBUTION_LINK; 00074 } 00075 00076 void set_encryption(bool enabled = true) { 00077 if (enabled) { 00078 _value |= KEY_DISTRIBUTION_ENCRYPTION; 00079 } else { 00080 _value &= ~KEY_DISTRIBUTION_ENCRYPTION; 00081 } 00082 } 00083 void set_identity(bool enabled = true) { 00084 if (enabled) { 00085 _value |= KEY_DISTRIBUTION_IDENTITY; 00086 } else { 00087 _value &= ~KEY_DISTRIBUTION_IDENTITY; 00088 } 00089 } 00090 void set_signing(bool enabled = true) { 00091 if (enabled) { 00092 _value |= KEY_DISTRIBUTION_SIGNING; 00093 } else { 00094 _value &= ~KEY_DISTRIBUTION_SIGNING; 00095 } 00096 } 00097 void set_link(bool enabled = true) { 00098 if (enabled) { 00099 _value |= KEY_DISTRIBUTION_LINK; 00100 } else { 00101 _value &= ~KEY_DISTRIBUTION_LINK; 00102 } 00103 } 00104 00105 operator uint8_t() { 00106 return _value; 00107 } 00108 00109 KeyDistribution operator&(const KeyDistribution& other) const { 00110 KeyDistribution result(this->value() & other.value()); 00111 return result; 00112 } 00113 00114 KeyDistribution& operator&=(const KeyDistribution& other) { 00115 this->_value = this->_value & other.value(); 00116 return *this; 00117 } 00118 00119 uint8_t value() const { 00120 return _value; 00121 } 00122 00123 private: 00124 uint8_t _value; 00125 }; 00126 00127 /** 00128 * Authentication mask as required by the SMP with convenient setters and getters, 00129 * use value() to get the octet you can use directly in the PDU. 00130 */ 00131 class AuthenticationMask { 00132 public: 00133 enum AuthenticationFlags_t { 00134 AUTHENTICATION_BONDABLE = 0x01, 00135 AUTHENTICATION_MITM = 0x04, /* 0x02 missing because bonding uses two bits */ 00136 AUTHENTICATION_SECURE_CONNECTIONS = 0x08, 00137 AUTHENTICATION_KEYPRESS_NOTIFICATION = 0x10 00138 }; 00139 00140 AuthenticationMask() : _value(0) { } 00141 AuthenticationMask(uint8_t value) : _value(value) { } 00142 AuthenticationMask(bool bondable, 00143 bool mitm, 00144 bool secure_connections, 00145 bool keypress) : _value(0) { 00146 set_bondable(bondable); 00147 set_mitm(mitm); 00148 set_secure_connections(secure_connections); 00149 set_keypress_notification(keypress); 00150 } 00151 00152 bool get_bondable() const { 00153 return _value & AUTHENTICATION_BONDABLE; 00154 } 00155 bool get_mitm() const { 00156 return _value & AUTHENTICATION_MITM; 00157 } 00158 bool get_secure_connections() const { 00159 return _value & AUTHENTICATION_SECURE_CONNECTIONS; 00160 } 00161 bool get_keypress_notification() const { 00162 return _value & AUTHENTICATION_KEYPRESS_NOTIFICATION; 00163 } 00164 00165 void set_bondable(bool enabled = true) { 00166 if (enabled) { 00167 _value |= AUTHENTICATION_BONDABLE; 00168 } else { 00169 _value &= ~AUTHENTICATION_BONDABLE; 00170 } 00171 } 00172 void set_mitm(bool enabled = true) { 00173 if (enabled) { 00174 _value |= AUTHENTICATION_MITM; 00175 } else { 00176 _value &= ~AUTHENTICATION_MITM; 00177 } 00178 } 00179 void set_secure_connections(bool enabled = true) { 00180 if (enabled) { 00181 _value |= AUTHENTICATION_SECURE_CONNECTIONS; 00182 } else { 00183 _value &= ~AUTHENTICATION_SECURE_CONNECTIONS; 00184 } 00185 } 00186 void set_keypress_notification(bool enabled = true) { 00187 if (enabled) { 00188 _value |= AUTHENTICATION_KEYPRESS_NOTIFICATION; 00189 } else { 00190 _value &= ~AUTHENTICATION_KEYPRESS_NOTIFICATION; 00191 } 00192 } 00193 00194 operator uint8_t() { 00195 return _value; 00196 } 00197 uint8_t value() const { 00198 return _value; 00199 } 00200 00201 private: 00202 uint8_t _value; 00203 }; 00204 00205 /** 00206 * Handle events generated by ble::pal::SecurityManager 00207 */ 00208 template<class Impl> 00209 class SecurityManagerEventHandler : 00210 public StaticInterface<Impl, SecurityManagerEventHandler> 00211 { 00212 using StaticInterface<Impl, ble::pal::SecurityManagerEventHandler>::impl; 00213 00214 public: 00215 //////////////////////////////////////////////////////////////////////////// 00216 // Pairing 00217 // 00218 00219 /** 00220 * Request pairing. This is called on the slave in response to a request from the master. 00221 * Upper layer shall either send a pairing response (send_pairing_response) 00222 * or cancel the pairing procedure (cancel_pairing). 00223 * 00224 * @param[in] connection connection handle 00225 * @param[in] oob_data_flag is out of band data present 00226 * @param[in] authentication_requirements authentication requirements 00227 * @param[in] initiator_dist key distribution 00228 * @param[in] responder_dist key distribution 00229 */ 00230 void on_pairing_request( 00231 connection_handle_t connection, 00232 bool oob_data_flag, 00233 AuthenticationMask authentication_requirements, 00234 KeyDistribution initiator_dist, 00235 KeyDistribution responder_dist 00236 ) { 00237 impl ()->on_pairing_request_( 00238 connection, 00239 oob_data_flag, 00240 authentication_requirements, 00241 initiator_dist, 00242 responder_dist 00243 ); 00244 } 00245 00246 /** 00247 * Indicate that the pairing has failed. 00248 * 00249 * @note Any subsequent pairing procedure shall restart from the Pairing 00250 * Feature Exchange phase. 00251 * @param[in] connection connection handle 00252 * @param[in] error reason for the failed pairing 00253 */ 00254 void on_pairing_error( 00255 connection_handle_t connection, 00256 pairing_failure_t error 00257 ) { 00258 impl ()->on_pairing_error_(connection, error); 00259 } 00260 00261 /** 00262 * Indicate that the pairing has timed out. 00263 * 00264 * @param[in] connection connection handle 00265 */ 00266 void on_pairing_timed_out( 00267 connection_handle_t connection 00268 ) { 00269 impl ()->on_pairing_timed_out_(connection); 00270 } 00271 00272 /** 00273 * Indicate that the pairing for the link has completed. 00274 * 00275 * @param[in] connection connection handle 00276 */ 00277 void on_pairing_completed( 00278 connection_handle_t connection 00279 ) { 00280 impl ()->on_pairing_completed_(connection); 00281 } 00282 00283 //////////////////////////////////////////////////////////////////////////// 00284 // Security 00285 // 00286 00287 /** 00288 * Indicate that the authentication timeout time has elapsed 00289 * and we received no packets with a valid MIC in that time. 00290 * 00291 * @param[in] connection connection handle 00292 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 6, Part B, 5.4 00293 */ 00294 void on_valid_mic_timeout( 00295 connection_handle_t connection 00296 ) { 00297 impl ()->on_valid_mic_timeout_(connection); 00298 } 00299 00300 /** 00301 * Ask the stack to evaluate the security request received from the slave. 00302 * This might result in the stack enabling encryption, or pairing/re-pairing. 00303 * 00304 * @param[in] connection connection handle 00305 * @param[in] authentication authentication requirements from the slave 00306 */ 00307 void on_slave_security_request( 00308 connection_handle_t connection, 00309 AuthenticationMask authentication 00310 ) { 00311 impl ()->on_slave_security_request_(connection, authentication); 00312 } 00313 00314 //////////////////////////////////////////////////////////////////////////// 00315 // Encryption 00316 // 00317 00318 /** 00319 * Inform the application of the result of an encryption request. 00320 * @note Do no call if request timed out, call on_link_encryption_request_timed_out 00321 * instead. 00322 * 00323 * @param[in] connection connection handle 00324 * @param[in] result encryption state of the link 00325 */ 00326 void on_link_encryption_result( 00327 connection_handle_t connection, 00328 link_encryption_t result 00329 ) { 00330 impl ()->on_link_encryption_result_(connection, result); 00331 } 00332 00333 /** 00334 * Indicate that the encryption request failed due to timeout. 00335 * 00336 * @param[in] connection connection handle 00337 */ 00338 void on_link_encryption_request_timed_out( 00339 connection_handle_t connection 00340 ) { 00341 impl ()->on_link_encryption_request_timed_out_(connection); 00342 } 00343 00344 //////////////////////////////////////////////////////////////////////////// 00345 // MITM 00346 // 00347 00348 /** 00349 * Inform the application that should display a passkey. 00350 * 00351 * @param[in] connection connection handle 00352 * @param[in] passkey passkey to be displayed 00353 */ 00354 void on_passkey_display( 00355 connection_handle_t connection, 00356 passkey_num_t passkey 00357 ) { 00358 impl ()->on_passkey_display_( 00359 connection, 00360 passkey 00361 ); 00362 } 00363 00364 /** 00365 * Indicate that user confirmation is required to confirm matching 00366 * passkeys displayed on devices. 00367 * 00368 * @param[in] connection connection handle 00369 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E, 7.7.42 00370 */ 00371 void on_confirmation_request( 00372 connection_handle_t connection 00373 ) { 00374 impl ()->on_confirmation_request_(connection); 00375 } 00376 00377 /** 00378 * Request the passkey entered during pairing. 00379 * 00380 * @note shall be followed by: pal::SecurityManager::passkey_request_reply 00381 * @param[in] connection connection handle 00382 * or a cancellation of the procedure. 00383 */ 00384 void on_passkey_request( 00385 connection_handle_t connection 00386 ) { 00387 impl ()->on_passkey_request_(connection); 00388 } 00389 00390 /** 00391 * Indicate that a key has been pressed by the peer. 00392 * 00393 * @param[in] connection connection handle 00394 * @param[in] keypress type of keypress event 00395 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H, 3.5.8 00396 */ 00397 void on_keypress_notification( 00398 connection_handle_t connection, 00399 Keypress_t keypress 00400 ) { 00401 impl ()->on_keypress_notification_(connection, keypress); 00402 } 00403 00404 /** 00405 * Request OOB data from the user application. 00406 * 00407 * @param[in] connection connection handle 00408 * @note shall be followed by: pal::SecurityManager::secure_connections_oob_request_reply 00409 * or a cancellation of the procedure. 00410 */ 00411 void on_secure_connections_oob_request( 00412 connection_handle_t connection 00413 ) { 00414 impl ()->on_secure_connections_oob_request_(connection); 00415 } 00416 00417 /** 00418 * Request OOB data from the user application. 00419 * 00420 * @param[in] connection connection handle 00421 * @note shall be followed by: pal::SecurityManager::legacy_pairing_oob_request_reply 00422 * or a cancellation of the procedure. 00423 */ 00424 void on_legacy_pairing_oob_request( 00425 connection_handle_t connection 00426 ) { 00427 impl ()->on_legacy_pairing_oob_request_(connection); 00428 } 00429 00430 /** 00431 * Send OOB data to the application for transport to the peer. 00432 * 00433 * @param[in] connection connection handle 00434 * @param[in] random random number used to generate the confirmation 00435 * @param[in] confirm confirmation value to be use for authentication 00436 * in secure connections pairing 00437 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00438 */ 00439 void on_secure_connections_oob_generated( 00440 const oob_lesc_value_t &random, 00441 const oob_confirm_t &confirm 00442 ) { 00443 impl ()->on_secure_connections_oob_generated_(random, confirm); 00444 } 00445 00446 //////////////////////////////////////////////////////////////////////////// 00447 // Keys 00448 // 00449 00450 /** 00451 * Store the results of key generation of the stage 2 of secure connections pairing 00452 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 2.3.5.6.5 00453 * 00454 * @param[in] connection connection handle 00455 * @param[in] ltk long term key from the peer 00456 */ 00457 void on_secure_connections_ltk_generated( 00458 connection_handle_t connection, 00459 const ltk_t <k 00460 ) { 00461 impl ()->on_secure_connections_ltk_generated_(connection, ltk); 00462 } 00463 00464 /** 00465 * Store the results of key distribution after LTK has been received. 00466 * 00467 * @param[in] connection connection handle 00468 * @param[in] ltk long term key from the peer 00469 */ 00470 void on_keys_distributed_ltk( 00471 connection_handle_t connection, 00472 const ltk_t <k 00473 ) { 00474 impl ()->on_keys_distributed_ltk_(connection, ltk); 00475 } 00476 00477 /** 00478 * Store the results of key distribution after EDIV and RAND has been received. 00479 * 00480 * @param[in] connection connection handle 00481 * @param[in] ltk long term key from the peer 00482 */ 00483 void on_keys_distributed_ediv_rand( 00484 connection_handle_t connection, 00485 const ediv_t &ediv, 00486 const rand_t &rand 00487 ) { 00488 impl ()->on_keys_distributed_ediv_rand_(connection, ediv, rand); 00489 } 00490 00491 /** 00492 * Store the local key, if we are slave now or in the future 00493 * this will be used to encrypt. 00494 * 00495 * @param[in] connection connection handle 00496 * @param[in] ltk key sent to the peer 00497 */ 00498 void on_keys_distributed_local_ltk( 00499 connection_handle_t connection, 00500 const ltk_t <k 00501 ) { 00502 impl ()->on_keys_distributed_local_ltk_(connection, ltk); 00503 } 00504 00505 /** 00506 * Store the EDIV and RAND that will be used to identify 00507 * the stored local LTK. if we are slave that LTK will be 00508 * used to encrypt, otherwise this will be stored to 00509 * be used in case of role reversal. 00510 * 00511 * @param[in] connection connection handle 00512 * @param[in] ediv identifies LTK 00513 * @param[in] rand identifies LTK 00514 */ 00515 void on_keys_distributed_local_ediv_rand( 00516 connection_handle_t connection, 00517 const ediv_t &ediv, 00518 const rand_t &rand 00519 ) { 00520 impl ()->on_keys_distributed_local_ediv_rand_(connection, ediv, rand); 00521 } 00522 00523 /** 00524 * Store the results of key distribution after IRK has been received. 00525 * 00526 * @param[in] connection connection handle 00527 * @param[in] irk identity resolution key 00528 */ 00529 void on_keys_distributed_irk( 00530 connection_handle_t connection, 00531 const irk_t &irk 00532 ) { 00533 impl ()->on_keys_distributed_irk_(connection, irk); 00534 } 00535 00536 /** 00537 * Store the identity address of the peer after it has been distributed. 00538 * 00539 * @param[in] connection connection handle 00540 * @param[in] peer_identity_address_type public or private address indication 00541 * @param[in] peer_identity_address peer address 00542 */ 00543 void on_keys_distributed_bdaddr( 00544 connection_handle_t connection, 00545 advertising_peer_address_type_t peer_identity_address_type, 00546 const address_t &peer_identity_address 00547 ) { 00548 impl ()->on_keys_distributed_bdaddr_(connection, peer_identity_address_type, peer_identity_address); 00549 } 00550 00551 /** 00552 * Store the peer's CSRK after it has been distributed. 00553 * 00554 * @param[in] connection connection handle 00555 * @param[in] csrk signing key 00556 */ 00557 void on_keys_distributed_csrk( 00558 connection_handle_t connection, 00559 const csrk_t &csrk 00560 ) { 00561 impl ()->on_keys_distributed_csrk_(connection, csrk); 00562 } 00563 00564 /** 00565 * Request the LTK since the peer is asking us to encrypt the link. We need to 00566 * provide the LTK based on the EDIV and RAND provided by the other side. This 00567 * is called on the slave. 00568 * 00569 * @param[in] connection connection handle 00570 * @param[in] ediv identifies LTK 00571 * @param[in] rand identifies LTK 00572 */ 00573 void on_ltk_request( 00574 connection_handle_t connection, 00575 const ediv_t &ediv, 00576 const rand_t &rand 00577 ) { 00578 impl ()->on_ltk_request_(connection, ediv, rand); 00579 } 00580 00581 /** 00582 * Request the LTK since the peer is asking us to encrypt the link. 00583 * @note No EDIV or RAND is provided as this requests a secure 00584 * connections LTK where their values are all zeroes 00585 * 00586 * @param[in] connection connection handle 00587 */ 00588 void on_ltk_request( 00589 connection_handle_t connection 00590 ) { 00591 impl ()->on_ltk_request_(connection); 00592 } 00593 }; 00594 00595 00596 /** 00597 * Adaptation layer of the Security Manager. 00598 */ 00599 template<class Impl, class EventHandler> 00600 class SecurityManager : private mbed::NonCopyable<SecurityManager<Impl, EventHandler> > { 00601 00602 Impl* impl() { 00603 return static_cast<Impl*>(this); 00604 } 00605 00606 public: 00607 SecurityManager() : _pal_event_handler(NULL) { }; 00608 00609 ~SecurityManager() { }; 00610 00611 //////////////////////////////////////////////////////////////////////////// 00612 // SM lifecycle management 00613 // 00614 00615 /** 00616 * Initialise stack. Called before first use. 00617 * 00618 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00619 */ 00620 ble_error_t initialize() { 00621 return impl()->initialize_(); 00622 } 00623 00624 /** 00625 * Finalise all actions. Called before shutdown. 00626 * 00627 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00628 */ 00629 ble_error_t terminate() { 00630 return impl()->terminate_(); 00631 } 00632 00633 /** 00634 * Reset to same state as after initialize. 00635 * 00636 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00637 */ 00638 ble_error_t reset() { 00639 return impl()->reset_(); 00640 } 00641 00642 //////////////////////////////////////////////////////////////////////////// 00643 // Resolving list management 00644 // 00645 /** 00646 * Return the number of address translation entries that can be stored by the 00647 * subsystem. 00648 * 00649 * @warning: The number of entries is considered fixed. 00650 * 00651 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.41 00652 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00653 */ 00654 uint8_t read_resolving_list_capacity() { 00655 return impl()->read_resolving_list_capacity_(); 00656 } 00657 00658 /** 00659 * Add a device definition into the resolving list of the LE subsystem. 00660 * 00661 * @param[in] peer_identity_address_type public/private indicator 00662 * @param[in] peer_identity_address address of the device whose entry is to be added 00663 * @param[in] peer_irk peer identity resolving key 00664 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.38 00665 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00666 */ 00667 ble_error_t add_device_to_resolving_list( 00668 advertising_peer_address_type_t peer_identity_address_type, 00669 const address_t &peer_identity_address, 00670 const irk_t &peer_irk 00671 ) { 00672 return impl()->add_device_to_resolving_list_( 00673 peer_identity_address_type, 00674 peer_identity_address, 00675 peer_irk 00676 ); 00677 } 00678 00679 /** 00680 * Add a device definition from the resolving list of the LE subsystem. 00681 * 00682 * @param[in] peer_identity_address_type public/private indicator 00683 * @param[in] peer_identity_address address of the device whose entry is to be removed 00684 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.39 00685 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00686 */ 00687 ble_error_t remove_device_from_resolving_list( 00688 advertising_peer_address_type_t peer_identity_address_type, 00689 const address_t &peer_identity_address 00690 ) { 00691 return impl()->remove_device_from_resolving_list_( 00692 peer_identity_address_type, 00693 peer_identity_address 00694 ); 00695 } 00696 00697 /** 00698 * Remove all devices from the resolving list. 00699 * 00700 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E: 7.8.40 00701 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00702 */ 00703 ble_error_t clear_resolving_list() { 00704 return impl()->clear_resolving_list_(); 00705 } 00706 00707 //////////////////////////////////////////////////////////////////////////// 00708 // Pairing 00709 // 00710 00711 /** 00712 * Send a pairing request to a slave. 00713 * 00714 * @param[in] connection connection handle 00715 * @param[in] oob_data_flag is oob data present 00716 * @param[in] authentication_requirements authentication requirements 00717 * @param[in] initiator_dist key distribution 00718 * @param[in] responder_dist key distribution 00719 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.1 00720 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00721 */ 00722 ble_error_t send_pairing_request( 00723 connection_handle_t connection, 00724 bool oob_data_flag, 00725 AuthenticationMask authentication_requirements, 00726 KeyDistribution initiator_dist, 00727 KeyDistribution responder_dist 00728 ) { 00729 return impl()->send_pairing_request_( 00730 connection, 00731 oob_data_flag, 00732 authentication_requirements, 00733 initiator_dist, 00734 responder_dist 00735 ); 00736 } 00737 00738 /** 00739 * Send a pairing response to a master. 00740 * 00741 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.2* 00742 * @param[in] connection connection handle 00743 * @param[in] oob_data_flag is oob data present 00744 * @param[in] authentication_requirements authentication requirements 00745 * @param[in] initiator_dist key distribution 00746 * @param[in] responder_dist key distribution 00747 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00748 */ 00749 ble_error_t send_pairing_response( 00750 connection_handle_t connection, 00751 bool oob_data_flag, 00752 AuthenticationMask authentication_requirements, 00753 KeyDistribution initiator_dist, 00754 KeyDistribution responder_dist 00755 ) { 00756 return impl()->send_pairing_response_( 00757 connection, 00758 oob_data_flag, 00759 authentication_requirements, 00760 initiator_dist, 00761 responder_dist 00762 ); 00763 } 00764 00765 /** 00766 * Cancel an ongoing pairing. 00767 * 00768 * @param[in] connection connection handle 00769 * @param[in] reason pairing failure error 00770 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part H - 3.5.5 00771 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00772 */ 00773 ble_error_t cancel_pairing( 00774 connection_handle_t connection, 00775 pairing_failure_t reason 00776 ) { 00777 return impl()->cancel_pairing_( 00778 connection, 00779 reason 00780 ); 00781 } 00782 00783 //////////////////////////////////////////////////////////////////////////// 00784 // Feature support 00785 // 00786 00787 /** 00788 * Check if the Secure Connections feature is supported by the stack and controller. 00789 * 00790 * @param[out] enabled true if SC are supported 00791 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00792 */ 00793 ble_error_t get_secure_connections_support( 00794 bool &enabled 00795 ) { 00796 return impl()->get_secure_connections_support_(enabled); 00797 } 00798 00799 /** 00800 * Set the IO capability that will be used during pairing feature exchange. 00801 * 00802 * @param[in] io_capability type of IO capabilities available on the local device 00803 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00804 */ 00805 ble_error_t set_io_capability( 00806 io_capability_t io_capability 00807 ) { 00808 return impl()->set_io_capability_(io_capability); 00809 } 00810 00811 //////////////////////////////////////////////////////////////////////////// 00812 // Security settings 00813 // 00814 00815 /** 00816 * Set the time after which an event will be generated unless we received a packet with 00817 * a valid MIC. 00818 * 00819 * @param[in] connection connection handle 00820 * @param[in] timeout_in_10ms time measured in units of 10 milliseconds 00821 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00822 */ 00823 ble_error_t set_authentication_timeout( 00824 connection_handle_t connection, 00825 uint16_t timeout_in_10ms 00826 ) { 00827 return impl()->set_authentication_timeout_( 00828 connection, 00829 timeout_in_10ms 00830 ); 00831 } 00832 00833 /** 00834 * Get the time after which an event will be generated unless we received a packet with 00835 * a valid MIC. 00836 * 00837 * @param[in] connection connection handle 00838 * @param[out] timeout_in_10ms time measured in units of 10 milliseconds 00839 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00840 */ 00841 ble_error_t get_authentication_timeout( 00842 connection_handle_t connection, 00843 uint16_t &timeout_in_10ms 00844 ) { 00845 return impl()->get_authentication_timeout_( 00846 connection, 00847 timeout_in_10ms 00848 ); 00849 } 00850 00851 /** 00852 * Set the key size boundaries that will be used during pairing feature 00853 * exchange. 00854 * 00855 * @param[in] min_encryption_key_size The minimum encryption key size in bytes 00856 * required for pairing. This value shall be in the range [7 : 16]. 00857 * 00858 * @param[in] max_encryption_key_size The maximum encryption key size in bytes 00859 * required for pairing. This value shall be in the range 00860 * [min_encryption_key_size : 16]. 00861 * 00862 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00863 */ 00864 ble_error_t set_encryption_key_requirements( 00865 uint8_t min_encryption_key_size, 00866 uint8_t max_encryption_key_size 00867 ) { 00868 return impl()->set_encryption_key_requirements_( 00869 min_encryption_key_size, 00870 max_encryption_key_size 00871 ); 00872 } 00873 00874 /** 00875 * Request change of security level from the master. This is called by the slave when 00876 * it needs to elevate the security level as it can't change it itself. This will be 00877 * received by the master who will take the decision about what action to take 00878 * (encryption, pairing, re-paring). 00879 * 00880 * @param[in] connection connection handle 00881 * @param[in] authentication authentication requirements 00882 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00883 */ 00884 ble_error_t slave_security_request( 00885 connection_handle_t connection, 00886 AuthenticationMask authentication 00887 ) { 00888 return impl()->slave_security_request_( 00889 connection, 00890 authentication 00891 ); 00892 } 00893 00894 //////////////////////////////////////////////////////////////////////////// 00895 // Encryption 00896 // 00897 00898 /** 00899 * Enabled encryption using the LTK given. The EDIV and RAND will be sent to the peer and 00900 * used to identify the LTK. This is called by the master. This will refresh the key if 00901 * enabled on an already encrypted link. 00902 * 00903 * @param[in] connection connection handle 00904 * @param[in] ltk long term key from the peer 00905 * @param[in] ediv encryption diversifier from the peer 00906 * @param[in] rand random value from the peer 00907 * @param[in] mitm does the LTK have man in the middle protection 00908 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00909 */ 00910 ble_error_t enable_encryption( 00911 connection_handle_t connection, 00912 const ltk_t <k, 00913 const rand_t &rand, 00914 const ediv_t &ediv, 00915 bool mitm 00916 ) { 00917 return impl()->enable_encryption_( 00918 connection, 00919 ltk, 00920 rand, 00921 ediv, 00922 mitm 00923 ); 00924 } 00925 00926 /** 00927 * Enabled encryption using the LTK given on a connection established with secure 00928 * connections pairing. 00929 * 00930 * @param[in] connection connection handle 00931 * @param[in] ltk long term key from the peer 00932 * @param[in] mitm does the LTK have man in the middle protection 00933 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00934 */ 00935 ble_error_t enable_encryption( 00936 connection_handle_t connection, 00937 const ltk_t <k, 00938 bool mitm 00939 ) { 00940 return impl()->enable_encryption_( 00941 connection, 00942 ltk, 00943 mitm 00944 ); 00945 } 00946 00947 /** 00948 * Encrypt data with a given key. This uses the facility on the controller to 00949 * perform the encryption. 00950 * 00951 * @param[in] key encryption key 00952 * @param[in,out] data data to be encrypted, if successful contains the result 00953 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00954 */ 00955 ble_error_t encrypt_data( 00956 const byte_array_t<16> &key, 00957 encryption_block_t &data 00958 ) { 00959 return impl()->encrypt_data_(key, data); 00960 } 00961 00962 //////////////////////////////////////////////////////////////////////////// 00963 // Privacy 00964 // 00965 00966 ble_error_t set_private_address_timeout( 00967 uint16_t timeout_in_seconds 00968 ) { 00969 return impl()->set_private_address_timeout(timeout_in_seconds); 00970 } 00971 00972 //////////////////////////////////////////////////////////////////////////// 00973 // Keys 00974 // 00975 00976 /** 00977 * Set the LTK that is to be used for encryption. 00978 * 00979 * @param[in] connection connection handle 00980 * @param[in] ltk long term key 00981 * @param[in] mitm does the LTK have man in the middle protection 00982 * @param[in] secure_connections is this a secure_connections pairing 00983 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00984 */ 00985 ble_error_t set_ltk( 00986 connection_handle_t connection, 00987 const ltk_t <k, 00988 bool mitm, 00989 bool secure_connections 00990 ) { 00991 return impl()->set_ltk_(connection, ltk, mitm, secure_connections); 00992 } 00993 00994 /** 00995 * Inform the stack we don't have the LTK. 00996 * 00997 * @param[in] connection connection handle 00998 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 00999 */ 01000 ble_error_t set_ltk_not_found( 01001 connection_handle_t connection 01002 ) { 01003 return impl()->set_ltk_not_found_(connection); 01004 } 01005 01006 /** 01007 * Set the local IRK. 01008 * 01009 * @param[in] irk identity resolution key 01010 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01011 */ 01012 ble_error_t set_irk( 01013 const irk_t &irk 01014 ) { 01015 return impl()->set_irk_(irk); 01016 } 01017 01018 /** 01019 * Set the local CSRK. 01020 * 01021 * @param[in] csrk local signing key 01022 * @param[in] sign_counter local signing counter 01023 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01024 */ 01025 ble_error_t set_csrk( 01026 const csrk_t &csrk, 01027 sign_count_t sign_counter 01028 ) { 01029 return impl()->set_csrk_(csrk, sign_counter); 01030 } 01031 01032 /** 01033 * Set the peer CSRK for particular connection. 01034 * 01035 * @param[in] connection connection handle 01036 * @param[in] csrk signing key 01037 * @param[in] authenticated is the CSRK authenticated 01038 * @param[in] sign_counter signing counter 01039 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure 01040 */ 01041 ble_error_t set_peer_csrk( 01042 connection_handle_t connection, 01043 const csrk_t &csrk, 01044 bool authenticated, 01045 sign_count_t sign_counter 01046 ) { 01047 return impl()->set_peer_csrk_( 01048 connection, 01049 csrk, 01050 authenticated, 01051 sign_counter 01052 ); 01053 } 01054 01055 ble_error_t remove_peer_csrk(connection_handle_t connection) { 01056 return impl()->remove_peer_csrk_(connection); 01057 } 01058 01059 //////////////////////////////////////////////////////////////////////////// 01060 // Authentication 01061 // 01062 01063 /** 01064 * Generate and return 8 octets of random data compliant with [FIPS PUB 140-2] 01065 * 01066 * @param[out] random_data returns 8 octets of random data 01067 * @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part H 2 01068 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01069 */ 01070 ble_error_t get_random_data( 01071 byte_array_t<8> &random_data 01072 ) { 01073 return impl()->get_random_data_(random_data); 01074 } 01075 01076 //////////////////////////////////////////////////////////////////////////// 01077 // MITM 01078 // 01079 01080 /** 01081 * Set the default passkey that will be used when the SM needs a passkey to 01082 * be displayed. 01083 * 01084 * By default, the pal security manager generates a random passkey when a 01085 * passkey has to be displayed by the application. A call to this function 01086 * with a valid passkey alter this behaviour and the SecurityManager shall 01087 * pass the passkey set into SecurityManagerEvent::on_passkey_display . 01088 * 01089 * A call to this function with a zero value will reset the behaviour and 01090 * indicates to the security manager that passkeys passed to 01091 * SecurityManagerEvent::on_passkey_display shall be randomly generated. 01092 * 01093 * @param[in] passkey Set the passkey that shall be used by the security 01094 * manager when SecurityManagerEvent::on_passkey_display is called. If 01095 * passkey is set to 0 then the security manager generates a random 01096 * passkey every time it calls SecurityManagerEvent::on_passkey_display. 01097 * 01098 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01099 */ 01100 ble_error_t set_display_passkey( 01101 passkey_num_t passkey 01102 ) { 01103 return impl()->set_display_passkey_(passkey); 01104 } 01105 01106 /** 01107 * Reply to a passkey request received from the SecurityManagerEventHandler. 01108 * 01109 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01110 */ 01111 ble_error_t passkey_request_reply( 01112 connection_handle_t connection, 01113 passkey_num_t passkey 01114 ) { 01115 return impl()->passkey_request_reply_(connection, passkey); 01116 } 01117 01118 /** 01119 * Reply to a Secure Connections oob data request received from the SecurityManagerEventHandler. 01120 * 01121 * @param[in] connection connection handle 01122 * @param[in] local_random local random number used for the last oob exchange 01123 * @param[in] peer_random random number used to generate the confirmation on peer 01124 * @param[in] peer_confirm confirmation value to be use for authentication 01125 * in secure connections pairing 01126 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01127 */ 01128 ble_error_t secure_connections_oob_request_reply( 01129 connection_handle_t connection, 01130 const oob_lesc_value_t &local_random, 01131 const oob_lesc_value_t &peer_random, 01132 const oob_confirm_t &peer_confirm 01133 ) { 01134 return impl()->secure_connections_oob_request_reply_( 01135 connection, 01136 local_random, 01137 peer_random, 01138 peer_confirm 01139 ); 01140 } 01141 01142 /** 01143 * Reply to a legacy pairing oob data request received from the SecurityManagerEventHandler. 01144 * 01145 * @param[in] connection connection handle 01146 * @param[in] oob_data pointer to out of band data 01147 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01148 */ 01149 ble_error_t legacy_pairing_oob_request_reply( 01150 connection_handle_t connection, 01151 const oob_tk_t &oob_data 01152 ) { 01153 return impl()->legacy_pairing_oob_request_reply_(connection, oob_data); 01154 } 01155 01156 /** 01157 * Notify the stack that the user has confirmed the values during numerical 01158 * comparison stage of pairing. 01159 * 01160 * @param[in] connection connection handle 01161 * @param[in] confirmation true if the user indicated the numbers match 01162 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01163 */ 01164 ble_error_t confirmation_entered( 01165 connection_handle_t connection, 01166 bool confirmation 01167 ) { 01168 return impl()->confirmation_entered_(connection, confirmation); 01169 } 01170 01171 /** 01172 * Notify the stack that the user pressed a key. This will be sent to the peer and create 01173 * an appropriate event there if the keypress protocol is enabled. 01174 * 01175 * @param[in] connection connection handle 01176 * @param[in] keypress type of keypress event 01177 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01178 */ 01179 ble_error_t send_keypress_notification( 01180 connection_handle_t connection, 01181 Keypress_t keypress 01182 ) { 01183 return impl()->send_keypress_notification_(connection, keypress); 01184 } 01185 01186 /** 01187 * Generate local OOB data to be sent to the application which sends it to the peer. 01188 * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure 01189 */ 01190 ble_error_t generate_secure_connections_oob() { 01191 return impl()->generate_secure_connections_oob_(); 01192 } 01193 01194 /* Entry points for the underlying stack to report events back to the user. */ 01195 public: 01196 /** 01197 * Sets the event handler that us called by the PAL porters to notify the stack of events 01198 * which will in turn be passed onto the user application when appropriate. 01199 * 01200 * @param[in] event_handler the new event handler interface implementation. Memory 01201 * owned by caller who is responsible for updating this pointer if interface changes. 01202 */ 01203 void set_event_handler( 01204 EventHandler *event_handler 01205 ) { 01206 _pal_event_handler = event_handler; 01207 } 01208 01209 EventHandler* get_event_handler() { 01210 return _pal_event_handler; 01211 } 01212 01213 private: 01214 EventHandler *_pal_event_handler; 01215 01216 }; 01217 01218 } /* namespace pal */ 01219 } /* namespace ble */ 01220 01221 #endif /* MBED_OS_FEATURES_FEATURE_BLE_BLE_PAL_PALSM_H_ */
Generated on Tue Jul 12 2022 13:54:40 by
