Skip to content

Commit 9bb70c5

Browse files
committed
nrf_security: drivers: cracen: Implement ECDSA in cracenpsa
Add support for ECDSA in cracenpsa dirctly using silexpk/sxsymcrypt This bypasses sicrypto, which saves on flash usage Remove sicrypto implementation of ECDSA from being accessible from cracenpsa. Signed-off-by: Dag Erik Gjørvad <dag.erik.gjorvad@nordicsemi.no>
1 parent db636a5 commit 9bb70c5

File tree

13 files changed

+1139
-153
lines changed

13 files changed

+1139
-153
lines changed

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

+10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ list(APPEND cracen_driver_sources
1515
${CMAKE_CURRENT_LIST_DIR}/src/common.c
1616
${CMAKE_CURRENT_LIST_DIR}/src/mem_helpers.c
1717
${CMAKE_CURRENT_LIST_DIR}/src/ec_helpers.c
18+
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
19+
${CMAKE_CURRENT_LIST_DIR}/src/rndinrange.c
20+
${CMAKE_CURRENT_LIST_DIR}/src/util.c
1821

1922
# Note: We always need to have blkcipher.c and ctr_drbg.c since it
2023
# is used directly by many Cracen drivers.
@@ -44,7 +47,11 @@ endif()
4447
if(CONFIG_PSA_NEED_CRACEN_ASYMMETRIC_SIGNATURE_DRIVER)
4548
list(APPEND cracen_driver_sources
4649
${CMAKE_CURRENT_LIST_DIR}/src/sign.c
50+
${CMAKE_CURRENT_LIST_DIR}/src/ecdsa.c
51+
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
4752
${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c
53+
${CMAKE_CURRENT_LIST_DIR}/src/util.c
54+
${CMAKE_CURRENT_LIST_DIR}/src/hmac.c
4855
)
4956
endif()
5057

@@ -62,7 +69,10 @@ endif()
6269

6370
if(CONFIG_PSA_NEED_CRACEN_KEY_MANAGEMENT_DRIVER OR CONFIG_PSA_NEED_CRACEN_KMU_DRIVER OR CONFIG_MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
6471
list(APPEND cracen_driver_sources
72+
${CMAKE_CURRENT_LIST_DIR}/src/ed25519.c
6573
${CMAKE_CURRENT_LIST_DIR}/src/key_management.c
74+
${CMAKE_CURRENT_LIST_DIR}/src/ecdsa.c
75+
${CMAKE_CURRENT_LIST_DIR}/src/ecc.c
6676
)
6777
endif()
6878

subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h

+44
Original file line numberDiff line numberDiff line change
@@ -375,4 +375,48 @@ int cracen_ed25519ph_verify(const uint8_t *pub_key, const char *message, size_t
375375

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

378+
int be_cmp(const unsigned char *a, const unsigned char *b, size_t sz, int carry);
379+
380+
int ecc_create_genpubkey(const char *priv_key, char *pub_key, const struct sx_pk_ecurve *curve);
381+
382+
int ecc_create_genprivkey(const struct sx_pk_ecurve *curve, char *priv_key, size_t priv_key_size);
383+
384+
int cracen_ecdsa_verify_message(char *pubkey, const struct sxhashalg *hashalg,
385+
const uint8_t *message, size_t message_length,
386+
const struct sx_pk_ecurve *curve, const uint8_t *signature);
387+
388+
int cracen_ecdsa_verify_digest(char *pubkey, const struct sxhashalg *hashalg, const uint8_t *digest,
389+
size_t digestsz, const struct sx_pk_ecurve *curve,
390+
const uint8_t *signature);
391+
392+
int cracen_ecdsa_sign_message(const struct eccsk *privkey, size_t privkey_size,
393+
const struct sxhashalg *hashalg, const struct sx_pk_ecurve *curve,
394+
const uint8_t *message, size_t message_length, uint8_t *signature,
395+
size_t signature_size, size_t *signature_length);
396+
397+
int cracen_ecdsa_sign_digest(const struct eccsk *privkey, size_t privkey_size,
398+
const struct sxhashalg *hashalg, const struct sx_pk_ecurve *curve,
399+
const uint8_t *message, size_t message_length, uint8_t *signature,
400+
size_t signature_size, size_t *signature_length);
401+
402+
int cracen_ecdsa_sign_message_deterministic(const struct eccsk *privkey, size_t privkey_size,
403+
const struct sxhashalg *hashalg,
404+
const struct sx_pk_ecurve *curve, const uint8_t *digest,
405+
size_t digest_length, uint8_t *signature,
406+
size_t signature_size, size_t *signature_length);
407+
408+
int cracen_ecdsa_sign_digest_deterministic(const struct eccsk *privkey, size_t privkey_size,
409+
const struct sxhashalg *hashalg,
410+
const struct sx_pk_ecurve *curve, const uint8_t *digest,
411+
size_t digest_length, uint8_t *signature,
412+
size_t signature_size, size_t *signature_length);
413+
414+
int rndinrange_create(const unsigned char *n, size_t nsz, unsigned char *out);
415+
416+
int mac_create_hmac(const struct sxhashalg *hashalg, struct sxhash *hashopctx, const char *key,
417+
size_t keysz, char *workmem, size_t workmemsz);
418+
419+
int hmac_produce(struct sxhash *hashctx, const struct sxhashalg *hashalg, char *out, size_t sz,
420+
char *workmem);
421+
378422
#endif /* CRACEN_PSA_H */

subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa_primitives.h

+23
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,27 @@ struct cracen_pake_operation {
371371
};
372372
};
373373
typedef struct cracen_pake_operation cracen_pake_operation_t;
374+
375+
struct sx_pk_ecurve;
376+
377+
struct ecdsa_signature {
378+
size_t sz; /**< Total signature size, in bytes. */
379+
char *r; /**< Signature element "r". */
380+
char *s; /**< Signature element "s". */
381+
};
382+
struct eccsk {
383+
const struct sx_pk_ecurve *curve;
384+
char *d;
385+
};
386+
387+
struct eccpk {
388+
const struct sx_pk_ecurve *curve;
389+
char *qx;
390+
char *qy;
391+
};
392+
393+
struct ecc_keypair {
394+
struct eccsk sk;
395+
struct eccpk pk;
396+
};
374397
#endif /* CRACEN_PSA_PRIMITIVES_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* ECC key pair generation.
2+
* Based on FIPS 186-4, section B.4.2 "Key Pair Generation by Testing
3+
* Candidates".
4+
*
5+
* Copyright (c) 2023 Nordic Semiconductor ASA
6+
*
7+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
8+
*/
9+
10+
#include <string.h>
11+
#include <silexpk/core.h>
12+
#include <silexpk/iomem.h>
13+
#include <silexpk/cmddefs/ecc.h>
14+
#include <cracen/statuscodes.h>
15+
#include "cracen_psa.h"
16+
17+
#define MAX_ECC_ATTEMPTS 10
18+
19+
int ecc_create_genpubkey(const char *priv_key, char *pub_key, const struct sx_pk_ecurve *curve)
20+
{
21+
const char **outputs;
22+
struct sx_pk_acq_req pkreq;
23+
struct sx_pk_inops_ecp_mult inputs;
24+
int opsz;
25+
int status;
26+
27+
for (int i = 0; i <= MAX_ECC_ATTEMPTS; i++) {
28+
pkreq = sx_pk_acquire_req(SX_PK_CMD_ECC_PTMUL);
29+
if (pkreq.status) {
30+
return pkreq.status;
31+
}
32+
pkreq.status =
33+
sx_pk_list_ecc_inslots(pkreq.req, curve, 0, (struct sx_pk_slot *)&inputs);
34+
if (pkreq.status) {
35+
return pkreq.status;
36+
}
37+
38+
opsz = sx_pk_curve_opsize(curve);
39+
40+
/* Write the private key (random) into ba414ep device memory */
41+
sx_wrpkmem(inputs.k.addr, priv_key, opsz);
42+
sx_pk_write_curve_gen(pkreq.req, curve, inputs.px, inputs.py);
43+
44+
sx_pk_run(pkreq.req);
45+
46+
status = sx_pk_has_finished(pkreq.req);
47+
48+
status = sx_pk_wait(pkreq.req);
49+
if (status != SX_OK) {
50+
return status;
51+
}
52+
/* static int on_generated_public(struct sitask *t, struct siwq *wq) */
53+
outputs = sx_pk_get_output_ops(pkreq.req);
54+
55+
/* When countermeasures are used, the operation may fail with error code
56+
* SX_ERR_NOT_INVERTIBLE. In this case we can try again.
57+
*/
58+
if (status == SX_ERR_NOT_INVERTIBLE) {
59+
sx_pk_release_req(pkreq.req);
60+
if (i == MAX_ECC_ATTEMPTS) {
61+
return SX_ERR_TOO_MANY_ATTEMPTS;
62+
}
63+
} else {
64+
break;
65+
}
66+
}
67+
sx_rdpkmem(pub_key, outputs[0], opsz);
68+
sx_rdpkmem(pub_key + opsz, outputs[1], opsz);
69+
sx_pk_release_req(pkreq.req);
70+
return status;
71+
}
72+
73+
int ecc_create_genprivkey(const struct sx_pk_ecurve *curve, char *priv_key, size_t priv_key_size)
74+
{
75+
size_t keysz = (size_t)sx_pk_curve_opsize(curve);
76+
int status;
77+
int opsz = sx_pk_curve_opsize(curve);
78+
const char *curve_n = sx_pk_curve_order(curve);
79+
80+
if (priv_key_size < keysz) {
81+
return SX_ERR_OUTPUT_BUFFER_TOO_SMALL;
82+
}
83+
84+
/* generate private key, a random in [1, n-1], where n is the curve
85+
* order
86+
*/
87+
status = rndinrange_create((const unsigned char *)curve_n, opsz, priv_key);
88+
89+
return status;
90+
}

0 commit comments

Comments
 (0)