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/new.hpp"
55 #include "config/crypto.h"
56 #include "crypto/ecdsa.hpp"
57 #include "crypto/hmac_sha256.hpp"
58 #include "crypto/storage.hpp"
59 #include "instance/instance.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() * kBitsPerByte)) == 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 #if OPENTHREAD_FTD
666
otPlatCryptoPbkdf2GenerateKey(const uint8_t * aPassword,uint16_t aPasswordLen,const uint8_t * aSalt,uint16_t aSaltLen,uint32_t aIterationCounter,uint16_t aKeyLen,uint8_t * aKey)667 OT_TOOL_WEAK otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
668 uint16_t aPasswordLen,
669 const uint8_t *aSalt,
670 uint16_t aSaltLen,
671 uint32_t aIterationCounter,
672 uint16_t aKeyLen,
673 uint8_t *aKey)
674 {
675 #if (MBEDTLS_VERSION_NUMBER >= 0x03050000)
676 const size_t kBlockSize = MBEDTLS_CMAC_MAX_BLOCK_SIZE;
677 #else
678 const size_t kBlockSize = MBEDTLS_CIPHER_BLKSIZE_MAX;
679 #endif
680 uint8_t prfInput[OT_CRYPTO_PBDKF2_MAX_SALT_SIZE + 4]; // Salt || INT(), for U1 calculation
681 long prfOne[kBlockSize / sizeof(long)];
682 long prfTwo[kBlockSize / sizeof(long)];
683 long keyBlock[kBlockSize / sizeof(long)];
684 uint32_t blockCounter = 0;
685 uint8_t *key = aKey;
686 uint16_t keyLen = aKeyLen;
687 uint16_t useLen = 0;
688 Error error = kErrorNone;
689 int ret;
690
691 OT_ASSERT(aSaltLen <= sizeof(prfInput));
692 memcpy(prfInput, aSalt, aSaltLen);
693 OT_ASSERT(aIterationCounter % 2 == 0);
694 aIterationCounter /= 2;
695
696 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
697 // limit iterations to avoid OSS-Fuzz timeouts
698 aIterationCounter = 2;
699 #endif
700
701 while (keyLen)
702 {
703 ++blockCounter;
704 prfInput[aSaltLen + 0] = static_cast<uint8_t>(blockCounter >> 24);
705 prfInput[aSaltLen + 1] = static_cast<uint8_t>(blockCounter >> 16);
706 prfInput[aSaltLen + 2] = static_cast<uint8_t>(blockCounter >> 8);
707 prfInput[aSaltLen + 3] = static_cast<uint8_t>(blockCounter);
708
709 // Calculate U_1
710 ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, prfInput, aSaltLen + 4,
711 reinterpret_cast<uint8_t *>(keyBlock));
712 VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
713
714 // Calculate U_2
715 ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(keyBlock), kBlockSize,
716 reinterpret_cast<uint8_t *>(prfOne));
717 VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
718
719 for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
720 {
721 keyBlock[j] ^= prfOne[j];
722 }
723
724 for (uint32_t i = 1; i < aIterationCounter; ++i)
725 {
726 // Calculate U_{2 * i - 1}
727 ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfOne),
728 kBlockSize, reinterpret_cast<uint8_t *>(prfTwo));
729 VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
730 // Calculate U_{2 * i}
731 ret = mbedtls_aes_cmac_prf_128(aPassword, aPasswordLen, reinterpret_cast<const uint8_t *>(prfTwo),
732 kBlockSize, reinterpret_cast<uint8_t *>(prfOne));
733 VerifyOrExit(ret == 0, error = MbedTls::MapError(ret));
734
735 for (uint32_t j = 0; j < kBlockSize / sizeof(long); ++j)
736 {
737 keyBlock[j] ^= prfOne[j] ^ prfTwo[j];
738 }
739 }
740
741 useLen = Min(keyLen, static_cast<uint16_t>(kBlockSize));
742 memcpy(key, keyBlock, useLen);
743 key += useLen;
744 keyLen -= useLen;
745 }
746
747 exit:
748 return error;
749 }
750
751 #endif // #if OPENTHREAD_FTD
752
753 #elif OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
754
755 #if !OPENTHREAD_RADIO
756 #if OPENTHREAD_CONFIG_ECDSA_ENABLE
757
otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair * aKeyPair)758 OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
759 {
760 OT_UNUSED_VARIABLE(aKeyPair);
761
762 return OT_ERROR_NOT_CAPABLE;
763 }
764
otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair * aKeyPair,otPlatCryptoEcdsaPublicKey * aPublicKey)765 OT_TOOL_WEAK otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair,
766 otPlatCryptoEcdsaPublicKey *aPublicKey)
767 {
768 OT_UNUSED_VARIABLE(aKeyPair);
769 OT_UNUSED_VARIABLE(aPublicKey);
770
771 return OT_ERROR_NOT_CAPABLE;
772 }
773
otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair * aKeyPair,const otPlatCryptoSha256Hash * aHash,otPlatCryptoEcdsaSignature * aSignature)774 OT_TOOL_WEAK otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
775 const otPlatCryptoSha256Hash *aHash,
776 otPlatCryptoEcdsaSignature *aSignature)
777 {
778 OT_UNUSED_VARIABLE(aKeyPair);
779 OT_UNUSED_VARIABLE(aHash);
780 OT_UNUSED_VARIABLE(aSignature);
781
782 return OT_ERROR_NOT_CAPABLE;
783 }
784
otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey * aPublicKey,const otPlatCryptoSha256Hash * aHash,const otPlatCryptoEcdsaSignature * aSignature)785 OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
786 const otPlatCryptoSha256Hash *aHash,
787 const otPlatCryptoEcdsaSignature *aSignature)
788
789 {
790 OT_UNUSED_VARIABLE(aPublicKey);
791 OT_UNUSED_VARIABLE(aHash);
792 OT_UNUSED_VARIABLE(aSignature);
793
794 return OT_ERROR_NOT_CAPABLE;
795 }
796 #endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
797
798 #endif // #if !OPENTHREAD_RADIO
799
800 #if OPENTHREAD_FTD
801
otPlatCryptoPbkdf2GenerateKey(const uint8_t * aPassword,uint16_t aPasswordLen,const uint8_t * aSalt,uint16_t aSaltLen,uint32_t aIterationCounter,uint16_t aKeyLen,uint8_t * aKey)802 OT_TOOL_WEAK otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
803 uint16_t aPasswordLen,
804 const uint8_t *aSalt,
805 uint16_t aSaltLen,
806 uint32_t aIterationCounter,
807 uint16_t aKeyLen,
808 uint8_t *aKey)
809 {
810 OT_UNUSED_VARIABLE(aPassword);
811 OT_UNUSED_VARIABLE(aPasswordLen);
812 OT_UNUSED_VARIABLE(aSalt);
813 OT_UNUSED_VARIABLE(aSaltLen);
814 OT_UNUSED_VARIABLE(aIterationCounter);
815 OT_UNUSED_VARIABLE(aKeyLen);
816 OT_UNUSED_VARIABLE(aKey);
817
818 return OT_ERROR_NOT_CAPABLE;
819 }
820
821 #endif // #if OPENTHREAD_FTD
822
823 #endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
824