From 50e306904b62ffda472019798141ea558e2a34f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20Erik=20Gj=C3=B8rvad?= Date: Thu, 19 Dec 2024 15:59:55 +0100 Subject: [PATCH] nrf_security: drivers: cracen: Adding support for ed25519 without sicrypto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding support for directly using silexpk and sxsymcrypt files for ed25519 This bypasses sicrypto, which saves on flash usage This is a prototype, not ready for use Signed-off-by: Dag Erik Gjørvad --- .../cracen/cracenpsa/include/cracen_psa.h | 7 + .../cracen/cracenpsa/src/ed25519_test.c | 216 ++++++++++++++++++ .../cracen/cracenpsa/src/key_management.c | 25 +- 3 files changed, 243 insertions(+), 5 deletions(-) create mode 100644 subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519_test.c diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h b/subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h index 1719f9e675d8..2d040238fcef 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h @@ -361,4 +361,11 @@ psa_status_t cracen_spake2p_get_shared_key(cracen_spake2p_operation_t *operation psa_status_t cracen_spake2p_abort(cracen_spake2p_operation_t *operation); +int no_si_ed25519_sign(const uint8_t *ed25519, char *signature, const uint8_t *message); + +int no_si_create_ed25519_verify(const uint8_t *pubkey, const char* message, size_t message_length, const char *signature); + +int no_si_sig_create_ed25519_pubkey(const uint8_t *ed25519, + uint8_t *pubkey); + #endif /* CRACEN_PSA_H */ diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519_test.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519_test.c new file mode 100644 index 000000000000..fe3b8b29a842 --- /dev/null +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519_test.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include +#include +#include + +int no_si_ed25519_sign(const uint8_t *ed25519, char *signature, const uint8_t *message) +{ + char workmem[160]; + struct sxhash hashopctx; + char pointr_buffer[64]; + char *pointr = pointr_buffer; + int r; + + /*Hash the private key, the digest is stored in the first 64 bytes of workmem*/ + r = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, ed25519, 32); + if (r != 0) { + return r; + } + r = sx_hash_digest(&hashopctx, workmem); + if (r != 0) { + return r; + } + /*Wait to make sure hash operation is finished before doing calculations on it*/ + r = sx_hash_wait(&hashopctx); + if (r != 0) { + return r; + } + /* Obtain r by hashing (prefix || message), where prefix is the second + * half of the private key digest. + */ + + r = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, workmem+32, 32); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, message, 100); + if (r != 0) { + return r; + } + r = sx_hash_digest(&hashopctx, workmem+96); + if (r != 0) { + return r; + } + + /* Perform point multiplication R = [r]B. This is the encoded point R, + * which is the first part of the signature. + */ + r = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem + 96), (struct sx_ed25519_pt *)pointr); + if (r != 0) { + return r; + + } + /* The secret scalar s is computed in place from the first half of the + * private key digest. + */ + decode_scalar_25519(workmem); + + /* Clear second half of private key digest: sx_async_ed25519_ptmult_go() + * works on an input of SX_ED25519_DGST_SZ bytes. + */ + safe_memset(workmem + 32, 128, 0, 32); + + /* Perform point multiplication A = [s]B, to obtain the public key A. which is stored in workmem[32:63] */ + r = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem), (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)((char *)workmem + 32)); + if (r != 0) { + return r; + } + + /* Obtain k by hashing (R || A || message). */ + r = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, pointr, 32); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, workmem+32, 32); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, message, 100); + if (r != 0) { + return r; + } + r = sx_hash_digest(&hashopctx, workmem+32); + if (r != 0) { + return r; + } + + /* Compute (r + k * s) mod L. This gives the second part of the + * signature, which is the encoded S which is stored in pointr. + */ + + r = sx_ed25519_sign( + (const struct sx_ed25519_dgst *)(workmem + 32), + (const struct sx_ed25519_dgst *)(workmem + 3 * 32), + (const struct sx_ed25519_v *)workmem, + (struct sx_ed25519_v *)(pointr + SX_ED25519_PT_SZ)); + if (r != 0) { + return r; + } + + memcpy(signature, pointr, 64); + + return r; + /*End ed25519_sign_finish*/ + +/*end si_sig_create_ed_25510 sign*/ + + +} + +int no_si_create_ed25519_verify(const uint8_t *pubkey, const char* message, size_t message_length, const char *signature) +{ + + char workmem[64]; + struct sxhash hashopctx; + int r; + + + r = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, signature, 32); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, pubkey, 32); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, message, message_length); + if (r != 0) { + return r; + } + r = sx_hash_digest(&hashopctx, workmem); + if (r != 0) { + return r; + } + + + r = sx_ed25519_verify( + (struct sx_ed25519_dgst *)workmem, + (struct sx_ed25519_pt *)pubkey, + (const struct sx_ed25519_v *)(signature + 32), + (const struct sx_ed25519_pt *)signature); + + return r; + /*end finish_ed25519_ver*/ + +} + +int no_si_sig_create_ed25519_pubkey(const uint8_t *ed25519, + uint8_t *pubkey) +{ + /*Si_sig_create_ed_25519_sign*/ + char workmem[64]; + struct sxhash hashopctx; + int r; + + /*ed25519_sign_hash_privkey*/ + r = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (r != 0) { + return r; + } + r = sx_hash_feed(&hashopctx, ed25519, 32); + if (r != 0) { + return r; + } + r = sx_hash_digest(&hashopctx, workmem); + if (r != 0) { + return r; + } + /*Wait to make sure hash operation is finished before doing calculations on it + * removing this breaks pubkey generation + */ + r = sx_hash_wait(&hashopctx); + if (r != 0) { + return r; + } + /* The secret scalar s is computed in place from the first half of the + * private key digest. + */ + decode_scalar_25519(workmem); + + /* Clear second half of private key digest: sx_async_ed25519_ptmult_go() + * works on an input of SX_ED25519_DGST_SZ bytes. + */ + safe_memset(workmem+32, 32, 0, 32); + /* Perform point multiplication A = [s]B, to obtain the public key A. */ + r = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem), (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)((char *)workmem + 32)); + if (r != 0) { + return r; + } + memcpy(pubkey, workmem+32, 32); + + return r; + +} \ No newline at end of file diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c index 340f657f1f83..9fcef205eb31 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,12 @@ #include #include +#define NO_SI_CRYPTO_TEST (1) +#if NO_SI_CRYPTO_TEST +#else +#include +#endif + extern const uint8_t cracen_N3072[384]; extern nrf_security_mutex_t cracen_mutex_symmetric; @@ -603,8 +608,10 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ size_t expected_pub_key_size = 0; int si_status = 0; const struct sx_pk_ecurve *sx_curve; +#if NO_SI_CRYPTO_TEST +#else struct sitask t; - +#endif switch (psa_curve) { case PSA_ECC_FAMILY_BRAINPOOL_P_R1: case PSA_ECC_FAMILY_SECP_R1: @@ -629,9 +636,10 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ struct si_sig_privkey priv_key; struct si_sig_pubkey pub_key; - +#if NO_SI_CRYPTO_TEST +#else char workmem[SX_ED448_DGST_SZ] = {}; - +#endif if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)) == PSA_KEY_LOCATION_CRACEN) { if (key_buffer_size != sizeof(ikg_opaque_key)) { @@ -672,6 +680,8 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ } break; case PSA_ECC_FAMILY_TWISTED_EDWARDS: +#if NO_SI_CRYPTO_TEST +#else if (key_bits_attr == 255) { priv_key.def = si_sig_def_ed25519; priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer; @@ -681,12 +691,16 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ priv_key.key.ed448 = (struct sx_ed448_v *)key_buffer; pub_key.key.ed448 = (struct sx_ed448_pt *)data; } +#endif break; default: return PSA_ERROR_NOT_SUPPORTED; } } - +#if NO_SI_CRYPTO_TEST + si_status = no_si_sig_create_ed25519_pubkey(key_buffer, data); + *data_length = 32; +#else si_task_init(&t, workmem, sizeof(workmem)); si_sig_create_pubkey(&t, &priv_key, &pub_key); si_task_run(&t); @@ -698,6 +712,7 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ } *data_length = expected_pub_key_size; +#endif return PSA_SUCCESS; } static psa_status_t export_rsa_public_key_from_keypair(const psa_key_attributes_t *attributes,