High level Bluetooth Low Energy API and radio abstraction layer
Dependents: BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more
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, 00110 SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, 00111 const Passkey_t passkey = NULL) { 00112 /* Avoid compiler warnings about unused variables. */ 00113 (void)enableBonding; 00114 (void)requireMITM; 00115 (void)iocaps; 00116 (void)passkey; 00117 00118 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00119 } 00120 00121 /** 00122 * Get the security status of a connection. 00123 * 00124 * @param[in] connectionHandle Handle to identify the connection. 00125 * @param[out] securityStatusP Security status. 00126 * 00127 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00128 */ 00129 virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { 00130 /* Avoid compiler warnings about unused variables. */ 00131 (void)connectionHandle; 00132 (void)securityStatusP; 00133 00134 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00135 } 00136 00137 /** 00138 * Set the security mode on a connection. Useful for elevating the security mode 00139 * once certain conditions are met, e.g., a particular service is found. 00140 * 00141 * @param[in] connectionHandle Handle to identify the connection. 00142 * @param[in] securityMode Requested security mode. 00143 * 00144 * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 00145 */ 00146 virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) { 00147 /* Avoid compiler warnings about unused variables. */ 00148 (void)connectionHandle; 00149 (void)securityMode; 00150 00151 return BLE_ERROR_NOT_IMPLEMENTED; 00152 } 00153 00154 /** 00155 * Delete all peer device context and all related bonding information from 00156 * the database within the security manager. 00157 * 00158 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00159 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00160 * application registration. 00161 */ 00162 virtual ble_error_t purgeAllBondingState(void) { 00163 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00164 } 00165 00166 /** 00167 * Get a list of addresses from all peers in the bond table. 00168 * 00169 * @param[in,out] addresses 00170 * (on input) addresses.capacity contains the maximum 00171 * number of addresses to be returned. 00172 * (on output) The populated table with copies of the 00173 * addresses in the implementation's whitelist. 00174 * 00175 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 00176 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 00177 * application registration. 00178 * 00179 * @experimental 00180 */ 00181 virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const { 00182 /* Avoid compiler warnings about unused variables */ 00183 (void) addresses; 00184 00185 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 00186 } 00187 00188 /* Event callback handlers. */ 00189 public: 00190 /** 00191 * Setup a callback to be invoked to notify the user application that the 00192 * SecurityManager instance is about to shutdown (possibly as a result of a call 00193 * to BLE::shutdown()). 00194 * 00195 * @note It is possible to chain together multiple onShutdown callbacks 00196 * (potentially from different modules of an application) to be notified 00197 * before the SecurityManager is shutdown. 00198 * 00199 * @note It is also possible to set up a callback into a member function of 00200 * some object. 00201 * 00202 * @note It is possible to unregister a callback using onShutdown().detach(callback) 00203 */ 00204 void onShutdown(const SecurityManagerShutdownCallback_t& callback) { 00205 shutdownCallChain.add(callback); 00206 } 00207 template <typename T> 00208 void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 00209 shutdownCallChain.add(objPtr, memberPtr); 00210 } 00211 00212 /** 00213 * @brief provide access to the callchain of shutdown event callbacks 00214 * It is possible to register callbacks using onShutdown().add(callback); 00215 * It is possible to unregister callbacks using onShutdown().detach(callback) 00216 * @return The shutdown event callbacks chain 00217 */ 00218 SecurityManagerShutdownCallbackChain_t& onShutdown() { 00219 return shutdownCallChain; 00220 } 00221 00222 /** 00223 * To indicate that a security procedure for the link has started. 00224 */ 00225 virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} 00226 00227 /** 00228 * To indicate that the security procedure for the link has completed. 00229 */ 00230 virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} 00231 00232 /** 00233 * To indicate that the link with the peer is secured. For bonded devices, 00234 * subsequent reconnections with a bonded peer will result only in this callback 00235 * when the link is secured; setup procedures will not occur (unless the 00236 * bonding information is either lost or deleted on either or both sides). 00237 */ 00238 virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} 00239 00240 /** 00241 * To indicate that device context is stored persistently. 00242 */ 00243 virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} 00244 00245 /** 00246 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 00247 */ 00248 virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} 00249 00250 /* Entry points for the underlying stack to report events back to the user. */ 00251 public: 00252 void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 00253 if (securitySetupInitiatedCallback) { 00254 securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); 00255 } 00256 } 00257 00258 void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { 00259 if (securitySetupCompletedCallback) { 00260 securitySetupCompletedCallback(handle, status); 00261 } 00262 } 00263 00264 void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { 00265 if (linkSecuredCallback) { 00266 linkSecuredCallback(handle, securityMode); 00267 } 00268 } 00269 00270 void processSecurityContextStoredEvent(Gap::Handle_t handle) { 00271 if (securityContextStoredCallback) { 00272 securityContextStoredCallback(handle); 00273 } 00274 } 00275 00276 void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { 00277 if (passkeyDisplayCallback) { 00278 passkeyDisplayCallback(handle, passkey); 00279 } 00280 } 00281 00282 protected: 00283 SecurityManager() : 00284 securitySetupInitiatedCallback(), 00285 securitySetupCompletedCallback(), 00286 linkSecuredCallback(), 00287 securityContextStoredCallback(), 00288 passkeyDisplayCallback() { 00289 /* empty */ 00290 } 00291 00292 public: 00293 /** 00294 * Notify all registered onShutdown callbacks that the SecurityManager is 00295 * about to be shutdown and clear all SecurityManager state of the 00296 * associated object. 00297 * 00298 * This function is meant to be overridden in the platform-specific 00299 * sub-class. Nevertheless, the sub-class is only expected to reset its 00300 * state and not the data held in SecurityManager members. This shall be 00301 * achieved by a call to SecurityManager::reset() from the sub-class' 00302 * reset() implementation. 00303 * 00304 * @return BLE_ERROR_NONE on success. 00305 */ 00306 virtual ble_error_t reset(void) { 00307 /* Notify that the instance is about to shutdown */ 00308 shutdownCallChain.call(this); 00309 shutdownCallChain.clear(); 00310 00311 securitySetupInitiatedCallback = NULL; 00312 securitySetupCompletedCallback = NULL; 00313 linkSecuredCallback = NULL; 00314 securityContextStoredCallback = NULL; 00315 passkeyDisplayCallback = NULL; 00316 00317 return BLE_ERROR_NONE; 00318 } 00319 00320 protected: 00321 SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 00322 SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 00323 LinkSecuredCallback_t linkSecuredCallback; 00324 HandleSpecificEvent_t securityContextStoredCallback; 00325 PasskeyDisplayCallback_t passkeyDisplayCallback; 00326 00327 private: 00328 SecurityManagerShutdownCallbackChain_t shutdownCallChain; 00329 }; 00330 00331 #endif /*__SECURITY_MANAGER_H__*/
Generated on Tue Jul 12 2022 12:49:01 by 1.7.2