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.
Fork of BLE_API by
SecurityManager.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 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 __SECURITY_MANAGER_H__ 00018 #define __SECURITY_MANAGER_H__ 00019 00020 #include <stdint.h> 00021 00022 #include "Gap.h" 00023 #include "CallChainOfFunctionPointersWithContext.h" 00024 00025 class SecurityManager { 00026 public: 00027 enum SecurityMode_t { 00028 SECURITY_MODE_NO_ACCESS, 00029 SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< Require no protection, open link. */ 00030 SECURITY_MODE_ENCRYPTION_NO_MITM, /**< Require encryption, but no MITM protection. */ 00031 SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< Require encryption and MITM protection. */ 00032 SECURITY_MODE_SIGNED_NO_MITM, /**< Require signing or encryption, but no MITM protection. */ 00033 SECURITY_MODE_SIGNED_WITH_MITM, /**< Require signing or encryption, and MITM protection. */ 00034 }; 00035 00036 /** 00037 * @brief Defines possible security status or states. 00038 * 00039 * @details Defines possible security status or states of a link when requested by getLinkSecurity(). 00040 */ 00041 enum LinkSecurityStatus_t { 00042 NOT_ENCRYPTED, /**< The link is not secured. */ 00043 ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ 00044 ENCRYPTED /**< The link is secure.*/ 00045 }; 00046 00047 enum SecurityIOCapabilities_t { 00048 IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display only. */ 00049 IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and yes/no entry. */ 00050 IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ 00051 IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ 00052 IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and display. */ 00053 }; 00054 00055 enum SecurityCompletionStatus_t { 00056 SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ 00057 SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ 00058 SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ 00059 SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ 00060 SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ 00061 SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ 00062 SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ 00063 SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ 00064 SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ 00065 SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ 00066 SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ 00067 SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ 00068 SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ 00069 }; 00070 00071 /** 00072 * Declaration of type containing a passkey to be used during pairing. This 00073 * is passed into initializeSecurity() to specify a pre-programmed passkey 00074 * for authentication instead of generating a random one. 00075 */ 00076 static const unsigned PASSKEY_LEN = 6; 00077 typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ 00078 00079 public: 00080 typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle); 00081 typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); 00082 typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status); 00083 typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); 00084 typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); 00085 00086 typedef FunctionPointerWithContext<const SecurityManager *> SecurityManagerShutdownCallback_t; 00087 typedef CallChainOfFunctionPointersWithContext<const SecurityManager *> SecurityManagerShutdownCallbackChain_t; 00088 00089 /* 00090 * The following functions are meant to be overridden in the platform-specific sub-class. 00091 */ 00092 public: 00093 /** 00094 * Enable the BLE stack's Security Manager. The Security Manager implements 00095 * the actual cryptographic algorithms and protocol exchanges that allow two 00096 * devices to securely exchange data and privately detect each other. 00097 * Calling this API is a prerequisite for encryption and pairing (bonding). 00098 * 00099 * @param[in] enableBonding Allow for bonding. 00100 * @param[in] requireMITM Require protection for man-in-the-middle attacks. 00101 * @param[in] iocaps To specify the I/O capabilities of this peripheral, 00102 * such as availability of a display or keyboard, to 00103 * support out-of-band exchanges of security data. 00104 * @param[in] passkey To specify a static passkey. 00105 * 00106 * @return BLE_ERROR_NONE on success. 00107 */ 00108 virtual ble_error_t init(bool enableBonding = true, 00109 // bool requireMITM = true, HD 00110 bool requireMITM = false, 00111 SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, 00112 const Passkey_t passkey = NULL) { 00113 /* Avoid compiler warnings about unused variables. */ 00114 (void)enableBonding; 00115 (void)requireMITM; 00116 (void)iocaps; 00117 (void)passkey; 00118 00119 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00120 } 00121 00122 /** 00123 * Get the security status of a connection. 00124 * 00125 * @param[in] connectionHandle Handle to identify the connection. 00126 * @param[out] securityStatusP Security status. 00127 * 00128 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00129 */ 00130 virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { 00131 /* Avoid compiler warnings about unused variables. */ 00132 (void)connectionHandle; 00133 (void)securityStatusP; 00134 00135 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00136 } 00137 00138 /** 00139 * Set the security mode on a connection. Useful for elevating the security mode 00140 * once certain conditions are met, e.g., a particular service is found. 00141 * 00142 * @param[in] connectionHandle Handle to identify the connection. 00143 * @param[in] securityMode Requested security mode. 00144 * 00145 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00146 */ 00147 virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) { 00148 /* Avoid compiler warnings about unused variables. */ 00149 (void)connectionHandle; 00150 (void)securityMode; 00151 00152 return BLE_ERROR_NOT_IMPLEMENTED; 00153 } 00154 00155 /** 00156 * Delete all peer device context and all related bonding information from 00157 * the database within the security manager. 00158 * 00159 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00160 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00161 * application registration. 00162 */ 00163 virtual ble_error_t purgeAllBondingState(void) { 00164 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00165 } 00166 00167 /** 00168 * Get a list of addresses from all peers in the bond table. 00169 * 00170 * @param[in,out] addresses 00171 * (on input) addresses.capacity contains the maximum 00172 * number of addresses to be returned. 00173 * (on output) The populated table with copies of the 00174 * addresses in the implementation's whitelist. 00175 * 00176 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00177 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00178 * application registration. 00179 * 00180 * @experimental 00181 */ 00182 virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const { 00183 /* Avoid compiler warnings about unused variables */ 00184 (void) addresses; 00185 00186 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00187 } 00188 00189 /* Event callback handlers. */ 00190 public: 00191 /** 00192 * Setup a callback to be invoked to notify the user application that the 00193 * SecurityManager instance is about to shutdown (possibly as a result of a call 00194 * to BLE::shutdown()). 00195 * 00196 * @note It is possible to chain together multiple onShutdown callbacks 00197 * (potentially from different modules of an application) to be notified 00198 * before the SecurityManager is shutdown. 00199 * 00200 * @note It is also possible to set up a callback into a member function of 00201 * some object. 00202 * 00203 * @note It is possible to unregister a callback using onShutdown().detach(callback) 00204 */ 00205 void onShutdown(const SecurityManagerShutdownCallback_t& callback) { 00206 shutdownCallChain.add(callback); 00207 } 00208 template <typename T> 00209 void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 00210 shutdownCallChain.add(objPtr, memberPtr); 00211 } 00212 00213 /** 00214 * @brief provide access to the callchain of shutdown event callbacks 00215 * It is possible to register callbacks using onShutdown().add(callback); 00216 * It is possible to unregister callbacks using onShutdown().detach(callback) 00217 * @return The shutdown event callbacks chain 00218 */ 00219 SecurityManagerShutdownCallbackChain_t& onShutdown() { 00220 return shutdownCallChain; 00221 } 00222 00223 /** 00224 * To indicate that a security procedure for the link has started. 00225 */ 00226 virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} 00227 00228 /** 00229 * To indicate that the security procedure for the link has completed. 00230 */ 00231 virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} 00232 00233 /** 00234 * To indicate that the link with the peer is secured. For bonded devices, 00235 * subsequent reconnections with a bonded peer will result only in this callback 00236 * when the link is secured; setup procedures will not occur (unless the 00237 * bonding information is either lost or deleted on either or both sides). 00238 */ 00239 virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} 00240 00241 /** 00242 * To indicate that device context is stored persistently. 00243 */ 00244 virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} 00245 00246 /** 00247 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 00248 */ 00249 virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} 00250 00251 /* Entry points for the underlying stack to report events back to the user. */ 00252 public: 00253 void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 00254 if (securitySetupInitiatedCallback) { 00255 securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); 00256 } 00257 } 00258 00259 void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { 00260 if (securitySetupCompletedCallback) { 00261 securitySetupCompletedCallback(handle, status); 00262 } 00263 } 00264 00265 void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { 00266 if (linkSecuredCallback) { 00267 linkSecuredCallback(handle, securityMode); 00268 } 00269 } 00270 00271 void processSecurityContextStoredEvent(Gap::Handle_t handle) { 00272 if (securityContextStoredCallback) { 00273 securityContextStoredCallback(handle); 00274 } 00275 } 00276 00277 void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { 00278 if (passkeyDisplayCallback) { 00279 passkeyDisplayCallback(handle, passkey); 00280 } 00281 } 00282 00283 protected: 00284 SecurityManager() : 00285 securitySetupInitiatedCallback(), 00286 securitySetupCompletedCallback(), 00287 linkSecuredCallback(), 00288 securityContextStoredCallback(), 00289 passkeyDisplayCallback() { 00290 /* empty */ 00291 } 00292 00293 public: 00294 /** 00295 * Notify all registered onShutdown callbacks that the SecurityManager is 00296 * about to be shutdown and clear all SecurityManager state of the 00297 * associated object. 00298 * 00299 * This function is meant to be overridden in the platform-specific 00300 * sub-class. Nevertheless, the sub-class is only expected to reset its 00301 * state and not the data held in SecurityManager members. This shall be 00302 * achieved by a call to SecurityManager::reset() from the sub-class' 00303 * reset() implementation. 00304 * 00305 * @return BLE_ERROR_NONE on success. 00306 */ 00307 virtual ble_error_t reset(void) { 00308 /* Notify that the instance is about to shutdown */ 00309 shutdownCallChain.call(this); 00310 shutdownCallChain.clear(); 00311 00312 securitySetupInitiatedCallback = NULL; 00313 securitySetupCompletedCallback = NULL; 00314 linkSecuredCallback = NULL; 00315 securityContextStoredCallback = NULL; 00316 passkeyDisplayCallback = NULL; 00317 00318 return BLE_ERROR_NONE; 00319 } 00320 00321 protected: 00322 SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 00323 SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 00324 LinkSecuredCallback_t linkSecuredCallback; 00325 HandleSpecificEvent_t securityContextStoredCallback; 00326 PasskeyDisplayCallback_t passkeyDisplayCallback; 00327 00328 private: 00329 SecurityManagerShutdownCallbackChain_t shutdownCallChain; 00330 }; 00331 00332 #endif /*__SECURITY_MANAGER_H__*/
Generated on Wed Jul 13 2022 09:31:10 by
1.7.2
