From 66dcd8a02bf009340ac7f7e98ec45430e06fb743 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 1/2] nrf_security: drivers: cracen: Remove sicrypto for ed25519 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for Ed25519 and Ed25519ph in cracenpsa directly using silexpk/sxsymcrypt. This bypasses sicrypto, which saves on flash usage Remove sicrypto implementation of Ed25519 from cracenpsa. Signed-off-by: Dag Erik Gjørvad --- .../drivers/cracen/cracenpsa/cracenpsa.cmake | 2 + .../cracen/cracenpsa/include/cracen_psa.h | 16 + .../drivers/cracen/cracenpsa/src/ed25519.c | 373 ++++++++++++++++++ .../cracen/cracenpsa/src/key_management.c | 24 +- .../src/drivers/cracen/cracenpsa/src/sign.c | 166 +++----- .../src/drivers/cracen/psa_driver.Kconfig | 1 - 6 files changed, 453 insertions(+), 129 deletions(-) create mode 100644 subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake b/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake index d18cc88822d2..2d01215eefb6 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake @@ -44,6 +44,7 @@ endif() if(CONFIG_PSA_NEED_CRACEN_ASYMMETRIC_SIGNATURE_DRIVER) list(APPEND cracen_driver_sources ${CMAKE_CURRENT_LIST_DIR}/src/sign.c + ${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c ) endif() @@ -61,6 +62,7 @@ endif() if(CONFIG_PSA_NEED_CRACEN_KEY_MANAGEMENT_DRIVER OR CONFIG_PSA_NEED_CRACEN_KMU_DRIVER OR CONFIG_MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) list(APPEND cracen_driver_sources + ${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c ${CMAKE_CURRENT_LIST_DIR}/src/key_management.c ) endif() 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 a5389c878853..ae7620db069c 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,20 @@ 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 ed25519_sign(const uint8_t *privkey, char *signature, + const uint8_t *message, size_t message_length); + +int ed25519_verify(const uint8_t *pubkey, const char *message, + size_t message_length, const char *signature); + + +int ed25519ph_sign(const uint8_t *privkey, char *signature, + const uint8_t *message, size_t message_length, int ismessage); + +int ed25519ph_verify(const uint8_t *pubkey, const char *message, + size_t message_length, const char *signature, int ismessage); + +int ed25519_create_pubkey(const uint8_t *privkey, + uint8_t *pubkey); + #endif /* CRACEN_PSA_H */ diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c new file mode 100644 index 000000000000..e6284936b553 --- /dev/null +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include +#include +#include + +/* This is the ASCII string with the + * PHflag 1 and context size 0 appended as defined in: + * https://datatracker.ietf.org/doc/html/rfc8032.html#section-2 + * used for domain seperation between Ed25519 and Ed25519ph + */ +const char dom2[34] = { + 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, + 0x35, 0x31, 0x39, 0x20, 0x6e, 0x6f, 0x20, + 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, + 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x01, 0x00 +}; + +int ed25519_hash_message(const char *message, size_t message_length, char *workmem) +{ + int status; + struct sxhash hashopctx; + + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, message, message_length); + if (status != 0) { + return status; + } + status = sx_hash_digest(&hashopctx, workmem); + if (status != 0) { + return status; + } + status = sx_hash_wait(&hashopctx); + + return status; + +} + +int ed25519_hash_privkey(struct sxhash hashopctx, char *workmem, const uint8_t *priv_key) +{ + + int status; + /*Hash the private key, the digest is stored in the first 64 bytes of workmem*/ + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, priv_key, SX_ED25519_SZ); + if (status != 0) { + return status; + } + status = sx_hash_digest(&hashopctx, workmem); + if (status != 0) { + return status; + } + /*Wait to make sure hash operation is finished before doing calculations on it*/ + status = sx_hash_wait(&hashopctx); + + return status; +} + + +int ed25519_calculate_r(struct sxhash hashopctx, char *workmem, const uint8_t *message, + size_t message_length, int prehash) +{ + int status; + + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (status != 0) { + return status; + } + if (prehash) { + status = sx_hash_feed(&hashopctx, dom2, 34); + if (status != 0) { + return status; + } + } + status = sx_hash_feed(&hashopctx, workmem+SX_ED25519_SZ, SX_ED25519_SZ); + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, message, message_length); + if (status != 0) { + return status; + } + status = sx_hash_digest(&hashopctx, workmem+96); + if (status != 0) { + return status; + } + status = sx_hash_wait(&hashopctx); + if (status != 0) { + return status; + } + + return status; +} + +int ed25519_calculate_k(struct sxhash hashopctx, char *workmem, char *pointr, + const char *message, size_t message_length, int prehash) +{ + /* Obtain k by hashing (R || A || message). where A is the public key */ + int status; + + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + + if (status != 0) { + return status; + } + if (prehash) { + status = sx_hash_feed(&hashopctx, dom2, sizeof(dom2)); + if (status != 0) { + return status; + } + } + status = sx_hash_feed(&hashopctx, pointr, SX_ED25519_SZ); + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, workmem+SX_ED25519_SZ, SX_ED25519_SZ); + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, message, message_length); + if (status != 0) { + return status; + } + status = sx_hash_digest(&hashopctx, workmem+SX_ED25519_SZ); + if (status != 0) { + return status; + } + status = sx_hash_wait(&hashopctx); + if (status != 0) { + return status; + } + return status; +} + +int ed25519_sign_internal(const uint8_t *priv_key, char *signature, const uint8_t *message, + size_t message_length, int prehash) +{ + char workmem[160]; + struct sxhash hashopctx; + char pointr_buffer[SX_ED25519_DGST_SZ]; + char *pointr = pointr_buffer; + int status; + + /*Hash the private key, the digest is stored in the first 64 bytes of workmem*/ + status = ed25519_hash_privkey(hashopctx, workmem, priv_key); + if (status != 0) { + return status; + } + + /* Obtain r by hashing (prefix || message), where prefix is the second + * half of the private key digest. + */ + status = ed25519_calculate_r(hashopctx, workmem, message, message_length, prehash); + /* Perform point multiplication R = [r]B. This is the encoded point R, + * which is the first part of the signature. + */ + status = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem + 96), + (struct sx_ed25519_pt *)pointr); + if (status != 0) { + return status; + + } + /* 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 + SX_ED25519_SZ, sizeof(workmem) - SX_ED25519_SZ, 0, SX_ED25519_SZ); + /* Perform point multiplication A = [s]B, + * to obtain the public key A. which is stored in workmem[32:63] + */ + status = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem), + (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)((char *)workmem + SX_ED25519_PT_SZ)); + + if (status != 0) { + return status; + } + + status = ed25519_calculate_k(hashopctx, workmem, pointr, message, message_length, prehash); + if (status != 0) { + return status; + } + + /* Compute (r + k * s) mod L. This gives the second part of the + * signature, which is the encoded S which is stored in pointr. + */ + + status = sx_ed25519_sign( + (const struct sx_ed25519_dgst *)(workmem + SX_ED25519_SZ), + (const struct sx_ed25519_dgst *)(workmem + 3 * SX_ED25519_SZ), + (const struct sx_ed25519_v *)workmem, + (struct sx_ed25519_v *)(pointr + SX_ED25519_PT_SZ)); + if (status != 0) { + return status; + } + + memcpy(signature, pointr, SX_ED25519_DGST_SZ); + + return status; + +} + + +int ed25519_sign(const uint8_t *priv_key, char *signature, + const uint8_t *message, size_t message_length) +{ + return ed25519_sign_internal(priv_key, signature, message, message_length, 0); +} + +int ed25519ph_sign(const uint8_t *priv_key, char *signature, + const uint8_t *message, size_t message_length, int ismessage) +{ + char hashedmessage[SX_ED25519_DGST_SZ]; + int status; + + if (ismessage) { + status = ed25519_hash_message(message, message_length, hashedmessage); + if (status != 0) { + return status; + } + return ed25519_sign_internal(priv_key, signature, + hashedmessage, SX_ED25519_DGST_SZ, 1); + } else { + return ed25519_sign_internal(priv_key, signature, message, message_length, 1); + } +} + +int ed25519_verify_internal(const uint8_t *pubkey, const char *message, + size_t message_length, const char *signature, int prehash) +{ + char workmem[SX_ED25519_DGST_SZ]; + struct sxhash hashopctx; + int status; + + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + + if (status != 0) { + return status; + } + if (prehash) { + status = sx_hash_feed(&hashopctx, dom2, sizeof(dom2)); + if (status != 0) { + return status; + } + } + status = sx_hash_feed(&hashopctx, signature, SX_ED25519_SZ); + + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, pubkey, SX_ED25519_SZ); + + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, message, message_length); + + if (status != 0) { + return status; + } + status = sx_hash_digest(&hashopctx, workmem); + if (status != 0) { + return status; + } + status = sx_hash_wait(&hashopctx); + if (status != 0) { + return status; + } + + status = sx_ed25519_verify( + (struct sx_ed25519_dgst *)workmem, + (struct sx_ed25519_pt *)pubkey, + (const struct sx_ed25519_v *)(signature + SX_ED25519_SZ), + (const struct sx_ed25519_pt *)signature); + + return status; +} + +int ed25519_verify(const uint8_t *pubkey, const char *message, + size_t message_length, const char *signature) +{ + return ed25519_verify_internal(pubkey, message, + message_length, signature, 0); +} + +int ed25519ph_verify(const uint8_t *pubkey, const char *message, + size_t message_length, const char *signature, int ismessage) +{ + int status; + char hashedmessage[SX_ED25519_DGST_SZ]; + + if (ismessage) { + status = ed25519_hash_message(message, message_length, hashedmessage); + if (status != 0) { + return status; + } + return ed25519_verify_internal(pubkey, hashedmessage, + SX_ED25519_DGST_SZ, signature, 1); + } + return ed25519_verify_internal(pubkey, message, message_length, signature, 1); +} + +int ed25519_create_pubkey(const uint8_t *priv_key, + uint8_t *pubkey) +{ + char workmem[SX_ED25519_DGST_SZ]; + struct sxhash hashopctx; + int status; + + /*Hash the privat key*/ + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + if (status != 0) { + return status; + } + + status = sx_hash_feed(&hashopctx, priv_key, SX_ED25519_SZ); + if (status != 0) { + return status; + } + + status = sx_hash_digest(&hashopctx, workmem); + if (status != 0) { + return status; + } + + /*Wait to make sure hash operation is finished before doing + * calculations on it. Removing this breaks pubkey generation + */ + status = sx_hash_wait(&hashopctx); + if (status != 0) { + return status; + } + + /* 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+SX_ED25519_SZ, SX_ED25519_SZ, 0, SX_ED25519_SZ); + + /* Perform point multiplication A = [s]B, to obtain the public key A. */ + status = sx_ed25519_ptmult((const struct sx_ed25519_dgst *)(workmem), + (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)((char *)workmem + SX_ED25519_PT_SZ)); + + if (status != 0) { + return status; + } + + memcpy(pubkey, workmem+SX_ED25519_SZ, SX_ED25519_SZ); + + return status; + +} 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 d52287b80077..8d1d615051b8 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 @@ -10,12 +10,9 @@ #include "cracen_psa.h" #include "platform_keys/platform_keys.h" #include - #include #include #include -#include -#include #include #include #include @@ -603,10 +600,9 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ psa_status_t psa_status; size_t expected_pub_key_size = 0; int si_status = 0; - psa_algorithm_t key_alg = psa_get_key_algorithm(attributes); const struct sx_pk_ecurve *sx_curve; - struct sitask t; + struct sitask t; switch (psa_curve) { case PSA_ECC_FAMILY_BRAINPOOL_P_R1: case PSA_ECC_FAMILY_SECP_R1: @@ -631,7 +627,6 @@ 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; - char workmem[SX_ED448_DGST_SZ] = {}; if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)) == @@ -675,15 +670,14 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ break; case PSA_ECC_FAMILY_TWISTED_EDWARDS: if (key_bits_attr == 255) { - if (key_alg == PSA_ALG_ED25519PH) { - priv_key.def = si_sig_def_ed25519ph; - priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer; - pub_key.key.ed25519 = (struct sx_ed25519_pt *)data; - } else { - priv_key.def = si_sig_def_ed25519; - priv_key.key.ed25519 = (struct sx_ed25519_v *)key_buffer; - pub_key.key.ed25519 = (struct sx_ed25519_pt *)data; - } + (void)t; + si_status = ed25519_create_pubkey(key_buffer, data); + *data_length = 32; + if (si_status != SX_OK) { + return silex_statuscodes_to_psa(si_status); + } + safe_memzero(workmem, sizeof(workmem)); + return PSA_SUCCESS; } else { priv_key.def = si_sig_def_ed448; priv_key.key.ed448 = (struct sx_ed448_v *)key_buffer; diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c index d2686b77fcce..36301d9f64f9 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include #include @@ -31,7 +29,6 @@ #include "common.h" #include "cracen_psa.h" - #define SI_IS_MESSAGE (1) #define SI_IS_HASH (0) #define SI_EXTRACT_PUBKEY (1) @@ -120,25 +117,8 @@ static int cracen_signature_prepare_ec_prvkey(struct si_sig_privkey *privkey, ch return SX_ERR_INVALID_ARG; } - if (IS_ENABLED(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS)) { - if (alg == PSA_ALG_PURE_EDDSA) { - privkey->def = si_sig_def_ed25519; - privkey->key.ed25519 = (struct sx_ed25519_v *)key_buffer; - return SX_OK; - } - } - - if (IS_ENABLED(PSA_NEED_CRACEN_ED25519PH)) { - if (alg == PSA_ALG_ED25519PH) { - privkey->def = si_sig_def_ed25519ph; - privkey->key.ed25519 = (struct sx_ed25519_v *)key_buffer; - if (message) { - return cracen_signature_set_hashalgo(&privkey->hashalg, alg); - } else { - return cracen_signature_set_hashalgo_from_digestsz( - &privkey->hashalg, alg, digestsz); - } - } + if (alg == PSA_ALG_PURE_EDDSA || alg == PSA_ALG_ED25519PH) { + return SX_OK; } if (IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_R1) || @@ -211,36 +191,13 @@ static int cracen_signature_prepare_ec_pubkey(struct sitask *t, struct si_sig_pu if (IS_ENABLED(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS)) { if (alg == PSA_ALG_PURE_EDDSA) { - pubkey->def = si_sig_def_ed25519; - if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(psa_get_key_type(attributes))) { - pubkey->key.ed25519 = (struct sx_ed25519_pt *)key_buffer; + memcpy(pubkey_buffer, key_buffer, key_buffer_size); return SX_OK; } - if (curvesz != key_buffer_size) { - return SX_ERR_INVALID_KEY_SZ; - } - pubkey->key.ed25519 = (struct sx_ed25519_pt *)pubkey_buffer; - } - } - - if (IS_ENABLED(PSA_NEED_CRACEN_ED25519PH) && alg == PSA_ALG_ED25519PH) { - pubkey->def = si_sig_def_ed25519ph; - if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(psa_get_key_type(attributes))) { - pubkey->key.ed25519 = (struct sx_ed25519_pt *)key_buffer; - if (message) { - cracen_signature_set_hashalgo(&pubkey->hashalg, - alg); - } else { - cracen_signature_set_hashalgo_from_digestsz(&pubkey->hashalg, - alg, digestsz); - } - return SX_OK; - } - if (curvesz != key_buffer_size) { - return SX_ERR_INVALID_KEY_SZ; + status = ed25519_create_pubkey(key_buffer, pubkey_buffer); + return status; } - pubkey->key.ed25519 = (struct sx_ed25519_pt *)pubkey_buffer; } if (IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_R1) || @@ -299,16 +256,6 @@ static psa_status_t cracen_signature_ecc_sign(int message, const psa_key_attribu size_t signature_size, size_t *signature_length) { int si_status; - const struct sx_pk_ecurve *curve; - struct si_sig_privkey privkey = {0}; - struct si_sig_signature sign = {0}; - struct sitask t; - /* Workmem for ecc sign task is 4 * digestsz + hmac block size + curve size */ - char workmem[4 * PSA_HASH_MAX_SIZE + PSA_HMAC_MAX_HASH_BLOCK_SIZE + - PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - - si_task_init(&t, workmem, sizeof(workmem)); - if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_get_key_type(attributes))) { return silex_statuscodes_to_psa(SX_ERR_INCOMPATIBLE_HW); } @@ -321,7 +268,26 @@ static psa_status_t cracen_signature_ecc_sign(int message, const psa_key_attribu ((!message) && (!SI_PSA_IS_KEY_FLAG(PSA_KEY_USAGE_SIGN_HASH, attributes)))) { return PSA_ERROR_INVALID_ARGUMENT; } + if (alg == PSA_ALG_ED25519PH) { + si_status = ed25519ph_sign(key_buffer, signature, input, input_length, message); + *signature_length = 64; + return silex_statuscodes_to_psa(si_status); + + } else if (alg == PSA_ALG_PURE_EDDSA) { + si_status = ed25519_sign(key_buffer, signature, input, input_length); + *signature_length = 64; + return silex_statuscodes_to_psa(si_status); + } + const struct sx_pk_ecurve *curve; + struct si_sig_privkey privkey = {0}; + struct si_sig_signature sign = {0}; + struct sitask t; + /* Workmem for ecc sign task is 4 * digestsz + hmac block size + curve size */ + char workmem[4 * PSA_HASH_MAX_SIZE + PSA_HMAC_MAX_HASH_BLOCK_SIZE + + PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; + + si_task_init(&t, workmem, sizeof(workmem)); si_status = cracen_signature_prepare_ec_prvkey(&privkey, (char *)key_buffer, key_buffer_size, &curve, alg, attributes, message, input_length); @@ -333,44 +299,23 @@ static psa_status_t cracen_signature_ecc_sign(int message, const psa_key_attribu if ((int)signature_size < 2 * curve->sz) { return silex_statuscodes_to_psa(SX_ERR_OUTPUT_BUFFER_TOO_SMALL); } - *signature_length = 2 * curve->sz; sign.sz = *signature_length; sign.r = (char *)signature; sign.s = (char *)signature + *signature_length / 2; - /* Ed25519ph requires prehashing and supports sign and verify message - * the message is therefore hashed here before si_sig_verify is called - */ - if (alg == PSA_ALG_ED25519PH && message) { - uint8_t status; - uint8_t hash[64]; - size_t output_len; - - status = psa_hash_compute(PSA_ALG_SHA_512, - input, input_length, hash, - sizeof(hash), &output_len); - if (status != PSA_SUCCESS) { - return status; - } - + if (message) { si_sig_create_sign(&t, &privkey, &sign); - si_task_consume(&t, (char *)hash, sizeof(hash)); } else { - if (message) { - si_sig_create_sign(&t, &privkey, &sign); - } else { - si_sig_create_sign_digest(&t, &privkey, &sign); - - } - si_task_consume(&t, (char *)input, - message ? input_length : sx_hash_get_alg_digestsz(privkey.hashalg)); + si_sig_create_sign_digest(&t, &privkey, &sign); } + si_task_consume(&t, (char *)input, + message ? input_length : sx_hash_get_alg_digestsz(privkey.hashalg)); + si_task_run(&t); si_status = si_task_wait(&t); safe_memzero(workmem, sizeof(workmem)); - return silex_statuscodes_to_psa(si_status); } @@ -405,52 +350,47 @@ static psa_status_t cracen_signature_ecc_verify(int message, const psa_key_attri } si_task_init(&t, workmem, sizeof(workmem)); - si_status = cracen_signature_prepare_ec_pubkey(&t, &pubkey, (char *)key_buffer, key_buffer_size, &curve, alg, attributes, message, input_length, pubkey_buffer); - if (si_status) { - return silex_statuscodes_to_psa(si_status); - } if ((int)signature_length != 2 * curve->sz) { return silex_statuscodes_to_psa(SX_ERR_INVALID_SIGNATURE); } + + if (alg == PSA_ALG_ED25519PH) { + si_status = ed25519ph_verify(pubkey_buffer, (char *)input, + input_length, signature, message); + (void)t; + return silex_statuscodes_to_psa(si_status); + } else if (alg == PSA_ALG_PURE_EDDSA) { + si_status = ed25519_verify(pubkey_buffer, (char *)input, + input_length, signature); + (void)t; + return silex_statuscodes_to_psa(si_status); + } + + if (si_status) { + return silex_statuscodes_to_psa(si_status); + } + sign.sz = signature_length; sign.r = (char *)signature; sign.s = (char *)signature + signature_length / 2; - /* Ed25519ph requires prehashing and supports sign and verify message - * the message is therefore hashed here before si_sig_verify is called - */ - if (alg == PSA_ALG_ED25519PH && message) { - psa_status_t status; - uint8_t hash[64]; - size_t output_len; - - status = psa_hash_compute(PSA_ALG_SHA_512, - input, input_length, hash, - sizeof(hash), &output_len); - if (status != PSA_SUCCESS) { - return status; - } - + if (message) { si_sig_create_verify(&t, &pubkey, &sign); - si_task_consume(&t, (char *)hash, sizeof(hash)); } else { - if (message) { - si_sig_create_verify(&t, &pubkey, &sign); - } else { - if (sx_hash_get_alg_digestsz(pubkey.hashalg) != input_length) { - return PSA_ERROR_INVALID_ARGUMENT; - } - si_sig_create_verify_digest(&t, &pubkey, &sign); + if (sx_hash_get_alg_digestsz(pubkey.hashalg) != input_length) { + return PSA_ERROR_INVALID_ARGUMENT; } - - si_task_consume(&t, (char *)input, input_length); + si_sig_create_verify_digest(&t, &pubkey, &sign); } + si_task_consume(&t, (char *)input, input_length); si_task_run(&t); si_status = si_task_wait(&t); + safe_memzero(workmem, sizeof(workmem)); + return silex_statuscodes_to_psa(si_status); } diff --git a/subsys/nrf_security/src/drivers/cracen/psa_driver.Kconfig b/subsys/nrf_security/src/drivers/cracen/psa_driver.Kconfig index 57b478a9ef92..f40a793a7677 100644 --- a/subsys/nrf_security/src/drivers/cracen/psa_driver.Kconfig +++ b/subsys/nrf_security/src/drivers/cracen/psa_driver.Kconfig @@ -1859,5 +1859,4 @@ config PSA_NEED_CRACEN_PLATFORM_KEYS depends on PSA_WANT_AES_KEY_SIZE_256 depends on SOC_NRF54H20_CPUSEC - endmenu From e29d25590b0b6531f6665ccd92f95205b3726adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20Erik=20Gj=C3=B8rvad?= Date: Tue, 21 Jan 2025 11:41:10 +0100 Subject: [PATCH 2/2] nrf_security: drivers: cracen: Adding extra wait to ed25519 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test to see if it fixes bootloader issues Signed-off-by: Dag Erik Gjørvad --- .../drivers/cracen/cracenpsa/src/ed25519.c | 29 ++++++++++++++++--- .../src/drivers/cracen/cracenpsa/src/sign.c | 4 +-- .../cracen/sxsymcrypt/sxsymcrypt.cmake | 1 + 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c index e6284936b553..738ec1f576fc 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c @@ -9,6 +9,8 @@ #include #include #include +#include "crypmasterregs.h" +#include "hw.h" /* This is the ASCII string with the * PHflag 1 and context size 0 appended as defined in: @@ -249,37 +251,56 @@ int ed25519_verify_internal(const uint8_t *pubkey, const char *message, struct sxhash hashopctx; int status; - status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); + status = sx_hash_create(&hashopctx, &sxhashalg_sha2_512, sizeof(hashopctx)); if (status != 0) { return status; } if (prehash) { status = sx_hash_feed(&hashopctx, dom2, sizeof(dom2)); + if (status != 0) { return status; } } - status = sx_hash_feed(&hashopctx, signature, SX_ED25519_SZ); - + status = sx_hash_feed(&hashopctx, signature, SX_ED25519_SZ/2); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); if (status != 0) { return status; } - status = sx_hash_feed(&hashopctx, pubkey, SX_ED25519_SZ); + status = sx_hash_feed(&hashopctx, signature+16, SX_ED25519_SZ/2); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); + + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, pubkey, SX_ED25519_SZ/2); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); + if (status != 0) { + return status; + } + status = sx_hash_feed(&hashopctx, pubkey+16, SX_ED25519_SZ/2); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); if (status != 0) { return status; } status = sx_hash_feed(&hashopctx, message, message_length); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); if (status != 0) { return status; } status = sx_hash_digest(&hashopctx, workmem); + while ((sx_rdreg(REG_STATUS) & REG_STATUS_BUSY_MASK) != 0); + + if (status != 0) { return status; } status = sx_hash_wait(&hashopctx); + + if (status != 0) { return status; } diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c index 36301d9f64f9..a8b81d3dcd9c 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c @@ -190,14 +190,14 @@ static int cracen_signature_prepare_ec_pubkey(struct sitask *t, struct si_sig_pu status = SX_ERR_INCOMPATIBLE_HW; if (IS_ENABLED(PSA_NEED_CRACEN_PURE_EDDSA_TWISTED_EDWARDS)) { - if (alg == PSA_ALG_PURE_EDDSA) { + if (alg == PSA_ALG_PURE_EDDSA || alg == PSA_ALG_ED25519PH) { if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(psa_get_key_type(attributes))) { memcpy(pubkey_buffer, key_buffer, key_buffer_size); return SX_OK; } status = ed25519_create_pubkey(key_buffer, pubkey_buffer); return status; - } + } } if (IS_ENABLED(PSA_NEED_CRACEN_ECDSA_SECP_R1) || diff --git a/subsys/nrf_security/src/drivers/cracen/sxsymcrypt/sxsymcrypt.cmake b/subsys/nrf_security/src/drivers/cracen/sxsymcrypt/sxsymcrypt.cmake index 774dd1e15d56..7b0e269aeac2 100644 --- a/subsys/nrf_security/src/drivers/cracen/sxsymcrypt/sxsymcrypt.cmake +++ b/subsys/nrf_security/src/drivers/cracen/sxsymcrypt/sxsymcrypt.cmake @@ -18,4 +18,5 @@ list(APPEND cracen_driver_sources list(APPEND cracen_driver_include_dirs ${CMAKE_CURRENT_LIST_DIR}/include + ${CMAKE_CURRENT_LIST_DIR}/src )