Skip to content

Commit bde1ed4

Browse files
committed
[ot] hw/opentitan: ot_keymgr: Add invalid KMAC input errors & debug
Improve handling of invalid KMAC inputs using the all-0/1 integrity check functionality, and correct `KMAC_INPUT_ERROR` to only be visible after the current operation has completed by using `valid_inputs`. Refactors `Advance` data validity checks to use this new state so that each check can update its own unique DEBUG register field on failure. Note: this commit still does not implement the KMAC key integrity check, because keys are still wiped/init with 0s instead of random entropy. Signed-off-by: Alex Jones <[email protected]>
1 parent b0b5901 commit bde1ed4

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

hw/opentitan/ot_keymgr.c

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,19 @@ static void ot_keymgr_push_kdf_key(OtKeyMgrState *s, const uint8_t *key_share0,
883883
{
884884
trace_ot_keymgr_push_kdf_key(s->ot_id, valid);
885885

886-
/* @todo: add additional KMAC KDF key integrity checks */
886+
/*
887+
* @todo: when key invalidating/wiping with entropy is implemented,
888+
* pushing a new KDF key should perform a validity check for all 0s
889+
* or all 1s, and set R_DEBUG_INVALID_KEY_MASK if so, i.e.:
890+
*
891+
* if (!ot_keymgr_valid_data_check(key_share0, OT_KMAC_KEY_SIZE)) {
892+
* s->regs[R_DEBUG] |= R_DEBUG_INVALID_KEY_MASK;
893+
* s->op_state.valid_inputs = false;
894+
* }
895+
*
896+
* @todo: when KMAC masking is introduced, this should check both key
897+
* shares and not just key share 0 for validity.
898+
*/
887899

888900
ot_keymgr_push_key(s, KEYMGR_KEY_SINK_KMAC, key_share0, key_share1, valid,
889901
false);
@@ -932,45 +944,54 @@ static size_t ot_keymgr_kdf_append_rev_seed(OtKeyMgrState *s)
932944
return KEYMGR_SEED_BYTES;
933945
}
934946

935-
static size_t ot_keymgr_kdf_append_rom_digest(OtKeyMgrState *s, bool *dvalid)
947+
static size_t ot_keymgr_kdf_append_rom_digest(OtKeyMgrState *s)
936948
{
937949
uint8_t rom_digest[OT_ROM_DIGEST_BYTES] = { 0u };
938950

939951
OtRomCtrlClass *rcc = OT_ROM_CTRL_GET_CLASS(s->rom_ctrl);
940952
rcc->get_rom_digest(s->rom_ctrl, rom_digest);
941953

942954
ot_keymgr_kdf_push_bytes(s, rom_digest, OT_ROM_DIGEST_BYTES);
943-
*dvalid &= ot_keymgr_valid_data_check(rom_digest, OT_ROM_DIGEST_BYTES);
955+
if (!ot_keymgr_valid_data_check(rom_digest, OT_ROM_DIGEST_BYTES)) {
956+
s->regs[R_DEBUG] |= R_DEBUG_INVALID_DIGEST_MASK;
957+
s->op_state.valid_inputs = false;
958+
}
944959

945960
ot_keymgr_dump_kdf_material(s, "ROM_DIGEST", rom_digest,
946961
OT_ROM_DIGEST_BYTES);
947962
return OT_ROM_DIGEST_BYTES;
948963
}
949964

950-
static size_t ot_keymgr_kdf_append_km_div(OtKeyMgrState *s, bool *dvalid)
965+
static size_t ot_keymgr_kdf_append_km_div(OtKeyMgrState *s)
951966
{
952967
OtLcCtrlKeyMgrDiv km_div = { 0u };
953968

954969
OtLcCtrlClass *lc = OT_LC_CTRL_GET_CLASS(s->lc_ctrl);
955970
lc->get_keymgr_div(s->lc_ctrl, &km_div);
956971

957972
ot_keymgr_kdf_push_bytes(s, km_div.data, OT_LC_KEYMGR_DIV_BYTES);
958-
*dvalid &= ot_keymgr_valid_data_check(km_div.data, OT_LC_KEYMGR_DIV_BYTES);
973+
if (!ot_keymgr_valid_data_check(km_div.data, OT_LC_KEYMGR_DIV_BYTES)) {
974+
s->regs[R_DEBUG] |= R_DEBUG_INVALID_HEALTH_STATE_MASK;
975+
s->op_state.valid_inputs = false;
976+
}
959977

960978
ot_keymgr_dump_kdf_material(s, "KM_DIV", km_div.data,
961979
OT_LC_KEYMGR_DIV_BYTES);
962980
return OT_LC_KEYMGR_DIV_BYTES;
963981
}
964982

965-
static size_t ot_keymgr_kdf_append_dev_id(OtKeyMgrState *s, bool *dvalid)
983+
static size_t ot_keymgr_kdf_append_dev_id(OtKeyMgrState *s)
966984
{
967985
OtOTPClass *otp_oc = OBJECT_GET_CLASS(OtOTPClass, s->otp_ctrl, TYPE_OT_OTP);
968986
const OtOTPHWCfg *hw_cfg = otp_oc->get_hw_cfg(s->otp_ctrl);
969987

970988
ot_keymgr_kdf_push_bytes(s, hw_cfg->device_id,
971989
OT_OTP_HWCFG_DEVICE_ID_BYTES);
972-
*dvalid &= ot_keymgr_valid_data_check(hw_cfg->device_id,
973-
OT_OTP_HWCFG_DEVICE_ID_BYTES);
990+
if (!ot_keymgr_valid_data_check(hw_cfg->device_id,
991+
OT_OTP_HWCFG_DEVICE_ID_BYTES)) {
992+
s->regs[R_DEBUG] |= R_DEBUG_INVALID_DEV_ID_MASK;
993+
s->op_state.valid_inputs = false;
994+
}
974995

975996
ot_keymgr_dump_kdf_material(s, "DEVICE_ID", hw_cfg->device_id,
976997
OT_OTP_HWCFG_DEVICE_ID_BYTES);
@@ -979,17 +1000,20 @@ static size_t ot_keymgr_kdf_append_dev_id(OtKeyMgrState *s, bool *dvalid)
9791000

9801001
static size_t
9811002
ot_keymgr_kdf_append_flash_seed(OtKeyMgrState *s, OtFlashKeyMgrSecretType type,
982-
const char *seed_name, bool *dvalid)
1003+
const char *seed_name, uint32_t debug_mask)
9831004
{
9841005
OtFlashKeyMgrSecret seed = { 0u };
9851006

9861007
OtFlashClass *fc = OT_FLASH_GET_CLASS(s->flash_ctrl);
9871008
fc->get_keymgr_secret(s->flash_ctrl, type, &seed);
9881009

9891010
ot_keymgr_kdf_push_bytes(s, seed.secret, OT_FLASH_KEYMGR_SECRET_BYTES);
990-
*dvalid &=
1011+
bool data_valid =
9911012
ot_keymgr_valid_data_check(seed.secret, OT_FLASH_KEYMGR_SECRET_BYTES);
992-
*dvalid &= seed.valid;
1013+
if (!seed.valid || !data_valid) {
1014+
s->regs[R_DEBUG] |= debug_mask;
1015+
s->op_state.valid_inputs = false;
1016+
}
9931017

9941018
ot_keymgr_dump_kdf_material(s, seed_name, seed.secret,
9951019
OT_FLASH_KEYMGR_SECRET_BYTES);
@@ -1145,8 +1169,6 @@ static void ot_keymgr_operation_advance(OtKeyMgrState *s, OtKeyMgrStage stage,
11451169
trace_ot_keymgr_advance(s->ot_id, STAGE_NAME(stage), (int)stage,
11461170
CDI_NAME(cdi), (int)cdi);
11471171

1148-
bool dvalid = true;
1149-
11501172
/* @todo: do we need to check for any error states here? */
11511173

11521174
ot_keymgr_reset_kdf_buffer(s);
@@ -1159,25 +1181,27 @@ static void ot_keymgr_operation_advance(OtKeyMgrState *s, OtKeyMgrStage stage,
11591181
expected_kdf_len += ot_keymgr_kdf_append_rev_seed(s);
11601182

11611183
/* Rom Digest (from rom_ctrl) */
1162-
expected_kdf_len += ot_keymgr_kdf_append_rom_digest(s, &dvalid);
1184+
expected_kdf_len += ot_keymgr_kdf_append_rom_digest(s);
11631185

11641186
/* KeyManager Diversification (from lc_ctrl) */
1165-
expected_kdf_len += ot_keymgr_kdf_append_km_div(s, &dvalid);
1187+
expected_kdf_len += ot_keymgr_kdf_append_km_div(s);
11661188

11671189
/* Device ID (from OTP) */
1168-
expected_kdf_len += ot_keymgr_kdf_append_dev_id(s, &dvalid);
1190+
expected_kdf_len += ot_keymgr_kdf_append_dev_id(s);
11691191
break;
11701192
case KEYMGR_STAGE_OWNER_INT:
11711193
/* Creator Seed (from flash) */
11721194
expected_kdf_len +=
11731195
ot_keymgr_kdf_append_flash_seed(s, FLASH_KEYMGR_SECRET_CREATOR_SEED,
1174-
"CREATOR_SEED", &dvalid);
1196+
"CREATOR_SEED",
1197+
R_DEBUG_INVALID_CREATOR_SEED_MASK);
11751198
break;
11761199
case KEYMGR_STAGE_OWNER:
11771200
/* Owner Seed (from flash) */
11781201
expected_kdf_len +=
11791202
ot_keymgr_kdf_append_flash_seed(s, FLASH_KEYMGR_SECRET_OWNER_SEED,
1180-
"OWNER_SEED", &dvalid);
1203+
"OWNER_SEED",
1204+
R_DEBUG_INVALID_OWNER_SEED_MASK);
11811205
break;
11821206
case KEYMGR_STAGE_DISABLE:
11831207
/* you can "advance" from the OwnerRootKey to the `Disabled` state */
@@ -1193,14 +1217,6 @@ static void ot_keymgr_operation_advance(OtKeyMgrState *s, OtKeyMgrStage stage,
11931217
/* check that we have pushed all expected KDF data */
11941218
g_assert(s->kdf_buf.length == expected_kdf_len);
11951219

1196-
/*
1197-
* @todo: store `dvalid` somewhere and, if the data is invalid, replace the
1198-
* KMAC response with decoy data (a random permutation of entropy share 1).
1199-
*/
1200-
if (!dvalid) {
1201-
s->regs[R_ERR_CODE] |= R_ERR_CODE_INVALID_KMAC_INPUT_MASK;
1202-
}
1203-
12041220
g_assert(s->kdf_buf.length <= KEYMGR_ADV_DATA_BYTES);
12051221
s->kdf_buf.length = KEYMGR_ADV_DATA_BYTES;
12061222

0 commit comments

Comments
 (0)