• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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