Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No sicrypto ecdsa #20136

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ list(APPEND cracen_driver_sources
${CMAKE_CURRENT_LIST_DIR}/src/common.c
${CMAKE_CURRENT_LIST_DIR}/src/mem_helpers.c
${CMAKE_CURRENT_LIST_DIR}/src/ec_helpers.c
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
${CMAKE_CURRENT_LIST_DIR}/src/rndinrange.c

# Note: We always need to have blkcipher.c and ctr_drbg.c since it
# is used directly by many Cracen drivers.
Expand Down Expand Up @@ -44,7 +46,10 @@ 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/ecdsa.c
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c
${CMAKE_CURRENT_LIST_DIR}/src/hmac.c
)
endif()

Expand All @@ -62,8 +67,11 @@ 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
${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c
${CMAKE_CURRENT_LIST_DIR}/src/ecdsa.c
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
)
endif()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,44 @@ int cracen_ed25519ph_verify(const uint8_t *pub_key, const char *message, size_t

int cracen_ed25519_create_pubkey(const uint8_t *priv_key, uint8_t *pub_key);

int be_cmp(const unsigned char *a, const unsigned char *b, size_t sz, int carry);

int ecc_create_genpubkey(const char *priv_key, char *pub_key, const struct sx_pk_ecurve *curve);

int ecc_create_genprivkey(const struct sx_pk_ecurve *curve, char *priv_key, size_t priv_key_size);

int cracen_ecdsa_verify_message(const char *pubkey, const struct sxhashalg *hashalg,
const uint8_t *message, size_t message_length,
const struct sx_pk_ecurve *curve, const uint8_t *signature);

int cracen_ecdsa_verify_digest(const char *pubkey, const uint8_t *digest, size_t digestsz,
const struct sx_pk_ecurve *curve, const uint8_t *signature);

int cracen_ecdsa_sign_message(const struct ecc_priv_key *privkey, const struct sxhashalg *hashalg,
const struct sx_pk_ecurve *curve, const uint8_t *message,
size_t message_length, const uint8_t *signature);

int cracen_ecdsa_sign_digest(const struct ecc_priv_key *privkey, const struct sxhashalg *hashalg,
const struct sx_pk_ecurve *curve, const uint8_t *digest,
size_t digest_length, const uint8_t *signature);

int cracen_ecdsa_sign_message_deterministic(const struct ecc_priv_key *privkey,
const struct sxhashalg *hashalg,
const struct sx_pk_ecurve *curve,
const uint8_t *message, size_t message_length,
const uint8_t *signature);

int cracen_ecdsa_sign_digest_deterministic(const struct ecc_priv_key *privkey,
const struct sxhashalg *hashalg,
const struct sx_pk_ecurve *curve, const uint8_t *digest,
size_t digestsz, const uint8_t *signature);

int rndinrange_create(const unsigned char *n, size_t nsz, unsigned char *out);

int mac_create_hmac(const struct sxhashalg *hashalg, struct sxhash *hashopctx, const char *key,
size_t keysz, char *workmem, size_t workmemsz);

int hmac_produce(struct sxhash *hashctx, const struct sxhashalg *hashalg, char *out, size_t sz,
char *workmem);

#endif /* CRACEN_PSA_H */
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,27 @@ struct cracen_pake_operation {
};
};
typedef struct cracen_pake_operation cracen_pake_operation_t;

struct sx_pk_ecurve;

struct ecdsa_signature {
size_t sz; /**< Total signature size, in bytes. */
const char *r; /**< Signature element "r". */
const char *s; /**< Signature element "s". */
};
struct ecc_priv_key {
const struct sx_pk_ecurve *curve;
const char *d; /** Privat key value d */
};

struct ecc_pub_key {
const struct sx_pk_ecurve *curve;
char *qx; /** x coordinate of a point on the curve */
char *qy; /** y coordinate of a point on the curve */
};

struct ecc_keypair {
struct ecc_priv_key priv_key;
struct ecc_pub_key pub_key;
};
#endif /* CRACEN_PSA_PRIMITIVES_H */
67 changes: 67 additions & 0 deletions subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,3 +852,70 @@ psa_status_t cracen_get_opaque_size(const psa_key_attributes_t *attributes, size

return PSA_ERROR_INVALID_ARGUMENT;
}

void be_add(unsigned char *v, size_t sz, size_t summand)
{
while (sz > 0) {
sz--;
summand += v[sz];
v[sz] = summand & 0xFF;
summand >>= 8;
}
}

int be_cmp(const unsigned char *a, const unsigned char *b, size_t sz, int carry)
{
unsigned int neq = 0;
unsigned int gt = 0;
unsigned int ucarry;
unsigned int d;
unsigned int lt;

/* transform carry to work with unsigned numbers */
ucarry = 0x100 + carry;

for (int i = sz - 1; i >= 0; i--) {
d = ucarry + a[i] - b[i];
ucarry = 0xFF + (d >> 8);
neq |= d & 0xFF;
}

neq |= ucarry & 0xFF;
lt = ucarry < 0x100;
gt = neq && !lt;

return (gt ? 1 : 0) - (lt ? 1 : 0);
}

int hash_all_inputs(const char *inputs[], const size_t inputs_lengths[], size_t input_count,
const struct sxhashalg *hashalg, char *digest)
{
int status;
struct sxhash hashopctx;

status = sx_hash_create(&hashopctx, hashalg, sizeof(hashopctx));
if (status != SX_OK) {
return status;
}

for (size_t i = 0; i < input_count; i++) {
status = sx_hash_feed(&hashopctx, inputs[i], inputs_lengths[i]);
if (status != SX_OK) {
return status;
}
}
status = sx_hash_digest(&hashopctx, digest);
if (status != SX_OK) {
return status;
}

status = sx_hash_wait(&hashopctx);

return status;
}

int hash_input(const char *input, const size_t input_length, const struct sxhashalg *hashalg,
char *digest)
{
return hash_all_inputs(&input, &input_length, 1, hashalg, digest);
}
51 changes: 51 additions & 0 deletions subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,54 @@ psa_status_t cracen_cipher_crypt_ecb(const struct sxkeyref *key, const uint8_t *
* @return sxsymcrypt error code.
*/
int cracen_prepare_ik_key(const uint8_t *user_data);

/**
* @brief Big-Endian addition.
*
* @param v Big-endian Value
* @param v_size size of v
* @param summand Summand.
*
*/
void be_add(unsigned char *v, size_t v_size, size_t summand);

/**
* @brief Big-Endian compare with carry.
*
* @param a First value to be compared
* @param b Second value to be compared
* @param size Size of a and b.
* @param carry Value of the carry.
*
* \retval 0 if equal.
* \retval 1 if a > b.
* \retval -1 if a < b.
*/
int be_cmp(const unsigned char *a, const unsigned char *b, size_t sz, int carry);

/**
* @brief Hash several elements at different locations in memory
*
* @param inputs[in] Array of pointers to elements that will be hashed.
* @param inputs_lengths[in] Array of lengths of elements to be hashed.
* @param input_count[in] Number of elements to be hashed.
* @param hashalg[in] Hash algorithm to be used in sxhashalg format.
* @param digest[out] Buffer of at least sx_hash_get_alg_digestsz(hashalg) bytes.
*
* @return sxsymcrypt error code.
*/
int hash_all_inputs(const char *inputs[], const size_t inputs_lengths[], size_t input_count,
const struct sxhashalg *hashalg, char *digest);

/**
* @brief Hash a single element
*
* @param inputs[in] Pointer to elements that will be hashed.
* @param inputs_lengths[in] Length of element to be hashed.
* @param hashalg[in] hash algorithm to be used in sxhashalg format.
* @param digest[out] Buffer of at least sx_hash_get_alg_digestsz(hashalg) bytes.
*
* @return sxsymcrypt error code.
*/
int hash_input(const char *input, const size_t input_length, const struct sxhashalg *hashalg,
char *digest);
87 changes: 87 additions & 0 deletions subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ecc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* ECC key pair generation.
* Based on FIPS 186-4, section B.4.2 "Key Pair Generation by Testing
* Candidates".
*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <string.h>
#include <silexpk/core.h>
#include <silexpk/iomem.h>
#include <silexpk/cmddefs/ecc.h>
#include <cracen/statuscodes.h>
#include "cracen_psa.h"

#define MAX_ECC_ATTEMPTS 10

int ecc_create_genpubkey(const char *priv_key, char *pub_key, const struct sx_pk_ecurve *curve)
{
const char **outputs;
struct sx_pk_acq_req pkreq;
struct sx_pk_inops_ecp_mult inputs;
int opsz;
int status;

for (int i = 0; i <= MAX_ECC_ATTEMPTS; i++) {
pkreq = sx_pk_acquire_req(SX_PK_CMD_ECC_PTMUL);
if (pkreq.status) {
return pkreq.status;
}
pkreq.status = sx_pk_list_ecc_inslots(pkreq.req, curve, 0,
(struct sx_pk_slot *)&inputs);
if (pkreq.status) {
return pkreq.status;
}

opsz = sx_pk_curve_opsize(curve);

/* Write the private key (random) into ba414ep device memory */
sx_wrpkmem(inputs.k.addr, priv_key, opsz);
sx_pk_write_curve_gen(pkreq.req, curve, inputs.px, inputs.py);

sx_pk_run(pkreq.req);

status = sx_pk_wait(pkreq.req);
if (status != SX_OK) {
return status;
}
outputs = sx_pk_get_output_ops(pkreq.req);

/* When countermeasures are used, the operation may fail with error code
* SX_ERR_NOT_INVERTIBLE. In this case we can try again.
*/
if (status == SX_ERR_NOT_INVERTIBLE) {
sx_pk_release_req(pkreq.req);
if (i == MAX_ECC_ATTEMPTS) {
return SX_ERR_TOO_MANY_ATTEMPTS;
}
} else {
break;
}
}
sx_rdpkmem(pub_key, outputs[0], opsz);
sx_rdpkmem(pub_key + opsz, outputs[1], opsz);
sx_pk_release_req(pkreq.req);
return status;
}

int ecc_create_genprivkey(const struct sx_pk_ecurve *curve, char *priv_key, size_t priv_key_size)
{
int status;
int opsz = sx_pk_curve_opsize(curve);
const char *curve_n = sx_pk_curve_order(curve);
size_t keysz = (size_t)sx_pk_curve_opsize(curve);

if (priv_key_size < keysz) {
return SX_ERR_OUTPUT_BUFFER_TOO_SMALL;
}

/* generate private key, a random number in [1, n-1], where n is the curve
* order
*/
status = rndinrange_create((const unsigned char *)curve_n, opsz, priv_key);

return status;
}
Loading
Loading