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