Skip to content

Commit 9e4cd47

Browse files
degjorvanordicjm
authored andcommitted
nrf_security: cracen: Add support for ED25519PH
Adding ED25519PH to the supported algorithms for cracen Updated logic for selecting which algorithm to use cracen key_management.c to handle different algorithms using same curve and key_bits Signed-off-by: Dag Erik Gjørvad <[email protected]>
1 parent dee077d commit 9e4cd47

File tree

9 files changed

+590
-18
lines changed

9 files changed

+590
-18
lines changed

subsys/nrf_security/cmake/psa_crypto_config.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_255
6060
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_448)
6161
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS)
6262
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_RSA_PKCS1V15_SIGN)
63+
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_ED25519PH)
6364
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_RSA_PSS)
6465
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_ASYMMETRIC_SIGNATURE_ANY_ECC)
6566
kconfig_check_and_set_base_to_one(PSA_NEED_CRACEN_ASYMMETRIC_SIGNATURE_ANY_RSA)

subsys/nrf_security/configs/psa_crypto_config.h.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@
272272
#cmakedefine PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_255 @PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_255@
273273
#cmakedefine PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_448 @PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_448@
274274
#cmakedefine PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS @PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS@
275+
#cmakedefine PSA_NEED_CRACEN_ED25519PH @PSA_NEED_CRACEN_ED25519PH@
275276
#cmakedefine PSA_NEED_CRACEN_RSA_PKCS1V15_SIGN @PSA_NEED_CRACEN_RSA_PKCS1V15_SIGN@
276277
#cmakedefine PSA_NEED_CRACEN_RSA_PSS @PSA_NEED_CRACEN_RSA_PSS@
277278
#cmakedefine PSA_NEED_CRACEN_RSA_OAEP @PSA_NEED_CRACEN_RSA_OAEP@

subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <sicrypto/ecc.h>
1616
#include <sicrypto/ecdsa.h>
1717
#include <sicrypto/ed25519.h>
18+
#include <sicrypto/ed25519ph.h>
1819
#include <sicrypto/ed448.h>
1920
#include <sicrypto/montgomery.h>
2021
#include <sicrypto/rsa_keygen.h>
@@ -602,6 +603,7 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_
602603
psa_status_t psa_status;
603604
size_t expected_pub_key_size = 0;
604605
int si_status = 0;
606+
psa_algorithm_t key_alg = psa_get_key_algorithm(attributes);
605607
const struct sx_pk_ecurve *sx_curve;
606608
struct sitask t;
607609

@@ -673,9 +675,15 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_
673675
break;
674676
case PSA_ECC_FAMILY_TWISTED_EDWARDS:
675677
if (key_bits_attr == 255) {
676-
priv_key.def = si_sig_def_ed25519;
677-
priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer;
678-
pub_key.key.ed25519 = (struct sx_ed25519_pt *)data;
678+
if (key_alg == PSA_ALG_ED25519PH) {
679+
priv_key.def = si_sig_def_ed25519ph;
680+
priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer;
681+
pub_key.key.ed25519 = (struct sx_ed25519_pt *)data;
682+
} else {
683+
priv_key.def = si_sig_def_ed25519;
684+
priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer;
685+
pub_key.key.ed25519 = (struct sx_ed25519_pt *)data;
686+
}
679687
} else {
680688
priv_key.def = si_sig_def_ed448;
681689
priv_key.key.ed448 = (struct sx_ed448_v *)key_buffer;
@@ -700,6 +708,7 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_
700708
*data_length = expected_pub_key_size;
701709
return PSA_SUCCESS;
702710
}
711+
703712
static psa_status_t export_rsa_public_key_from_keypair(const psa_key_attributes_t *attributes,
704713
const uint8_t *key_buffer,
705714
size_t key_buffer_size, uint8_t *data,

subsys/nrf_security/src/drivers/cracen/cracenpsa/src/kmu.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ enum kmu_metadata_algorithm {
6161
METADATA_ALG_CMAC = 9,
6262
METADATA_ALG_ED25519 = 10,
6363
METADATA_ALG_ECDSA = 11,
64-
METADATA_ALG_RESERVED2 = 12,
64+
METADATA_ALG_ED25519PH = 12,
6565
METADATA_ALG_RESERVED3 = 13,
6666
METADATA_ALG_RESERVED4 = 14,
6767
METADATA_ALG_RESERVED5 = 15,
@@ -463,6 +463,15 @@ static psa_status_t convert_to_psa_attributes(kmu_metadata *metadata,
463463
: PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS));
464464
psa_set_key_algorithm(key_attr, PSA_ALG_PURE_EDDSA);
465465
break;
466+
case METADATA_ALG_ED25519PH:
467+
/* If the key can sign it is assumed it is a private key */
468+
psa_set_key_type(
469+
key_attr,
470+
can_sign(key_attr)
471+
? PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS)
472+
: PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS));
473+
psa_set_key_algorithm(key_attr, PSA_ALG_ED25519PH);
474+
break;
466475
case METADATA_ALG_ECDSA:
467476
psa_set_key_type(key_attr,
468477
can_sign(key_attr)
@@ -614,6 +623,19 @@ psa_status_t convert_from_psa_attributes(const psa_key_attributes_t *key_attr,
614623
metadata->algorithm = METADATA_ALG_ED25519;
615624
break;
616625

626+
case PSA_ALG_ED25519PH:
627+
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(key_attr)) !=
628+
PSA_ECC_FAMILY_TWISTED_EDWARDS) {
629+
return PSA_ERROR_NOT_SUPPORTED;
630+
}
631+
/* Don't support private keys that are only used for verify */
632+
if (!can_sign(key_attr) &&
633+
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_get_key_type(key_attr))) {
634+
return PSA_ERROR_NOT_SUPPORTED;
635+
}
636+
metadata->algorithm = METADATA_ALG_ED25519PH;
637+
break;
638+
617639
case PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):
618640
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(key_attr)) !=
619641
PSA_ECC_FAMILY_SECP_R1) {

subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <sicrypto/drbghash.h>
1414
#include <sicrypto/ecdsa.h>
1515
#include <sicrypto/ed25519.h>
16+
#include <sicrypto/ed25519ph.h>
1617
#include <sicrypto/ik.h>
1718
#include <sicrypto/internal.h>
1819
#include <sicrypto/rsapss.h>
@@ -127,6 +128,19 @@ static int cracen_signature_prepare_ec_prvkey(struct si_sig_privkey *privkey, ch
127128
}
128129
}
129130

131+
if (IS_ENABLED(PSA_NEED_CRACEN_ED25519PH)) {
132+
if (alg == PSA_ALG_ED25519PH) {
133+
privkey->def = si_sig_def_ed25519ph;
134+
privkey->key.ed25519 = (struct sx_ed25519_v *)key_buffer;
135+
if (message) {
136+
return cracen_signature_set_hashalgo(&privkey->hashalg, alg);
137+
} else {
138+
return cracen_signature_set_hashalgo_from_digestsz(
139+
&privkey->hashalg, alg, digestsz);
140+
}
141+
}
142+
}
143+
130144
if (IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_R1) ||
131145
IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_K1) ||
132146
IS_ENABLED(PSA_NEED_CRACEN_ECDSA_BRAINPOOL_P_R1)) {
@@ -210,6 +224,25 @@ static int cracen_signature_prepare_ec_pubkey(struct sitask *t, struct si_sig_pu
210224
}
211225
}
212226

227+
if (IS_ENABLED(PSA_NEED_CRACEN_ED25519PH) && alg == PSA_ALG_ED25519PH) {
228+
pubkey->def = si_sig_def_ed25519ph;
229+
if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(psa_get_key_type(attributes))) {
230+
pubkey->key.ed25519 = (struct sx_ed25519_pt *)key_buffer;
231+
if (message) {
232+
cracen_signature_set_hashalgo(&pubkey->hashalg,
233+
alg);
234+
} else {
235+
cracen_signature_set_hashalgo_from_digestsz(&pubkey->hashalg,
236+
alg, digestsz);
237+
}
238+
return SX_OK;
239+
}
240+
if (curvesz != key_buffer_size) {
241+
return SX_ERR_INVALID_KEY_SZ;
242+
}
243+
pubkey->key.ed25519 = (struct sx_ed25519_pt *)pubkey_buffer;
244+
}
245+
213246
if (IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_R1) ||
214247
IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_K1) ||
215248
IS_ENABLED(PSA_NEED_CRACEN_ECDSA_BRAINPOOL_P_R1)) {
@@ -280,7 +313,7 @@ static psa_status_t cracen_signature_ecc_sign(int message, const psa_key_attribu
280313
return silex_statuscodes_to_psa(SX_ERR_INCOMPATIBLE_HW);
281314
}
282315

283-
if (!PSA_ALG_IS_ECDSA(alg) && alg != PSA_ALG_PURE_EDDSA) {
316+
if (!PSA_ALG_IS_ECDSA(alg) && alg != PSA_ALG_PURE_EDDSA && alg != PSA_ALG_ED25519PH) {
284317
return PSA_ERROR_INVALID_ARGUMENT;
285318
}
286319

@@ -306,14 +339,34 @@ static psa_status_t cracen_signature_ecc_sign(int message, const psa_key_attribu
306339
sign.r = (char *)signature;
307340
sign.s = (char *)signature + *signature_length / 2;
308341

309-
if (message) {
342+
/* ED25519PH requires prehashing and supports sign and verify message
343+
* the message is therefore hashed here before si_sig_verify is called
344+
*/
345+
if (alg == PSA_ALG_ED25519PH && message) {
346+
uint8_t status;
347+
uint8_t hash[64];
348+
size_t output_len;
349+
350+
status = psa_hash_compute(PSA_ALG_SHA_512,
351+
input, input_length, hash,
352+
sizeof(hash), &output_len);
353+
if (status != PSA_SUCCESS) {
354+
return status;
355+
}
356+
310357
si_sig_create_sign(&t, &privkey, &sign);
311-
si_task_consume(&t, (char *)input, input_length);
358+
si_task_consume(&t, (char *)hash, sizeof(hash));
312359
} else {
313-
si_sig_create_sign_digest(&t, &privkey, &sign);
314-
si_task_consume(&t, (char *)input, sx_hash_get_alg_digestsz(privkey.hashalg));
315-
}
360+
if (message) {
361+
si_sig_create_sign(&t, &privkey, &sign);
362+
} else {
363+
si_sig_create_sign_digest(&t, &privkey, &sign);
316364

365+
}
366+
si_task_consume(&t, (char *)input,
367+
message ? input_length : sx_hash_get_alg_digestsz(privkey.hashalg));
368+
369+
}
317370
si_task_run(&t);
318371
si_status = si_task_wait(&t);
319372
safe_memzero(workmem, sizeof(workmem));
@@ -342,7 +395,7 @@ static psa_status_t cracen_signature_ecc_verify(int message, const psa_key_attri
342395
return silex_statuscodes_to_psa(SX_ERR_INCOMPATIBLE_HW);
343396
}
344397

345-
if (!PSA_ALG_IS_ECDSA(alg) && alg != PSA_ALG_PURE_EDDSA) {
398+
if (!PSA_ALG_IS_ECDSA(alg) && alg != PSA_ALG_PURE_EDDSA && !PSA_ALG_IS_HASH_EDDSA(alg)) {
346399
return PSA_ERROR_NOT_SUPPORTED;
347400
}
348401

@@ -366,20 +419,37 @@ static psa_status_t cracen_signature_ecc_verify(int message, const psa_key_attri
366419
sign.sz = signature_length;
367420
sign.r = (char *)signature;
368421
sign.s = (char *)signature + signature_length / 2;
422+
/* ED25519PH requires prehashing and supports sign and verify message
423+
* the message is therefore hashed here before si_sig_verify is called
424+
*/
425+
if (alg == PSA_ALG_ED25519PH && message) {
426+
psa_status_t status;
427+
uint8_t hash[64];
428+
uint32_t output_len;
429+
430+
status = psa_hash_compute(PSA_ALG_SHA_512,
431+
input, input_length, hash,
432+
sizeof(hash), &output_len);
433+
if (status != PSA_SUCCESS) {
434+
return status;
435+
}
369436

370-
if (message) {
371437
si_sig_create_verify(&t, &pubkey, &sign);
438+
si_task_consume(&t, (char *)hash, sizeof(hash));
372439
} else {
373-
if (sx_hash_get_alg_digestsz(pubkey.hashalg) != input_length) {
374-
return PSA_ERROR_INVALID_ARGUMENT;
440+
if (message) {
441+
si_sig_create_verify(&t, &pubkey, &sign);
442+
} else {
443+
if (sx_hash_get_alg_digestsz(pubkey.hashalg) != input_length) {
444+
return PSA_ERROR_INVALID_ARGUMENT;
445+
}
446+
si_sig_create_verify_digest(&t, &pubkey, &sign);
375447
}
376-
si_sig_create_verify_digest(&t, &pubkey, &sign);
377-
}
378448

379-
si_task_consume(&t, (char *)input, input_length);
449+
si_task_consume(&t, (char *)input, input_length);
450+
}
380451
si_task_run(&t);
381452
si_status = si_task_wait(&t);
382-
383453
safe_memzero(workmem, sizeof(workmem));
384454
return silex_statuscodes_to_psa(si_status);
385455
}

subsys/nrf_security/src/drivers/cracen/psa_driver.Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,14 @@ config PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS_448
364364
depends on PSA_WANT_ECC_TWISTED_EDWARDS_448
365365
depends on PSA_USE_CRACEN_ASYMMETRIC_DRIVER
366366

367+
config PSA_NEED_CRACEN_ED25519PH
368+
bool
369+
default y
370+
select PSA_ACCEL_ED25519PH
371+
depends on PSA_WANT_ALG_ED25519PH
372+
depends on PSA_WANT_ECC_TWISTED_EDWARDS_255
373+
depends on PSA_USE_CRACEN_ASYMMETRIC_DRIVER
374+
367375
config PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS
368376
bool
369377
default y
@@ -376,6 +384,7 @@ config PSA_NEED_CRACEN_ASYMMETRIC_SIGNATURE_ANY_ECC
376384
depends on PSA_NEED_CRACEN_ECDSA_BRAINPOOL_P_R1 || \
377385
PSA_NEED_CRACEN_ECDSA_SECP_R1 || \
378386
PSA_NEED_CRACEN_ECDSA_SECP_K1 || \
387+
PSA_NEED_CRACEN_ED25519PH || \
379388
PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS
380389

381390
config PSA_NEED_CRACEN_RSA_PKCS1V15_SIGN
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/** Ed25519 signature-related operations.
2+
*
3+
* @file
4+
*
5+
* @copyright Copyright (c) 2023 Nordic Semiconductor ASA
6+
*
7+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
8+
*/
9+
10+
#ifndef SICRYPTO_ED25519PH_HEADER_FILE
11+
#define SICRYPTO_ED25519PH_HEADER_FILE
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
#include "sig.h"
18+
19+
/** Signature definitions for ED25519PH keys.
20+
*
21+
* The following constraints apply when using Ed25519ph keys:
22+
*
23+
* When generating a signature with si_sig_create_sign():
24+
* - The task needs a workmem buffer of at least 160 bytes.
25+
* - The message to be signed must be given with a single call to
26+
* si_task_consume().
27+
* - The buffer for private key material must be in DMA memory.
28+
* - The signature buffer must be in DMA memory.
29+
*
30+
* When verifying a signature with si_sig_create_verify():
31+
* - The task needs a workmem buffer of at least 64 bytes.
32+
* - The buffer for public key material must be in DMA memory.
33+
* - The signature buffer must be in DMA memory.
34+
* - The task can use partial processing. For the first partial run, the sum of
35+
* the sizes of the provided message chunks plus 64 must be a multiple of
36+
* 128 bytes. For any other partial run, the sum of the sizes of the provided
37+
* message chunks must be a multiple of 128 bytes.
38+
*
39+
* When computing a public key with si_sig_create_pubkey():
40+
* - The task needs a workmem buffer of at least 64 bytes.
41+
* - The buffer for private key material must be in DMA memory.
42+
*/
43+
extern const struct si_sig_def *const si_sig_def_ed25519ph;
44+
45+
#ifdef __cplusplus
46+
}
47+
#endif
48+
49+
#endif

subsys/nrf_security/src/drivers/cracen/sicrypto/sicrypto.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ list(APPEND cracen_driver_sources
1010
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
1111
${CMAKE_CURRENT_LIST_DIR}/src/ecdsa.c
1212
${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c
13+
${CMAKE_CURRENT_LIST_DIR}/src/ed25519ph.c
1314
${CMAKE_CURRENT_LIST_DIR}/src/ed448.c
1415
${CMAKE_CURRENT_LIST_DIR}/src/hash.c
1516
${CMAKE_CURRENT_LIST_DIR}/src/hkdf.c

0 commit comments

Comments
 (0)