From 71412f879c3e93bf3cd4e6e30bdc5cc84ef6667f Mon Sep 17 00:00:00 2001 From: Fatih Balli Date: Mon, 6 May 2024 15:12:07 +0000 Subject: [PATCH 1/4] [driver, hmac] Add streaming calls to HMAC driver Adds streaming functions to HMAC driver that supports SHA/HMAC-256/384/512. Signed-off-by: Fatih Balli --- sw/device/lib/crypto/drivers/hmac.c | 487 ++++++++++++++++++++++------ sw/device/lib/crypto/drivers/hmac.h | 189 ++++++++--- 2 files changed, 526 insertions(+), 150 deletions(-) diff --git a/sw/device/lib/crypto/drivers/hmac.c b/sw/device/lib/crypto/drivers/hmac.c index d4a2a5ed2e148..536e081d4dc85 100644 --- a/sw/device/lib/crypto/drivers/hmac.c +++ b/sw/device/lib/crypto/drivers/hmac.c @@ -8,6 +8,7 @@ #include "sw/device/lib/base/bitfield.h" #include "sw/device/lib/base/hardened.h" #include "sw/device/lib/base/memory.h" +#include "sw/device/lib/crypto/impl/status.h" #include "hmac_regs.h" // Generated. #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" @@ -15,141 +16,415 @@ // Module ID for status codes. #define MODULE_ID MAKE_MODULE_ID('d', 'h', 'm') +OT_ASSERT_ENUM_VALUE(HMAC_KEY_1_REG_OFFSET, HMAC_KEY_0_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_2_REG_OFFSET, HMAC_KEY_1_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_3_REG_OFFSET, HMAC_KEY_2_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_4_REG_OFFSET, HMAC_KEY_3_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_5_REG_OFFSET, HMAC_KEY_4_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_6_REG_OFFSET, HMAC_KEY_5_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_7_REG_OFFSET, HMAC_KEY_6_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_8_REG_OFFSET, HMAC_KEY_7_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_9_REG_OFFSET, HMAC_KEY_8_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_10_REG_OFFSET, HMAC_KEY_9_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_11_REG_OFFSET, HMAC_KEY_10_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_12_REG_OFFSET, HMAC_KEY_11_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_13_REG_OFFSET, HMAC_KEY_12_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_14_REG_OFFSET, HMAC_KEY_13_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_15_REG_OFFSET, HMAC_KEY_14_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_16_REG_OFFSET, HMAC_KEY_15_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_17_REG_OFFSET, HMAC_KEY_16_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_18_REG_OFFSET, HMAC_KEY_17_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_19_REG_OFFSET, HMAC_KEY_18_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_20_REG_OFFSET, HMAC_KEY_19_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_21_REG_OFFSET, HMAC_KEY_20_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_22_REG_OFFSET, HMAC_KEY_21_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_23_REG_OFFSET, HMAC_KEY_22_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_24_REG_OFFSET, HMAC_KEY_23_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_25_REG_OFFSET, HMAC_KEY_24_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_26_REG_OFFSET, HMAC_KEY_25_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_27_REG_OFFSET, HMAC_KEY_26_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_28_REG_OFFSET, HMAC_KEY_27_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_29_REG_OFFSET, HMAC_KEY_28_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_30_REG_OFFSET, HMAC_KEY_29_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_KEY_31_REG_OFFSET, HMAC_KEY_30_REG_OFFSET + 4); + +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_1_REG_OFFSET, HMAC_DIGEST_0_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_2_REG_OFFSET, HMAC_DIGEST_1_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_3_REG_OFFSET, HMAC_DIGEST_2_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_4_REG_OFFSET, HMAC_DIGEST_3_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_5_REG_OFFSET, HMAC_DIGEST_4_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_6_REG_OFFSET, HMAC_DIGEST_5_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_7_REG_OFFSET, HMAC_DIGEST_6_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_8_REG_OFFSET, HMAC_DIGEST_7_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_9_REG_OFFSET, HMAC_DIGEST_8_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_10_REG_OFFSET, HMAC_DIGEST_9_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_11_REG_OFFSET, HMAC_DIGEST_10_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_12_REG_OFFSET, HMAC_DIGEST_11_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_13_REG_OFFSET, HMAC_DIGEST_12_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_14_REG_OFFSET, HMAC_DIGEST_13_REG_OFFSET + 4); +OT_ASSERT_ENUM_VALUE(HMAC_DIGEST_15_REG_OFFSET, HMAC_DIGEST_14_REG_OFFSET + 4); + +/** + * The following values are the only key sizes supported natively bw HWIP. + */ +enum { + /* The beginning of the address space of HMAC. */ + kHmacBaseAddr = TOP_EARLGREY_HMAC_BASE_ADDR, + /* Internal block size for SHA-256/HMAC-256 in bits. */ + kHmacSha256InternalBlockBits = 512, + kHmacSha256InternalBlockBytes = kHmacSha256InternalBlockBits / 8, + /* Internal block size for SHA-384/HMAC-384 in bits. */ + kHmacSha384InternalBlockBits = 1024, + kHmacSha384InternalBlockBytes = kHmacSha384InternalBlockBits / 8, + /* Internal block size for SHA-512/HMAC-512 in bits. */ + kHmacSha512InternalBlockBits = 1024, + kHmacSha512InternalBlockBytes = kHmacSha512InternalBlockBits / 8, +}; + /** - * Stop any current operation on the HMAC block. + * Wait until HMAC raises `hmac_done` interrupt. After interrupt is observed, + * clear it. * - * In addition to stopping any in-progress operation, this routine: - * - clears secret internal values and keys using the WIPE_SECRET register. - * - disables and clears interrupts. + * TODO(#23191): Avoid constant loop and use to-be-implemented Idle/status bit + * instead. */ -static void hmac_halt(void) { - // Clear the config, which stops operation if the HMAC block was running. - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_CFG_REG_OFFSET, 0); - - // Wipe secrets (e.g. key). - // TODO: this value is used directy by the HMAC hardware to overwrite the - // key; replace it with a random number read from Ibex's RND. - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_WIPE_SECRET_REG_OFFSET, - 0xffffffff); - - // Disable and clear interrupts. INTR_STATE register is rw1c. - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_INTR_ENABLE_REG_OFFSET, - 0); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_INTR_STATE_REG_OFFSET, - UINT32_MAX); +static void hmac_done_wait(void) { + uint32_t intr_reg = 0; + while (bitfield_bit32_read(intr_reg, HMAC_INTR_STATE_HMAC_DONE_BIT) == 0) { + intr_reg = abs_mmio_read32(kHmacBaseAddr + HMAC_INTR_STATE_REG_OFFSET); + } + + // Clear the interrupt by writing 1, because `INTR_STATE` is rw1c type. + abs_mmio_write32(kHmacBaseAddr + HMAC_INTR_STATE_REG_OFFSET, intr_reg); } /** - * Initialize the HMAC block. + * Clear the state of HMAC HWIP so that further driver calls can use it. * - * If `enable_hmac` is `kHardenedBoolTrue`, starts the block in HMAC mode. If - * it is `kHardenedBoolFalse`, starts in SHA256 mode. + * This function cannot force stop HWIP, and ongoing operations will not simply + * stop by deasserting `sha_en` bit. Instead it should be used after HWIP + * raises `hmac_done` interrupt (see `hmac_done_wait` function). * - * @param enable_hmac Whether to start HMAC mode. - * @param big_endian Whether to return digest in big-endian form. + * It also clears the internal state of HWIP by overwriting sensitive values + * with 1s. */ -static void hmac_init(hardened_bool_t enable_hmac) { - uint32_t cfg = 0; - // Digest should be big-endian to match the SHA-256 specification. - cfg = bitfield_bit32_write(cfg, HMAC_CFG_DIGEST_SWAP_BIT, true); - // Message should be little-endian to match Ibex's endianness. - cfg = bitfield_bit32_write(cfg, HMAC_CFG_ENDIAN_SWAP_BIT, false); - cfg = bitfield_bit32_write(cfg, HMAC_CFG_SHA_EN_BIT, true); - if (launder32(enable_hmac) == kHardenedBoolTrue) { - HARDENED_CHECK_EQ(enable_hmac, kHardenedBoolTrue); - cfg = bitfield_bit32_write(cfg, HMAC_CFG_HMAC_EN_BIT, true); - } else { - HARDENED_CHECK_EQ(enable_hmac, kHardenedBoolFalse); - cfg = bitfield_bit32_write(cfg, HMAC_CFG_HMAC_EN_BIT, false); +static void hmac_hwip_clear(void) { + // Do not clear the config yet, we just need to deassert sha_en, see #23014. + // TODO handle digest size changes. + uint32_t cfg_reg = abs_mmio_read32(kHmacBaseAddr + HMAC_CFG_REG_OFFSET); + cfg_reg = bitfield_bit32_write(cfg_reg, HMAC_CFG_SHA_EN_BIT, false); + abs_mmio_write32(kHmacBaseAddr + HMAC_CFG_REG_OFFSET, cfg_reg); + + // TODO(#23191): Use a random value from EDN to wipe. + abs_mmio_write32(kHmacBaseAddr + HMAC_WIPE_SECRET_REG_OFFSET, UINT32_MAX); +} + +/** + * Restore the internal state of HWIP from `ctx` struct, and resume the + * operation. + * + * The first HWIP operation requires the call of `start` instead of `continue`. + * Therefore, `ctx->hw_started` flag is used to distinguish the first call. This + * function also updated `ctx->hw_started` after the first such call. + * + * If this function is being called from `ctx` object with previously stored + * context (i.e. `ctx->hw_started = true`), then this state is restored. + * + * @param ctx Context from which values are written to CSRs. + */ +static void context_restore(hmac_ctx_t *ctx) { + // Restore CFG register from `ctx->cfg_reg`. + abs_mmio_write32(kHmacBaseAddr + HMAC_CFG_REG_OFFSET, ctx->cfg_reg); + + // Write to KEY registers for HMAC operations. If the operation is SHA-2, + // `key_len` is set to 0 during `ctx` initialization. + for (size_t i = 0; i < ctx->key_len; i++) { + abs_mmio_write32(kHmacBaseAddr + HMAC_KEY_0_REG_OFFSET + 4 * i, + ctx->key[i]); } - // configure to run SHA-2 256 with 256-bit key - cfg = bitfield_field32_write(cfg, HMAC_CFG_DIGEST_SIZE_FIELD, - HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256); - cfg = bitfield_field32_write(cfg, HMAC_CFG_KEY_LENGTH_FIELD, - HMAC_CFG_KEY_LENGTH_VALUE_KEY_256); + uint32_t cmd_reg = HMAC_CMD_REG_RESVAL; + // Decide if we need to invoke `start` or `continue` command. + if (ctx->hw_started) { + cmd_reg = bitfield_bit32_write(cmd_reg, HMAC_CMD_HASH_CONTINUE_BIT, 1); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_CFG_REG_OFFSET, cfg); + // For SHA-256 and HMAC-256, we do not need to write to the second half of + // DIGEST registers, but we do it anyway to keep the driver simple. + for (size_t i = 0; i < kHmacMaxDigestWords; i++) { + abs_mmio_write32(kHmacBaseAddr + HMAC_DIGEST_0_REG_OFFSET + 4 * i, + ctx->H[i]); + } + abs_mmio_write32(kHmacBaseAddr + HMAC_MSG_LENGTH_LOWER_REG_OFFSET, + ctx->lower); + abs_mmio_write32(kHmacBaseAddr + HMAC_MSG_LENGTH_UPPER_REG_OFFSET, + ctx->upper); + } else { + cmd_reg = bitfield_bit32_write(cmd_reg, HMAC_CMD_HASH_START_BIT, 1); + ctx->hw_started = 1; + } - uint32_t cmd = bitfield_bit32_write(0, HMAC_CMD_HASH_START_BIT, true); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_CMD_REG_OFFSET, cmd); -} + // We could not set `sha_en` before updating context registers (see #23014). + // Now that context registers are restored, enable `sha_en`. + uint32_t cfg_reg = abs_mmio_read32(kHmacBaseAddr + HMAC_CFG_REG_OFFSET); + cfg_reg = bitfield_bit32_write(cfg_reg, HMAC_CFG_SHA_EN_BIT, true); + abs_mmio_write32(kHmacBaseAddr + HMAC_CFG_REG_OFFSET, cfg_reg); -void hmac_sha_init(void) { - // Stop any currently in-progress operation. - hmac_halt(); + // Now we can finally write the command to the register to actually issue + // `start` or `continue`. + abs_mmio_write32(kHmacBaseAddr + HMAC_CMD_REG_OFFSET, cmd_reg); +} - // Initialize in SHA256 mode. - hmac_init(kHardenedBoolFalse); +/** + * Save the context from HWIP into `ctx` object. + * + * This function should be called only after `stop` command is invoked and HWIP + * confirms that it stopped via interrupt. + * + * @param[out] ctx Context to which values are written. + */ +static void context_save(hmac_ctx_t *ctx) { + // For SHA-256 and HMAC-256, we do not need to save to the second half of + // DIGEST registers, but we do it anyway to keep the driver simple. + for (size_t i = 0; i < kHmacMaxDigestWords; i++) { + ctx->H[i] = + abs_mmio_read32(kHmacBaseAddr + HMAC_DIGEST_0_REG_OFFSET + 4 * i); + } + ctx->lower = + abs_mmio_read32(kHmacBaseAddr + HMAC_MSG_LENGTH_LOWER_REG_OFFSET); + ctx->upper = + abs_mmio_read32(kHmacBaseAddr + HMAC_MSG_LENGTH_UPPER_REG_OFFSET); } -void hmac_hmac_init(const hmac_key_t *key) { - // Stop any currently in-progress operation. - hmac_halt(); - - // Write key registers. - static_assert(ARRAYSIZE(key->key) == 8, "Unexpected HMAC key size."); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_0_REG_OFFSET, - key->key[0]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_1_REG_OFFSET, - key->key[1]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_2_REG_OFFSET, - key->key[2]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_3_REG_OFFSET, - key->key[3]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_4_REG_OFFSET, - key->key[4]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_5_REG_OFFSET, - key->key[5]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_6_REG_OFFSET, - key->key[6]); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_KEY_7_REG_OFFSET, - key->key[7]); - - // Initialize in HMAC mode. - hmac_init(kHardenedBoolTrue); +/** + * Write given byte array into the `MSG_FIFO`. This function should only be + * called when HWIP is already running and expecting further message bytes. + */ +static void msg_fifo_write(const uint8_t *msg, size_t msg_len) { + // TODO(#23191): Improve message copying by writing them in 32b at a time. + for (size_t i = 0; i < msg_len; i++) { + abs_mmio_write8(kHmacBaseAddr + HMAC_MSG_FIFO_REG_OFFSET, msg[i]); + } } -void hmac_update(const uint8_t *data, size_t len) { - // Individual byte writes are needed if the buffer isn't word aligned. - for (; len != 0 && (uintptr_t)data & 3; --len) { - abs_mmio_write8(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_MSG_FIFO_REG_OFFSET, - *data++); +status_t hmac_init(hmac_ctx_t *ctx, const hmac_mode_t hmac_mode, + const hmac_key_t *key) { + if (ctx == NULL) { + return OTCRYPTO_BAD_ARGS; } + // TODO(#23191) Zeroise or randomly populate ctx struct during init. + + // Prepare cfg_reg in context. + ctx->cfg_reg = HMAC_CFG_REG_RESVAL; + // The endianness is fixed at driver level and not exposed to the caller. + // Digest should be big-endian to match the SHA-256 specification. + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_DIGEST_SWAP_BIT, true); + // Message should be little-endian to match Ibex's endianness. + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_ENDIAN_SWAP_BIT, false); - for (; len >= sizeof(uint32_t); len -= sizeof(uint32_t)) { - uint32_t data_aligned = read_32(data); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_MSG_FIFO_REG_OFFSET, - data_aligned); - data += sizeof(uint32_t); + // We need to keep `sha_en` low until context is restored, see #23014. + ctx->cfg_reg = bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_SHA_EN_BIT, false); + + // Default value for `hmac_en` is false, HMAC calls set it to true below. + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_HMAC_EN_BIT, false); + + switch (hmac_mode) { + case kHmacModeHmac256: + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_HMAC_EN_BIT, true); + OT_FALLTHROUGH_INTENDED; + case kHmacModeSha256: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_DIGEST_SIZE_FIELD, + HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256); + // The unit for `ctx->msg_block_len` is bytes. + ctx->msg_block_len = kHmacSha256InternalBlockBytes; + // The unit for `ctx->digest_len` is bytes. + ctx->digest_len = kHmacSha256DigestBytes; + break; + case kHmacModeHmac384: + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_HMAC_EN_BIT, true); + OT_FALLTHROUGH_INTENDED; + case kHmacModeSha384: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_DIGEST_SIZE_FIELD, + HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_384); + // The unit for `ctx->msg_block_len` is bytes. + ctx->msg_block_len = kHmacSha384InternalBlockBytes; + // The unit for `ctx->digest_len` is bytes. + ctx->digest_len = kHmacSha384DigestBytes; + break; + case kHmacModeHmac512: + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_HMAC_EN_BIT, true); + OT_FALLTHROUGH_INTENDED; + case kHmacModeSha512: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_DIGEST_SIZE_FIELD, + HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_512); + // The unit for `ctx->msg_block_len` is bytes. + ctx->msg_block_len = kHmacSha512InternalBlockBytes; + // The unit for `ctx->digest_len` is bytes. + ctx->digest_len = kHmacSha512DigestBytes; + break; + default: + return OTCRYPTO_BAD_ARGS; } - // Handle non-32bit aligned bytes at the end of the buffer. - for (; len != 0; --len) { - abs_mmio_write8(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_MSG_FIFO_REG_OFFSET, - *data++); + if (hmac_mode == kHmacModeHmac256 || hmac_mode == kHmacModeHmac384 || + hmac_mode == kHmacModeHmac512) { + if (key == NULL) { + return OTCRYPTO_BAD_ARGS; + } + ctx->cfg_reg = + bitfield_bit32_write(ctx->cfg_reg, HMAC_CFG_HMAC_EN_BIT, true); + // Key values supported natively by HW are {128, 256, 384, 512, 1024}. + switch (key->len) { + case kHmacKey128Bytes: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_KEY_LENGTH_FIELD, + HMAC_CFG_KEY_LENGTH_VALUE_KEY_128); + break; + case kHmacKey256Bytes: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_KEY_LENGTH_FIELD, + HMAC_CFG_KEY_LENGTH_VALUE_KEY_256); + break; + case kHmacKey384Bytes: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_KEY_LENGTH_FIELD, + HMAC_CFG_KEY_LENGTH_VALUE_KEY_384); + break; + case kHmacKey512Bytes: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_KEY_LENGTH_FIELD, + HMAC_CFG_KEY_LENGTH_VALUE_KEY_512); + break; + case kHmacKey1024Bytes: + ctx->cfg_reg = + bitfield_field32_write(ctx->cfg_reg, HMAC_CFG_KEY_LENGTH_FIELD, + HMAC_CFG_KEY_LENGTH_VALUE_KEY_1024); + break; + default: + return OTCRYPTO_BAD_ARGS; + } + // `ctx->key_len` has 32b as unit. + ctx->key_len = key->len / sizeof(uint32_t); + for (size_t i = 0; i < ctx->key_len; i++) { + // TODO(#23158): Use `key_swap` to avoid endianness change. + ctx->key[i] = (0xff & key->key[0]) << 24 | (0xff00 & key->key[1]) << 8 | + (0xff0000 & key->key[2]) >> 8 | + (0xff000000 & key->key[3]) >> 24; + } + } else { + // Ensure that `key` is NULL for hashing operations. + if (key != NULL) { + return OTCRYPTO_BAD_ARGS; + } + // Set `key_len` to 0, so that it is clear this is hash operation. This + // value is later used to skip writing to KEY registers. + ctx->key_len = 0; } + + ctx->hw_started = 0; + ctx->partial_block_len = 0; + + return OTCRYPTO_OK; +} + +status_t hmac_update(hmac_ctx_t *ctx, const uint8_t *data, size_t len) { + if (ctx == NULL || (data == NULL && len > 0)) { + return OTCRYPTO_BAD_ARGS; + } + + // Check if incoming message bits with `ctx->partial_block` together has + // enough bits to fill an internal SHA-2 block. Otherwise, this function just + // appends the incoming bits to partial_block and returns without invoking + // HWIP operation. + if (ctx->partial_block_len + len < ctx->msg_block_len) { + memcpy(ctx->partial_block + ctx->partial_block_len, data, len); + ctx->partial_block_len += len; + return OTCRYPTO_OK; + } + + // `leftover` bits refers to the size of the next partial block, after we + // handle the current partial block and the incoming message bytes. + size_t leftover_len = (ctx->partial_block_len + len) % ctx->msg_block_len; + + // The previous caller should have left it clean, but it doesn't hurt to + // clear again. + hmac_hwip_clear(); + // Retore context will restore the context and also hit start or continue + // button as necessary. + context_restore(ctx); + + // Write `partial_block` to MSG_FIFO + msg_fifo_write(ctx->partial_block, ctx->partial_block_len); + + // Keep writing incoming bytes + // TODO(#23191): Should we handle backpressure here? + msg_fifo_write(data, len - leftover_len); + + // Time to tell HWIP to stop, because we do not have enough message bytes for + // another round. + uint32_t cmd_reg = + bitfield_bit32_write(HMAC_CMD_REG_RESVAL, HMAC_CMD_HASH_STOP_BIT, 1); + abs_mmio_write32(kHmacBaseAddr + HMAC_CMD_REG_OFFSET, cmd_reg); + + // Wait for HWIP to be done. + hmac_done_wait(); + + // Store context into `ctx`. + context_save(ctx); + + // Write leftover bytes to `partial_block`, so that future update/final call + // can feed them to HWIP. + memcpy(ctx->partial_block, data + len - leftover_len, leftover_len); + ctx->partial_block_len = leftover_len; + + // Clean up HWIP so it can be reused by other driver calls. + hmac_hwip_clear(); + return OTCRYPTO_OK; } -void hmac_final(hmac_digest_t *digest) { - uint32_t reg = 0; - reg = bitfield_bit32_write(reg, HMAC_CMD_HASH_PROCESS_BIT, true); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_CMD_REG_OFFSET, reg); +status_t hmac_final(hmac_ctx_t *ctx, hmac_digest_t *digest) { + if (ctx == NULL || digest == NULL) { + return OTCRYPTO_BAD_ARGS; + } + + // Check that `digest_len` match the one from ctx. + if (ctx->digest_len != digest->len) { + return OTCRYPTO_BAD_ARGS; + } + + // The previous caller should have left it clean, but it doesn't hurt to + // clear again. + hmac_hwip_clear(); - do { - reg = abs_mmio_read32(TOP_EARLGREY_HMAC_BASE_ADDR + - HMAC_INTR_STATE_REG_OFFSET); - } while (!bitfield_bit32_read(reg, HMAC_INTR_STATE_HMAC_DONE_BIT)); - abs_mmio_write32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_INTR_STATE_REG_OFFSET, - reg); + // Retore context will restore the context and also hit start or continue + // button as necessary. + context_restore(ctx); - // Read the digest. - for (size_t i = 0; i < ARRAYSIZE(digest->digest); ++i) { + // Feed the final leftover bytes to HWIP. + msg_fifo_write(ctx->partial_block, ctx->partial_block_len); + + // All message bytes are fed, now hit the process button. + uint32_t cmd_reg = + bitfield_bit32_write(HMAC_CMD_REG_RESVAL, HMAC_CMD_HASH_PROCESS_BIT, 1); + abs_mmio_write32(kHmacBaseAddr + HMAC_CMD_REG_OFFSET, cmd_reg); + hmac_done_wait(); + + for (size_t i = 0; i < ctx->digest_len / sizeof(uint32_t); i++) { digest->digest[i] = - abs_mmio_read32(TOP_EARLGREY_HMAC_BASE_ADDR + HMAC_DIGEST_0_REG_OFFSET + - (i * sizeof(uint32_t))); + abs_mmio_read32(kHmacBaseAddr + HMAC_DIGEST_0_REG_OFFSET + 4 * i); } - // Clean up and put the block back in an idle state. - hmac_halt(); + // Clean up HWIP so it can be reused by other driver calls. + hmac_hwip_clear(); + + // TODO(#23191): Destroy sensitive values in the ctx object. + return OTCRYPTO_OK; } diff --git a/sw/device/lib/crypto/drivers/hmac.h b/sw/device/lib/crypto/drivers/hmac.h index c0bd9163d6b34..454c1147b3f1c 100644 --- a/sw/device/lib/crypto/drivers/hmac.h +++ b/sw/device/lib/crypto/drivers/hmac.h @@ -7,88 +7,189 @@ #include #include +#include "sw/device/lib/base/hardened.h" #include "sw/device/lib/base/macros.h" +#include "sw/device/lib/crypto/impl/status.h" + +#include "hmac_regs.h" #ifdef __cplusplus extern "C" { #endif enum { - /* Number of bits in an HMAC or SHA-256 digest. */ - kHmacDigestNumBits = 256, - /* Number of bytes in an HMAC or SHA-256 digest. */ - kHmacDigestNumBytes = kHmacDigestNumBits / 8, - /* Number of words in an HMAC or SHA-256 digest. */ - kHmacDigestNumWords = kHmacDigestNumBytes / sizeof(uint32_t), - /* Number of bits in an HMAC key. */ - kHmacKeyNumBits = 256, - /* Number of bytes in an HMAC key. */ - kHmacKeyNumBytes = kHmacKeyNumBits / 8, - /* Number of words in an HMAC key. */ - kHmacKeyNumWords = kHmacKeyNumBytes / sizeof(uint32_t), + /* Digest size for SHA-256/HMAC-256 in bits, bytes and word respectively. */ + kHmacSha256DigestBits = 256, + kHmacSha256DigestBytes = kHmacSha256DigestBits / 8, + kHmacSha256DigestWords = kHmacSha256DigestBytes / sizeof(uint32_t), + /* Digest size for SHA-384/HMAC-384 in bits, bytes and word respectively. */ + kHmacSha384DigestBits = 384, + kHmacSha384DigestBytes = kHmacSha384DigestBits / 8, + kHmacSha384DigestWords = kHmacSha384DigestBytes / sizeof(uint32_t), + /* Digest size for SHA-512/HMAC-512 in bits, bytes and word respectively. */ + kHmacSha512DigestBits = 512, + kHmacSha512DigestBytes = kHmacSha512DigestBits / 8, + kHmacSha512DigestWords = kHmacSha512DigestBytes / sizeof(uint32_t), + /* Maximum digest size supported by HW natively in bits and words + respectively. */ + kHmacMaxDigestBits = 512, + kHmacMaxDigestWords = kHmacMaxDigestBits / sizeof(uint32_t) / 8, + /* Maximum internal block size bits, bytes and words respectively. */ + kHmacMaxBlockBits = 1024, + kHmacMaxBlockBytes = kHmacMaxBlockBits / 8, + kHmacMaxBlockWords = kHmacMaxBlockBytes / sizeof(uint32_t), +}; + +/* Supported key sizes from HWIP in bytes. */ +enum { + /* 128 bit key. */ + kHmacKey128Bytes = 128 / 8, + /* 256 bit key. */ + kHmacKey256Bytes = 256 / 8, + /* 384 bit key. */ + kHmacKey384Bytes = 384 / 8, + /* 512 bit key. */ + kHmacKey512Bytes = 512 / 8, + /* 1024 bit key. */ + kHmacKey1024Bytes = 1024 / 8, + /* Number of words for maximum key size supported by HW natively. */ + kHmacMaxKeyWords = kHmacKey1024Bytes / sizeof(uint32_t), }; /** - * A typed representation of the HMAC or SHA256 digest. + * A typed representation of the SHA-2/HMAC digests. */ typedef struct hmac_digest { - uint32_t digest[kHmacDigestNumWords]; + uint32_t digest[kHmacMaxDigestWords]; + // Length of `digest` in bytes. + size_t len; } hmac_digest_t; /** - * A typed representation of an HMAC key. + * A typed representation of an HMAC key. HWIP supports 128, 256, 384, 512, 1024 + * bit keys natively. */ typedef struct hmac_key { - uint32_t key[kHmacKeyNumWords]; + uint32_t key[kHmacMaxKeyWords]; + // Length of `key` in bytes. + size_t len; } hmac_key_t; /** - * Initializes the HMAC block in SHA256 mode. - * - * If the HMAC block is non-idle, calling this function aborts the previous - * operation. - * - * This function resets the HMAC module to clear the digest register. - * It then configures the HMAC block in SHA256 mode with little endian - * data input and digest output. + * A context struct maintained for streaming operations. */ -void hmac_sha_init(void); +typedef struct hmac_ctx { + // Back up cfg register, except SHA bit. + uint32_t cfg_reg; + // Need to keep some extra info around to reconfigure HW every time. + uint32_t key[kHmacMaxKeyWords]; + // Length of `key` in words. + // key_len == 0 is used to infer that this is SHA-2 operation. + size_t key_len; + // The internal block size of HMAC/SHA2 in bytes. + size_t msg_block_len; + size_t digest_len; + // The following fields are saved and restored during streaming. + uint32_t H[kHmacMaxDigestWords]; + uint32_t lower; + uint32_t upper; + // The following are flags exclusively used by the driver to make whether + // or not the driver needs to pass the incoming requests to HMAC IP. + uint32_t hw_started; + uint8_t partial_block[kHmacMaxBlockBytes]; + // The number of valid bytes in `partial_block`. + size_t partial_block_len; +} hmac_ctx_t; + +typedef enum hmac_mode { + // SHA2-256 + kHmacModeSha256, + // SHA2-384 + kHmacModeSha384, + // SHA2-512 + kHmacModeSha512, + // HMAC-256 + kHmacModeHmac256, + // HMAC-384 + kHmacModeHmac384, + // HMAC-512 + kHmacModeHmac512, +} hmac_mode_t; /** - * Initializes the HMAC block in HMAC mode. + * Initializes the context `ctx` according to given `hmac_mode` and `key`. + * + * This function does not invoke HMAC HWIP operation, but instead prepares `ctx` + * with necessary data for the streaming operations to be called later: + * i) Prepare CFG register value (with the exception of `sha_en` bit, #23014) + * and store it into `ctx`. This value is repetitively loaded into HWIP during + * future `hmac_update` and `hmac_final` calls. * - * If the HMAC block is non-idle, calling this function aborts the previous - * operation. + * ii) Copy given key and its length into `ctx` if the operation is HMAC. + * iii) Initialize `hw_started` flag to false which indicates whether the very + * first HWIP operation is executed or not. This helps decide whether start or + * continue operation needs to be issues to HWIP later. + * iv) Compute and store message block length and digest len fields to `ctx`. * - * This function resets the HMAC module to clear the digest register. - * It then configures the HMAC block in SHA256 mode with little endian - * data input and digest output. + * For SHA-2 operation, `key` must be set to NULL. + * For HMAC operations, `key` must point to a valid `hmac_key_t` struct where + * `key->len` corresponds to either one of the natively supported key lengths: + * {128, 256, 384, 512, 1024} bits. `key->key` should have sufficient number of + * words for the matching key length. * - * @param key HMAC key. + * @param[out] ctx Initialized context object for SHA2/HMAC-SHA2 operations. + * @param hmac_mode Specifies the mode among SHA2-256/384/512, HMAC-256/384/512. + * @param key HMAC key. The key to be used with HMAC calls. + * @return Error status. */ -void hmac_hmac_init(const hmac_key_t *key); +OT_WARN_UNUSED_RESULT +status_t hmac_init(hmac_ctx_t *ctx, const hmac_mode_t hmac_mode, + const hmac_key_t *key); /** - * Sends `len` bytes from `data` to the HMAC or SHA2-256 function. + * Updates the state of `ctx` with given additional messsage bytes. * - * This function does not check for the size of the available HMAC - * FIFO. Since the this function is meant to run in blocking mode, - * polling for FIFO status is equivalent to stalling on FIFO write. + * This function first checks whether incoming byte messages together with the + * pending bytes `ctx->partial_block` are larger than the SHA-2/HMAC internal + * block size implied by `ctx`. * - * @param data Buffer to copy data from. + * If the available message bytes are larger than the internal block size, then + * the state of HWIP is restored from `ctx` and message bytes are fed into + * MSG_FIFO in internal block granularity. When all blocks are processed, HWIP + * is stopped and the state of HWIP is saved to `ctx`. The leftover message + * bytes that are not sufficient to be a block are stored in `ctx-partial_block` + * to be used in future `hmac_update` or `hmac_final` calls. Finally, the state + * of HWIP is cleared. + + * If the available message bytes are smaller than a single internal block, + * `ctx->partial_block` is appended with the incoming bytes and no HWIP + * operation is issued. + * + * @param ctx Context object referring to a particular SHA-2/HMAC stream. + * @param data Incoming message bytes to be processed into the stream. * @param len size of the `data` buffer in bytes. + * @return Error status. */ -void hmac_update(const uint8_t *data, size_t len); +OT_WARN_UNUSED_RESULT +status_t hmac_update(hmac_ctx_t *ctx, const uint8_t *data, size_t len); /** - * Finalizes HMAC or SHA256 operation and writes `digest` buffer. + * Finalize the SHA-2/HMAC stream and return digest/tag. + * + * This function works similar to `hmac_update`, in terms of how reamining + * message bytes are handled, if there are any. * - * Blocks while the device is processing. Clears the hardware digest registers - * and configuration when done. + * First, the state of HWIP is restored. Then, any remaining message byte from + * `ctx->partial_block` are fed to MSG_FIFO. At the end, process command is + * invoked at HWIP to conclude SHA-2/HMAC operation and produce the digest/tag. + * The result is read from HWIP into `digest` and the state of HWIP is cleared. * - * @param[out] digest Buffer to copy digest to. + * @param ctx Context object referring to a particular stream. + * @param[out] digest The digest value to be returned. + * @return Error status. */ -void hmac_final(hmac_digest_t *digest); +OT_WARN_UNUSED_RESULT +status_t hmac_final(hmac_ctx_t *ctx, hmac_digest_t *digest); #ifdef __cplusplus } From 4f9b0f7e15779053368907cd794bca5fb7c9a207 Mon Sep 17 00:00:00 2001 From: Fatih Balli Date: Wed, 22 May 2024 21:49:12 +0000 Subject: [PATCH 2/4] [cryptolib, ecdsa] Fix HMAC calls in functest Because of the large change in HMAC driver, ecdsa_p256_verify_functest is affected. This commit fixes the HMAC calls. Signed-off-by: Fatih Balli --- .../tests/crypto/ecdsa_p256_verify_functest.c | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sw/device/tests/crypto/ecdsa_p256_verify_functest.c b/sw/device/tests/crypto/ecdsa_p256_verify_functest.c index a0600eda69a00..a19bdcc65c24b 100644 --- a/sw/device/tests/crypto/ecdsa_p256_verify_functest.c +++ b/sw/device/tests/crypto/ecdsa_p256_verify_functest.c @@ -16,19 +16,23 @@ // the version of this file matching the Bazel rule under test. #include "ecdsa_p256_verify_testvectors.h" -static void compute_digest(size_t msg_len, const uint8_t *msg, - hmac_digest_t *digest) { - // Compute the SHA-256 digest using the HMAC device. - hmac_sha_init(); - hmac_update(msg, msg_len); - hmac_final(digest); +static status_t compute_digest(size_t msg_len, const uint8_t *msg, + hmac_digest_t *digest) { + // Compute the SHA-256 digest using the HMAC HWIP. + hmac_ctx_t hwip_ctx; + TRY(hmac_init(&hwip_ctx, kHmacModeSha256, /*key=*/NULL)); + TRY(hmac_update(&hwip_ctx, msg, msg_len)); + TRY(hmac_final(&hwip_ctx, digest)); + return OTCRYPTO_OK; } status_t ecdsa_p256_verify_test( const ecdsa_p256_verify_test_vector_t *testvec) { // Hash message. - hmac_digest_t digest; - compute_digest(testvec->msg_len, testvec->msg, &digest); + hmac_digest_t digest = { + .len = kHmacSha256DigestBytes, + }; + TRY(compute_digest(testvec->msg_len, testvec->msg, &digest)); // Attempt to verify signature. TRY(ecdsa_p256_verify_start(&testvec->signature, digest.digest, From 673466ed7f3060ec045b021202fd74a3cce56c36 Mon Sep 17 00:00:00 2001 From: Fatih Balli Date: Thu, 23 May 2024 14:20:55 +0000 Subject: [PATCH 3/4] [cryptolib, rsa] Fix HMAC references Signed-off-by: Fatih Balli --- .../lib/crypto/impl/rsa/rsa_3072_verify.c | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c index cf8208294a8bb..bf8a473c75e04 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c @@ -49,8 +49,6 @@ static const uint32_t kOtbnRsaModeModexp = 2; status_t rsa_3072_encode_sha256(const uint8_t *msg, size_t msgLen, rsa_3072_int_t *result) { - enum { kSha256DigestNumWords = 8 }; - if (msg == NULL && msgLen != 0) { return OTCRYPTO_BAD_ARGS; } @@ -78,25 +76,28 @@ status_t rsa_3072_encode_sha256(const uint8_t *msg, size_t msgLen, // Set 0x00 || 0x01 bytes at most significant end result->data[kRsa3072NumWords - 1] = 0x0001ffff; - // Compute the SHA-256 message digest. - hmac_sha_init(); - hmac_update(msg, msgLen); - hmac_digest_t digest; - hmac_final(&digest); + // Compute the SHA-256 digest using the HMAC HWIP. + hmac_ctx_t hwip_ctx; + hmac_digest_t digest = { + .len = kHmacSha256DigestBytes, + }; + TRY(hmac_init(&hwip_ctx, kHmacModeSha256, /*key=*/NULL)); + TRY(hmac_update(&hwip_ctx, msg, msgLen)); + TRY(hmac_final(&hwip_ctx, &digest)); // Copy the message digest into the least significant end of the result, // reversing the order of bytes to get little-endian form. - for (size_t i = 0; i < kSha256DigestNumWords; i++) { + for (size_t i = 0; i < kHmacSha256DigestWords; i++) { result->data[i] = - __builtin_bswap32(digest.digest[kSha256DigestNumWords - 1 - i]); + __builtin_bswap32(digest.digest[kHmacSha256DigestWords - 1 - i]); } // Set remainder of 0x00 || T section - result->data[kSha256DigestNumWords] = 0x05000420; - result->data[kSha256DigestNumWords + 1] = 0x03040201; - result->data[kSha256DigestNumWords + 2] = 0x86480165; - result->data[kSha256DigestNumWords + 3] = 0x0d060960; - result->data[kSha256DigestNumWords + 4] = 0x00303130; + result->data[kHmacSha256DigestWords] = 0x05000420; + result->data[kHmacSha256DigestWords + 1] = 0x03040201; + result->data[kHmacSha256DigestWords + 2] = 0x86480165; + result->data[kHmacSha256DigestWords + 3] = 0x0d060960; + result->data[kHmacSha256DigestWords + 4] = 0x00303130; return OTCRYPTO_OK; } From cdd05911ccedc5e2bb92091bffed3f7b02134c86 Mon Sep 17 00:00:00 2001 From: Fatih Balli Date: Mon, 20 May 2024 12:18:25 +0000 Subject: [PATCH 4/4] [cryptolib, hmac] Update cryptolib + tests for driver changes Signed-off-by: Fatih Balli --- sw/device/lib/crypto/impl/hash.c | 19 +++++++++---------- sw/device/tests/crypto/sha256_functest.c | 6 +++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/sw/device/lib/crypto/impl/hash.c b/sw/device/lib/crypto/impl/hash.c index 8e14870756d03..d0f0277d7b6cb 100644 --- a/sw/device/lib/crypto/impl/hash.c +++ b/sw/device/lib/crypto/impl/hash.c @@ -188,19 +188,18 @@ static status_t check_digest_len(otcrypto_hash_digest_t digest) { OT_WARN_UNUSED_RESULT static status_t hmac_sha256(otcrypto_const_byte_buf_t message, otcrypto_hash_digest_t digest) { - HARDENED_CHECK_EQ(digest.len, kHmacDigestNumWords); + HARDENED_CHECK_EQ(digest.len, kHmacSha256DigestWords); HARDENED_CHECK_EQ(digest.mode, kOtcryptoHashModeSha256); - // Initialize the hardware. - hmac_sha_init(); + hmac_ctx_t hwip_ctx; + hmac_digest_t hmac_digest = { + .len = kHmacSha256DigestBytes, + }; + HARDENED_TRY(hmac_init(&hwip_ctx, kHmacModeSha256, /*key=*/NULL)); + HARDENED_TRY(hmac_update(&hwip_ctx, message.data, message.len)); + HARDENED_TRY(hmac_final(&hwip_ctx, &hmac_digest)); - // Pass the message and check the length. - hmac_update(message.data, message.len); - - // Retrieve the digest and copy it to the destination buffer. - hmac_digest_t hmac_digest; - hmac_final(&hmac_digest); - hardened_memcpy(digest.data, hmac_digest.digest, kHmacDigestNumWords); + hardened_memcpy(digest.data, hmac_digest.digest, kHmacSha256DigestWords); return OTCRYPTO_OK; } diff --git a/sw/device/tests/crypto/sha256_functest.c b/sw/device/tests/crypto/sha256_functest.c index 4d8fc9a5ea4e5..1428c2b58bf6e 100644 --- a/sw/device/tests/crypto/sha256_functest.c +++ b/sw/device/tests/crypto/sha256_functest.c @@ -56,14 +56,14 @@ static const uint8_t kExactBlockExpDigest[] = { */ static status_t run_test(otcrypto_const_byte_buf_t msg, const uint32_t *exp_digest) { - uint32_t act_digest[kHmacDigestNumWords]; + uint32_t act_digest[kHmacSha256DigestWords]; otcrypto_hash_digest_t digest_buf = { .data = act_digest, - .len = kHmacDigestNumWords, + .len = kHmacSha256DigestWords, .mode = kOtcryptoHashModeSha256, }; TRY(otcrypto_hash(msg, digest_buf)); - TRY_CHECK_ARRAYS_EQ(act_digest, exp_digest, kHmacDigestNumWords); + TRY_CHECK_ARRAYS_EQ(act_digest, exp_digest, kHmacSha256DigestWords); return OK_STATUS(); }