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 the DER encoded peer x509 certificate. 176 * 177 * @note Requires the build-time feature `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to 178 * be enabled. 179 * 180 * @param[in] aInstance A pointer to an OpenThread instance. 181 * @param[out] aPeerCert A pointer to the DER encoded certificate 182 * buffer. 183 * @param[in,out] aCertLength On input, the size the max size of @p 184 * aPeerCert. On output, the length of the 185 * DER encoded peer certificate. 186 * 187 * @retval OT_ERROR_NONE Successfully get the peer certificate. 188 * @retval OT_ERROR_INVALID_ARGS @p aInstance or @p aCertLength is invalid. 189 * @retval OT_ERROR_INVALID_STATE Not connected yet. 190 * @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate. 191 */ 192 otError otBleSecureGetPeerCertificateDer(otInstance *aInstance, unsigned char *aPeerCert, size_t *aCertLength); 193 194 /** 195 * Returns an attribute value identified by its OID from the subject 196 * of the peer x509 certificate. The peer OID is provided in binary format. 197 * The attribute length is set if the attribute was successfully read or zero 198 * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard 199 * if the attribute was successfully read. 200 * 201 * @note Requires the build-time feature 202 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 203 * 204 * @param[in] aInstance A pointer to an OpenThread instance. 205 * @param[in] aOid A pointer to the OID to be found. 206 * @param[in] aOidLength The length of the OID. 207 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 208 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 209 * On output, the length of the attribute written to the buffer. 210 * @param[out] aAsn1Type A pointer to the ASN.1 type of the attribute written to the buffer. 211 * 212 * @retval OT_ERROR_INVALID_STATE Not connected yet. 213 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 214 * @retval OT_ERROR_NONE Successfully read attribute. 215 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 216 */ 217 otError otBleSecureGetPeerSubjectAttributeByOid(otInstance *aInstance, 218 const char *aOid, 219 size_t aOidLength, 220 uint8_t *aAttributeBuffer, 221 size_t *aAttributeLength, 222 int *aAsn1Type); 223 224 /** 225 * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of 226 * the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor. 227 * The attribute length is set if the attribute was successfully read or zero if unsuccessful. 228 * Requires a connection to be active. 229 * 230 * @note Requires the build-time feature 231 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 232 * 233 * @param[in] aInstance A pointer to an OpenThread instance. 234 * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. 235 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 236 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 237 * On output, the length of the attribute written to the buffer. 238 * 239 * @retval OT_ERROR_NONE Successfully read attribute. 240 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 241 * @retval OT_NOT_FOUND The requested attribute was not found. 242 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 243 * @retval OT_ERROR_INVALID_STATE Not connected yet. 244 * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. 245 * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. 246 */ 247 otError otBleSecureGetThreadAttributeFromPeerCertificate(otInstance *aInstance, 248 int aThreadOidDescriptor, 249 uint8_t *aAttributeBuffer, 250 size_t *aAttributeLength); 251 252 /** 253 * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of 254 * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor. 255 * The attribute length is set if the attribute was successfully read or zero if unsuccessful. 256 * Requires a connection to be active. 257 * 258 * @param[in] aInstance A pointer to an OpenThread instance. 259 * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. 260 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 261 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 262 * On output, the length of the attribute written to the buffer. 263 * 264 * @retval OT_ERROR_NONE Successfully read attribute. 265 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 266 * @retval OT_NOT_FOUND The requested attribute was not found. 267 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 268 * @retval OT_ERROR_INVALID_STATE Not connected yet. 269 * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. 270 * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. 271 */ 272 otError otBleSecureGetThreadAttributeFromOwnCertificate(otInstance *aInstance, 273 int aThreadOidDescriptor, 274 uint8_t *aAttributeBuffer, 275 size_t *aAttributeLength); 276 277 /** 278 * Sets the authentication mode for the BLE secure connection. 279 * 280 * Disable or enable the verification of peer certificate. 281 * Must be called before start. 282 * 283 * @param[in] aInstance A pointer to an OpenThread instance. 284 * @param[in] aVerifyPeerCertificate true, to verify the peer certificate. 285 */ 286 void otBleSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate); 287 288 /** 289 * Sets the local device's X509 certificate with corresponding private key for 290 * TLS session with TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. 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] aX509Cert A pointer to the PEM formatted X509 certificate. 296 * @param[in] aX509Length The length of certificate. 297 * @param[in] aPrivateKey A pointer to the PEM formatted private key. 298 * @param[in] aPrivateKeyLength The length of the private key. 299 */ 300 void otBleSecureSetCertificate(otInstance *aInstance, 301 const uint8_t *aX509Cert, 302 uint32_t aX509Length, 303 const uint8_t *aPrivateKey, 304 uint32_t aPrivateKeyLength); 305 306 /** 307 * Sets the trusted top level CAs. It is needed for validating the 308 * certificate of the peer. 309 * 310 * TLS mode "ECDHE ECDSA with AES 128 CCM 8" for secure BLE. 311 * 312 * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 313 * 314 * @param[in] aInstance A pointer to an OpenThread instance. 315 * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. 316 * @param[in] aX509CaCertChainLength The length of chain. 317 */ 318 void otBleSecureSetCaCertificateChain(otInstance *aInstance, 319 const uint8_t *aX509CaCertificateChain, 320 uint32_t aX509CaCertChainLength); 321 322 /** 323 * Initializes TLS session with a peer using an already open BLE connection. 324 * 325 * @param[in] aInstance A pointer to an OpenThread instance. 326 * 327 * @retval OT_ERROR_NONE Successfully started TLS connection. 328 */ 329 otError otBleSecureConnect(otInstance *aInstance); 330 331 /** 332 * Stops the BLE and TLS connection. 333 * 334 * @param[in] aInstance A pointer to an OpenThread instance. 335 */ 336 void otBleSecureDisconnect(otInstance *aInstance); 337 338 /** 339 * Indicates whether or not the TLS session is active (connected or connecting). 340 * 341 * @param[in] aInstance A pointer to an OpenThread instance. 342 * 343 * @retval TRUE If TLS session is active. 344 * @retval FALSE If TLS session is not active. 345 */ 346 bool otBleSecureIsConnectionActive(otInstance *aInstance); 347 348 /** 349 * Indicates whether or not the TLS session is connected. 350 * 351 * @param[in] aInstance A pointer to an OpenThread instance. 352 * 353 * @retval TRUE The TLS session is connected. 354 * @retval FALSE The TLS session is not connected. 355 */ 356 bool otBleSecureIsConnected(otInstance *aInstance); 357 358 /** 359 * Indicates whether or not the TCAT agent is enabled. 360 * 361 * @retval TRUE The TCAT agent is enabled. 362 * @retval FALSE The TCAT agent is not enabled. 363 */ 364 bool otBleSecureIsTcatEnabled(otInstance *aInstance); 365 366 /** 367 * Indicates whether or not a TCAT command class is authorized. 368 * 369 * @param[in] aInstance A pointer to an OpenThread instance. 370 * @param[in] aCommandClass A command class to check. 371 * 372 * @retval TRUE The command class is authorized. 373 * @retval FALSE The command class is not authorized. 374 */ 375 bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass); 376 377 /** 378 * Sends a secure BLE message. 379 * 380 * @param[in] aInstance A pointer to an OpenThread instance. 381 * @param[in] aMessage A pointer to the message to send. 382 * 383 * If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer 384 * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage, 385 * including freeing @p aMessage if the message buffer is no longer needed. 386 * 387 * @retval OT_ERROR_NONE Successfully sent message. 388 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 389 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 390 */ 391 otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage); 392 393 /** 394 * Sends a secure BLE data packet. 395 * 396 * @param[in] aInstance A pointer to an OpenThread instance. 397 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 398 * @param[in] aLength A number indicating the length of the data buffer. 399 * 400 * @retval OT_ERROR_NONE Successfully sent data. 401 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 402 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 403 */ 404 otError otBleSecureSend(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 405 406 /** 407 * Sends a secure BLE data packet containing a TCAT Send Application Data TLV. 408 * 409 * @param[in] aInstance A pointer to an OpenThread instance. 410 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 411 * @param[in] aLength A number indicating the length of the data buffer. 412 * 413 * @retval OT_ERROR_NONE Successfully sent data. 414 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 415 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 416 */ 417 otError otBleSecureSendApplicationTlv(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 418 419 /** 420 * Flushes the send buffer. 421 * 422 * @param[in] aInstance A pointer to an OpenThread instance. 423 * 424 * @retval OT_ERROR_NONE Successfully flushed output buffer. 425 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 426 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 427 */ 428 otError otBleSecureFlush(otInstance *aInstance); 429 430 /** 431 * Gets the Install Code Verify Status during the current session. 432 * 433 * @param[in] aInstance A pointer to an OpenThread instance. 434 * 435 * @retval TRUE The install code was correctly verified. 436 * @retval FALSE The install code was not verified. 437 */ 438 bool otBleSecureGetInstallCodeVerifyStatus(otInstance *aInstance); 439 440 /** 441 * @} 442 */ 443 444 #ifdef __cplusplus 445 } // extern "C" 446 #endif 447 448 #endif /* OPENTHREAD_BLE_SECURE_H_ */ 449