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 &sect;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