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 implements the necessary hooks for mbedTLS.
32  */
33 
34 #include "dtls.hpp"
35 
36 #include <mbedtls/debug.h>
37 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
38 #include <mbedtls/pem.h>
39 #endif
40 #include <openthread/platform/radio.h>
41 
42 #include "common/code_utils.hpp"
43 #include "common/debug.hpp"
44 #include "common/encoding.hpp"
45 #include "common/instance.hpp"
46 #include "common/locator_getters.hpp"
47 #include "common/logging.hpp"
48 #include "common/timer.hpp"
49 #include "crypto/mbedtls.hpp"
50 #include "crypto/sha256.hpp"
51 #include "thread/thread_netif.hpp"
52 
53 #if OPENTHREAD_CONFIG_DTLS_ENABLE
54 
55 namespace ot {
56 namespace MeshCoP {
57 
58 const mbedtls_ecp_group_id Dtls::sCurves[] = {MBEDTLS_ECP_DP_SECP256R1, MBEDTLS_ECP_DP_NONE};
59 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
60 const int Dtls::sHashes[] = {MBEDTLS_MD_SHA256, MBEDTLS_MD_NONE};
61 #endif
62 
Dtls(Instance & aInstance,bool aLayerTwoSecurity)63 Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity)
64     : InstanceLocator(aInstance)
65     , mState(kStateClosed)
66     , mPskLength(0)
67     , mVerifyPeerCertificate(true)
68     , mTimer(aInstance, Dtls::HandleTimer, this)
69     , mTimerIntermediate(0)
70     , mTimerSet(false)
71     , mLayerTwoSecurity(aLayerTwoSecurity)
72     , mReceiveMessage(nullptr)
73     , mConnectedHandler(nullptr)
74     , mReceiveHandler(nullptr)
75     , mContext(nullptr)
76     , mSocket(aInstance)
77     , mTransportCallback(nullptr)
78     , mTransportContext(nullptr)
79     , mMessageSubType(Message::kSubTypeNone)
80     , mMessageDefaultSubType(Message::kSubTypeNone)
81 {
82 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
83 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
84     mPreSharedKey         = nullptr;
85     mPreSharedKeyIdentity = nullptr;
86     mPreSharedKeyIdLength = 0;
87     mPreSharedKeyLength   = 0;
88 #endif
89 
90 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
91     mCaChainSrc       = nullptr;
92     mCaChainLength    = 0;
93     mOwnCertSrc       = nullptr;
94     mOwnCertLength    = 0;
95     mPrivateKeySrc    = nullptr;
96     mPrivateKeyLength = 0;
97     memset(&mCaChain, 0, sizeof(mCaChain));
98     memset(&mOwnCert, 0, sizeof(mOwnCert));
99     memset(&mPrivateKey, 0, sizeof(mPrivateKey));
100 #endif
101 #endif
102 
103     memset(mCipherSuites, 0, sizeof(mCipherSuites));
104     memset(mPsk, 0, sizeof(mPsk));
105     memset(&mSsl, 0, sizeof(mSsl));
106     memset(&mConf, 0, sizeof(mConf));
107 
108 #ifdef MBEDTLS_SSL_COOKIE_C
109     memset(&mCookieCtx, 0, sizeof(mCookieCtx));
110 #endif
111 }
112 
FreeMbedtls(void)113 void Dtls::FreeMbedtls(void)
114 {
115 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
116     mbedtls_ssl_cookie_free(&mCookieCtx);
117 #endif
118 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
119 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
120     mbedtls_x509_crt_free(&mCaChain);
121     mbedtls_x509_crt_free(&mOwnCert);
122     mbedtls_pk_free(&mPrivateKey);
123 #endif
124 #endif
125     mbedtls_ssl_config_free(&mConf);
126     mbedtls_ssl_free(&mSsl);
127 }
128 
Open(ReceiveHandler aReceiveHandler,ConnectedHandler aConnectedHandler,void * aContext)129 Error Dtls::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext)
130 {
131     Error error;
132 
133     VerifyOrExit(mState == kStateClosed, error = kErrorAlready);
134 
135     SuccessOrExit(error = mSocket.Open(&Dtls::HandleUdpReceive, this));
136 
137     mReceiveHandler   = aReceiveHandler;
138     mConnectedHandler = aConnectedHandler;
139     mContext          = aContext;
140     mState            = kStateOpen;
141 
142 exit:
143     return error;
144 }
145 
Connect(const Ip6::SockAddr & aSockAddr)146 Error Dtls::Connect(const Ip6::SockAddr &aSockAddr)
147 {
148     Error error;
149 
150     VerifyOrExit(mState == kStateOpen, error = kErrorInvalidState);
151 
152     mMessageInfo.SetPeerAddr(aSockAddr.GetAddress());
153     mMessageInfo.SetPeerPort(aSockAddr.mPort);
154 
155     error = Setup(true);
156 
157 exit:
158     return error;
159 }
160 
HandleUdpReceive(void * aContext,otMessage * aMessage,const otMessageInfo * aMessageInfo)161 void Dtls::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
162 {
163     static_cast<Dtls *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
164                                                     *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
165 }
166 
HandleUdpReceive(Message & aMessage,const Ip6::MessageInfo & aMessageInfo)167 void Dtls::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
168 {
169     switch (mState)
170     {
171     case MeshCoP::Dtls::kStateClosed:
172         ExitNow();
173 
174     case MeshCoP::Dtls::kStateOpen:
175         IgnoreError(mSocket.Connect(Ip6::SockAddr(aMessageInfo.GetPeerAddr(), aMessageInfo.GetPeerPort())));
176 
177         mMessageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
178         mMessageInfo.SetPeerPort(aMessageInfo.GetPeerPort());
179         mMessageInfo.SetIsHostInterface(aMessageInfo.IsHostInterface());
180 
181         if (Get<ThreadNetif>().HasUnicastAddress(aMessageInfo.GetSockAddr()))
182         {
183             mMessageInfo.SetSockAddr(aMessageInfo.GetSockAddr());
184         }
185 
186         mMessageInfo.SetSockPort(aMessageInfo.GetSockPort());
187 
188         SuccessOrExit(Setup(false));
189         break;
190 
191     default:
192         // Once DTLS session is started, communicate only with a peer.
193         VerifyOrExit((mMessageInfo.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
194                      (mMessageInfo.GetPeerPort() == aMessageInfo.GetPeerPort()));
195         break;
196     }
197 
198 #ifdef MBEDTLS_SSL_SRV_C
199     if (mState == MeshCoP::Dtls::kStateConnecting)
200     {
201         IgnoreError(SetClientId(mMessageInfo.GetPeerAddr().mFields.m8, sizeof(mMessageInfo.GetPeerAddr().mFields)));
202     }
203 #endif
204 
205     Receive(aMessage);
206 
207 exit:
208     return;
209 }
210 
GetUdpPort(void) const211 uint16_t Dtls::GetUdpPort(void) const
212 {
213     return mSocket.GetSockName().GetPort();
214 }
215 
Bind(uint16_t aPort)216 Error Dtls::Bind(uint16_t aPort)
217 {
218     Error error;
219 
220     VerifyOrExit(mState == kStateOpen, error = kErrorInvalidState);
221     VerifyOrExit(mTransportCallback == nullptr, error = kErrorAlready);
222 
223     SuccessOrExit(error = mSocket.Bind(aPort, OT_NETIF_UNSPECIFIED));
224 
225 exit:
226     return error;
227 }
228 
Bind(TransportCallback aCallback,void * aContext)229 Error Dtls::Bind(TransportCallback aCallback, void *aContext)
230 {
231     Error error = kErrorNone;
232 
233     VerifyOrExit(mState == kStateOpen, error = kErrorInvalidState);
234     VerifyOrExit(!mSocket.IsBound(), error = kErrorAlready);
235     VerifyOrExit(mTransportCallback == nullptr, error = kErrorAlready);
236 
237     mTransportCallback = aCallback;
238     mTransportContext  = aContext;
239 
240 exit:
241     return error;
242 }
243 
Setup(bool aClient)244 Error Dtls::Setup(bool aClient)
245 {
246     int rval;
247 
248     // do not handle new connection before guard time expired
249     VerifyOrExit(mState == kStateOpen, rval = MBEDTLS_ERR_SSL_TIMEOUT);
250 
251     mState = kStateInitializing;
252 
253     mbedtls_ssl_init(&mSsl);
254     mbedtls_ssl_config_init(&mConf);
255 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
256 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
257     mbedtls_x509_crt_init(&mCaChain);
258     mbedtls_x509_crt_init(&mOwnCert);
259     mbedtls_pk_init(&mPrivateKey);
260 #endif
261 #endif
262 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
263     mbedtls_ssl_cookie_init(&mCookieCtx);
264 #endif
265 
266     rval = mbedtls_ssl_config_defaults(&mConf, aClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
267                                        MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
268     VerifyOrExit(rval == 0);
269 
270 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
271     if (mVerifyPeerCertificate && mCipherSuites[0] == MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)
272     {
273         mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED);
274     }
275     else
276     {
277         mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_NONE);
278     }
279 #else
280     OT_UNUSED_VARIABLE(mVerifyPeerCertificate);
281 #endif
282 
283     mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, Random::Crypto::MbedTlsContextGet());
284     mbedtls_ssl_conf_min_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
285     mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
286 
287     OT_ASSERT(mCipherSuites[1] == 0);
288     mbedtls_ssl_conf_ciphersuites(&mConf, mCipherSuites);
289     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
290     {
291         mbedtls_ssl_conf_curves(&mConf, sCurves);
292 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
293         mbedtls_ssl_conf_sig_hashes(&mConf, sHashes);
294 #endif
295     }
296     mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this);
297     mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000);
298     mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, this);
299 
300 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
301     if (!aClient)
302     {
303         rval = mbedtls_ssl_cookie_setup(&mCookieCtx, mbedtls_ctr_drbg_random, Random::Crypto::MbedTlsContextGet());
304         VerifyOrExit(rval == 0);
305 
306         mbedtls_ssl_conf_dtls_cookies(&mConf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &mCookieCtx);
307     }
308 #endif
309 
310     rval = mbedtls_ssl_setup(&mSsl, &mConf);
311     VerifyOrExit(rval == 0);
312 
313     mbedtls_ssl_set_bio(&mSsl, this, &Dtls::HandleMbedtlsTransmit, HandleMbedtlsReceive, nullptr);
314     mbedtls_ssl_set_timer_cb(&mSsl, this, &Dtls::HandleMbedtlsSetTimer, HandleMbedtlsGetTimer);
315 
316     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
317     {
318         rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
319     }
320 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
321     else
322     {
323         rval = SetApplicationCoapSecureKeys();
324     }
325 #endif
326     VerifyOrExit(rval == 0);
327 
328     mReceiveMessage = nullptr;
329     mMessageSubType = Message::kSubTypeNone;
330     mState          = kStateConnecting;
331 
332     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
333     {
334         otLogInfoMeshCoP("DTLS started");
335     }
336 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
337     else
338     {
339         otLogInfoCoap("Application Coap Secure DTLS started");
340     }
341 #endif
342 
343     mState = kStateConnecting;
344 
345     Process();
346 
347 exit:
348     if ((mState == kStateInitializing) && (rval != 0))
349     {
350         mState = kStateOpen;
351         FreeMbedtls();
352     }
353 
354     return Crypto::MbedTls::MapError(rval);
355 }
356 
357 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
SetApplicationCoapSecureKeys(void)358 int Dtls::SetApplicationCoapSecureKeys(void)
359 {
360     int rval = 0;
361 
362     switch (mCipherSuites[0])
363     {
364     case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
365 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
366         if (mCaChainSrc != nullptr)
367         {
368             rval = mbedtls_x509_crt_parse(&mCaChain, static_cast<const unsigned char *>(mCaChainSrc),
369                                           static_cast<size_t>(mCaChainLength));
370             VerifyOrExit(rval == 0);
371             mbedtls_ssl_conf_ca_chain(&mConf, &mCaChain, nullptr);
372         }
373 
374         if (mOwnCertSrc != nullptr && mPrivateKeySrc != nullptr)
375         {
376             rval = mbedtls_x509_crt_parse(&mOwnCert, static_cast<const unsigned char *>(mOwnCertSrc),
377                                           static_cast<size_t>(mOwnCertLength));
378             VerifyOrExit(rval == 0);
379             rval = mbedtls_pk_parse_key(&mPrivateKey, static_cast<const unsigned char *>(mPrivateKeySrc),
380                                         static_cast<size_t>(mPrivateKeyLength), nullptr, 0);
381             VerifyOrExit(rval == 0);
382             rval = mbedtls_ssl_conf_own_cert(&mConf, &mOwnCert, &mPrivateKey);
383             VerifyOrExit(rval == 0);
384         }
385 #endif
386         break;
387 
388     case MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8:
389 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
390         rval = mbedtls_ssl_conf_psk(&mConf, static_cast<const unsigned char *>(mPreSharedKey), mPreSharedKeyLength,
391                                     static_cast<const unsigned char *>(mPreSharedKeyIdentity), mPreSharedKeyIdLength);
392         VerifyOrExit(rval == 0);
393 #endif
394         break;
395 
396     default:
397         otLogCritCoap("Application Coap Secure DTLS: Not supported cipher.");
398         rval = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
399         ExitNow();
400         break;
401     }
402 
403 exit:
404     return rval;
405 }
406 
407 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
408 
Close(void)409 void Dtls::Close(void)
410 {
411     Disconnect();
412 
413     mState             = kStateClosed;
414     mTransportCallback = nullptr;
415     mTransportContext  = nullptr;
416     mTimerSet          = false;
417 
418     IgnoreError(mSocket.Close());
419     mTimer.Stop();
420 }
421 
Disconnect(void)422 void Dtls::Disconnect(void)
423 {
424     VerifyOrExit(mState == kStateConnecting || mState == kStateConnected);
425 
426     mbedtls_ssl_close_notify(&mSsl);
427     mState = kStateCloseNotify;
428     mTimer.Start(kGuardTimeNewConnectionMilli);
429 
430     mMessageInfo.Clear();
431     IgnoreError(mSocket.Connect());
432 
433     FreeMbedtls();
434 
435 exit:
436     return;
437 }
438 
SetPsk(const uint8_t * aPsk,uint8_t aPskLength)439 Error Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
440 {
441     Error error = kErrorNone;
442 
443     VerifyOrExit(aPskLength <= sizeof(mPsk), error = kErrorInvalidArgs);
444 
445     memcpy(mPsk, aPsk, aPskLength);
446     mPskLength       = aPskLength;
447     mCipherSuites[0] = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8;
448     mCipherSuites[1] = 0;
449 
450 exit:
451     return error;
452 }
453 
454 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
455 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
456 
SetCertificate(const uint8_t * aX509Certificate,uint32_t aX509CertLength,const uint8_t * aPrivateKey,uint32_t aPrivateKeyLength)457 void Dtls::SetCertificate(const uint8_t *aX509Certificate,
458                           uint32_t       aX509CertLength,
459                           const uint8_t *aPrivateKey,
460                           uint32_t       aPrivateKeyLength)
461 {
462     OT_ASSERT(aX509CertLength > 0);
463     OT_ASSERT(aX509Certificate != nullptr);
464 
465     OT_ASSERT(aPrivateKeyLength > 0);
466     OT_ASSERT(aPrivateKey != nullptr);
467 
468     mOwnCertSrc       = aX509Certificate;
469     mOwnCertLength    = aX509CertLength;
470     mPrivateKeySrc    = aPrivateKey;
471     mPrivateKeyLength = aPrivateKeyLength;
472 
473     mCipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
474     mCipherSuites[1] = 0;
475 }
476 
SetCaCertificateChain(const uint8_t * aX509CaCertificateChain,uint32_t aX509CaCertChainLength)477 void Dtls::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
478 {
479     OT_ASSERT(aX509CaCertChainLength > 0);
480     OT_ASSERT(aX509CaCertificateChain != nullptr);
481 
482     mCaChainSrc    = aX509CaCertificateChain;
483     mCaChainLength = aX509CaCertChainLength;
484 }
485 
486 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
487 
488 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
SetPreSharedKey(const uint8_t * aPsk,uint16_t aPskLength,const uint8_t * aPskIdentity,uint16_t aPskIdLength)489 void Dtls::SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength)
490 {
491     OT_ASSERT(aPsk != nullptr);
492     OT_ASSERT(aPskIdentity != nullptr);
493     OT_ASSERT(aPskLength > 0);
494     OT_ASSERT(aPskIdLength > 0);
495 
496     mPreSharedKey         = aPsk;
497     mPreSharedKeyLength   = aPskLength;
498     mPreSharedKeyIdentity = aPskIdentity;
499     mPreSharedKeyIdLength = aPskIdLength;
500 
501     mCipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8;
502     mCipherSuites[1] = 0;
503 }
504 #endif
505 
506 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
GetPeerCertificateBase64(unsigned char * aPeerCert,size_t * aCertLength,size_t aCertBufferSize)507 Error Dtls::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
508 {
509     Error error = kErrorNone;
510 
511     VerifyOrExit(mState == kStateConnected, error = kErrorInvalidState);
512 
513     VerifyOrExit(mbedtls_base64_encode(aPeerCert, aCertBufferSize, aCertLength, mSsl.session->peer_cert->raw.p,
514                                        mSsl.session->peer_cert->raw.len) == 0,
515                  error = kErrorNoBufs);
516 
517 exit:
518     return error;
519 }
520 #endif // defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
521 
522 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
523 
524 #ifdef MBEDTLS_SSL_SRV_C
SetClientId(const uint8_t * aClientId,uint8_t aLength)525 Error Dtls::SetClientId(const uint8_t *aClientId, uint8_t aLength)
526 {
527     int rval = mbedtls_ssl_set_client_transport_id(&mSsl, aClientId, aLength);
528     return Crypto::MbedTls::MapError(rval);
529 }
530 #endif
531 
Send(Message & aMessage,uint16_t aLength)532 Error Dtls::Send(Message &aMessage, uint16_t aLength)
533 {
534     Error   error = kErrorNone;
535     uint8_t buffer[kApplicationDataMaxLength];
536 
537     VerifyOrExit(aLength <= kApplicationDataMaxLength, error = kErrorNoBufs);
538 
539     // Store message specific sub type.
540     if (aMessage.GetSubType() != Message::kSubTypeNone)
541     {
542         mMessageSubType = aMessage.GetSubType();
543     }
544 
545     aMessage.ReadBytes(0, buffer, aLength);
546 
547     SuccessOrExit(error = Crypto::MbedTls::MapError(mbedtls_ssl_write(&mSsl, buffer, aLength)));
548 
549     aMessage.Free();
550 
551 exit:
552     return error;
553 }
554 
Receive(Message & aMessage)555 void Dtls::Receive(Message &aMessage)
556 {
557     mReceiveMessage = &aMessage;
558 
559     Process();
560 
561     mReceiveMessage = nullptr;
562 }
563 
HandleMbedtlsTransmit(void * aContext,const unsigned char * aBuf,size_t aLength)564 int Dtls::HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength)
565 {
566     return static_cast<Dtls *>(aContext)->HandleMbedtlsTransmit(aBuf, aLength);
567 }
568 
HandleMbedtlsTransmit(const unsigned char * aBuf,size_t aLength)569 int Dtls::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
570 {
571     Error error;
572     int   rval = 0;
573 
574     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
575     {
576         otLogDebgMeshCoP("Dtls::HandleMbedtlsTransmit");
577     }
578 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
579     else
580     {
581         otLogDebgCoap("Dtls::ApplicationCoapSecure HandleMbedtlsTransmit");
582     }
583 #endif
584 
585     error = HandleDtlsSend(aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
586 
587     // Restore default sub type.
588     mMessageSubType = mMessageDefaultSubType;
589 
590     switch (error)
591     {
592     case kErrorNone:
593         rval = static_cast<int>(aLength);
594         break;
595 
596     case kErrorNoBufs:
597         rval = MBEDTLS_ERR_SSL_WANT_WRITE;
598         break;
599 
600     default:
601         otLogWarnMeshCoP("Dtls::HandleMbedtlsTransmit: %s error", ErrorToString(error));
602         rval = MBEDTLS_ERR_NET_SEND_FAILED;
603         break;
604     }
605 
606     return rval;
607 }
608 
HandleMbedtlsReceive(void * aContext,unsigned char * aBuf,size_t aLength)609 int Dtls::HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength)
610 {
611     return static_cast<Dtls *>(aContext)->HandleMbedtlsReceive(aBuf, aLength);
612 }
613 
HandleMbedtlsReceive(unsigned char * aBuf,size_t aLength)614 int Dtls::HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength)
615 {
616     int rval;
617 
618     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
619     {
620         otLogDebgMeshCoP("Dtls::HandleMbedtlsReceive");
621     }
622 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
623     else
624     {
625         otLogDebgCoap("Dtls:: ApplicationCoapSecure HandleMbedtlsReceive");
626     }
627 #endif
628 
629     VerifyOrExit(mReceiveMessage != nullptr && (rval = mReceiveMessage->GetLength() - mReceiveMessage->GetOffset()) > 0,
630                  rval = MBEDTLS_ERR_SSL_WANT_READ);
631 
632     if (aLength > static_cast<size_t>(rval))
633     {
634         aLength = static_cast<size_t>(rval);
635     }
636 
637     rval = mReceiveMessage->ReadBytes(mReceiveMessage->GetOffset(), aBuf, static_cast<uint16_t>(aLength));
638     mReceiveMessage->MoveOffset(rval);
639 
640 exit:
641     return rval;
642 }
643 
HandleMbedtlsGetTimer(void * aContext)644 int Dtls::HandleMbedtlsGetTimer(void *aContext)
645 {
646     return static_cast<Dtls *>(aContext)->HandleMbedtlsGetTimer();
647 }
648 
HandleMbedtlsGetTimer(void)649 int Dtls::HandleMbedtlsGetTimer(void)
650 {
651     int rval;
652 
653     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
654     {
655         otLogDebgMeshCoP("Dtls::HandleMbedtlsGetTimer");
656     }
657 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
658     else
659     {
660         otLogDebgCoap("Dtls:: ApplicationCoapSecure HandleMbedtlsGetTimer");
661     }
662 #endif
663 
664     if (!mTimerSet)
665     {
666         rval = -1;
667     }
668     else if (!mTimer.IsRunning())
669     {
670         rval = 2;
671     }
672     else if (mTimerIntermediate <= TimerMilli::GetNow())
673     {
674         rval = 1;
675     }
676     else
677     {
678         rval = 0;
679     }
680 
681     return rval;
682 }
683 
HandleMbedtlsSetTimer(void * aContext,uint32_t aIntermediate,uint32_t aFinish)684 void Dtls::HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish)
685 {
686     static_cast<Dtls *>(aContext)->HandleMbedtlsSetTimer(aIntermediate, aFinish);
687 }
688 
HandleMbedtlsSetTimer(uint32_t aIntermediate,uint32_t aFinish)689 void Dtls::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish)
690 {
691     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
692     {
693         otLogDebgMeshCoP("Dtls::SetTimer");
694     }
695 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
696     else
697     {
698         otLogDebgCoap("Dtls::ApplicationCoapSecure SetTimer");
699     }
700 #endif
701 
702     if (aFinish == 0)
703     {
704         mTimerSet = false;
705         mTimer.Stop();
706     }
707     else
708     {
709         mTimerSet = true;
710         mTimer.Start(aFinish);
711         mTimerIntermediate = TimerMilli::GetNow() + aIntermediate;
712     }
713 }
714 
HandleMbedtlsExportKeys(void * aContext,const unsigned char * aMasterSecret,const unsigned char * aKeyBlock,size_t aMacLength,size_t aKeyLength,size_t aIvLength)715 int Dtls::HandleMbedtlsExportKeys(void *               aContext,
716                                   const unsigned char *aMasterSecret,
717                                   const unsigned char *aKeyBlock,
718                                   size_t               aMacLength,
719                                   size_t               aKeyLength,
720                                   size_t               aIvLength)
721 {
722     return static_cast<Dtls *>(aContext)->HandleMbedtlsExportKeys(aMasterSecret, aKeyBlock, aMacLength, aKeyLength,
723                                                                   aIvLength);
724 }
725 
HandleMbedtlsExportKeys(const unsigned char * aMasterSecret,const unsigned char * aKeyBlock,size_t aMacLength,size_t aKeyLength,size_t aIvLength)726 int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
727                                   const unsigned char *aKeyBlock,
728                                   size_t               aMacLength,
729                                   size_t               aKeyLength,
730                                   size_t               aIvLength)
731 {
732     OT_UNUSED_VARIABLE(aMasterSecret);
733 
734     Crypto::Sha256::Hash kek;
735     Crypto::Sha256       sha256;
736 
737     sha256.Start();
738     sha256.Update(aKeyBlock, 2 * static_cast<uint16_t>(aMacLength + aKeyLength + aIvLength));
739     sha256.Finish(kek);
740 
741     Get<KeyManager>().SetKek(kek.GetBytes());
742 
743     if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
744     {
745         otLogDebgMeshCoP("Generated KEK");
746     }
747 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
748     else
749     {
750         otLogDebgCoap("ApplicationCoapSecure Generated KEK");
751     }
752 #endif
753     return 0;
754 }
755 
HandleTimer(Timer & aTimer)756 void Dtls::HandleTimer(Timer &aTimer)
757 {
758     static_cast<Dtls *>(static_cast<TimerMilliContext &>(aTimer).GetContext())->HandleTimer();
759 }
760 
HandleTimer(void)761 void Dtls::HandleTimer(void)
762 {
763     switch (mState)
764     {
765     case kStateConnecting:
766     case kStateConnected:
767         Process();
768         break;
769 
770     case kStateCloseNotify:
771         mState = kStateOpen;
772         mTimer.Stop();
773 
774         if (mConnectedHandler != nullptr)
775         {
776             mConnectedHandler(mContext, false);
777         }
778         break;
779 
780     default:
781         OT_ASSERT(false);
782         OT_UNREACHABLE_CODE(break);
783     }
784 }
785 
Process(void)786 void Dtls::Process(void)
787 {
788     uint8_t buf[OPENTHREAD_CONFIG_DTLS_MAX_CONTENT_LEN];
789     bool    shouldDisconnect = false;
790     int     rval;
791 
792     while ((mState == kStateConnecting) || (mState == kStateConnected))
793     {
794         if (mState == kStateConnecting)
795         {
796             rval = mbedtls_ssl_handshake(&mSsl);
797 
798             if (mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER)
799             {
800                 mState = kStateConnected;
801 
802                 if (mConnectedHandler != nullptr)
803                 {
804                     mConnectedHandler(mContext, true);
805                 }
806             }
807         }
808         else
809         {
810             rval = mbedtls_ssl_read(&mSsl, buf, sizeof(buf));
811         }
812 
813         if (rval > 0)
814         {
815             if (mReceiveHandler != nullptr)
816             {
817                 mReceiveHandler(mContext, buf, static_cast<uint16_t>(rval));
818             }
819         }
820         else if (rval == 0 || rval == MBEDTLS_ERR_SSL_WANT_READ || rval == MBEDTLS_ERR_SSL_WANT_WRITE)
821         {
822             break;
823         }
824         else
825         {
826             switch (rval)
827             {
828             case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
829                 mbedtls_ssl_close_notify(&mSsl);
830                 ExitNow(shouldDisconnect = true);
831                 OT_UNREACHABLE_CODE(break);
832 
833             case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED:
834                 break;
835 
836             case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
837                 mbedtls_ssl_close_notify(&mSsl);
838                 ExitNow(shouldDisconnect = true);
839                 OT_UNREACHABLE_CODE(break);
840 
841             case MBEDTLS_ERR_SSL_INVALID_MAC:
842                 if (mSsl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
843                 {
844                     mbedtls_ssl_send_alert_message(&mSsl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
845                                                    MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
846                     ExitNow(shouldDisconnect = true);
847                 }
848 
849                 break;
850 
851             default:
852                 if (mSsl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
853                 {
854                     mbedtls_ssl_send_alert_message(&mSsl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
855                                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
856                     ExitNow(shouldDisconnect = true);
857                 }
858 
859                 break;
860             }
861 
862             mbedtls_ssl_session_reset(&mSsl);
863             if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
864             {
865                 mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
866             }
867             break;
868         }
869     }
870 
871 exit:
872 
873     if (shouldDisconnect)
874     {
875         Disconnect();
876     }
877 }
878 
HandleMbedtlsDebug(void * aContext,int aLevel,const char * aFile,int aLine,const char * aStr)879 void Dtls::HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr)
880 {
881     static_cast<Dtls *>(aContext)->HandleMbedtlsDebug(aLevel, aFile, aLine, aStr);
882 }
883 
HandleMbedtlsDebug(int aLevel,const char * aFile,int aLine,const char * aStr)884 void Dtls::HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr)
885 {
886     OT_UNUSED_VARIABLE(aStr);
887     OT_UNUSED_VARIABLE(aFile);
888     OT_UNUSED_VARIABLE(aLine);
889 
890     switch (aLevel)
891     {
892     case 1:
893         otLogCritMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
894         break;
895 
896     case 2:
897         otLogWarnMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
898         break;
899 
900     case 3:
901         otLogInfoMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
902         break;
903 
904     case 4:
905     default:
906         otLogDebgMbedTls("[%hu] %s", mSocket.GetSockName().mPort, aStr);
907         break;
908     }
909 }
910 
HandleDtlsSend(const uint8_t * aBuf,uint16_t aLength,Message::SubType aMessageSubType)911 Error Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType)
912 {
913     Error        error   = kErrorNone;
914     ot::Message *message = nullptr;
915 
916     VerifyOrExit((message = mSocket.NewMessage(0)) != nullptr, error = kErrorNoBufs);
917     message->SetSubType(aMessageSubType);
918     message->SetLinkSecurityEnabled(mLayerTwoSecurity);
919 
920     SuccessOrExit(error = message->AppendBytes(aBuf, aLength));
921 
922     // Set message sub type in case Joiner Finalize Response is appended to the message.
923     if (aMessageSubType != Message::kSubTypeNone)
924     {
925         message->SetSubType(aMessageSubType);
926     }
927 
928     if (mTransportCallback)
929     {
930         SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mMessageInfo));
931     }
932     else
933     {
934         SuccessOrExit(error = mSocket.SendTo(*message, mMessageInfo));
935     }
936 
937 exit:
938     FreeMessageOnError(message, error);
939     return error;
940 }
941 
942 } // namespace MeshCoP
943 } // namespace ot
944 
945 #endif // OPENTHREAD_CONFIG_DTLS_ENABLE
946