1 /*
2  *    Copyright (c) 2021, 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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file implements the Crypto platform callbacks into OpenThread and default/weak Crypto platform APIs.
31  */
32 
33 #include "openthread-core-config.h"
34 
35 #include <string.h>
36 
37 #include <mbedtls/aes.h>
38 #include <mbedtls/cmac.h>
39 #include <mbedtls/ctr_drbg.h>
40 #include <mbedtls/ecdsa.h>
41 #include <mbedtls/entropy.h>
42 #include <mbedtls/md.h>
43 #include <mbedtls/pk.h>
44 #include <mbedtls/sha256.h>
45 #include <mbedtls/version.h>
46 
47 #include <openthread/instance.h>
48 #include <openthread/platform/crypto.h>
49 #include <openthread/platform/entropy.h>
50 #include <openthread/platform/time.h>
51 
52 #include "common/code_utils.hpp"
53 #include "common/debug.hpp"
54 #include "common/instance.hpp"
55 #include "common/new.hpp"
56 #include "config/crypto.h"
57 #include "crypto/ecdsa.hpp"
58 #include "crypto/hmac_sha256.hpp"
59 #include "crypto/storage.hpp"
60 
61 using namespace ot;
62 using namespace Crypto;
63 
64 #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
65 
66 //---------------------------------------------------------------------------------------------------------------------
67 // Default/weak implementation of crypto platform APIs
68 
69 #if (!defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
70      (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) || defined(MBEDTLS_HAVEGE_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT)))
71 #define OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
72 #endif
73 
74 #if !OPENTHREAD_RADIO
75 static mbedtls_ctr_drbg_context sCtrDrbgContext;
76 static mbedtls_entropy_context  sEntropyContext;
77 #ifndef OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
78 static constexpr uint16_t kEntropyMinThreshold = 16;
79 #endif
80 #endif
81 
otPlatCryptoInit(void)82 OT_TOOL_WEAK void otPlatCryptoInit(void)
83 {
84     // Intentionally empty.
85 }
86 
87 // AES  Implementation
otPlatCryptoAesInit(otCryptoContext * aContext)88 OT_TOOL_WEAK otError otPlatCryptoAesInit(otCryptoContext *aContext)
89 {
90     Error                error = kErrorNone;
91     mbedtls_aes_context *context;
92 
93     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
94     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
95 
96     context = static_cast<mbedtls_aes_context *>(aContext->mContext);
97     mbedtls_aes_init(context);
98 
99 exit:
100     return error;
101 }
102 
otPlatCryptoAesSetKey(otCryptoContext * aContext,const otCryptoKey * aKey)103 OT_TOOL_WEAK otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey)
104 {
105     Error                error = kErrorNone;
106     mbedtls_aes_context *context;
107     const LiteralKey     key(*static_cast<const Key *>(aKey));
108 
109     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
110     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
111 
112     context = static_cast<mbedtls_aes_context *>(aContext->mContext);
113     VerifyOrExit((mbedtls_aes_setkey_enc(context, key.GetBytes(), (key.GetLength() * CHAR_BIT)) == 0),
114                  error = kErrorFailed);
115 
116 exit:
117     return error;
118 }
119 
otPlatCryptoAesEncrypt(otCryptoContext * aContext,const uint8_t * aInput,uint8_t * aOutput)120 OT_TOOL_WEAK otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput)
121 {
122     Error                error = kErrorNone;
123     mbedtls_aes_context *context;
124 
125     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
126     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
127 
128     context = static_cast<mbedtls_aes_context *>(aContext->mContext);
129     VerifyOrExit((mbedtls_aes_crypt_ecb(context, MBEDTLS_AES_ENCRYPT, aInput, aOutput) == 0), error = kErrorFailed);
130 
131 exit:
132     return error;
133 }
134 
otPlatCryptoAesFree(otCryptoContext * aContext)135 OT_TOOL_WEAK otError otPlatCryptoAesFree(otCryptoContext *aContext)
136 {
137     Error                error = kErrorNone;
138     mbedtls_aes_context *context;
139 
140     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
141     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
142 
143     context = static_cast<mbedtls_aes_context *>(aContext->mContext);
144     mbedtls_aes_free(context);
145 
146 exit:
147     return error;
148 }
149 
150 #if !OPENTHREAD_RADIO
151 
152 // HMAC implementations
otPlatCryptoHmacSha256Init(otCryptoContext * aContext)153 OT_TOOL_WEAK otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext)
154 {
155     Error                    error  = kErrorNone;
156     const mbedtls_md_info_t *mdInfo = nullptr;
157     mbedtls_md_context_t    *context;
158 
159     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
160     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
161 
162     context = static_cast<mbedtls_md_context_t *>(aContext->mContext);
163     mbedtls_md_init(context);
164     mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
165     VerifyOrExit((mbedtls_md_setup(context, mdInfo, 1) == 0), error = kErrorFailed);
166 
167 exit:
168     return error;
169 }
170 
otPlatCryptoHmacSha256Deinit(otCryptoContext * aContext)171 OT_TOOL_WEAK otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext)
172 {
173     Error                 error = kErrorNone;
174     mbedtls_md_context_t *context;
175 
176     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
177     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
178 
179     context = static_cast<mbedtls_md_context_t *>(aContext->mContext);
180     mbedtls_md_free(context);
181 
182 exit:
183     return error;
184 }
185 
otPlatCryptoHmacSha256Start(otCryptoContext * aContext,const otCryptoKey * aKey)186 OT_TOOL_WEAK otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey)
187 {
188     Error                 error = kErrorNone;
189     const LiteralKey      key(*static_cast<const Key *>(aKey));
190     mbedtls_md_context_t *context;
191 
192     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
193     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
194 
195     context = static_cast<mbedtls_md_context_t *>(aContext->mContext);
196     VerifyOrExit((mbedtls_md_hmac_starts(context, key.GetBytes(), key.GetLength()) == 0), error = kErrorFailed);
197 
198 exit:
199     return error;
200 }
201 
otPlatCryptoHmacSha256Update(otCryptoContext * aContext,const void * aBuf,uint16_t aBufLength)202 OT_TOOL_WEAK otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
203 {
204     Error                 error = kErrorNone;
205     mbedtls_md_context_t *context;
206 
207     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
208     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
209 
210     context = static_cast<mbedtls_md_context_t *>(aContext->mContext);
211     VerifyOrExit((mbedtls_md_hmac_update(context, reinterpret_cast<const uint8_t *>(aBuf), aBufLength) == 0),
212                  error = kErrorFailed);
213 
214 exit:
215     return error;
216 }
217 
otPlatCryptoHmacSha256Finish(otCryptoContext * aContext,uint8_t * aBuf,size_t aBufLength)218 OT_TOOL_WEAK otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength)
219 {
220     OT_UNUSED_VARIABLE(aBufLength);
221 
222     Error                 error = kErrorNone;
223     mbedtls_md_context_t *context;
224 
225     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
226     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
227 
228     context = static_cast<mbedtls_md_context_t *>(aContext->mContext);
229     VerifyOrExit((mbedtls_md_hmac_finish(context, aBuf) == 0), error = kErrorFailed);
230 
231 exit:
232     return error;
233 }
234 
otPlatCryptoHkdfInit(otCryptoContext * aContext)235 otError otPlatCryptoHkdfInit(otCryptoContext *aContext)
236 {
237     Error error = kErrorNone;
238 
239     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
240     VerifyOrExit(aContext->mContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
241 
242     new (aContext->mContext) HmacSha256::Hash();
243 
244 exit:
245     return error;
246 }
247 
otPlatCryptoHkdfExpand(otCryptoContext * aContext,const uint8_t * aInfo,uint16_t aInfoLength,uint8_t * aOutputKey,uint16_t aOutputKeyLength)248 OT_TOOL_WEAK otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
249                                             const uint8_t   *aInfo,
250                                             uint16_t         aInfoLength,
251                                             uint8_t         *aOutputKey,
252                                             uint16_t         aOutputKeyLength)
253 {
254     Error             error = kErrorNone;
255     HmacSha256        hmac;
256     HmacSha256::Hash  hash;
257     uint8_t           iter = 0;
258     uint16_t          copyLength;
259     HmacSha256::Hash *prk;
260 
261     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
262     VerifyOrExit(aContext->mContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
263 
264     prk = static_cast<HmacSha256::Hash *>(aContext->mContext);
265 
266     // The aOutputKey is calculated as follows [RFC5889]:
267     //
268     //   N = ceil( aOutputKeyLength / HashSize)
269     //   T = T(1) | T(2) | T(3) | ... | T(N)
270     //   aOutputKey is first aOutputKeyLength of T
271     //
272     // Where:
273     //   T(0) = empty string (zero length)
274     //   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
275     //   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
276     //   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
277     //   ...
278 
279     while (aOutputKeyLength > 0)
280     {
281         Key cryptoKey;
282 
283         cryptoKey.Set(prk->GetBytes(), sizeof(HmacSha256::Hash));
284         hmac.Start(cryptoKey);
285 
286         if (iter != 0)
287         {
288             hmac.Update(hash);
289         }
290 
291         hmac.Update(aInfo, aInfoLength);
292 
293         iter++;
294         hmac.Update(iter);
295         hmac.Finish(hash);
296 
297         copyLength = Min(aOutputKeyLength, static_cast<uint16_t>(sizeof(hash)));
298 
299         memcpy(aOutputKey, hash.GetBytes(), copyLength);
300         aOutputKey += copyLength;
301         aOutputKeyLength -= copyLength;
302     }
303 
304 exit:
305     return error;
306 }
307 
otPlatCryptoHkdfExtract(otCryptoContext * aContext,const uint8_t * aSalt,uint16_t aSaltLength,const otCryptoKey * aInputKey)308 OT_TOOL_WEAK otError otPlatCryptoHkdfExtract(otCryptoContext   *aContext,
309                                              const uint8_t     *aSalt,
310                                              uint16_t           aSaltLength,
311                                              const otCryptoKey *aInputKey)
312 {
313     Error             error = kErrorNone;
314     HmacSha256        hmac;
315     Key               cryptoKey;
316     HmacSha256::Hash *prk;
317     const LiteralKey  inputKey(*static_cast<const Key *>(aInputKey));
318 
319     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
320     VerifyOrExit(aContext->mContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
321 
322     prk = static_cast<HmacSha256::Hash *>(aContext->mContext);
323 
324     cryptoKey.Set(aSalt, aSaltLength);
325     // PRK is calculated as HMAC-Hash(aSalt, aInputKey)
326     hmac.Start(cryptoKey);
327     hmac.Update(inputKey.GetBytes(), inputKey.GetLength());
328     hmac.Finish(*prk);
329 
330 exit:
331     return error;
332 }
333 
otPlatCryptoHkdfDeinit(otCryptoContext * aContext)334 otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext)
335 {
336     Error             error = kErrorNone;
337     HmacSha256::Hash *prk;
338 
339     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
340     VerifyOrExit(aContext->mContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
341 
342     prk = static_cast<HmacSha256::Hash *>(aContext->mContext);
343     prk->~Hash();
344     aContext->mContext     = nullptr;
345     aContext->mContextSize = 0;
346 
347 exit:
348     return error;
349 }
350 
351 // SHA256 platform implementations
otPlatCryptoSha256Init(otCryptoContext * aContext)352 OT_TOOL_WEAK otError otPlatCryptoSha256Init(otCryptoContext *aContext)
353 {
354     Error                   error = kErrorNone;
355     mbedtls_sha256_context *context;
356 
357     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
358 
359     context = static_cast<mbedtls_sha256_context *>(aContext->mContext);
360     mbedtls_sha256_init(context);
361 
362 exit:
363     return error;
364 }
365 
otPlatCryptoSha256Deinit(otCryptoContext * aContext)366 OT_TOOL_WEAK otError otPlatCryptoSha256Deinit(otCryptoContext *aContext)
367 {
368     Error                   error = kErrorNone;
369     mbedtls_sha256_context *context;
370 
371     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
372     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
373 
374     context = static_cast<mbedtls_sha256_context *>(aContext->mContext);
375     mbedtls_sha256_free(context);
376     aContext->mContext     = nullptr;
377     aContext->mContextSize = 0;
378 
379 exit:
380     return error;
381 }
382 
otPlatCryptoSha256Start(otCryptoContext * aContext)383 OT_TOOL_WEAK otError otPlatCryptoSha256Start(otCryptoContext *aContext)
384 {
385     Error                   error = kErrorNone;
386     mbedtls_sha256_context *context;
387 
388     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
389     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
390 
391     context = static_cast<mbedtls_sha256_context *>(aContext->mContext);
392 
393 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
394     VerifyOrExit((mbedtls_sha256_starts(context, 0) == 0), error = kErrorFailed);
395 #else
396     VerifyOrExit((mbedtls_sha256_starts_ret(context, 0) == 0), error = kErrorFailed);
397 #endif
398 
399 exit:
400     return error;
401 }
402 
otPlatCryptoSha256Update(otCryptoContext * aContext,const void * aBuf,uint16_t aBufLength)403 OT_TOOL_WEAK otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
404 {
405     Error                   error = kErrorNone;
406     mbedtls_sha256_context *context;
407 
408     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
409     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
410 
411     context = static_cast<mbedtls_sha256_context *>(aContext->mContext);
412 
413 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
414     VerifyOrExit((mbedtls_sha256_update(context, reinterpret_cast<const uint8_t *>(aBuf), aBufLength) == 0),
415                  error = kErrorFailed);
416 #else
417     VerifyOrExit((mbedtls_sha256_update_ret(context, reinterpret_cast<const uint8_t *>(aBuf), aBufLength) == 0),
418                  error = kErrorFailed);
419 #endif
420 
421 exit:
422     return error;
423 }
424 
otPlatCryptoSha256Finish(otCryptoContext * aContext,uint8_t * aHash,uint16_t aHashSize)425 OT_TOOL_WEAK otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize)
426 {
427     OT_UNUSED_VARIABLE(aHashSize);
428 
429     Error                   error = kErrorNone;
430     mbedtls_sha256_context *context;
431 
432     VerifyOrExit(aContext != nullptr, error = kErrorInvalidArgs);
433     VerifyOrExit(aContext->mContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
434 
435     context = static_cast<mbedtls_sha256_context *>(aContext->mContext);
436 
437 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
438     VerifyOrExit((mbedtls_sha256_finish(context, aHash) == 0), error = kErrorFailed);
439 #else
440     VerifyOrExit((mbedtls_sha256_finish_ret(context, aHash) == 0), error = kErrorFailed);
441 #endif
442 
443 exit:
444     return error;
445 }
446 
447 #ifndef OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
448 
handleMbedtlsEntropyPoll(void * aData,unsigned char * aOutput,size_t aInLen,size_t * aOutLen)449 static int handleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen)
450 {
451     int rval = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
452 
453     SuccessOrExit(otPlatEntropyGet(reinterpret_cast<uint8_t *>(aOutput), static_cast<uint16_t>(aInLen)));
454     rval = 0;
455 
456     VerifyOrExit(aOutLen != nullptr);
457     *aOutLen = aInLen;
458 
459 exit:
460     OT_UNUSED_VARIABLE(aData);
461     return rval;
462 }
463 
464 #endif // OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
465 
otPlatCryptoRandomInit(void)466 OT_TOOL_WEAK void otPlatCryptoRandomInit(void)
467 {
468     mbedtls_entropy_init(&sEntropyContext);
469 
470 #ifndef OT_MBEDTLS_STRONG_DEFAULT_ENTROPY_PRESENT
471     mbedtls_entropy_add_source(&sEntropyContext, handleMbedtlsEntropyPoll, nullptr, kEntropyMinThreshold,
472                                MBEDTLS_ENTROPY_SOURCE_STRONG);
473 #endif
474 
475     mbedtls_ctr_drbg_init(&sCtrDrbgContext);
476 
477     int rval = mbedtls_ctr_drbg_seed(&sCtrDrbgContext, mbedtls_entropy_func, &sEntropyContext, nullptr, 0);
478     OT_ASSERT(rval == 0);
479     OT_UNUSED_VARIABLE(rval);
480 }
481 
otPlatCryptoRandomDeinit(void)482 OT_TOOL_WEAK void otPlatCryptoRandomDeinit(void)
483 {
484     mbedtls_entropy_free(&sEntropyContext);
485     mbedtls_ctr_drbg_free(&sCtrDrbgContext);
486 }
487 
otPlatCryptoRandomGet(uint8_t * aBuffer,uint16_t aSize)488 OT_TOOL_WEAK otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize)
489 {
490     return ot::Crypto::MbedTls::MapError(
491         mbedtls_ctr_drbg_random(&sCtrDrbgContext, static_cast<unsigned char *>(aBuffer), static_cast<size_t>(aSize)));
492 }
493 
494 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
495 
otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair * aKeyPair)496 OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
497 {
498     mbedtls_pk_context pk;
499     int                ret;
500 
501     mbedtls_pk_init(&pk);
502 
503     ret = mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
504     VerifyOrExit(ret == 0);
505 
506     ret = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(pk), MbedTls::CryptoSecurePrng, nullptr);
507     VerifyOrExit(ret == 0);
508 
509     ret = mbedtls_pk_write_key_der(&pk, aKeyPair->mDerBytes, OT_CRYPTO_ECDSA_MAX_DER_SIZE);
510     VerifyOrExit(ret > 0);
511 
512     aKeyPair->mDerLength = static_cast<uint8_t>(ret);
513 
514     memmove(aKeyPair->mDerBytes, aKeyPair->mDerBytes + OT_CRYPTO_ECDSA_MAX_DER_SIZE - aKeyPair->mDerLength,
515             aKeyPair->mDerLength);
516 
517 exit:
518     mbedtls_pk_free(&pk);
519 
520     return (ret >= 0) ? kErrorNone : MbedTls::MapError(ret);
521 }
522 
otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair * aKeyPair,otPlatCryptoEcdsaPublicKey * aPublicKey)523 OT_TOOL_WEAK otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair,
524                                                    otPlatCryptoEcdsaPublicKey     *aPublicKey)
525 {
526     Error                error = kErrorNone;
527     mbedtls_pk_context   pk;
528     mbedtls_ecp_keypair *keyPair;
529     int                  ret;
530 
531     mbedtls_pk_init(&pk);
532 
533     VerifyOrExit(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0, error = kErrorFailed);
534 
535 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
536     VerifyOrExit(mbedtls_pk_parse_key(&pk, aKeyPair->mDerBytes, aKeyPair->mDerLength, nullptr, 0,
537                                       MbedTls::CryptoSecurePrng, nullptr) == 0,
538                  error = kErrorParse);
539 #else
540     VerifyOrExit(mbedtls_pk_parse_key(&pk, aKeyPair->mDerBytes, aKeyPair->mDerLength, nullptr, 0) == 0,
541                  error = kErrorParse);
542 #endif
543 
544     keyPair = mbedtls_pk_ec(pk);
545 
546     ret = mbedtls_mpi_write_binary(&keyPair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), aPublicKey->m8,
547                                    Ecdsa::P256::kMpiSize);
548     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
549 
550     ret = mbedtls_mpi_write_binary(&keyPair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y),
551                                    aPublicKey->m8 + Ecdsa::P256::kMpiSize, Ecdsa::P256::kMpiSize);
552     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
553 
554 exit:
555     mbedtls_pk_free(&pk);
556     return error;
557 }
558 
otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair * aKeyPair,const otPlatCryptoSha256Hash * aHash,otPlatCryptoEcdsaSignature * aSignature)559 OT_TOOL_WEAK otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
560                                            const otPlatCryptoSha256Hash   *aHash,
561                                            otPlatCryptoEcdsaSignature     *aSignature)
562 {
563     Error                 error = kErrorNone;
564     mbedtls_pk_context    pk;
565     mbedtls_ecp_keypair  *keypair;
566     mbedtls_ecdsa_context ecdsa;
567     mbedtls_mpi           r;
568     mbedtls_mpi           s;
569     int                   ret;
570 
571     mbedtls_pk_init(&pk);
572     mbedtls_ecdsa_init(&ecdsa);
573     mbedtls_mpi_init(&r);
574     mbedtls_mpi_init(&s);
575 
576     VerifyOrExit(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0, error = kErrorFailed);
577 
578 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
579     VerifyOrExit(mbedtls_pk_parse_key(&pk, aKeyPair->mDerBytes, aKeyPair->mDerLength, nullptr, 0,
580                                       MbedTls::CryptoSecurePrng, nullptr) == 0,
581                  error = kErrorParse);
582 #else
583     VerifyOrExit(mbedtls_pk_parse_key(&pk, aKeyPair->mDerBytes, aKeyPair->mDerLength, nullptr, 0) == 0,
584                  error = kErrorParse);
585 #endif
586 
587     keypair = mbedtls_pk_ec(pk);
588 
589     ret = mbedtls_ecdsa_from_keypair(&ecdsa, keypair);
590     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
591 
592 #if (MBEDTLS_VERSION_NUMBER >= 0x02130000)
593     ret = mbedtls_ecdsa_sign_det_ext(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), aHash->m8,
594                                      Sha256::Hash::kSize, MBEDTLS_MD_SHA256, MbedTls::CryptoSecurePrng, nullptr);
595 #else
596     ret = mbedtls_ecdsa_sign_det(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), aHash->m8,
597                                  Sha256::Hash::kSize, MBEDTLS_MD_SHA256);
598 #endif
599     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
600 
601     OT_ASSERT(mbedtls_mpi_size(&r) <= Ecdsa::P256::kMpiSize);
602 
603     ret = mbedtls_mpi_write_binary(&r, aSignature->m8, Ecdsa::P256::kMpiSize);
604     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
605 
606     ret = mbedtls_mpi_write_binary(&s, aSignature->m8 + Ecdsa::P256::kMpiSize, Ecdsa::P256::kMpiSize);
607     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
608 
609 exit:
610     mbedtls_pk_free(&pk);
611     mbedtls_mpi_free(&s);
612     mbedtls_mpi_free(&r);
613     mbedtls_ecdsa_free(&ecdsa);
614 
615     return error;
616 }
617 
otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey * aPublicKey,const otPlatCryptoSha256Hash * aHash,const otPlatCryptoEcdsaSignature * aSignature)618 OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
619                                              const otPlatCryptoSha256Hash     *aHash,
620                                              const otPlatCryptoEcdsaSignature *aSignature)
621 {
622     Error                 error = kErrorNone;
623     mbedtls_ecdsa_context ecdsa;
624     mbedtls_mpi           r;
625     mbedtls_mpi           s;
626     int                   ret;
627 
628     mbedtls_ecdsa_init(&ecdsa);
629     mbedtls_mpi_init(&r);
630     mbedtls_mpi_init(&s);
631 
632     ret = mbedtls_ecp_group_load(&ecdsa.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
633     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
634 
635     ret = mbedtls_mpi_read_binary(&ecdsa.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), aPublicKey->m8, Ecdsa::P256::kMpiSize);
636     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
637     ret = mbedtls_mpi_read_binary(&ecdsa.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), aPublicKey->m8 + Ecdsa::P256::kMpiSize,
638                                   Ecdsa::P256::kMpiSize);
639     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
640     ret = mbedtls_mpi_lset(&ecdsa.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
641     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
642 
643     ret = mbedtls_mpi_read_binary(&r, aSignature->m8, Ecdsa::P256::kMpiSize);
644     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
645 
646     ret = mbedtls_mpi_read_binary(&s, aSignature->m8 + Ecdsa::P256::kMpiSize, Ecdsa::P256::kMpiSize);
647     VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
648 
649     ret = mbedtls_ecdsa_verify(&ecdsa.MBEDTLS_PRIVATE(grp), aHash->m8, Sha256::Hash::kSize, &ecdsa.MBEDTLS_PRIVATE(Q),
650                                &r, &s);
651     VerifyOrExit(ret == 0, error = kErrorSecurity);
652 
653 exit:
654     mbedtls_mpi_free(&s);
655     mbedtls_mpi_free(&r);
656     mbedtls_ecdsa_free(&ecdsa);
657 
658     return error;
659 }
660 
661 #endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
662 
663 #endif // #if !OPENTHREAD_RADIO
664 
665 #elif OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
666 
667 #if !OPENTHREAD_RADIO
668 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
669 
otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair * aKeyPair)670 OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
671 {
672     OT_UNUSED_VARIABLE(aKeyPair);
673 
674     return OT_ERROR_NOT_CAPABLE;
675 }
676 
otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair * aKeyPair,otPlatCryptoEcdsaPublicKey * aPublicKey)677 OT_TOOL_WEAK otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair,
678                                                    otPlatCryptoEcdsaPublicKey     *aPublicKey)
679 {
680     OT_UNUSED_VARIABLE(aKeyPair);
681     OT_UNUSED_VARIABLE(aPublicKey);
682 
683     return OT_ERROR_NOT_CAPABLE;
684 }
685 
otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair * aKeyPair,const otPlatCryptoSha256Hash * aHash,otPlatCryptoEcdsaSignature * aSignature)686 OT_TOOL_WEAK otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
687                                            const otPlatCryptoSha256Hash   *aHash,
688                                            otPlatCryptoEcdsaSignature     *aSignature)
689 {
690     OT_UNUSED_VARIABLE(aKeyPair);
691     OT_UNUSED_VARIABLE(aHash);
692     OT_UNUSED_VARIABLE(aSignature);
693 
694     return OT_ERROR_NOT_CAPABLE;
695 }
696 
otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey * aPublicKey,const otPlatCryptoSha256Hash * aHash,const otPlatCryptoEcdsaSignature * aSignature)697 OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
698                                              const otPlatCryptoSha256Hash     *aHash,
699                                              const otPlatCryptoEcdsaSignature *aSignature)
700 
701 {
702     OT_UNUSED_VARIABLE(aPublicKey);
703     OT_UNUSED_VARIABLE(aHash);
704     OT_UNUSED_VARIABLE(aSignature);
705 
706     return OT_ERROR_NOT_CAPABLE;
707 }
708 #endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
709 
710 #endif // #if !OPENTHREAD_RADIO
711 
712 #endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
713 
714 //---------------------------------------------------------------------------------------------------------------------
715 // APIs to be used in "hybrid" mode by every OPENTHREAD_CONFIG_CRYPTO_LIB variant until full PSA support is ready
716 
717 #if OPENTHREAD_FTD
718 
otPlatCryptoPbkdf2GenerateKey(const uint8_t * aPassword,uint16_t aPasswordLen,const uint8_t * aSalt,uint16_t aSaltLen,uint32_t aIterationCounter,uint16_t aKeyLen,uint8_t * aKey)719 OT_TOOL_WEAK void otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
720                                                 uint16_t       aPasswordLen,
721                                                 const uint8_t *aSalt,
722                                                 uint16_t       aSaltLen,
723                                                 uint32_t       aIterationCounter,
724                                                 uint16_t       aKeyLen,
725                                                 uint8_t       *aKey)
726 {
727     const size_t kBlockSize = MBEDTLS_CIPHER_BLKSIZE_MAX;
728     uint8_t      prfInput[OT_CRYPTO_PBDKF2_MAX_SALT_SIZE + 4]; // Salt || INT(), for U1 calculation
729     long         prfOne[kBlockSize / sizeof(long)];
730     long         prfTwo[kBlockSize / sizeof(long)];
731     long         keyBlock[kBlockSize / sizeof(long)];
732     uint32_t     blockCounter = 0;
733     uint8_t     *key          = aKey;
734     uint16_t     keyLen       = aKeyLen;
735     uint16_t     useLen       = 0;
736 
737     OT_ASSERT(aSaltLen <= sizeof(prfInput));
738     memcpy(prfInput, aSalt, aSaltLen);
739     OT_ASSERT(aIterationCounter % 2 == 0);
740     aIterationCounter /= 2;
741 
742 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
743     // limit iterations to avoid OSS-Fuzz timeouts
744     aIterationCounter = 2;
745 #endif
746 
747     while (keyLen)
748     {
749         ++blockCounter;
750         prfInput[aSaltLen + 0] = static_cast<uint8_t>(blockCounter >> 24);
751         prfInput[aSaltLen + 1] = static_cast<uint8_t>(blockCounter >> 16);
752         prfInput[aSaltLen + 2] = static_cast<uint8_t>(blockCounter >> 8);
753         prfInput[aSaltLen + 3] = static_cast<uint8_t>(blockCounter);
754 
755         // Calculate U_1
756         mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, prfInput, aSaltLen + 4,
757                                  reinterpret_cast<uint8_t *>(keyBlock));
758 
759         // Calculate U_2
760         mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(keyBlock), kBlockSize,
761                                  reinterpret_cast<uint8_t *>(prfOne));
762 
763         for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
764         {
765             keyBlock[j] ^= prfOne[j];
766         }
767 
768         for (uint32_t i = 1; i < aIterationCounter; ++i)
769         {
770             // Calculate U_{2 * i - 1}
771             mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfOne), kBlockSize,
772                                      reinterpret_cast<uint8_t *>(prfTwo));
773             // Calculate U_{2 * i}
774             mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfTwo), kBlockSize,
775                                      reinterpret_cast<uint8_t *>(prfOne));
776 
777             for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
778             {
779                 keyBlock[j] ^= prfOne[j] ^ prfTwo[j];
780             }
781         }
782 
783         useLen = Min(keyLen, static_cast<uint16_t>(kBlockSize));
784         memcpy(key, keyBlock, useLen);
785         key += useLen;
786         keyLen -= useLen;
787     }
788 }
789 
790 #endif // #if OPENTHREAD_FTD
791