xref: /aosp_15_r20/external/openthread/src/core/meshcop/secure_transport.hpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2016, 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  *   This file includes definitions for using mbedTLS.
32  */
33 
34 #ifndef SECURE_TRANSPORT_HPP_
35 #define SECURE_TRANSPORT_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #ifdef OPENTHREAD_CONFIG_TLS_API_ENABLE
40 #error `OPENTHREAD_CONFIG_TLS_API_ENABLE` must not be defined directly, it is determined from `COAP_SECURE_API_ENABLE` and `BLE_TCAT_ENABLE`
41 #endif
42 
43 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE || OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
44 #define OPENTHREAD_CONFIG_TLS_API_ENABLE 1
45 #else
46 #define OPENTHREAD_CONFIG_TLS_API_ENABLE 0
47 #endif
48 
49 #include <mbedtls/net_sockets.h>
50 #include <mbedtls/ssl.h>
51 #include <mbedtls/ssl_cookie.h>
52 #include <mbedtls/version.h>
53 
54 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
55 #ifndef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
56 #error OPENTHREAD_CONFIG_BLE_TCAT_ENABLE requires MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
57 #endif
58 #endif
59 
60 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
61 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
62 #include <mbedtls/base64.h>
63 #endif
64 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
65 #include <mbedtls/x509.h>
66 #include <mbedtls/x509_crl.h>
67 #include <mbedtls/x509_crt.h>
68 #include <mbedtls/x509_csr.h>
69 #endif
70 #endif
71 
72 #include <openthread/coap_secure.h>
73 
74 #include "common/callback.hpp"
75 #include "common/locator.hpp"
76 #include "common/log.hpp"
77 #include "common/message.hpp"
78 #include "common/random.hpp"
79 #include "common/timer.hpp"
80 #include "crypto/sha256.hpp"
81 #include "meshcop/meshcop_tlvs.hpp"
82 #include "net/socket.hpp"
83 #include "net/udp6.hpp"
84 
85 namespace ot {
86 
87 namespace MeshCoP {
88 
89 class SecureTransport : public InstanceLocator
90 {
91 public:
92     typedef otCoapSecureConnectEvent ConnectEvent; ///< A connect event.
93 
94     static constexpr ConnectEvent kConnected               = OT_COAP_SECURE_CONNECTED;
95     static constexpr ConnectEvent kDisconnectedPeerClosed  = OT_COAP_SECURE_DISCONNECTED_PEER_CLOSED;
96     static constexpr ConnectEvent kDisconnectedLocalClosed = OT_COAP_SECURE_DISCONNECTED_LOCAL_CLOSED;
97     static constexpr ConnectEvent kDisconnectedMaxAttempts = OT_COAP_SECURE_DISCONNECTED_MAX_ATTEMPTS;
98     static constexpr ConnectEvent kDisconnectedError       = OT_COAP_SECURE_DISCONNECTED_ERROR;
99 
100     static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length.
101 
102     /**
103      * Function pointer which is called reporting a connection event (when connection established or disconnected)
104      *
105      */
106     typedef otHandleCoapSecureClientConnect ConnectedHandler;
107 
108     /**
109      * Initializes the SecureTransport object.
110      *
111      * @param[in]  aInstance            A reference to the OpenThread instance.
112      * @param[in]  aLayerTwoSecurity    Specifies whether to use layer two security or not.
113      * @param[in]  aDatagramTransport   Specifies if dtls of tls connection should be used.
114      *
115      */
116     explicit SecureTransport(Instance &aInstance, bool aLayerTwoSecurity, bool aDatagramTransport = true);
117 
118     /**
119      * Pointer is called when data is received from the session.
120      *
121      * @param[in]  aContext  A pointer to application-specific context.
122      * @param[in]  aBuf      A pointer to the received data buffer.
123      * @param[in]  aLength   Number of bytes in the received data buffer.
124      *
125      */
126     typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
127 
128     /**
129      * Pointer is called when secure CoAP server want to send encrypted message.
130      *
131      * @param[in]  aContext      A pointer to arbitrary context information.
132      * @param[in]  aMessage      A reference to the message to send.
133      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
134      *
135      */
136     typedef Error (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
137 
138     /**
139      * Callback to notify when the socket is automatically closed due to reaching the maximum number of connection
140      * attempts (set from `SetMaxConnectionAttempts()`).
141      *
142      * @param[in] aContext    A pointer to arbitrary context information.
143      *
144      */
145     typedef void (*AutoCloseCallback)(void *aContext);
146 
147     /**
148      * Opens the socket.
149      *
150      * @param[in]  aReceiveHandler      A pointer to a function that is called to receive payload.
151      * @param[in]  aConnectedHandler    A pointer to a function that is called when connected or disconnected.
152      * @param[in]  aContext             A pointer to arbitrary context information.
153      *
154      * @retval kErrorNone     Successfully opened the socket.
155      * @retval kErrorAlready  The connection is already open.
156      *
157      */
158     Error Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);
159 
160     /**
161      * Sets the maximum number of allowed connection requests before socket is automatically closed.
162      *
163      * This method can be called when socket is closed. Otherwise `kErrorInvalidSatet` is returned.
164      *
165      * If @p aMaxAttempts is zero, no limit is applied and connections are allowed until the socket is closed. This is
166      * the default behavior if `SetMaxConnectionAttempts()` is not called.
167      *
168      * @param[in] aMaxAttempts    Maximum number of allowed connection attempts.
169      * @param[in] aCallback       Callback to notify when max number of attempts has reached and socket is closed.
170      * @param[in] aContext        A pointer to arbitrary context to use with `AutoCloseCallback`.
171      *
172      * @retval kErrorNone          Successfully set the maximum allowed connection attempts and callback.
173      * @retval kErrorInvalidState  Socket is not closed.
174      *
175      */
176     Error SetMaxConnectionAttempts(uint16_t aMaxAttempts, AutoCloseCallback aCallback, void *aContext);
177 
178     /**
179      * Binds this DTLS to a UDP port.
180      *
181      * @param[in]  aPort              The port to bind.
182      *
183      * @retval kErrorNone           Successfully bound the socket.
184      * @retval kErrorInvalidState   The socket is not open.
185      * @retval kErrorAlready        Already bound.
186      *
187      */
188     Error Bind(uint16_t aPort);
189 
190     /**
191      * Gets the UDP port of this session.
192      *
193      * @returns  UDP port number.
194      *
195      */
196     uint16_t GetUdpPort(void) const;
197 
198     /**
199      * Binds with a transport callback.
200      *
201      * @param[in]  aCallback  A pointer to a function for sending messages.
202      * @param[in]  aContext   A pointer to arbitrary context information.
203      *
204      * @retval kErrorNone           Successfully bound the socket.
205      * @retval kErrorInvalidState   The socket is not open.
206      * @retval kErrorAlready        Already bound.
207      *
208      */
209     Error Bind(TransportCallback aCallback, void *aContext);
210 
211     /**
212      * Establishes a secure session.
213      *
214      * For CoAP Secure API do first:
215      * Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
216      * set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
217      *
218      * @param[in]  aSockAddr               A reference to the remote sockaddr.
219      *
220      * @retval kErrorNone          Successfully started handshake.
221      * @retval kErrorInvalidState  The socket is not open.
222      *
223      */
224     Error Connect(const Ip6::SockAddr &aSockAddr);
225 
226     /**
227      * Indicates whether or not the session is active.
228      *
229      * @retval TRUE  If session is active.
230      * @retval FALSE If session is not active.
231      *
232      */
IsConnectionActive(void) const233     bool IsConnectionActive(void) const { return mState >= kStateConnecting; }
234 
235     /**
236      * Indicates whether or not the session is connected.
237      *
238      * @retval TRUE   The session is connected.
239      * @retval FALSE  The session is not connected.
240      *
241      */
IsConnected(void) const242     bool IsConnected(void) const { return mState == kStateConnected; }
243 
244     /**
245      * Indicates whether or not the session is closed.
246      *
247      * @retval TRUE   The session is closed.
248      * @retval FALSE  The session is not closed.
249      *
250      */
IsClosed(void) const251     bool IsClosed(void) const { return mState == kStateClosed; }
252 
253     /**
254      * Disconnects the session.
255      *
256      */
257     void Disconnect(void);
258 
259     /**
260      * Closes the socket.
261      *
262      */
263     void Close(void);
264 
265     /**
266      * Sets the PSK.
267      *
268      * @param[in]  aPsk  A pointer to the PSK.
269      *
270      * @retval kErrorNone          Successfully set the PSK.
271      * @retval kErrorInvalidArgs   The PSK is invalid.
272      *
273      */
274     Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
275 
276 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
277 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
278     /**
279      * Sets the Pre-Shared Key (PSK) for sessions-
280      * identified by a PSK.
281      *
282      * DTLS mode "PSK with AES 128 CCM 8" for Application CoAPS.
283      *
284      * @param[in]  aPsk          A pointer to the PSK.
285      * @param[in]  aPskLength    The PSK char length.
286      * @param[in]  aPskIdentity  The Identity Name for the PSK.
287      * @param[in]  aPskIdLength  The PSK Identity Length.
288      *
289      * @retval kErrorNone  Successfully set the PSK.
290      *
291      */
292     void SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength);
293 
294 #endif
295 
296 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
297     /**
298      * Sets a reference to the own x509 certificate with corresponding private key.
299      *
300      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
301      *
302      * @param[in]  aX509Certificate   A pointer to the PEM formatted X509 certificate.
303      * @param[in]  aX509CertLength    The length of certificate.
304      * @param[in]  aPrivateKey        A pointer to the PEM formatted private key.
305      * @param[in]  aPrivateKeyLength  The length of the private key.
306      *
307      */
308     void SetCertificate(const uint8_t *aX509Certificate,
309                         uint32_t       aX509CertLength,
310                         const uint8_t *aPrivateKey,
311                         uint32_t       aPrivateKeyLength);
312 
313     /**
314      * Sets the trusted top level CAs. It is needed for validate the
315      * certificate of the peer.
316      *
317      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
318      *
319      * @param[in]  aX509CaCertificateChain  A pointer to the PEM formatted X509 CA chain.
320      * @param[in]  aX509CaCertChainLength   The length of chain.
321      *
322      */
323     void SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength);
324 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
325 
326 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
327     /**
328      * Returns the peer x509 certificate base64 encoded.
329      *
330      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
331      *
332      * @param[out]  aPeerCert        A pointer to the base64 encoded certificate buffer.
333      * @param[out]  aCertLength      The length of the base64 encoded peer certificate.
334      * @param[in]   aCertBufferSize  The buffer size of aPeerCert.
335      *
336      * @retval kErrorInvalidState   Not connected yet.
337      * @retval kErrorNone           Successfully get the peer certificate.
338      * @retval kErrorNoBufs         Can't allocate memory for certificate.
339      *
340      */
341     Error GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
342 #endif // defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
343 
344 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
345     /**
346      * Returns an attribute value identified by its OID from the subject
347      * of the peer x509 certificate. The peer OID is provided in binary format.
348      * The attribute length is set if the attribute was successfully read or zero
349      * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard
350      * if the attribute was successfully read.
351      *
352      * @param[in]     aOid                A pointer to the OID to be found.
353      * @param[in]     aOidLength          The length of the OID.
354      * @param[out]    aAttributeBuffer    A pointer to the attribute buffer.
355      * @param[in,out] aAttributeLength    On input, the size the max size of @p aAttributeBuffer.
356      *                                    On output, the length of the attribute written to the buffer.
357      * @param[out]    aAsn1Type           A pointer to the ASN.1 type of the attribute written to the buffer.
358      *
359      * @retval kErrorInvalidState   Not connected yet.
360      * @retval kErrorInvalidArgs    Invalid attribute length.
361      * @retval kErrorNone           Successfully read attribute.
362      * @retval kErrorNoBufs         Insufficient memory for storing the attribute value.
363      *
364      */
365     Error GetPeerSubjectAttributeByOid(const char *aOid,
366                                        size_t      aOidLength,
367                                        uint8_t    *aAttributeBuffer,
368                                        size_t     *aAttributeLength,
369                                        int        *aAsn1Type);
370 
371     /**
372      * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
373      * the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor.
374      * The attribute length is set if the attribute was successfully read or zero if unsuccessful.
375      * Requires a connection to be active.
376      *
377      * @param[in]      aThreadOidDescriptor  The last digit of the Thread attribute OID.
378      * @param[out]     aAttributeBuffer      A pointer to the attribute buffer.
379      * @param[in,out]  aAttributeLength      On input, the size the max size of @p aAttributeBuffer.
380      *                                           On output, the length of the attribute written to the buffer.
381      *
382      * @retval kErrorNone             Successfully read attribute.
383      * @retval kErrorInvalidArgs      Invalid attribute length.
384      * @retval kErrorNotFound         The requested attribute was not found.
385      * @retval kErrorNoBufs           Insufficient memory for storing the attribute value.
386      * @retval kErrorInvalidState     Not connected yet.
387      * @retval kErrorNotImplemented   The value of aThreadOidDescriptor is >127.
388      * @retval kErrorParse            The certificate extensions could not be parsed.
389      *
390      */
391     Error GetThreadAttributeFromPeerCertificate(int      aThreadOidDescriptor,
392                                                 uint8_t *aAttributeBuffer,
393                                                 size_t  *aAttributeLength);
394 #endif // defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
395 
396     /**
397      * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
398      * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor.
399      * The attribute length is set if the attribute was successfully read or zero if unsuccessful.
400      * Requires a connection to be active.
401      *
402      * @param[in]      aThreadOidDescriptor  The last digit of the Thread attribute OID.
403      * @param[out]     aAttributeBuffer      A pointer to the attribute buffer.
404      * @param[in,out]  aAttributeLength      On input, the size the max size of @p aAttributeBuffer.
405      *                                       On output, the length of the attribute written to the buffer.
406      *
407      * @retval kErrorNone             Successfully read attribute.
408      * @retval kErrorInvalidArgs      Invalid attribute length.
409      * @retval kErrorNotFound         The requested attribute was not found.
410      * @retval kErrorNoBufs           Insufficient memory for storing the attribute value.
411      * @retval kErrorInvalidState     Not connected yet.
412      * @retval kErrorNotImplemented   The value of aThreadOidDescriptor is >127.
413      * @retval kErrorParse            The certificate extensions could not be parsed.
414      *
415      */
416     Error GetThreadAttributeFromOwnCertificate(int      aThreadOidDescriptor,
417                                                uint8_t *aAttributeBuffer,
418                                                size_t  *aAttributeLength);
419 
420     /**
421      * Set the authentication mode for a connection.
422      *
423      * Disable or enable the verification of peer certificate.
424      * Must called before start.
425      *
426      * @param[in]  aVerifyPeerCertificate  true, if the peer certificate should verify.
427      *
428      */
SetSslAuthMode(bool aVerifyPeerCertificate)429     void SetSslAuthMode(bool aVerifyPeerCertificate) { mVerifyPeerCertificate = aVerifyPeerCertificate; }
430 #endif // OPENTHREAD_CONFIG_TLS_API_ENABLE
431 
432 #ifdef MBEDTLS_SSL_SRV_C
433     /**
434      * Sets the Client ID used for generating the Hello Cookie.
435      *
436      * @param[in]  aClientId  A pointer to the Client ID.
437      * @param[in]  aLength    Number of bytes in the Client ID.
438      *
439      * @retval kErrorNone  Successfully set the Client ID.
440      *
441      */
442     Error SetClientId(const uint8_t *aClientId, uint8_t aLength);
443 #endif
444 
445     /**
446      * Sends data within the session.
447      *
448      * @param[in]  aMessage  A message to send via connection.
449      * @param[in]  aLength   Number of bytes in the data buffer.
450      *
451      * @retval kErrorNone     Successfully sent the data via the session.
452      * @retval kErrorNoBufs   A message is too long.
453      *
454      */
455     Error Send(Message &aMessage, uint16_t aLength);
456 
457     /**
458      * Provides a received message to the SecureTransport object.
459      *
460      * @param[in]  aMessage  A reference to the message.
461      *
462      */
463     void Receive(Message &aMessage);
464 
465     /**
466      * Sets the default message sub-type that will be used for all messages without defined
467      * sub-type.
468      *
469      * @param[in]  aMessageSubType  The default message sub-type.
470      *
471      */
SetDefaultMessageSubType(Message::SubType aMessageSubType)472     void SetDefaultMessageSubType(Message::SubType aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
473 
474     /**
475      * Returns the session's peer address.
476      *
477      * @return session's message info.
478      *
479      */
GetMessageInfo(void) const480     const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
481 
482     /**
483      * Checks and handles a received message provided to the SecureTransport object. If checks based on
484      * the message info and current connection state pass, the message is processed.
485      *
486      * @param[in]  aMessage  A reference to the message to receive.
487      * @param[in]  aMessageInfo A reference to the message info associated with @p aMessage.
488      *
489      */
490     void HandleReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
491 
492 private:
493     enum State : uint8_t
494     {
495         kStateClosed,       // UDP socket is closed.
496         kStateOpen,         // UDP socket is open.
497         kStateInitializing, // The service is initializing.
498         kStateConnecting,   // The service is establishing a connection.
499         kStateConnected,    // The service has a connection established.
500         kStateCloseNotify,  // The service is closing a connection.
501     };
502 
503     static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000;
504 
505 #if !OPENTHREAD_CONFIG_TLS_API_ENABLE
506     static constexpr uint16_t kApplicationDataMaxLength = 1152;
507 #else
508     static constexpr uint16_t         kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH;
509 #endif
510 
511     static constexpr size_t kSecureTransportKeyBlockSize     = 40;
512     static constexpr size_t kSecureTransportRandomBufferSize = 32;
513 
IsStateClosed(void) const514     bool IsStateClosed(void) const { return mState == kStateClosed; }
IsStateOpen(void) const515     bool IsStateOpen(void) const { return mState == kStateOpen; }
IsStateInitializing(void) const516     bool IsStateInitializing(void) const { return mState == kStateInitializing; }
IsStateConnecting(void) const517     bool IsStateConnecting(void) const { return mState == kStateConnecting; }
IsStateConnected(void) const518     bool IsStateConnected(void) const { return mState == kStateConnected; }
IsStateCloseNotify(void) const519     bool IsStateCloseNotify(void) const { return mState == kStateCloseNotify; }
IsStateConnectingOrConnected(void) const520     bool IsStateConnectingOrConnected(void) const { return mState == kStateConnecting || mState == kStateConnected; }
521     void SetState(State aState);
522 
523     void  FreeMbedtls(void);
524     Error Setup(bool aClient);
525 
526 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
527     /**
528      * Set keys and/or certificates for dtls session dependent of used cipher suite.
529      *
530      * @retval mbedtls error, 0 if successfully.
531      *
532      */
533     int SetApplicationSecureKeys(void);
534 
535     Error GetThreadAttributeFromCertificate(const mbedtls_x509_crt *aCert,
536                                             int                     aThreadOidDescriptor,
537                                             uint8_t                *aAttributeBuffer,
538                                             size_t                 *aAttributeLength);
539 #endif
540 
541     static void HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr);
542     void        HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr);
543 
544     static int HandleMbedtlsGetTimer(void *aContext);
545     int        HandleMbedtlsGetTimer(void);
546 
547     static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish);
548     void        HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish);
549 
550     static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength);
551     int        HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength);
552 
553     static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength);
554     int        HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength);
555 
556 #ifdef MBEDTLS_SSL_EXPORT_KEYS
557 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
558 
559     static void HandleMbedtlsExportKeys(void                       *aContext,
560                                         mbedtls_ssl_key_export_type aType,
561                                         const unsigned char        *aMasterSecret,
562                                         size_t                      aMasterSecretLen,
563                                         const unsigned char         aClientRandom[32],
564                                         const unsigned char         aServerRandom[32],
565                                         mbedtls_tls_prf_types       aTlsPrfType);
566 
567     void HandleMbedtlsExportKeys(mbedtls_ssl_key_export_type aType,
568                                  const unsigned char        *aMasterSecret,
569                                  size_t                      aMasterSecretLen,
570                                  const unsigned char         aClientRandom[32],
571                                  const unsigned char         aServerRandom[32],
572                                  mbedtls_tls_prf_types       aTlsPrfType);
573 
574 #else
575 
576     static int       HandleMbedtlsExportKeys(void                *aContext,
577                                              const unsigned char *aMasterSecret,
578                                              const unsigned char *aKeyBlock,
579                                              size_t               aMacLength,
580                                              size_t               aKeyLength,
581                                              size_t               aIvLength);
582     int              HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
583                                              const unsigned char *aKeyBlock,
584                                              size_t               aMacLength,
585                                              size_t               aKeyLength,
586                                              size_t               aIvLength);
587 
588 #endif // (MBEDTLS_VERSION_NUMBER >= 0x03000000)
589 #endif // MBEDTLS_SSL_EXPORT_KEYS
590 
591     static void HandleTimer(Timer &aTimer);
592     void        HandleTimer(void);
593 
594     void  HandleReceive(const uint8_t *aBuf, uint16_t aLength);
595     Error HandleSecureTransportSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType);
596 
597     void Process(void);
598     void Disconnect(ConnectEvent aEvent);
599 
600 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
601     static const char *StateToString(State aState);
602 #endif
603 
604     using TransportSocket = Ip6::Udp::SocketIn<SecureTransport, &SecureTransport::HandleReceive>;
605 
606     State mState;
607 
608     int     mCipherSuites[2];
609     uint8_t mPsk[kPskMaxLength];
610     uint8_t mPskLength;
611 
612 #if (MBEDTLS_VERSION_NUMBER >= 0x03010000)
613     static const uint16_t sGroups[];
614 #else
615     static const mbedtls_ecp_group_id sCurves[];
616 #endif
617 
618 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
619 #if (MBEDTLS_VERSION_NUMBER >= 0x03020000)
620     static const uint16_t sSignatures[];
621 #else
622     static const int sHashes[];
623 #endif
624 #endif
625 
626 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
627 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
628     const uint8_t     *mCaChainSrc;
629     uint32_t           mCaChainLength;
630     const uint8_t     *mOwnCertSrc;
631     uint32_t           mOwnCertLength;
632     const uint8_t     *mPrivateKeySrc;
633     uint32_t           mPrivateKeyLength;
634     mbedtls_x509_crt   mCaChain;
635     mbedtls_x509_crt   mOwnCert;
636     mbedtls_pk_context mPrivateKey;
637 #endif
638 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
639     const uint8_t *mPreSharedKey;
640     const uint8_t *mPreSharedKeyIdentity;
641     uint16_t       mPreSharedKeyLength;
642     uint16_t       mPreSharedKeyIdLength;
643 #endif
644 #endif
645 
646     bool mVerifyPeerCertificate;
647 
648     mbedtls_ssl_context mSsl;
649     mbedtls_ssl_config  mConf;
650 
651 #ifdef MBEDTLS_SSL_COOKIE_C
652     mbedtls_ssl_cookie_ctx mCookieCtx;
653 #endif
654 
655     TimerMilliContext mTimer;
656 
657     TimeMilli mTimerIntermediate;
658     bool      mTimerSet : 1;
659 
660     bool mLayerTwoSecurity : 1;
661     bool mDatagramTransport : 1;
662 
663     uint16_t                    mMaxConnectionAttempts;
664     uint16_t                    mRemainingConnectionAttempts;
665     Callback<AutoCloseCallback> mAutoCloseCallback;
666 
667     Message *mReceiveMessage;
668 
669     Callback<ConnectedHandler> mConnectedCallback;
670     Callback<ReceiveHandler>   mReceiveCallback;
671     void                      *mContext;
672 
673     Ip6::MessageInfo mMessageInfo;
674     TransportSocket  mSocket;
675 
676     Callback<TransportCallback> mTransportCallback;
677     void                       *mTransportContext;
678 
679     Message::SubType mMessageSubType;
680     Message::SubType mMessageDefaultSubType;
681 
682     ConnectEvent mConnectEvent;
683 };
684 
685 } // namespace MeshCoP
686 } // namespace ot
687 
688 #endif // SECURE_TRANSPORT_HPP_
689