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 /** 69 * Pointer to call when ble secure connection state changes. 70 * 71 * @param[in] aInstance A pointer to an OpenThread instance. 72 * @param[in] aConnected TRUE, if a secure connection was established, FALSE otherwise. 73 * @param[in] aBleConnectionOpen TRUE if a BLE connection was established to carry a TLS data stream, FALSE 74 * otherwise. 75 * @param[in] aContext A pointer to arbitrary context information. 76 * 77 */ 78 typedef void (*otHandleBleSecureConnect)(otInstance *aInstance, 79 bool aConnected, 80 bool aBleConnectionOpen, 81 void *aContext); 82 83 /** 84 * Pointer to call when data was received over a BLE Secure TLS connection. 85 * 86 */ 87 typedef otHandleTcatApplicationDataReceive otHandleBleSecureReceive; 88 89 /** 90 * Starts the BLE Secure service. 91 * When TLV mode is active, the function @p aReceiveHandler will be called once a complete TLV was received and the 92 * message offset points to the TLV value. 93 * 94 * @param[in] aInstance A pointer to an OpenThread instance. 95 * @param[in] aConnectHandler A pointer to a function that will be called when the connection 96 * state changes. 97 * @param[in] aReceiveHandler A pointer to a function that will be called once data has been received 98 * over the TLS connection. 99 * @param[in] aTlvMode A boolean value indicating if line mode shall be activated. 100 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 101 * 102 * @retval OT_ERROR_NONE Successfully started the BLE Secure server. 103 * @retval OT_ERROR_ALREADY The service was stated already. 104 * 105 */ 106 otError otBleSecureStart(otInstance *aInstance, 107 otHandleBleSecureConnect aConnectHandler, 108 otHandleBleSecureReceive aReceiveHandler, 109 bool aTlvMode, 110 void *aContext); 111 112 /** 113 * Enables the TCAT protocol over BLE Secure. 114 * 115 * @param[in] aInstance A pointer to an OpenThread instance. 116 * @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call, may be 117 * NULL). 118 * @param[in] aHandler A pointer to a function that is called when the join operation completes. 119 * 120 * @retval OT_ERROR_NONE Successfully started the BLE Secure Joiner role. 121 * @retval OT_ERROR_INVALID_ARGS @p aElevationPsk or @p aVendorInfo is invalid. 122 * @retval OT_ERROR_INVALID_STATE The BLE function has not been started or line mode is not selected. 123 * 124 */ 125 otError otBleSecureTcatStart(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo, otHandleTcatJoin aHandler); 126 127 /** 128 * Stops the BLE Secure server. 129 * 130 * @param[in] aInstance A pointer to an OpenThread instance. 131 * 132 */ 133 void otBleSecureStop(otInstance *aInstance); 134 135 /** 136 * Sets the Pre-Shared Key (PSK) and cipher suite 137 * TLS_PSK_WITH_AES_128_CCM_8. 138 * 139 * @note Requires the build-time feature `MBEDTLS_KEY_EXCHANGE_PSK_ENABLED` to be enabled. 140 * 141 * @param[in] aInstance A pointer to an OpenThread instance. 142 * @param[in] aPsk A pointer to the PSK. 143 * @param[in] aPskLength The PSK length. 144 * @param[in] aPskIdentity The Identity Name for the PSK. 145 * @param[in] aPskIdLength The PSK Identity Length. 146 * 147 */ 148 void otBleSecureSetPsk(otInstance *aInstance, 149 const uint8_t *aPsk, 150 uint16_t aPskLength, 151 const uint8_t *aPskIdentity, 152 uint16_t aPskIdLength); 153 154 /** 155 * Returns the peer x509 certificate base64 encoded. 156 * 157 * @note Requires the build-time features `MBEDTLS_BASE64_C` and 158 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 159 * 160 * @param[in] aInstance A pointer to an OpenThread instance. 161 * @param[out] aPeerCert A pointer to the base64 encoded certificate buffer. 162 * @param[in,out] aCertLength On input, the size the max size of @p aPeerCert. 163 * On output, the length of the base64 encoded peer certificate. 164 * 165 * @retval OT_ERROR_NONE Successfully get the peer certificate. 166 * @retval OT_ERROR_INVALID_ARGS @p aInstance or @p aCertLength is invalid. 167 * @retval OT_ERROR_INVALID_STATE Not connected yet. 168 * @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate. 169 * 170 */ 171 otError otBleSecureGetPeerCertificateBase64(otInstance *aInstance, unsigned char *aPeerCert, size_t *aCertLength); 172 173 /** 174 * Returns an attribute value identified by its OID from the subject 175 * of the peer x509 certificate. The peer OID is provided in binary format. 176 * The attribute length is set if the attribute was successfully read or zero 177 * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard 178 * if the attribute was successfully read. 179 * 180 * @note Requires the build-time feature 181 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 182 * 183 * @param[in] aInstance A pointer to an OpenThread instance. 184 * @param[in] aOid A pointer to the OID to be found. 185 * @param[in] aOidLength The length of the OID. 186 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 187 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 188 * On output, the length of the attribute written to the buffer. 189 * @param[out] aAsn1Type A pointer to the ASN.1 type of the attribute written to the buffer. 190 * 191 * @retval OT_ERROR_INVALID_STATE Not connected yet. 192 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 193 * @retval OT_ERROR_NONE Successfully read attribute. 194 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 195 * 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 */ 228 otError otBleSecureGetThreadAttributeFromPeerCertificate(otInstance *aInstance, 229 int aThreadOidDescriptor, 230 uint8_t *aAttributeBuffer, 231 size_t *aAttributeLength); 232 233 /** 234 * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of 235 * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor. 236 * The attribute length is set if the attribute was successfully read or zero if unsuccessful. 237 * Requires a connection to be active. 238 * 239 * @param[in] aInstance A pointer to an OpenThread instance. 240 * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. 241 * @param[out] aAttributeBuffer A pointer to the attribute buffer. 242 * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. 243 * On output, the length of the attribute written to the buffer. 244 * 245 * @retval OT_ERROR_NONE Successfully read attribute. 246 * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. 247 * @retval OT_NOT_FOUND The requested attribute was not found. 248 * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. 249 * @retval OT_ERROR_INVALID_STATE Not connected yet. 250 * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. 251 * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. 252 * 253 */ 254 otError otBleSecureGetThreadAttributeFromOwnCertificate(otInstance *aInstance, 255 int aThreadOidDescriptor, 256 uint8_t *aAttributeBuffer, 257 size_t *aAttributeLength); 258 259 /** 260 * Sets the authentication mode for the BLE secure connection. 261 * 262 * Disable or enable the verification of peer certificate. 263 * Must be called before start. 264 * 265 * @param[in] aInstance A pointer to an OpenThread instance. 266 * @param[in] aVerifyPeerCertificate true, to verify the peer certificate. 267 * 268 */ 269 void otBleSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate); 270 271 /** 272 * Sets the local device's X509 certificate with corresponding private key for 273 * TLS session with TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. 274 * 275 * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 276 * 277 * @param[in] aInstance A pointer to an OpenThread instance. 278 * @param[in] aX509Cert A pointer to the PEM formatted X509 certificate. 279 * @param[in] aX509Length The length of certificate. 280 * @param[in] aPrivateKey A pointer to the PEM formatted private key. 281 * @param[in] aPrivateKeyLength The length of the private key. 282 * 283 */ 284 void otBleSecureSetCertificate(otInstance *aInstance, 285 const uint8_t *aX509Cert, 286 uint32_t aX509Length, 287 const uint8_t *aPrivateKey, 288 uint32_t aPrivateKeyLength); 289 290 /** 291 * Sets the trusted top level CAs. It is needed for validating the 292 * certificate of the peer. 293 * 294 * TLS mode "ECDHE ECDSA with AES 128 CCM 8" for secure BLE. 295 * 296 * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 297 * 298 * @param[in] aInstance A pointer to an OpenThread instance. 299 * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. 300 * @param[in] aX509CaCertChainLength The length of chain. 301 * 302 */ 303 void otBleSecureSetCaCertificateChain(otInstance *aInstance, 304 const uint8_t *aX509CaCertificateChain, 305 uint32_t aX509CaCertChainLength); 306 307 /** 308 * Initializes TLS session with a peer using an already open BLE connection. 309 * 310 * @param[in] aInstance A pointer to an OpenThread instance. 311 * 312 * @retval OT_ERROR_NONE Successfully started TLS connection. 313 * 314 */ 315 otError otBleSecureConnect(otInstance *aInstance); 316 317 /** 318 * Stops the BLE and TLS connection. 319 * 320 * @param[in] aInstance A pointer to an OpenThread instance. 321 * 322 */ 323 void otBleSecureDisconnect(otInstance *aInstance); 324 325 /** 326 * Indicates whether or not the TLS session is active (connected or conneting). 327 * 328 * @param[in] aInstance A pointer to an OpenThread instance. 329 * 330 * @retval TRUE If TLS session is active. 331 * @retval FALSE If TLS session is not active. 332 * 333 */ 334 bool otBleSecureIsConnectionActive(otInstance *aInstance); 335 336 /** 337 * Indicates whether or not the TLS session is connected. 338 * 339 * @param[in] aInstance A pointer to an OpenThread instance. 340 * 341 * @retval TRUE The TLS session is connected. 342 * @retval FALSE The TLS session is not connected. 343 * 344 */ 345 bool otBleSecureIsConnected(otInstance *aInstance); 346 347 /** 348 * Indicates whether or not the TCAT agent is enabled. 349 * 350 * @retval TRUE The TCAT agent is enabled. 351 * @retval FALSE The TCAT agent is not enabled. 352 * 353 */ 354 bool otBleSecureIsTcatEnabled(otInstance *aInstance); 355 356 /** 357 * Indicates whether or not a TCAT command class is authorized. 358 * 359 * @param[in] aInstance A pointer to an OpenThread instance. 360 * @param[in] aCommandClass A command class to check. 361 * 362 * @retval TRUE The command class is authorized. 363 * @retval FALSE The command class is not authorized. 364 * 365 */ 366 bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass); 367 368 /** 369 * Sends a secure BLE message. 370 * 371 * @param[in] aInstance A pointer to an OpenThread instance. 372 * @param[in] aMessage A pointer to the message to send. 373 * 374 * If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer 375 * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage, 376 * including freeing @p aMessage if the message buffer is no longer needed. 377 * 378 * @retval OT_ERROR_NONE Successfully sent message. 379 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 380 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 381 * 382 */ 383 otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage); 384 385 /** 386 * Sends a secure BLE data packet. 387 * 388 * @param[in] aInstance A pointer to an OpenThread instance. 389 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 390 * @param[in] aLength A number indicating the length of the data buffer. 391 * 392 * @retval OT_ERROR_NONE Successfully sent data. 393 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 394 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 395 * 396 */ 397 otError otBleSecureSend(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 398 399 /** 400 * Sends a secure BLE data packet containing a TCAT Send Application Data TLV. 401 * 402 * @param[in] aInstance A pointer to an OpenThread instance. 403 * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. 404 * @param[in] aLength A number indicating the length of the data buffer. 405 * 406 * @retval OT_ERROR_NONE Successfully sent data. 407 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 408 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 409 * 410 */ 411 otError otBleSecureSendApplicationTlv(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); 412 413 /** 414 * Flushes the send buffer. 415 * 416 * @param[in] aInstance A pointer to an OpenThread instance. 417 * 418 * @retval OT_ERROR_NONE Successfully flushed output buffer. 419 * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. 420 * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. 421 * 422 */ 423 otError otBleSecureFlush(otInstance *aInstance); 424 425 /** 426 * @} 427 * 428 */ 429 430 #ifdef __cplusplus 431 } // extern "C" 432 #endif 433 434 #endif /* OPENTHREAD_BLE_SECURE_H_ */ 435