Skip to content

Commit 48e255e

Browse files
committed
modules: openthread: add HKDF support in crypto_psa
crypto_psa.c was missing an implementation for the following functions: - otPlatCryptoHkdfInit - otPlatCryptoHkdfExtract - otPlatCryptoHkdfExpand - otPlatCryptoHkdfDeinit which provide support for HKDF using PSA Crypto API. This commit fill this gap by copying the implementation from upstream PR 11445. Signed-off-by: Valerio Setti <[email protected]>
1 parent 2112401 commit 48e255e

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

modules/openthread/platform/crypto_psa.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ static psa_key_type_t toPsaKeyType(otCryptoKeyType aType)
4444
return PSA_KEY_TYPE_HMAC;
4545
case OT_CRYPTO_KEY_TYPE_ECDSA:
4646
return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
47+
case OT_CRYPTO_KEY_TYPE_DERIVE:
48+
return PSA_KEY_TYPE_DERIVE;
4749
default:
4850
return PSA_KEY_TYPE_NONE;
4951
}
@@ -58,6 +60,8 @@ static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm)
5860
return PSA_ALG_HMAC(PSA_ALG_SHA_256);
5961
case OT_CRYPTO_KEY_ALG_ECDSA:
6062
return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
63+
case OT_CRYPTO_KEY_ALG_HKDF_SHA256:
64+
return PSA_ALG_HKDF(PSA_ALG_SHA_256);
6165
default:
6266
/*
6367
* There is currently no constant like PSA_ALG_NONE, but 0 is used
@@ -91,6 +95,10 @@ static psa_key_usage_t toPsaKeyUsage(int aUsage)
9195
usage |= PSA_KEY_USAGE_VERIFY_HASH;
9296
}
9397

98+
if (aUsage & OT_CRYPTO_KEY_USAGE_DERIVE) {
99+
usage |= PSA_KEY_USAGE_DERIVE;
100+
}
101+
94102
return usage;
95103
}
96104

@@ -287,6 +295,143 @@ otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, s
287295
return psaToOtError(psa_mac_sign_finish(operation, aBuf, aBufLength, &mac_length));
288296
}
289297

298+
299+
otError otPlatCryptoHkdfInit(otCryptoContext *aContext)
300+
{
301+
psa_key_derivation_operation_t *operation;
302+
303+
if (!checkContext(aContext, sizeof(psa_key_derivation_operation_t))) {
304+
return OT_ERROR_INVALID_ARGS;
305+
}
306+
307+
operation = aContext->mContext;
308+
309+
memset(operation, 0, sizeof(psa_key_derivation_operation_t));
310+
311+
return psaToOtError(psa_key_derivation_setup(operation, PSA_ALG_HKDF(PSA_ALG_SHA_256)));
312+
}
313+
314+
otError otPlatCryptoHkdfExtract(otCryptoContext *aContext,
315+
const uint8_t *aSalt,
316+
uint16_t aSaltLength,
317+
const otCryptoKey *aInputKey)
318+
{
319+
otError error = OT_ERROR_NONE;
320+
psa_status_t status = PSA_SUCCESS;
321+
psa_key_derivation_operation_t *operation = NULL;
322+
otCryptoKeyRef key_ref = PSA_KEY_ID_NULL;
323+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
324+
psa_algorithm_t key_alg = PSA_ALG_NONE;
325+
size_t key_length = 0;
326+
const size_t key_buffer_size = 16;
327+
uint8_t key_buffer[key_buffer_size];
328+
329+
if (!checkContext(aContext, sizeof(psa_key_derivation_operation_t)) ||
330+
(aInputKey == NULL) || (aSalt == NULL) || (aSaltLength == 0)) {
331+
return OT_ERROR_INVALID_ARGS;
332+
}
333+
334+
operation = aContext->mContext;
335+
336+
status = psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, aSalt,
337+
aSaltLength);
338+
if (status != PSA_SUCCESS) {
339+
error = psaToOtError(status);
340+
goto exit;
341+
}
342+
343+
status = psa_get_key_attributes(aInputKey->mKeyRef, &attributes);
344+
if (status != PSA_SUCCESS) {
345+
error = psaToOtError(status);
346+
goto exit;
347+
}
348+
349+
key_alg = psa_get_key_algorithm(&attributes);
350+
351+
/* The PSA API enforces a policy that restricts each key to a single algorithm.
352+
* If the key is already HKDF-SHA256, we can use it directly.
353+
* Otherwise, export and re-import it as a volatile HKDF key.
354+
*/
355+
if (key_alg != toPsaAlgorithm(OT_CRYPTO_KEY_ALG_HKDF_SHA256)) {
356+
error = otPlatCryptoExportKey(aInputKey->mKeyRef, key_buffer, sizeof(key_buffer),
357+
&key_length);
358+
if (error != OT_ERROR_NONE) {
359+
goto exit;
360+
}
361+
error = otPlatCryptoImportKey(&key_ref, OT_CRYPTO_KEY_TYPE_DERIVE,
362+
OT_CRYPTO_KEY_ALG_HKDF_SHA256,
363+
OT_CRYPTO_KEY_USAGE_DERIVE,
364+
OT_CRYPTO_KEY_STORAGE_VOLATILE,
365+
key_buffer, key_length);
366+
if (error != OT_ERROR_NONE) {
367+
goto exit;
368+
}
369+
370+
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET,
371+
key_ref);
372+
if (status != PSA_SUCCESS) {
373+
error = psaToOtError(status);
374+
goto exit;
375+
}
376+
} else {
377+
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET,
378+
aInputKey->mKeyRef);
379+
if (status != PSA_SUCCESS) {
380+
error = psaToOtError(status);
381+
goto exit;
382+
}
383+
}
384+
385+
exit:
386+
psa_reset_key_attributes(&attributes);
387+
otPlatCryptoDestroyKey(key_ref);
388+
389+
return error;
390+
}
391+
392+
otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
393+
const uint8_t *aInfo,
394+
uint16_t aInfoLength,
395+
uint8_t *aOutputKey,
396+
uint16_t aOutputKeyLength)
397+
{
398+
psa_status_t status = PSA_SUCCESS;
399+
psa_key_derivation_operation_t *operation;
400+
401+
if (!checkContext(aContext, sizeof(psa_key_derivation_operation_t)) ||
402+
(aOutputKey == NULL) || (aOutputKeyLength == 0)) {
403+
return OT_ERROR_INVALID_ARGS;
404+
}
405+
406+
operation = aContext->mContext;
407+
408+
status = psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO,
409+
aInfo, aInfoLength);
410+
if (status != PSA_SUCCESS) {
411+
return psaToOtError(status);
412+
}
413+
414+
status = psa_key_derivation_output_bytes(operation, aOutputKey, aOutputKeyLength);
415+
if (status != PSA_SUCCESS) {
416+
return psaToOtError(status);
417+
}
418+
419+
return OT_ERROR_NONE;
420+
}
421+
422+
otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext)
423+
{
424+
psa_key_derivation_operation_t *operation;
425+
426+
if (!checkContext(aContext, sizeof(psa_key_derivation_operation_t))) {
427+
return OT_ERROR_INVALID_ARGS;
428+
}
429+
430+
operation = aContext->mContext;
431+
432+
return psaToOtError(psa_key_derivation_abort(operation));
433+
}
434+
290435
otError otPlatCryptoAesInit(otCryptoContext *aContext)
291436
{
292437
psa_key_id_t *key_ref;

0 commit comments

Comments
 (0)