| /* |
| * Copyright (c) 2023, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @file |
| * @brief |
| * This file defines the top-level functions for the OpenThread BLE Secure implementation. |
| * |
| * @note |
| * The functions in this module require the build-time feature `OPENTHREAD_CONFIG_BLE_TCAT_ENABLE=1`. |
| * |
| * @note |
| * To enable cipher suite DTLS_PSK_WITH_AES_128_CCM_8, MBEDTLS_KEY_EXCHANGE_PSK_ENABLED |
| * must be enabled in mbedtls-config.h |
| * To enable cipher suite DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
| * MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED must be enabled in mbedtls-config.h. |
| */ |
| |
| #ifndef OPENTHREAD_BLE_SECURE_H_ |
| #define OPENTHREAD_BLE_SECURE_H_ |
| |
| #include <stdint.h> |
| #include <openthread/message.h> |
| #include <openthread/tcat.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @addtogroup api-ble-secure |
| * |
| * @brief |
| * This module includes functions that control BLE Secure (TLS over BLE) communication. |
| * |
| * The functions in this module are available when BLE Secure API feature |
| * (`OPENTHREAD_CONFIG_BLE_TCAT_ENABLE`) is enabled. |
| * |
| * @{ |
| * |
| */ |
| |
| /** |
| * Pointer to call when ble secure connection state changes. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aConnected TRUE, if a secure connection was established, FALSE otherwise. |
| * @param[in] aBleConnectionOpen TRUE if a BLE connection was established to carry a TLS data stream, FALSE |
| * otherwise. |
| * @param[in] aContext A pointer to arbitrary context information. |
| * |
| */ |
| typedef void (*otHandleBleSecureConnect)(otInstance *aInstance, |
| bool aConnected, |
| bool aBleConnectionOpen, |
| void *aContext); |
| |
| /** |
| * Pointer to call when data was received over a BLE Secure TLS connection. |
| * |
| */ |
| typedef otHandleTcatApplicationDataReceive otHandleBleSecureReceive; |
| |
| /** |
| * Starts the BLE Secure service. |
| * When TLV mode is active, the function @p aReceiveHandler will be called once a complete TLV was received and the |
| * message offset points to the TLV value. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aConnectHandler A pointer to a function that will be called when the connection |
| * state changes. |
| * @param[in] aReceiveHandler A pointer to a function that will be called once data has been received |
| * over the TLS connection. |
| * @param[in] aTlvMode A boolean value indicating if line mode shall be activated. |
| * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. |
| * |
| * @retval OT_ERROR_NONE Successfully started the BLE Secure server. |
| * @retval OT_ERROR_ALREADY The service was stated already. |
| * |
| */ |
| otError otBleSecureStart(otInstance *aInstance, |
| otHandleBleSecureConnect aConnectHandler, |
| otHandleBleSecureReceive aReceiveHandler, |
| bool aTlvMode, |
| void *aContext); |
| |
| /** |
| * Enables the TCAT protocol over BLE Secure. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call, may be |
| * NULL). |
| * @param[in] aHandler A pointer to a function that is called when the join operation completes. |
| * |
| * @retval OT_ERROR_NONE Successfully started the BLE Secure Joiner role. |
| * @retval OT_ERROR_INVALID_ARGS @p aElevationPsk or @p aVendorInfo is invalid. |
| * @retval OT_ERROR_INVALID_STATE The BLE function has not been started or line mode is not selected. |
| * |
| */ |
| otError otBleSecureTcatStart(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo, otHandleTcatJoin aHandler); |
| |
| /** |
| * Stops the BLE Secure server. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| */ |
| void otBleSecureStop(otInstance *aInstance); |
| |
| /** |
| * Sets the Pre-Shared Key (PSK) and cipher suite |
| * TLS_PSK_WITH_AES_128_CCM_8. |
| * |
| * @note Requires the build-time feature `MBEDTLS_KEY_EXCHANGE_PSK_ENABLED` to be enabled. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aPsk A pointer to the PSK. |
| * @param[in] aPskLength The PSK length. |
| * @param[in] aPskIdentity The Identity Name for the PSK. |
| * @param[in] aPskIdLength The PSK Identity Length. |
| * |
| */ |
| void otBleSecureSetPsk(otInstance *aInstance, |
| const uint8_t *aPsk, |
| uint16_t aPskLength, |
| const uint8_t *aPskIdentity, |
| uint16_t aPskIdLength); |
| |
| /** |
| * Returns the peer x509 certificate base64 encoded. |
| * |
| * @note Requires the build-time features `MBEDTLS_BASE64_C` and |
| * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[out] aPeerCert A pointer to the base64 encoded certificate buffer. |
| * @param[in,out] aCertLength On input, the size the max size of @p aPeerCert. |
| * On output, the length of the base64 encoded peer certificate. |
| * |
| * @retval OT_ERROR_NONE Successfully get the peer certificate. |
| * @retval OT_ERROR_INVALID_ARGS @p aInstance or @p aCertLength is invalid. |
| * @retval OT_ERROR_INVALID_STATE Not connected yet. |
| * @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate. |
| * |
| */ |
| otError otBleSecureGetPeerCertificateBase64(otInstance *aInstance, unsigned char *aPeerCert, size_t *aCertLength); |
| |
| /** |
| * Returns an attribute value identified by its OID from the subject |
| * of the peer x509 certificate. The peer OID is provided in binary format. |
| * The attribute length is set if the attribute was successfully read or zero |
| * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard |
| * if the attribute was successfully read. |
| * |
| * @note Requires the build-time feature |
| * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aOid A pointer to the OID to be found. |
| * @param[in] aOidLength The length of the OID. |
| * @param[out] aAttributeBuffer A pointer to the attribute buffer. |
| * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. |
| * On output, the length of the attribute written to the buffer. |
| * @param[out] aAsn1Type A pointer to the ASN.1 type of the attribute written to the buffer. |
| * |
| * @retval OT_ERROR_INVALID_STATE Not connected yet. |
| * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. |
| * @retval OT_ERROR_NONE Successfully read attribute. |
| * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. |
| * |
| */ |
| otError otBleSecureGetPeerSubjectAttributeByOid(otInstance *aInstance, |
| const char *aOid, |
| size_t aOidLength, |
| uint8_t *aAttributeBuffer, |
| size_t *aAttributeLength, |
| int *aAsn1Type); |
| |
| /** |
| * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of |
| * the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor. |
| * The attribute length is set if the attribute was successfully read or zero if unsuccessful. |
| * Requires a connection to be active. |
| * |
| * @note Requires the build-time feature |
| * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. |
| * @param[out] aAttributeBuffer A pointer to the attribute buffer. |
| * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. |
| * On output, the length of the attribute written to the buffer. |
| * |
| * @retval OT_ERROR_NONE Successfully read attribute. |
| * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. |
| * @retval OT_NOT_FOUND The requested attribute was not found. |
| * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. |
| * @retval OT_ERROR_INVALID_STATE Not connected yet. |
| * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. |
| * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. |
| * |
| */ |
| otError otBleSecureGetThreadAttributeFromPeerCertificate(otInstance *aInstance, |
| int aThreadOidDescriptor, |
| uint8_t *aAttributeBuffer, |
| size_t *aAttributeLength); |
| |
| /** |
| * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of |
| * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor. |
| * The attribute length is set if the attribute was successfully read or zero if unsuccessful. |
| * Requires a connection to be active. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID. |
| * @param[out] aAttributeBuffer A pointer to the attribute buffer. |
| * @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer. |
| * On output, the length of the attribute written to the buffer. |
| * |
| * @retval OT_ERROR_NONE Successfully read attribute. |
| * @retval OT_ERROR_INVALID_ARGS Invalid attribute length. |
| * @retval OT_NOT_FOUND The requested attribute was not found. |
| * @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value. |
| * @retval OT_ERROR_INVALID_STATE Not connected yet. |
| * @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127. |
| * @retval OT_ERROR_PARSE The certificate extensions could not be parsed. |
| * |
| */ |
| otError otBleSecureGetThreadAttributeFromOwnCertificate(otInstance *aInstance, |
| int aThreadOidDescriptor, |
| uint8_t *aAttributeBuffer, |
| size_t *aAttributeLength); |
| |
| /** |
| * Sets the authentication mode for the BLE secure connection. |
| * |
| * Disable or enable the verification of peer certificate. |
| * Must be called before start. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aVerifyPeerCertificate true, to verify the peer certificate. |
| * |
| */ |
| void otBleSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate); |
| |
| /** |
| * Sets the local device's X509 certificate with corresponding private key for |
| * TLS session with TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. |
| * |
| * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aX509Cert A pointer to the PEM formatted X509 certificate. |
| * @param[in] aX509Length The length of certificate. |
| * @param[in] aPrivateKey A pointer to the PEM formatted private key. |
| * @param[in] aPrivateKeyLength The length of the private key. |
| * |
| */ |
| void otBleSecureSetCertificate(otInstance *aInstance, |
| const uint8_t *aX509Cert, |
| uint32_t aX509Length, |
| const uint8_t *aPrivateKey, |
| uint32_t aPrivateKeyLength); |
| |
| /** |
| * Sets the trusted top level CAs. It is needed for validating the |
| * certificate of the peer. |
| * |
| * TLS mode "ECDHE ECDSA with AES 128 CCM 8" for secure BLE. |
| * |
| * @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. |
| * @param[in] aX509CaCertChainLength The length of chain. |
| * |
| */ |
| void otBleSecureSetCaCertificateChain(otInstance *aInstance, |
| const uint8_t *aX509CaCertificateChain, |
| uint32_t aX509CaCertChainLength); |
| |
| /** |
| * Initializes TLS session with a peer using an already open BLE connection. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| * @retval OT_ERROR_NONE Successfully started TLS connection. |
| * |
| */ |
| otError otBleSecureConnect(otInstance *aInstance); |
| |
| /** |
| * Stops the BLE and TLS connection. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| */ |
| void otBleSecureDisconnect(otInstance *aInstance); |
| |
| /** |
| * Indicates whether or not the TLS session is active (connected or conneting). |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| * @retval TRUE If TLS session is active. |
| * @retval FALSE If TLS session is not active. |
| * |
| */ |
| bool otBleSecureIsConnectionActive(otInstance *aInstance); |
| |
| /** |
| * Indicates whether or not the TLS session is connected. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| * @retval TRUE The TLS session is connected. |
| * @retval FALSE The TLS session is not connected. |
| * |
| */ |
| bool otBleSecureIsConnected(otInstance *aInstance); |
| |
| /** |
| * Indicates whether or not the TCAT agent is enabled. |
| * |
| * @retval TRUE The TCAT agent is enabled. |
| * @retval FALSE The TCAT agent is not enabled. |
| * |
| */ |
| bool otBleSecureIsTcatEnabled(otInstance *aInstance); |
| |
| /** |
| * Indicates whether or not a TCAT command class is authorized. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aCommandClass A command class to check. |
| * |
| * @retval TRUE The command class is authorized. |
| * @retval FALSE The command class is not authorized. |
| * |
| */ |
| bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass); |
| |
| /** |
| * Sends a secure BLE message. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aMessage A pointer to the message to send. |
| * |
| * If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer |
| * reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage, |
| * including freeing @p aMessage if the message buffer is no longer needed. |
| * |
| * @retval OT_ERROR_NONE Successfully sent message. |
| * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. |
| * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. |
| * |
| */ |
| otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage); |
| |
| /** |
| * Sends a secure BLE data packet. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. |
| * @param[in] aLength A number indicating the length of the data buffer. |
| * |
| * @retval OT_ERROR_NONE Successfully sent data. |
| * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. |
| * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. |
| * |
| */ |
| otError otBleSecureSend(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); |
| |
| /** |
| * Sends a secure BLE data packet containing a TCAT Send Application Data TLV. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV. |
| * @param[in] aLength A number indicating the length of the data buffer. |
| * |
| * @retval OT_ERROR_NONE Successfully sent data. |
| * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. |
| * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. |
| * |
| */ |
| otError otBleSecureSendApplicationTlv(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength); |
| |
| /** |
| * Flushes the send buffer. |
| * |
| * @param[in] aInstance A pointer to an OpenThread instance. |
| * |
| * @retval OT_ERROR_NONE Successfully flushed output buffer. |
| * @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory. |
| * @retval OT_ERROR_INVALID_STATE TLS connection was not initialized. |
| * |
| */ |
| otError otBleSecureFlush(otInstance *aInstance); |
| |
| /** |
| * @} |
| * |
| */ |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #endif /* OPENTHREAD_BLE_SECURE_H_ */ |