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