Skip to content

Commit

Permalink
nrf_security: cracen: Add sign_digest support to sicrypto iksign
Browse files Browse the repository at this point in the history
Add support for sign_digest support to silex sicrypto drivers for
iksign.c, making it possible to sign_digest for the IKG.

Signed-off-by: Sigurd Hellesvik <sigurd.hellesvik@nordicsemi.no>
  • Loading branch information
hellesvik-nordic committed Dec 19, 2024
1 parent df37796 commit 5b35e9a
Showing 1 changed file with 59 additions and 9 deletions.
68 changes: 59 additions & 9 deletions subsys/nrf_security/src/drivers/cracen/sicrypto/src/iksig.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Other IK tasks don't need workmem memory.
*/

#include <string.h>
#include <silexpk/core.h>
#include <silexpk/iomem.h>
#include <sxsymcrypt/hash.h>
Expand Down Expand Up @@ -90,15 +91,15 @@ static int exit_ikg(struct sitask *t)
return SX_ERR_HW_PROCESSING;
}

static int start_ecdsa_ik_sign(struct sitask *t, struct siwq *wq);
static int start_ecdsa_ik_sign_wq(struct sitask *t, struct siwq *wq);

static int finish_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
{
(void)wq;

if ((t->statuscode == SX_ERR_INVALID_SIGNATURE) && (t->params.ik.attempts--)) {
sx_pk_release_req(t->pk);
si_wq_run_after(t, &t->params.ik.wq, start_ecdsa_ik_sign);
si_wq_run_after(t, &t->params.ik.wq, start_ecdsa_ik_sign_wq);
return (t->statuscode = SX_OK);
}

Expand All @@ -114,17 +115,12 @@ static int finish_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
return exit_ikg(t);
}

static int start_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
static int start_ecdsa_ik_sign(struct sitask *t)
{
struct sx_pk_acq_req pkreq;
struct sx_pk_inops_ik_ecdsa_sign inputs;
int opsz;
size_t digestsz = sx_hash_get_digestsz(&t->u.h);
(void)wq;

if (t->statuscode != SX_OK) {
return t->statuscode;
}

t->actions.status = si_silexpk_status;
t->actions.wait = si_silexpk_wait;
Expand All @@ -149,15 +145,47 @@ static int start_ecdsa_ik_sign(struct sitask *t, struct siwq *wq)
return SX_ERR_HW_PROCESSING;
}

static int start_ecdsa_ik_sign_wq(struct sitask *t, struct siwq *wq)
{
(void)wq;
if (t->statuscode != SX_OK) {
return t->statuscode;
}
return start_ecdsa_ik_sign(t);
}

static void run_ecdsa_ik_hash(struct sitask *t)
{
/* Override SX_ERR_HW_PROCESSING state pre-set by si_task_run()
* to be able to start the hash
*/
t->statuscode = SX_ERR_READY;
si_task_produce(t, t->workmem, sx_hash_get_digestsz(&t->u.h));
si_wq_run_after(t, &t->params.ik.wq, start_ecdsa_ik_sign_wq);
}

static void run_ik_sign(struct sitask *t)
{
start_ecdsa_ik_sign(t);
}

static void ik_sign_consume_digest(struct sitask *t, const char *data, size_t sz)
{
size_t digestsz = sx_hash_get_alg_digestsz(t->params.ik.privkey->hashalg);

if (sz < digestsz) {
si_task_mark_final(t, SX_ERR_INPUT_BUFFER_TOO_SMALL);
return;
} else if (sz > digestsz) {
si_task_mark_final(t, SX_ERR_TOO_BIG);
return;
}

si_wq_run_after(t, &t->params.ik.wq, start_ecdsa_ik_sign);
/* Copy the message digest to workmem. */
memcpy(t->workmem, data, sz);

t->actions.consume = NULL;
t->actions.run = run_ik_sign;
}

static void create_sign(struct sitask *t, const struct si_sig_privkey *privkey,
Expand All @@ -174,6 +202,27 @@ static void create_sign(struct sitask *t, const struct si_sig_privkey *privkey,
t->params.ik.signature = signature;
}


static void create_sign_digest(struct sitask *t, const struct si_sig_privkey *privkey,
struct si_sig_signature *signature)
{
size_t digestsz = sx_hash_get_alg_digestsz(privkey->hashalg);
size_t opsz = (size_t)sx_pk_curve_opsize(privkey->key.ref.curve);
size_t workmem_requirement = digestsz + opsz;

if (t->workmemsz < workmem_requirement) {
si_task_mark_final(t, SX_ERR_WORKMEM_BUFFER_TOO_SMALL);
return;
}

t->actions = (struct siactions){0};
t->statuscode = SX_ERR_READY;
t->actions.consume = ik_sign_consume_digest;
t->params.ik.privkey = privkey;
t->params.ik.signature = signature;
}


static int finish_ik_pubkey(struct sitask *t, struct siwq *wq)
{
(void)wq;
Expand Down Expand Up @@ -228,6 +277,7 @@ static void create_pubkey(struct sitask *t, const struct si_sig_privkey *privkey

static const struct si_sig_def si_sig_def_ik = {
.sign = create_sign,
.sign_digest = create_sign_digest,
.pubkey = create_pubkey,
};

Expand Down

0 comments on commit 5b35e9a

Please sign in to comment.