1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <openthread/platform/crypto.h>
8
9 #include <psa/crypto.h>
10
11 #include <zephyr/sys/__assert.h>
12
13 #if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_OPENTHREAD_CRYPTO_PSA)
14 #include <zephyr/settings/settings.h>
15 #endif
16
17 #if defined(CONFIG_OPENTHREAD_ECDSA)
18 #include <string.h>
19 #include <mbedtls/asn1.h>
20 #endif
21
psaToOtError(psa_status_t aStatus)22 static otError psaToOtError(psa_status_t aStatus)
23 {
24 switch (aStatus) {
25 case PSA_SUCCESS:
26 return OT_ERROR_NONE;
27 case PSA_ERROR_INVALID_ARGUMENT:
28 return OT_ERROR_INVALID_ARGS;
29 case PSA_ERROR_BUFFER_TOO_SMALL:
30 return OT_ERROR_NO_BUFS;
31 default:
32 return OT_ERROR_FAILED;
33 }
34 }
35
toPsaKeyType(otCryptoKeyType aType)36 static psa_key_type_t toPsaKeyType(otCryptoKeyType aType)
37 {
38 switch (aType) {
39 case OT_CRYPTO_KEY_TYPE_RAW:
40 return PSA_KEY_TYPE_RAW_DATA;
41 case OT_CRYPTO_KEY_TYPE_AES:
42 return PSA_KEY_TYPE_AES;
43 case OT_CRYPTO_KEY_TYPE_HMAC:
44 return PSA_KEY_TYPE_HMAC;
45 case OT_CRYPTO_KEY_TYPE_ECDSA:
46 return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
47 default:
48 return PSA_KEY_TYPE_NONE;
49 }
50 }
51
toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm)52 static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm)
53 {
54 switch (aAlgorithm) {
55 case OT_CRYPTO_KEY_ALG_AES_ECB:
56 return PSA_ALG_ECB_NO_PADDING;
57 case OT_CRYPTO_KEY_ALG_HMAC_SHA_256:
58 return PSA_ALG_HMAC(PSA_ALG_SHA_256);
59 case OT_CRYPTO_KEY_ALG_ECDSA:
60 return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
61 default:
62 /*
63 * There is currently no constant like PSA_ALG_NONE, but 0 is used
64 * to indicate an unknown algorithm.
65 */
66 return (psa_algorithm_t)0;
67 }
68 }
69
toPsaKeyUsage(int aUsage)70 static psa_key_usage_t toPsaKeyUsage(int aUsage)
71 {
72 psa_key_usage_t usage = 0;
73
74 if (aUsage & OT_CRYPTO_KEY_USAGE_EXPORT) {
75 usage |= PSA_KEY_USAGE_EXPORT;
76 }
77
78 if (aUsage & OT_CRYPTO_KEY_USAGE_ENCRYPT) {
79 usage |= PSA_KEY_USAGE_ENCRYPT;
80 }
81
82 if (aUsage & OT_CRYPTO_KEY_USAGE_DECRYPT) {
83 usage |= PSA_KEY_USAGE_DECRYPT;
84 }
85
86 if (aUsage & OT_CRYPTO_KEY_USAGE_SIGN_HASH) {
87 usage |= PSA_KEY_USAGE_SIGN_HASH;
88 }
89
90 if (aUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH) {
91 usage |= PSA_KEY_USAGE_VERIFY_HASH;
92 }
93
94 return usage;
95 }
96
checkKeyUsage(int aUsage)97 static bool checkKeyUsage(int aUsage)
98 {
99 /* Check if only supported flags have been passed */
100 int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT | OT_CRYPTO_KEY_USAGE_ENCRYPT |
101 OT_CRYPTO_KEY_USAGE_DECRYPT | OT_CRYPTO_KEY_USAGE_SIGN_HASH |
102 OT_CRYPTO_KEY_USAGE_VERIFY_HASH;
103
104 return (aUsage & ~supported_flags) == 0;
105 }
106
checkContext(otCryptoContext * aContext,size_t aMinSize)107 static bool checkContext(otCryptoContext *aContext, size_t aMinSize)
108 {
109 /* Verify that the passed context is initialized and points to a big enough buffer */
110 return aContext != NULL && aContext->mContext != NULL && aContext->mContextSize >= aMinSize;
111 }
112
otPlatCryptoInit(void)113 void otPlatCryptoInit(void)
114 {
115 psa_crypto_init();
116
117 #if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_OPENTHREAD_CRYPTO_PSA)
118 /*
119 * In OpenThread, Settings are initialized after KeyManager by default. If device uses
120 * PSA with emulated TFM, Settings have to be initialized at the end of otPlatCryptoInit(),
121 * to be available before storing Network Key.
122 */
123 __ASSERT_EVAL((void)settings_subsys_init(), int err = settings_subsys_init(), !err,
124 "Failed to initialize settings");
125 #endif
126 }
127
otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef,otCryptoKeyType aKeyType,otCryptoKeyAlgorithm aKeyAlgorithm,int aKeyUsage,otCryptoKeyStorage aKeyPersistence,const uint8_t * aKey,size_t aKeyLen)128 otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, otCryptoKeyType aKeyType,
129 otCryptoKeyAlgorithm aKeyAlgorithm, int aKeyUsage,
130 otCryptoKeyStorage aKeyPersistence, const uint8_t *aKey,
131 size_t aKeyLen)
132 {
133 #if defined(CONFIG_OPENTHREAD_ECDSA)
134 int version;
135 size_t len;
136 unsigned char *p = (unsigned char *)aKey;
137 unsigned char *end;
138 #endif
139
140 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
141 psa_status_t status = 0;
142
143 if (aKeyRef == NULL || aKey == NULL || !checkKeyUsage(aKeyUsage)) {
144 return OT_ERROR_INVALID_ARGS;
145 }
146
147 #if defined(CONFIG_OPENTHREAD_ECDSA)
148 /* Check if key is ECDSA pair and extract private key from it since PSA expects it. */
149 if (aKeyType == OT_CRYPTO_KEY_TYPE_ECDSA) {
150
151 end = p + aKeyLen;
152 status = mbedtls_asn1_get_tag(&p, end, &len,
153 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
154 if (status != 0) {
155 return OT_ERROR_FAILED;
156 }
157
158 end = p + len;
159 status = mbedtls_asn1_get_int(&p, end, &version);
160 if (status != 0) {
161 return OT_ERROR_FAILED;
162 }
163
164 status = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
165 if (status != 0 || len != 32) {
166 return OT_ERROR_FAILED;
167 }
168
169 aKey = p;
170 aKeyLen = len;
171 }
172 #endif
173
174 psa_set_key_type(&attributes, toPsaKeyType(aKeyType));
175 psa_set_key_algorithm(&attributes, toPsaAlgorithm(aKeyAlgorithm));
176 psa_set_key_usage_flags(&attributes, toPsaKeyUsage(aKeyUsage));
177
178 switch (aKeyPersistence) {
179 case OT_CRYPTO_KEY_STORAGE_PERSISTENT:
180 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
181 psa_set_key_id(&attributes, *aKeyRef);
182 break;
183 case OT_CRYPTO_KEY_STORAGE_VOLATILE:
184 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
185 break;
186 }
187
188 status = psa_import_key(&attributes, aKey, aKeyLen, aKeyRef);
189 psa_reset_key_attributes(&attributes);
190
191 return psaToOtError(status);
192 }
193
otPlatCryptoExportKey(otCryptoKeyRef aKeyRef,uint8_t * aBuffer,size_t aBufferLen,size_t * aKeyLen)194 otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen,
195 size_t *aKeyLen)
196 {
197 if (aBuffer == NULL) {
198 return OT_ERROR_INVALID_ARGS;
199 }
200
201 return psaToOtError(psa_export_key(aKeyRef, aBuffer, aBufferLen, aKeyLen));
202 }
203
otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef)204 otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef)
205 {
206 return psaToOtError(psa_destroy_key(aKeyRef));
207 }
208
otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)209 bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
210 {
211 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
212 psa_status_t status;
213
214 status = psa_get_key_attributes(aKeyRef, &attributes);
215 psa_reset_key_attributes(&attributes);
216
217 return status == PSA_SUCCESS;
218 }
219
otPlatCryptoHmacSha256Init(otCryptoContext * aContext)220 otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext)
221 {
222 psa_mac_operation_t *operation;
223
224 if (!checkContext(aContext, sizeof(psa_mac_operation_t))) {
225 return OT_ERROR_INVALID_ARGS;
226 }
227
228 operation = aContext->mContext;
229 *operation = psa_mac_operation_init();
230
231 return OT_ERROR_NONE;
232 }
233
otPlatCryptoHmacSha256Deinit(otCryptoContext * aContext)234 otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext)
235 {
236 psa_mac_operation_t *operation;
237
238 if (!checkContext(aContext, sizeof(psa_mac_operation_t))) {
239 return OT_ERROR_INVALID_ARGS;
240 }
241
242 operation = aContext->mContext;
243
244 return psaToOtError(psa_mac_abort(operation));
245 }
246
otPlatCryptoHmacSha256Start(otCryptoContext * aContext,const otCryptoKey * aKey)247 otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey)
248 {
249 psa_mac_operation_t *operation;
250 psa_status_t status;
251
252 if (aKey == NULL || !checkContext(aContext, sizeof(psa_mac_operation_t))) {
253 return OT_ERROR_INVALID_ARGS;
254 }
255
256 operation = aContext->mContext;
257 status = psa_mac_sign_setup(operation, aKey->mKeyRef, PSA_ALG_HMAC(PSA_ALG_SHA_256));
258
259 return psaToOtError(status);
260 }
261
otPlatCryptoHmacSha256Update(otCryptoContext * aContext,const void * aBuf,uint16_t aBufLength)262 otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf,
263 uint16_t aBufLength)
264 {
265 psa_mac_operation_t *operation;
266
267 if (aBuf == NULL || !checkContext(aContext, sizeof(psa_mac_operation_t))) {
268 return OT_ERROR_INVALID_ARGS;
269 }
270
271 operation = aContext->mContext;
272
273 return psaToOtError(psa_mac_update(operation, (const uint8_t *)aBuf, aBufLength));
274 }
275
otPlatCryptoHmacSha256Finish(otCryptoContext * aContext,uint8_t * aBuf,size_t aBufLength)276 otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength)
277 {
278 psa_mac_operation_t *operation;
279 size_t mac_length;
280
281 if (aBuf == NULL || !checkContext(aContext, sizeof(psa_mac_operation_t))) {
282 return OT_ERROR_INVALID_ARGS;
283 }
284
285 operation = aContext->mContext;
286
287 return psaToOtError(psa_mac_sign_finish(operation, aBuf, aBufLength, &mac_length));
288 }
289
otPlatCryptoAesInit(otCryptoContext * aContext)290 otError otPlatCryptoAesInit(otCryptoContext *aContext)
291 {
292 psa_key_id_t *key_ref;
293
294 if (!checkContext(aContext, sizeof(psa_key_id_t))) {
295 return OT_ERROR_INVALID_ARGS;
296 }
297
298 key_ref = aContext->mContext;
299 *key_ref = (psa_key_id_t)0; /* In TF-M 1.5.0 this can be replaced with PSA_KEY_ID_NULL */
300
301 return OT_ERROR_NONE;
302 }
303
otPlatCryptoAesSetKey(otCryptoContext * aContext,const otCryptoKey * aKey)304 otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey)
305 {
306 psa_key_id_t *key_ref;
307
308 if (aKey == NULL || !checkContext(aContext, sizeof(psa_key_id_t))) {
309 return OT_ERROR_INVALID_ARGS;
310 }
311
312 key_ref = aContext->mContext;
313 *key_ref = aKey->mKeyRef;
314
315 return OT_ERROR_NONE;
316 }
317
otPlatCryptoAesEncrypt(otCryptoContext * aContext,const uint8_t * aInput,uint8_t * aOutput)318 otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput)
319 {
320 const size_t block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES);
321 psa_status_t status = PSA_SUCCESS;
322 psa_key_id_t *key_ref;
323 size_t cipher_length;
324
325 if (aInput == NULL || aOutput == NULL || !checkContext(aContext, sizeof(psa_key_id_t))) {
326 return OT_ERROR_INVALID_ARGS;
327 }
328
329 key_ref = aContext->mContext;
330 status = psa_cipher_encrypt(*key_ref, PSA_ALG_ECB_NO_PADDING, aInput, block_size, aOutput,
331 block_size, &cipher_length);
332
333 return psaToOtError(status);
334 }
335
otPlatCryptoAesFree(otCryptoContext * aContext)336 otError otPlatCryptoAesFree(otCryptoContext *aContext)
337 {
338 return OT_ERROR_NONE;
339 }
340
otPlatCryptoSha256Init(otCryptoContext * aContext)341 otError otPlatCryptoSha256Init(otCryptoContext *aContext)
342 {
343 psa_hash_operation_t *operation;
344
345 if (!checkContext(aContext, sizeof(psa_hash_operation_t))) {
346 return OT_ERROR_INVALID_ARGS;
347 }
348
349 operation = aContext->mContext;
350 *operation = psa_hash_operation_init();
351
352 return OT_ERROR_NONE;
353 }
354
otPlatCryptoSha256Deinit(otCryptoContext * aContext)355 otError otPlatCryptoSha256Deinit(otCryptoContext *aContext)
356 {
357 psa_hash_operation_t *operation;
358
359 if (!checkContext(aContext, sizeof(psa_hash_operation_t))) {
360 return OT_ERROR_INVALID_ARGS;
361 }
362
363 operation = aContext->mContext;
364
365 return psaToOtError(psa_hash_abort(operation));
366 }
367
otPlatCryptoSha256Start(otCryptoContext * aContext)368 otError otPlatCryptoSha256Start(otCryptoContext *aContext)
369 {
370 psa_hash_operation_t *operation;
371
372 if (!checkContext(aContext, sizeof(psa_hash_operation_t))) {
373 return OT_ERROR_INVALID_ARGS;
374 }
375
376 operation = aContext->mContext;
377
378 return psaToOtError(psa_hash_setup(operation, PSA_ALG_SHA_256));
379 }
380
otPlatCryptoSha256Update(otCryptoContext * aContext,const void * aBuf,uint16_t aBufLength)381 otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
382 {
383 psa_hash_operation_t *operation;
384
385 if (aBuf == NULL || !checkContext(aContext, sizeof(psa_hash_operation_t))) {
386 return OT_ERROR_INVALID_ARGS;
387 }
388
389 operation = aContext->mContext;
390
391 return psaToOtError(psa_hash_update(operation, (const uint8_t *)aBuf, aBufLength));
392 }
393
otPlatCryptoSha256Finish(otCryptoContext * aContext,uint8_t * aHash,uint16_t aHashSize)394 otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize)
395 {
396 psa_hash_operation_t *operation;
397 size_t hash_size;
398
399 if (aHash == NULL || !checkContext(aContext, sizeof(psa_hash_operation_t))) {
400 return OT_ERROR_INVALID_ARGS;
401 }
402
403 operation = aContext->mContext;
404
405 return psaToOtError(psa_hash_finish(operation, aHash, aHashSize, &hash_size));
406 }
407
otPlatCryptoRandomInit(void)408 void otPlatCryptoRandomInit(void)
409 {
410 psa_crypto_init();
411 }
412
otPlatCryptoRandomDeinit(void)413 void otPlatCryptoRandomDeinit(void)
414 {
415 }
416
otPlatCryptoRandomGet(uint8_t * aBuffer,uint16_t aSize)417 otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize)
418 {
419 return psaToOtError(psa_generate_random(aBuffer, aSize));
420 }
421
422 #if defined(CONFIG_OPENTHREAD_ECDSA)
423
otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair * aKeyPair)424 otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
425 {
426 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
427 psa_key_id_t key_id = 0;
428 psa_status_t status;
429 size_t exported_length;
430
431 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
432 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
433 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
434 psa_set_key_bits(&attributes, 256);
435
436 status = psa_generate_key(&attributes, &key_id);
437 if (status != PSA_SUCCESS) {
438 goto out;
439 }
440
441 status = psa_export_key(key_id, aKeyPair->mDerBytes, OT_CRYPTO_ECDSA_MAX_DER_SIZE,
442 &exported_length);
443 if (status != PSA_SUCCESS) {
444 goto out;
445 }
446 aKeyPair->mDerLength = exported_length;
447
448 out:
449 psa_reset_key_attributes(&attributes);
450 psa_destroy_key(key_id);
451
452 return psaToOtError(status);
453 }
454
otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair * aKeyPair,const otPlatCryptoSha256Hash * aHash,otPlatCryptoEcdsaSignature * aSignature)455 otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
456 const otPlatCryptoSha256Hash *aHash,
457 otPlatCryptoEcdsaSignature *aSignature)
458 {
459 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
460 psa_key_id_t key_id;
461 psa_status_t status;
462 size_t signature_length;
463
464 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
465 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
466 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
467 psa_set_key_bits(&attributes, 256);
468
469 status = psa_import_key(&attributes, aKeyPair->mDerBytes, aKeyPair->mDerLength, &key_id);
470 if (status != PSA_SUCCESS) {
471 goto out;
472 }
473
474 status = psa_sign_hash(key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8,
475 OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8,
476 OT_CRYPTO_ECDSA_SIGNATURE_SIZE, &signature_length);
477 if (status != PSA_SUCCESS) {
478 goto out;
479 }
480
481 out:
482 psa_reset_key_attributes(&attributes);
483 psa_destroy_key(key_id);
484
485 return psaToOtError(status);
486 }
487
otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey * aPublicKey,const otPlatCryptoSha256Hash * aHash,const otPlatCryptoEcdsaSignature * aSignature)488 otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
489 const otPlatCryptoSha256Hash *aHash,
490 const otPlatCryptoEcdsaSignature *aSignature)
491 {
492 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
493 psa_key_id_t key_id;
494 psa_status_t status;
495 uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE];
496
497 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
498 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
499 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
500 psa_set_key_bits(&attributes, 256);
501
502 /*
503 * `psa_import_key` expects a key format as specified by SEC1 §2.3.3 for the
504 * uncompressed representation of the ECPoint.
505 */
506 buffer[0] = 0x04;
507 memcpy(buffer + 1, aPublicKey->m8, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
508 status = psa_import_key(&attributes, buffer, sizeof(buffer), &key_id);
509 if (status != PSA_SUCCESS) {
510 goto out;
511 }
512
513 status = psa_verify_hash(key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8,
514 OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8,
515 OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
516 if (status != PSA_SUCCESS) {
517 goto out;
518 }
519
520 out:
521 psa_reset_key_attributes(&attributes);
522 psa_destroy_key(key_id);
523
524 return psaToOtError(status);
525 }
526
otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,const otPlatCryptoSha256Hash * aHash,otPlatCryptoEcdsaSignature * aSignature)527 otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
528 const otPlatCryptoSha256Hash *aHash,
529 otPlatCryptoEcdsaSignature *aSignature)
530 {
531 psa_status_t status;
532 size_t signature_length;
533
534 status = psa_sign_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8,
535 OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8,
536 OT_CRYPTO_ECDSA_SIGNATURE_SIZE, &signature_length);
537 if (status != PSA_SUCCESS) {
538 goto out;
539 }
540
541 __ASSERT_NO_MSG(signature_length == OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
542 out:
543 return psaToOtError(status);
544 }
545
otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,const otPlatCryptoSha256Hash * aHash,const otPlatCryptoEcdsaSignature * aSignature)546 otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
547 const otPlatCryptoSha256Hash *aHash,
548 const otPlatCryptoEcdsaSignature *aSignature)
549 {
550 psa_status_t status;
551
552 status = psa_verify_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8,
553 OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8,
554 OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
555 if (status != PSA_SUCCESS) {
556 goto out;
557 }
558
559 out:
560 return psaToOtError(status);
561 }
562
otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef,otPlatCryptoEcdsaPublicKey * aPublicKey)563 otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef,
564 otPlatCryptoEcdsaPublicKey *aPublicKey)
565 {
566 psa_status_t status;
567 size_t exported_length;
568 uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE];
569
570 status = psa_export_public_key(aKeyRef, buffer, sizeof(buffer), &exported_length);
571 if (status != PSA_SUCCESS) {
572 goto out;
573 }
574
575 __ASSERT_NO_MSG(exported_length == sizeof(buffer));
576 memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
577
578 out:
579 return psaToOtError(status);
580 }
581
otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)582 otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
583 {
584 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
585 psa_status_t status;
586 psa_key_id_t key_id = (psa_key_id_t)aKeyRef;
587
588 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH);
589 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
590 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
591 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
592 psa_set_key_id(&attributes, key_id);
593 psa_set_key_bits(&attributes, 256);
594
595 status = psa_generate_key(&attributes, &key_id);
596 if (status != PSA_SUCCESS) {
597 goto out;
598 }
599
600 out:
601 psa_reset_key_attributes(&attributes);
602
603 return psaToOtError(status);
604 }
605
otPlatCryptoPbkdf2GenerateKey(const uint8_t * aPassword,uint16_t aPasswordLen,const uint8_t * aSalt,uint16_t aSaltLen,uint32_t aIterationCounter,uint16_t aKeyLen,uint8_t * aKey)606 otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
607 uint16_t aPasswordLen,
608 const uint8_t *aSalt,
609 uint16_t aSaltLen,
610 uint32_t aIterationCounter,
611 uint16_t aKeyLen,
612 uint8_t *aKey)
613 {
614 psa_status_t status = PSA_SUCCESS;
615 psa_key_id_t key_id = PSA_KEY_ID_NULL;
616 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
617 psa_algorithm_t algorithm = PSA_ALG_PBKDF2_AES_CMAC_PRF_128;
618 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
619
620 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
621 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
622 psa_set_key_algorithm(&attributes, algorithm);
623 psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
624 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(aPasswordLen));
625
626 status = psa_import_key(&attributes, aPassword, aPasswordLen, &key_id);
627 if (status != PSA_SUCCESS) {
628 goto out;
629 }
630
631 status = psa_key_derivation_setup(&operation, algorithm);
632 if (status != PSA_SUCCESS) {
633 goto out;
634 }
635
636 status = psa_key_derivation_input_integer(&operation, PSA_KEY_DERIVATION_INPUT_COST,
637 aIterationCounter);
638 if (status != PSA_SUCCESS) {
639 goto out;
640 }
641
642 status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT,
643 aSalt, aSaltLen);
644 if (status != PSA_SUCCESS) {
645 goto out;
646 }
647
648 status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_PASSWORD,
649 key_id);
650 if (status != PSA_SUCCESS) {
651 goto out;
652 }
653
654 status = psa_key_derivation_output_bytes(&operation, aKey, aKeyLen);
655 if (status != PSA_SUCCESS) {
656 goto out;
657 }
658
659 out:
660 psa_reset_key_attributes(&attributes);
661 psa_key_derivation_abort(&operation);
662 psa_destroy_key(key_id);
663
664 __ASSERT_NO_MSG(status == PSA_SUCCESS);
665 return psaToOtError(status);
666 }
667
668 #endif /* #if CONFIG_OPENTHREAD_ECDSA */
669