Skip to content

Commit 348f406

Browse files
committed
[ot] hw/opentitan: ot_hmac: Digest size write should not affect current hash
This commit updates the functionality for the HMAC's digest size configuration register field, updating it to match the current hardware behaviour. The hardware uses a `digest_size_started` field to allow the user to write a digest size at any time, while ensuring that if a hash is in progress it will carry on using the existing digest size. A similar field is introduced into the context/state struct to allow the QEMU HMAC model to keep track of the digest size when the last START/CONTINUE command was sent, and use that in place of checking the register value every time.
1 parent b9aa9ff commit 348f406

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

hw/opentitan/ot_hmac.c

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,22 @@ static const char *REG_NAMES[REGS_COUNT] = {
223223
};
224224
#undef REG_NAME_ENTRY
225225

226+
enum OtHMACDigestSize {
227+
HMAC_SHA2_256,
228+
HMAC_SHA2_384,
229+
HMAC_SHA2_512,
230+
HMAC_SHA2_NONE,
231+
};
232+
233+
enum OtHMACKeyLength {
234+
HMAC_KEY_128,
235+
HMAC_KEY_256,
236+
HMAC_KEY_384,
237+
HMAC_KEY_512,
238+
HMAC_KEY_1024,
239+
HMAC_KEY_NONE,
240+
};
241+
226242
struct OtHMACRegisters {
227243
uint32_t intr_state;
228244
uint32_t intr_enable;
@@ -239,6 +255,7 @@ typedef struct OtHMACRegisters OtHMACRegisters;
239255

240256
struct OtHMACContext {
241257
hash_state state;
258+
enum OtHMACDigestSize digest_size_started;
242259
};
243260
typedef struct OtHMACContext OtHMACContext;
244261

@@ -260,22 +277,6 @@ struct OtHMACState {
260277
char *ot_id;
261278
};
262279

263-
enum OtHMACDigestSize {
264-
HMAC_SHA2_256,
265-
HMAC_SHA2_384,
266-
HMAC_SHA2_512,
267-
HMAC_SHA2_NONE,
268-
};
269-
270-
enum OtHMACKeyLength {
271-
HMAC_KEY_128,
272-
HMAC_KEY_256,
273-
HMAC_KEY_384,
274-
HMAC_KEY_512,
275-
HMAC_KEY_1024,
276-
HMAC_KEY_NONE,
277-
};
278-
279280
static inline enum OtHMACDigestSize ot_hmac_get_digest_size(uint32_t cfg_reg)
280281
{
281282
switch ((cfg_reg & R_CFG_DIGEST_SIZE_MASK) >> R_CFG_DIGEST_SIZE_SHIFT) {
@@ -291,9 +292,9 @@ static inline enum OtHMACDigestSize ot_hmac_get_digest_size(uint32_t cfg_reg)
291292
}
292293
}
293294

294-
static inline size_t ot_hmac_get_digest_bytes(OtHMACState *s)
295+
static inline size_t ot_hmac_get_digest_bytes(enum OtHMACDigestSize digest_size)
295296
{
296-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
297+
switch (digest_size) {
297298
case HMAC_SHA2_256:
298299
return 32u;
299300
case HMAC_SHA2_384:
@@ -399,7 +400,7 @@ static void ot_hmac_writeback_digest_state(OtHMACState *s)
399400
{
400401
/* copy intermediary digest to mock HMAC operation for stop/continue
401402
behaviour. */
402-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
403+
switch (s->ctx->digest_size_started) {
403404
case HMAC_SHA2_256:
404405
for (unsigned idx = 0; idx < 8u; idx++) {
405406
STORE32H(s->ctx->state.sha256.state[idx], s->regs->digest + idx);
@@ -426,7 +427,7 @@ static void ot_hmac_writeback_digest_state(OtHMACState *s)
426427

427428
static void ot_hmac_restore_context(OtHMACState *s)
428429
{
429-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
430+
switch (s->ctx->digest_size_started) {
430431
case HMAC_SHA2_256:
431432
s->ctx->state.sha256.curlen = 0;
432433
s->ctx->state.sha256.length = s->regs->msg_length;
@@ -458,7 +459,7 @@ static void ot_hmac_restore_context(OtHMACState *s)
458459

459460
static size_t ot_hmac_get_curlen(OtHMACState *s)
460461
{
461-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
462+
switch (s->ctx->digest_size_started) {
462463
case HMAC_SHA2_256:
463464
return s->ctx->state.sha256.curlen;
464465
case HMAC_SHA2_384:
@@ -476,7 +477,7 @@ static size_t ot_hmac_get_curlen(OtHMACState *s)
476477

477478
static void ot_hmac_sha_init(OtHMACState *s, bool write_back)
478479
{
479-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
480+
switch (s->ctx->digest_size_started) {
480481
case HMAC_SHA2_256:
481482
sha256_init(&s->ctx->state);
482483
break;
@@ -502,7 +503,7 @@ static void ot_hmac_sha_init(OtHMACState *s, bool write_back)
502503
static void ot_hmac_sha_process(OtHMACState *s, const uint8_t *in, size_t inlen,
503504
bool write_back)
504505
{
505-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
506+
switch (s->ctx->digest_size_started) {
506507
case HMAC_SHA2_256:
507508
sha256_process(&s->ctx->state, in, inlen);
508509
break;
@@ -528,7 +529,7 @@ static void ot_hmac_sha_process(OtHMACState *s, const uint8_t *in, size_t inlen,
528529

529530
static void ot_hmac_sha_done(OtHMACState *s)
530531
{
531-
switch (ot_hmac_get_digest_size(s->regs->cfg)) {
532+
switch (s->ctx->digest_size_started) {
532533
case HMAC_SHA2_256:
533534
sha256_done(&s->ctx->state, (uint8_t *)s->regs->digest);
534535
return;
@@ -571,7 +572,9 @@ static void ot_hmac_compute_digest(OtHMACState *s)
571572
ot_hmac_sha_init(s, false);
572573
ot_hmac_sha_process(s, (const uint8_t *)opad, pad_length_b, false);
573574
ot_hmac_sha_process(s, (const uint8_t *)s->regs->digest,
574-
ot_hmac_get_digest_bytes(s), true);
575+
ot_hmac_get_digest_bytes(
576+
s->ctx->digest_size_started),
577+
true);
575578
}
576579
ot_hmac_sha_done(s);
577580
}
@@ -911,6 +914,10 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
911914

912915
ibex_irq_set(&s->clkmgr, true);
913916

917+
/* Hold the previous digest size until the HMAC is started with the
918+
new digest size configured */
919+
s->ctx->digest_size_started = ot_hmac_get_digest_size(s->regs->cfg);
920+
914921
ot_hmac_sha_init(s, true);
915922

916923
/* HMAC mode, process input padding */
@@ -976,6 +983,10 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
976983

977984
s->regs->cmd = R_CMD_HASH_CONTINUE_MASK;
978985

986+
/* Hold the previous digest size until the HMAC is started with the
987+
new digest size configured */
988+
s->ctx->digest_size_started = ot_hmac_get_digest_size(s->regs->cfg);
989+
979990
ot_hmac_restore_context(s);
980991

981992
/* trigger delayed processing of FIFO */

0 commit comments

Comments
 (0)