Skip to content

Commit 68a8807

Browse files
AlexJones0jwnrt
authored andcommitted
[ot] hw/opentitan: ot_hmac: Restore correct msg_length with HMAC_EN
HMAC can operate either with HMAC_EN, using HMAC algorithms, or without, using standard SHA algorithms. The HMAC algorithms introduce additional logic surrounding a key, and inner and outer padding. Relevant to this commit is that when computing HMAC, we first process a block of inner padding XORed with the key. This means that the message length reported to software in the msg_length register diverges from the message length reported by the tomcrypt cryptographic library's state. Specifically, with HMAC_EN=1, it undercounts by a block. This caused an error where, when saving and restoring context with HMAC_EN=1, the hash length would be undercounted by a block and thus the incorrect digest would be computed. This meant that save/restore and streaming operations were not working properly with HMAC_EN. This commit introduces the additional logic to fix this edge case. Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
1 parent 4ca0add commit 68a8807

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

hw/opentitan/ot_hmac.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* QEMU OpenTitan HMAC device
33
*
44
* Copyright (c) 2022-2024 Rivos, Inc.
5-
* Copyright (c) 2024 lowRISC contributors.
5+
* Copyright (c) 2024-2025 lowRISC contributors.
66
*
77
* Author(s):
88
* Loïc Lefort <loic@rivosinc.com>
@@ -443,10 +443,21 @@ static void ot_hmac_writeback_digest_state(OtHMACState *s)
443443

444444
static void ot_hmac_restore_context(OtHMACState *s)
445445
{
446+
/*
447+
* When restoring context, if HMAC is enabled we must add the block size to
448+
* the message length to keep our cryptographic library consistent with the
449+
* SW interface. This is because the extra block containing the key XORed
450+
* with the inner pad is not included in the SW-visible message length.
451+
*/
452+
unsigned msg_length = s->regs->msg_length;
453+
if (s->regs->cfg & R_CFG_HMAC_EN_MASK) {
454+
msg_length += ot_hmac_get_block_size_bytes(s) * 8u;
455+
}
456+
446457
switch (s->ctx->digest_size_started) {
447458
case HMAC_SHA2_256:
448459
s->ctx->state.sha256.curlen = 0;
449-
s->ctx->state.sha256.length = s->regs->msg_length;
460+
s->ctx->state.sha256.length = msg_length;
450461
for (unsigned idx = 0; idx < 8u; idx++) {
451462
LOAD32H(s->ctx->state.sha256.state[idx], s->regs->digest + idx);
452463
}
@@ -458,7 +469,7 @@ static void ot_hmac_restore_context(OtHMACState *s)
458469
*/
459470
case HMAC_SHA2_512:
460471
s->ctx->state.sha512.curlen = 0;
461-
s->ctx->state.sha512.length = s->regs->msg_length;
472+
s->ctx->state.sha512.length = msg_length;
462473
for (unsigned idx = 0; idx < 8u; idx++) {
463474
LOAD64H(s->ctx->state.sha512.state[idx], s->regs->digest + 2 * idx);
464475
}

0 commit comments

Comments
 (0)