1 /* 2 * Copyright (c) 2023, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * @brief 32 * This file defines the top-level functions for the OpenThread BLE Secure implementation. 33 * 34 * @note 35 * The functions in this module require the build-time feature `OPENTHREAD_CONFIG_BLE_TCAT_ENABLE=1`. 36 * 37 * @note 38 * To enable cipher suite DTLS_PSK_WITH_AES_128_CCM_8, MBEDTLS_KEY_EXCHANGE_PSK_ENABLED 39 * must be enabled in mbedtls-config.h 40 * To enable cipher suite DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, 41 * MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED must be enabled in mbedtls-config.h. 42 */ 43 44 #ifndef OPENTHREAD_BLE_SECURE_H_ 45 #define OPENTHREAD_BLE_SECURE_H_ 46 47 #include <stdint.h> 48 #include <openthread/message.h> 49 #include <openthread/tcat.h> 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 /** 56 * @addtogroup api-ble-secure 57 * 58 * @brief 59 * This module includes functions that control BLE Secure (TLS over BLE) communication. 60 * 61 * The functions in this module are available when BLE Secure API feature 62 * (`OPENTHREAD_CONFIG_BLE_TCAT_ENABLE`) is enabled. 63 * 64 * @{ 65 */ 66 67 /** 68 * Pointer to call when ble secure connection state changes. 69 * 70 * @param[in] aInstance A pointer to an OpenThread instance. 71 * @param[in] aConnected TRUE, if a secure connection was established, FALSE otherwise. 72 * @param[in] aBleConnectionOpen TRUE if a BLE connection was established to carry a TLS data stream, FALSE 73 * otherwise. 74 * @param[in] aContext A pointer to arbitrary context information. 75 */ 76 typedef void (*otHandleBleSecureConnect)(otInstance *aInstance, 77 bool aConnected, 78 bool aBleConnectionOpen, 79 void *aContext); 80 81 /** 82 * Pointer to call when data was received over a BLE Secure TLS connection. 83 */ 84 typedef otHandleTcatApplicationDataReceive otHandleBleSecureReceive; 85 86 /** 87 * Starts the BLE Secure service. 88 * When TLV mode is active, the function @p aReceiveHandler will be called once a complete TLV was received and the 89 * message offset points to the TLV value. 90 * 91 * @param[in] aInstance A pointer to an OpenThread instance. 92 * @param[in] aConnectHandler A pointer to a function that will be called when the connection 93 * state changes. 94 * @param[in] aReceiveHandler A pointer to a function that will be called once data has been received 95 * over the TLS connection. 96 * @param[in] aTlvMode A boolean value indicating if line mode shall be activated. 97 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 98 * 99 * @retval OT_ERROR_NONE Successfully started the BLE Secure server. 100 * @retval OT_ERROR_ALREADY The service was stated already. 101 */ 102 otError otBleSecureStart(otInstance *aInstance, 103 otHandleBleSecureConnect aConnectHandler, 104 otHandleBleSecureReceive aReceiveHandler, 105 bool aTlvMode, 106 void *aContext); 107 108 /** 109 * Sets TCAT vendor info 110 * 111 * @param[in] aInstance A pointer to an OpenThread instance. 112 * @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call. 113 * 114 * @retval OT_ERROR_NONE Successfully set value. 115 * @retval OT_ERROR_INVALID_ARGS Value not set. 116 */ 117 otError otBleSecureSetTcatVendorInfo(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo); 118 119 /** 120 * Enables the TCAT protocol over BLE Secure. 121 * 122 * @param[in] aInstance A pointer to an OpenThread instance. 123 * @param[in] aHandler A pointer to a function that is called when the join operation completes. 124 * 125 * @retval OT_ERROR_NONE Successfully started the BLE Secure Joiner role. 126 * @retval OT_ERROR_INVALID_ARGS @p aElevationPsk or @p aVendorInfo is invalid. 127 * @retval OT_ERROR_INVALID_STATE The BLE function has not been started or line mode is not selected. 128 */ 129 otError otBleSecureTcatStart(otInstance *aInstance, otHandleTcatJoin aHandler); 130 131 /** 132 * Stops the BLE Secure server. 133 * 134 * @param[in] aInstance A pointer to an OpenThread instance. 135 */ 136 void otBleSecureStop(otInstance *aInstance); 137 138 /** 139 * Sets the Pre-Shared Key (PSK) and cipher suite 140 * TLS_PSK_WITH_AES_128_CCM_8. 141 * 142 * @note Requires the build-time feature `MBEDTLS_KEY_EXCHANGE_PSK_ENABLED` to be enabled. 143 * 144 * @param[in] aInstance A pointer to an OpenThread instance. 145 * @param[in] aPsk A pointer to the PSK. 146 * @param[in] aPskLength The PSK length. 147 * @param[in] aPskIdentity The Identity Name for the PSK. 148 * @param[in] aPskIdLength The PSK Identity Length. 149 */ 150 void otBleSecureSetPsk(otInstance *aInstance, 151 const uint8_t *aPsk, 152 uint16_t aPskLength, 153 const uint8_t *aPskIdentity, 154 uint16_t aPskIdLength); 155 156 /** 157 * Returns the peer x509 certificate base64 encoded. 158 * 159 * @note Requires the build-time features `MBEDTLS_BASE64_C` and 160 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 161 * 162 * @param[in] aInstance A pointer to an OpenThread instance. 163 * @param[out] aPeerCert A pointer to the base64 encoded certificate buffer. 164 * @param[in,out] aCertLength On input, the size the max size of @p aPeerCert. 165 * On output, the length of the base64 encoded peer certificate. 166 * 167 * @retval OT_ERROR_NONE Successfully get the peer certificate. 168 * @retval OT_ERROR_INVALID_ARGS @p aInstance or @p aCertLength is invalid. 169 * @retval OT_ERROR_INVALID_STATE Not connected yet. 170 * @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate. 171 */ 172 otError otBleSecureGetPeerCertificateBase64(otInstance *aInstance, unsigned char *aPeerCert, size_t *aCertLength); 173 174 /** 175 * Returns an attribute value identified by its OID from the subject 176 * of the peer x509 certificate. The peer OID is provided in binary format. 177 * The attribute length is set if the attribute was successfully read or zero 178 * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard 179 * if the attribute was successfully read. 180 * 181 * @note Requires the build-time feature 182 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 183 * 184 * @param[in] aInstance A pointer to an OpenThread instance. 185 * @param[in] aOid A pointer to the OID to be found. 186 * @param[in] aOidLength The length of the OID. 187 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 188 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 189 * On output, the length of the attribute written to the buffer. 190 * @param[out] aAsn1Type A pointer to the ASN.1 type of the attribute written to the buffer. 191 * 192 * @retval OT_ERROR_INVALID_STATE Not connected yet. 193 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 194 * @retval OT_ERROR_NONE Successfully read attribute. 195 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 196 */ 197 otError otBleSecureGetPeerSubjectAttributeByOid(otInstance *aInstance, 198 const char *aOid, 199 size_t aOidLength, 200 uint8_t *aAttributeBuffer, 201 size_t *aAttributeLength, 202 int *aAsn1Type); 203 204 /** 205 * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of 206 * the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor. 207 * The attribute length is set if the attribute was successfully read or zero if unsuccessful. 208 * Requires a connection to be active. 209 * 210 * @note Requires the build-time feature 211 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 212 * 213 * @param[in] aInstance A pointer to an OpenThread instance. 214 * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. 215 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 216 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 217 * On output, the length of the attribute written to the buffer. 218 * 219 * @retval OT_ERROR_NONE Successfully read attribute. 220 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 221 * @retval OT_NOT_FOUND The requested attribute was not found. 222 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 223 * @retval OT_ERROR_INVALID_STATE Not connected yet. 224 * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. 225 * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. 226 */ 227 otError otBleSecureGetThreadAttributeFromPeerCertificate(otInstance *aInstance, 228 int aThreadOidDescriptor, 229 uint8_t *aAttributeBuffer, 230 size_t *aAttributeLength); 231 232 /** 233 * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of 234 * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor. 235 * The attribute length is set if the attribute was successfully read or zero if unsuccessful. 236 * Requires a connection to be active. 237 * 238 * @param[in] aInstance A pointer to an OpenThread instance. 239 * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. 240 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 241 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 242 * On output, the length of the attribute written to the buffer. 243 * 244 * @retval OT_ERROR_NONE Successfully read attribute. 245 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 246 * @retval OT_NOT_FOUND The requested attribute was not found. 247 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 248 * @retval OT_ERROR_INVALID_STATE Not connected yet. 249 * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. 250 * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. 251 */ 252 otError otBleSecureGetThreadAttributeFromOwnCertificate(otInstance *aInstance, 253 int aThreadOidDescriptor, 254 uint8_t *aAttributeBuffer, 255 size_t *aAttributeLength); 256 257 /** 258 * Sets the authentication mode for the BLE secure connection. 259 * 260 * Disable or enable the verification of peer certificate. 261 * Must be called before start. 262 * 263 * @param[in] aInstance A pointer to an OpenThread instance. 264 * @param[in] aVerifyPeerCertificate true, to verify the peer certificate. 265 */ 266 void otBleSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate); 267 268 /** 269 * Sets the local device's X509 certificate with corresponding private key for 270 * TLS session with TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. 271 * 272 * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 273 * 274 * @param[in] aInstance A pointer to an OpenThread instance. 275 * @param[in] aX509Cert A pointer to the PEM formatted X509 certificate. 276 * @param[in] aX509Length The length of certificate. 277 * @param[in] aPrivateKey A pointer to the PEM formatted private key. 278 * @param[in] aPrivateKeyLength The length of the private key. 279 */ 280 void otBleSecureSetCertificate(otInstance *aInstance, 281 const uint8_t *aX509Cert, 282 uint32_t aX509Length, 283 const uint8_t *aPrivateKey, 284 uint32_t aPrivateKeyLength); 285 286 /** 287 * Sets the trusted top level CAs. It is needed for validating the 288 * certificate of the peer. 289 * 290 * TLS mode "ECDHE ECDSA with AES 128 CCM 8" for secure BLE. 291 * 292 * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 293 * 294 * @param[in] aInstance A pointer to an OpenThread instance. 295 * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. 296 * @param[in] aX509CaCertChainLength The length of chain. 297 */ 298 void otBleSecureSetCaCertificateChain(otInstance *aInstance, 299 const uint8_t *aX509CaCertificateChain, 300 uint32_t aX509CaCertChainLength); 301 302 /** 303 * Initializes TLS session with a peer using an already open BLE connection. 304 * 305 * @param[in] aInstance A pointer to an OpenThread instance. 306 * 307 * @retval OT_ERROR_NONE Successfully started TLS connection. 308 */ 309 otError otBleSecureConnect(otInstance *aInstance); 310 311 /** 312 * Stops the BLE and TLS connection. 313 * 314 * @param[in] aInstance A pointer to an OpenThread instance. 315 */ 316 void otBleSecureDisconnect(otInstance *aInstance); 317 318 /** 319 * Indicates whether or not the TLS session is active (connected or connecting). 320 * 321 * @param[in] aInstance A pointer to an OpenThread instance. 322 * 323 * @retval TRUE If TLS session is active. 324 * @retval FALSE If TLS session is not active. 325 */ 326 bool otBleSecureIsConnectionActive(otInstance *aInstance); 327 328 /** 329 * Indicates whether or not the TLS session is connected. 330 * 331 * @param[in] aInstance A pointer to an OpenThread instance. 332 * 333 * @retval TRUE The TLS session is connected. 334 * @retval FALSE The TLS session is not connected. 335 */ 336 bool otBleSecureIsConnected(otInstance *aInstance); 337 338 /** 339 * Indicates whether or not the TCAT agent is enabled. 340 * 341 * @retval TRUE The TCAT agent is enabled. 342 * @retval FALSE The TCAT agent is not enabled. 343 */ 344 bool otBleSecureIsTcatEnabled(otInstance *aInstance); 345 346 /** 347 * Indicates whether or not a TCAT command class is authorized. 348 * 349 * @param[in] aInstance A pointer to an OpenThread instance. 350 * @param[in] aCommandClass A command class to check. 351 * 352 * @retval TRUE The command class is authorized. 353 * @retval FALSE The command class is not authorized. 354 */ 355 bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass); 356 357 /** 358 * Sends a secure BLE message. 359 * 360 * @param[in] aInstance A pointer to an OpenThread instance. 361 * @param[in] aMessage A pointer to the message to send. 362 * 363 * If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer 364 * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage, 365 * including freeing @p aMessage if the message buffer is no longer needed. 366 * 367 * @retval OT_ERROR_NONE Successfully sent message. 368 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 369 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 370 */ 371 otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage); 372 373 /** 374 * Sends a secure BLE data packet. 375 * 376 * @param[in] aInstance A pointer to an OpenThread instance. 377 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 378 * @param[in] aLength A number indicating the length of the data buffer. 379 * 380 * @retval OT_ERROR_NONE Successfully sent data. 381 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 382 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 383 */ 384 otError otBleSecureSend(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 385 386 /** 387 * Sends a secure BLE data packet containing a TCAT Send Application Data TLV. 388 * 389 * @param[in] aInstance A pointer to an OpenThread instance. 390 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 391 * @param[in] aLength A number indicating the length of the data buffer. 392 * 393 * @retval OT_ERROR_NONE Successfully sent data. 394 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 395 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 396 */ 397 otError otBleSecureSendApplicationTlv(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 398 399 /** 400 * Flushes the send buffer. 401 * 402 * @param[in] aInstance A pointer to an OpenThread instance. 403 * 404 * @retval OT_ERROR_NONE Successfully flushed output buffer. 405 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 406 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 407 */ 408 otError otBleSecureFlush(otInstance *aInstance); 409 410 /** 411 * Gets the Install Code Verify Status during the current session. 412 * 413 * @param[in] aInstance A pointer to an OpenThread instance. 414 * 415 * @retval TRUE The install code was correctly verified. 416 * @retval FALSE The install code was not verified. 417 */ 418 bool otBleSecureGetInstallCodeVerifyStatus(otInstance *aInstance); 419 420 /** 421 * @} 422 */ 423 424 #ifdef __cplusplus 425 } // extern "C" 426 #endif 427 428 #endif /* OPENTHREAD_BLE_SECURE_H_ */ 429