diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake b/subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake index d18cc88822d2..a91f1bf27fc9 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() @@ -90,6 +91,12 @@ if(CONFIG_PSA_NEED_CRACEN_KMU_DRIVER) ) endif() +if(CONFIG_PSA_NEED_CRACEN_KEY_AGREEMENT_DRIVER) + list(APPEND cracen_driver_sources + ${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c + ) +endif() + if(CONFIG_PSA_NEED_CRACEN_KEY_AGREEMENT_DRIVER OR CONFIG_PSA_NEED_CRACEN_KEY_DERIVATION_DRIVER) list(APPEND cracen_driver_sources ${CMAKE_CURRENT_LIST_DIR}/src/key_derivation.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 a5389c878853..6b437a17a2dc 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); +struct sxhashalg; + +int cracen_ed25519_sign(const uint8_t *ed25519, char *signature, const uint8_t *message, + size_t message_length); + +int cracen_ed25519_verify(const uint8_t *pubkey, const char *message, size_t message_length, + const char *signature); + +int cracen_ed25519ph_sign(const uint8_t *ed25519, char *signature, const uint8_t *message, + size_t message_length, int ismessage); + +int cracen_ed25519ph_verify(const uint8_t *pubkey, const char *message, size_t message_length, + const char *signature, int ismessage); + +int cracen_ed25519_create_pubkey(const uint8_t *ed25519, 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..78bf8eb58735 --- /dev/null +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ed25519.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + * + * The comments in this file use the notations and conventions from RFC 8032. + * + * Workmem layout for an Ed25519 signature verification task: + * 1. digest (size: 64 bytes). + * + * Workmem layout for an Ed25519 signature generation task: + * The workmem is made of 5 areas of 32 bytes each (total size 160 bytes). + * In the following we refer to these areas using the numbers 1 to 5. The + * first hash operation computes the private key's digest, which is stored + * in areas 1 and 2. The second hash operation computes r, which is stored + * in areas 4 and 5. The first point multiplication computes R, which is + * written directly to the output buffer. Then the secret scalar s is + * computed in place in area 1. Area 2 is cleared. The second point + * multiplication computes the public key A, which is stored in area 2. The + * third hash operation computes k, which is stored in areas 2 and 3. The + * final operation (r + k * s) mod L computes S, which is written directly + * to the output buffer. + * + * Workmem layout for an Ed25519 public key generation task: + * 1. digest (size: 64 bytes). The digest of the private key is written in + * this area. Then the secret scalar s is computed in place in the first + * 32 bytes of this area. + */ +#include +#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. + * This can not be stored as a const due to hardware limitations + */ +#define DOM2_SIZE 34 +#define AREA2_MEM_OFFSET 32 +#define AREA4_MEM_OFFSET 96 + +static char dom2[] = {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}; + +static size_t dom2sz = sizeof(dom2); + +int hash_all_inputs(char const *inputs[], size_t *inputs_lengths[], size_t inputs_count, + const struct sxhashalg *hashalg, char *out) +{ + struct sxhash hashopctx; + int status; + + status = sx_hash_create(&hashopctx, hashalg, sizeof(hashopctx)); + if (status != SX_OK) { + return status; + } + for (int i = 0; i < inputs_count; i++) { + status = sx_hash_feed(&hashopctx, inputs[i], *inputs_lengths[i]); + if (status != SX_OK) { + return status; + } + } + status = sx_hash_digest(&hashopctx, out); + if (status != SX_OK) { + return status; + } + status = sx_hash_wait(&hashopctx); + + return status; +} + +static int ed25519_hash_message(const char *message, size_t message_length, char *digest) +{ + char const *hash_array[] = {(char *)message}; + size_t *hash_array_lengths[] = {&message_length}; + + return hash_all_inputs(hash_array, hash_array_lengths, 1, &sxhashalg_sha2_512, digest); +} + +static int ed25519_hash_privkey(char *workmem, const uint8_t *priv_key) +{ + /* Hash the private key, the digest is stored in the first 64 bytes of workmem */ + char const *hash_array[] = {(char *)priv_key}; + size_t priv_key_length = SX_ED25519_SZ; + size_t *hash_array_lengths[] = {&priv_key_length}; + + return hash_all_inputs(hash_array, hash_array_lengths, 1, &sxhashalg_sha2_512, workmem); +} + +static int ed25519_calculate_r(char *workmem, const uint8_t *message, size_t message_length, + bool prehash) +{ + size_t point_r_sz = SX_ED25519_SZ; + char const *hash_array[] = {dom2, workmem + SX_ED25519_SZ, message}; + size_t *hash_array_lengths[] = {&dom2sz, &point_r_sz, &message_length}; + size_t input_count = prehash ? 3 : 2; + size_t offset = prehash ? 0 : 1; + + return hash_all_inputs(&hash_array[offset], &hash_array_lengths[offset], input_count, + &sxhashalg_sha2_512, workmem + 3 * SX_ED25519_SZ); +} + +static int ed25519_calculate_k(char *workmem, char *point_r, const char *message, + size_t message_length, int prehash) +{ + size_t point_r_sz = SX_ED25519_SZ; + char const *hash_array[] = {dom2, point_r, workmem + SX_ED25519_SZ, message}; + size_t *hash_array_lengths[] = {&dom2sz, &point_r_sz, &point_r_sz, &message_length}; + size_t input_count = prehash ? 4 : 3; + size_t offset = prehash ? 0 : 1; + + return hash_all_inputs(&hash_array[offset], &hash_array_lengths[offset], input_count, + &sxhashalg_sha2_512, workmem + SX_ED25519_SZ); +} + +int ed25519_sign_internal(const uint8_t *priv_key, char *signature, const uint8_t *message, + size_t message_length, int prehash) +{ + int status; + char workmem[5 * SX_ED25519_SZ]; + uint8_t pnt_r[SX_ED25519_DGST_SZ]; + char *area_1 = workmem; + char *area_2 = workmem + AREA2_MEM_OFFSET; + char *area_4 = workmem + AREA4_MEM_OFFSET; + + /*Hash the private key, the digest is stored in the first 64 bytes of workmem*/ + status = ed25519_hash_privkey(area_1, priv_key); + if (status != SX_OK) { + return status; + } + /* Obtain r by hashing (prefix || message), where prefix is the second + * half of the private key digest. + */ + status = ed25519_calculate_r(area_1, message, message_length, true); + if (status != SX_OK) { + return status; + } + /* 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 *)area_4, + (struct sx_ed25519_pt *)pnt_r); + if (status != SX_OK) { + return status; + } + /* The secret scalar s is computed in place from the first half of the + * private key digest. + */ + decode_scalar_25519(area_1); + + /* Clear second half of private key digest: sx_ed25519_ptmult() + * works on an input of SX_ED25519_DGST_SZ bytes. + */ + safe_memset(area_2, 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 *)(char *)area_1, + (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)(char *)area_2); + + if (status != SX_OK) { + return status; + } + + status = ed25519_calculate_k(area_1, pnt_r, message, message_length, prehash); + if (status != SX_OK) { + 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 pnt_r. + */ + + status = sx_ed25519_sign((const struct sx_ed25519_dgst *)(area_2), + (const struct sx_ed25519_dgst *)(area_4), + (const struct sx_ed25519_v *)area_1, + (struct sx_ed25519_v *)(pnt_r + SX_ED25519_PT_SZ)); + if (status != SX_OK) { + return status; + } + + memcpy(signature, pnt_r, SX_ED25519_DGST_SZ); + + return status; +} +int cracen_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 cracen_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 != SX_OK) { + return status; + } + return ed25519_sign_internal(priv_key, signature, hashedmessage, SX_ED25519_DGST_SZ, + true); + } else { + return ed25519_sign_internal(priv_key, signature, message, message_length, true); + } +} + +static int ed25519_verify_internal(const uint8_t *pub_key, const char *message, + size_t message_length, const char *signature, bool prehash) +{ + int status; + char digest[SX_ED25519_DGST_SZ]; + size_t ed25519_sz = SX_ED25519_SZ; + size_t input_count = prehash ? 4 : 3; + size_t offset = prehash ? 0 : 1; + + char const *hash_array[] = {dom2, (char *)signature, (char *)pub_key, (char *)message}; + size_t *hash_array_lengths[] = {&dom2sz, &ed25519_sz, &ed25519_sz, &message_length}; + + status = hash_all_inputs(&hash_array[offset], &hash_array_lengths[offset], input_count, + &sxhashalg_sha2_512, digest); + if (status != SX_OK) { + return status; + } + status = + sx_ed25519_verify((struct sx_ed25519_dgst *)digest, (struct sx_ed25519_pt *)pub_key, + (const struct sx_ed25519_v *)(signature + SX_ED25519_SZ), + (const struct sx_ed25519_pt *)signature); + + return status; +} + +int cracen_ed25519_verify(const uint8_t *pub_key, const char *message, size_t message_length, + const char *signature) +{ + return ed25519_verify_internal(pub_key, message, message_length, signature, false); +} + +int cracen_ed25519ph_verify(const uint8_t *pub_key, const char *message, size_t message_length, + const char *signature, int ismessage) +{ + int status; + char message_digest[SX_ED25519_DGST_SZ]; + + if (ismessage) { + status = ed25519_hash_message(message, message_length, message_digest); + if (status != SX_OK) { + return status; + } + return ed25519_verify_internal(pub_key, message_digest, SX_ED25519_DGST_SZ, + signature, true); + } + return ed25519_verify_internal(pub_key, message, message_length, signature, true); +} + +int cracen_ed25519_create_pubkey(const uint8_t *priv_key, uint8_t *pub_key) +{ + int status; + char digest[SX_ED25519_DGST_SZ]; + char *pub_key_A = digest + SX_ED25519_SZ; + + status = ed25519_hash_privkey(digest, priv_key); + if (status != SX_OK) { + return status; + } + /* The secret scalar s is computed in place from the first half of the + * private key digest. + */ + decode_scalar_25519(digest); + + /* Clear second half of private key digest: ed25519_ptmult_go() + * works on an input of SX_ED25519_DGST_SZ bytes. + */ + safe_memset(pub_key_A, 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 *)(digest), + (struct sx_ed25519_pt *)(struct sx_ed25519_pt *)((char *)pub_key_A)); + + if (status != SX_OK) { + return status; + } + + memcpy(pub_key, pub_key_A, 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 8eada3f22b00..0994ddcb8fb1 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,13 @@ 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 = cracen_ed25519_create_pubkey(key_buffer, data); + *data_length = expected_pub_key_size; + if (si_status != SX_OK) { + return silex_statuscodes_to_psa(si_status); } + 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..5e9e1028d114 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) || @@ -210,37 +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) { - pubkey->def = si_sig_def_ed25519; - + if (alg == PSA_ALG_PURE_EDDSA || alg == PSA_ALG_ED25519PH) { 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 = cracen_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,27 @@ 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 = + cracen_ed25519ph_sign(key_buffer, signature, input, input_length, message); + *signature_length = signature_size; + return silex_statuscodes_to_psa(si_status); + } else if (alg == PSA_ALG_PURE_EDDSA) { + si_status = cracen_ed25519_sign(key_buffer, signature, input, input_length); + *signature_length = signature_size; + 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 +300,22 @@ 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, + 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 = cracen_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 = cracen_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 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 )