Skip to content

Commit d8d4fb3

Browse files
siemen11nasahlpa
authored andcommitted
[crypto/hmac/kmac] Clean HW upon bad status
Clean the HMAC and KMAC also on errors by using a cleanup attribute. Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
1 parent ac0fd14 commit d8d4fb3

5 files changed

Lines changed: 60 additions & 17 deletions

File tree

sw/device/lib/crypto/drivers/hmac.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ static status_t clear(void) {
175175
return LAUNDERED_OTCRYPTO_OK;
176176
}
177177

178+
/**
179+
* Hardware wipe guard.
180+
*/
181+
static void hmac_wipe_guard(uint32_t *dummy) { (void)clear(); }
182+
178183
/**
179184
* Write given key to HMAC HWIP.
180185
*
@@ -438,6 +443,8 @@ static status_t ensure_idle(void) {
438443
static status_t oneshot(const uint32_t cfg, const hmac_key_t *key,
439444
const otcrypto_const_byte_buf_t *msg,
440445
size_t digest_wordlen, uint32_t *digest) {
446+
uint32_t hw_cleanup_guard __attribute__((cleanup(hmac_wipe_guard))) = 1;
447+
441448
// Check that the block is idle.
442449
HARDENED_TRY(ensure_idle());
443450

@@ -476,7 +483,7 @@ static status_t oneshot(const uint32_t cfg, const hmac_key_t *key,
476483

477484
HARDENED_CHECK_EQ(kHardenedBoolTrue, OTCRYPTO_CHECK_BUF(msg));
478485

479-
return clear();
486+
return OTCRYPTO_OK;
480487
}
481488

482489
/**
@@ -825,6 +832,8 @@ hardened_bool_t hmac_key_integrity_checksum_check(const hmac_key_t *key) {
825832
}
826833

827834
status_t hmac_update(hmac_ctx_t *ctx, const otcrypto_const_byte_buf_t *data) {
835+
uint32_t hw_cleanup_guard __attribute__((cleanup(hmac_wipe_guard))) = 1;
836+
828837
// If we don't have enough new bytes to fill a block, just update the partial
829838
// block and return.
830839
size_t block_bytelen = ctx->msg_block_wordlen * sizeof(uint32_t);
@@ -877,11 +886,12 @@ status_t hmac_update(hmac_ctx_t *ctx, const otcrypto_const_byte_buf_t *data) {
877886

878887
HARDENED_CHECK_EQ(kHardenedBoolTrue, OTCRYPTO_CHECK_BUF(data));
879888

880-
// Clean up.
881-
return clear();
889+
return OTCRYPTO_OK;
882890
}
883891

884892
status_t hmac_final(hmac_ctx_t *ctx, otcrypto_word32_buf_t *digest) {
893+
uint32_t hw_cleanup_guard __attribute__((cleanup(hmac_wipe_guard))) = 1;
894+
885895
// Restore context will restore the context and also hit start or continue
886896
// button as necessary.
887897
HARDENED_TRY(context_restore(ctx));
@@ -908,6 +918,5 @@ status_t hmac_final(hmac_ctx_t *ctx, otcrypto_word32_buf_t *digest) {
908918

909919
HARDENED_CHECK_EQ(kHardenedBoolTrue, OTCRYPTO_CHECK_BUF(digest));
910920

911-
// Clean up.
912-
return clear();
921+
return OTCRYPTO_OK;
913922
}

sw/device/lib/crypto/drivers/kmac.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ OT_ASSERT_ENUM_VALUE(ARRAYSIZE(prefix_offsets), KMAC_PREFIX_MULTIREG_COUNT);
152152
// Ensure each PREFIX register is 4 bytes
153153
OT_ASSERT_ENUM_VALUE(32, KMAC_PREFIX_PREFIX_FIELD_WIDTH);
154154

155+
/**
156+
* Hardware wipe guard.
157+
*/
158+
static void kmac_wipe_guard(uint32_t *dummy) {
159+
uint32_t cmd_reg = KMAC_CMD_REG_RESVAL;
160+
cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
161+
KMAC_CMD_CMD_VALUE_DONE);
162+
abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
163+
}
164+
155165
/**
156166
* Return the rate (in bytes) for given security strength.
157167
*
@@ -618,6 +628,9 @@ OT_WARN_UNUSED_RESULT
618628
static status_t kmac_process_msg_blocks(
619629
kmac_operation_t operation, const otcrypto_const_byte_buf_t *message,
620630
uint32_t *digest, size_t digest_len_bytes, hardened_bool_t masked_digest) {
631+
// This variable guarantees kmac_wipe_guard() is called on exit.
632+
uint32_t hw_cleanup_guard __attribute__((cleanup(kmac_wipe_guard))) = 1;
633+
621634
// Block until KMAC is idle.
622635
HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1));
623636

@@ -756,12 +769,6 @@ static status_t kmac_process_msg_blocks(
756769
// Poll the status register until in the 'squeeze' state.
757770
HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
758771

759-
// Release the KMAC core, so that it goes back to idle mode
760-
cmd_reg = KMAC_CMD_REG_RESVAL;
761-
cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
762-
KMAC_CMD_CMD_VALUE_DONE);
763-
abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
764-
765772
// Zero out the trailing bytes in the final word.
766773
size_t remainder_bytes = digest_len_bytes % sizeof(uint32_t);
767774
if (remainder_bytes > 0) {

sw/device/lib/crypto/impl/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ cc_library(
318318
":status",
319319
"//sw/device/lib/base:hardened_memory",
320320
"//sw/device/lib/base:math",
321+
"//sw/device/lib/crypto/drivers:keymgr",
321322
"//sw/device/lib/crypto/drivers:kmac",
322323
"//sw/device/lib/crypto/drivers:rv_core_ibex",
323324
"//sw/device/lib/crypto/include:datatypes",

sw/device/lib/crypto/impl/kmac.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
// Module ID for status codes.
1515
#define MODULE_ID MAKE_MODULE_ID('k', 'm', 'c')
1616

17+
/**
18+
* Sideload cleanup guard.
19+
*/
20+
static void sideload_wipe_guard(hardened_bool_t *is_sideloaded) {
21+
if (*is_sideloaded == kHardenedBoolTrue) {
22+
(void)keymgr_sideload_clear_kmac();
23+
}
24+
}
25+
1726
otcrypto_status_t otcrypto_kmac(
1827
otcrypto_blinded_key_t *key, const otcrypto_const_byte_buf_t *input_message,
1928
const otcrypto_const_byte_buf_t *customization_string,
@@ -39,6 +48,9 @@ otcrypto_status_t otcrypto_kmac(
3948
}
4049
#endif
4150

51+
hardened_bool_t is_sideloaded __attribute__((cleanup(sideload_wipe_guard))) =
52+
kHardenedBoolFalse;
53+
4254
// Ensure that tag buffer length and `required_output_len` match each other.
4355
size_t required_output_words =
4456
(required_output_len + sizeof(uint32_t) - 1) / sizeof(uint32_t);
@@ -71,6 +83,8 @@ otcrypto_status_t otcrypto_kmac(
7183
if (key_len != kKmacSideloadKeyLength / 8) {
7284
return OTCRYPTO_BAD_ARGS;
7385
}
86+
is_sideloaded = kHardenedBoolTrue;
87+
7488
// Configure keymgr with diversification input and then generate the
7589
// sideload key.
7690
keymgr_diversification_t diversification;
@@ -119,10 +133,6 @@ otcrypto_status_t otcrypto_kmac(
119133
// avoid that multiple cases were executed.
120134
HARDENED_CHECK_EQ(launder32(key_mode_used), key->config.key_mode);
121135

122-
if (key->config.hw_backed == kHardenedBoolTrue) {
123-
HARDENED_TRY(keymgr_sideload_clear_kmac());
124-
}
125-
126136
// Verify the input buffer
127137
HARDENED_CHECK_EQ(kHardenedBoolTrue,
128138
OTCRYPTO_CHECK_BUF(customization_string));

sw/device/lib/crypto/impl/kmac_kdf.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "sw/device/lib/base/hardened_memory.h"
88
#include "sw/device/lib/base/math.h"
9+
#include "sw/device/lib/crypto/drivers/keymgr.h"
910
#include "sw/device/lib/crypto/drivers/kmac.h"
1011
#include "sw/device/lib/crypto/impl/keyblob.h"
1112
#include "sw/device/lib/crypto/impl/status.h"
@@ -16,6 +17,15 @@
1617
// Module ID for status codes.
1718
#define MODULE_ID MAKE_MODULE_ID('k', 'k', 'd')
1819

20+
/**
21+
* Sideload cleanup guard.
22+
*/
23+
static void sideload_wipe_guard(hardened_bool_t *is_sideloaded) {
24+
if (*is_sideloaded == kHardenedBoolTrue) {
25+
(void)keymgr_sideload_clear_kmac();
26+
}
27+
}
28+
1929
otcrypto_status_t otcrypto_kmac_kdf(
2030
otcrypto_blinded_key_t *key_derivation_key,
2131
const otcrypto_const_byte_buf_t *label,
@@ -34,6 +44,10 @@ otcrypto_status_t otcrypto_kmac_kdf(
3444
return OTCRYPTO_BAD_ARGS;
3545
}
3646
#endif
47+
48+
hardened_bool_t is_sideloaded __attribute__((cleanup(sideload_wipe_guard))) =
49+
kHardenedBoolFalse;
50+
3751
// Because of KMAC HWIPs prefix limitation, `label` should not exceed
3852
// `kKmacCustStrMaxSize` bytes.
3953
if (label->len > kKmacCustStrMaxSize) {
@@ -75,6 +89,9 @@ otcrypto_status_t otcrypto_kmac_kdf(
7589
kKmacSideloadKeyLength / 8) {
7690
return OTCRYPTO_BAD_ARGS;
7791
}
92+
93+
is_sideloaded = kHardenedBoolTrue;
94+
7895
// Configure keymgr with diversification input and then generate the
7996
// sideload key.
8097
keymgr_diversification_t diversification;
@@ -152,6 +169,5 @@ otcrypto_status_t otcrypto_kmac_kdf(
152169
output_key_material->checksum =
153170
otcrypto_integrity_blinded_checksum(output_key_material);
154171

155-
// Clear the KMAC sideload slot in case the key was sideloaded.
156-
return otcrypto_eval_exit(keymgr_sideload_clear_kmac());
172+
return otcrypto_eval_exit(OTCRYPTO_OK);
157173
}

0 commit comments

Comments
 (0)