Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PalSecurityManager.h Source File

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  &ltk
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  &ltk
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  &ltk
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  &ltk,
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  &ltk,
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  &ltk,
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_ */