[keymgr] XOR OTP root key with fresh randomness Implements the masking improvement suggested at #7614. Removes continuously OTP loading behavior. It also fixes related doc and DV changes. Signed-off-by: Fatih Balli <fatihballi@google.com>
diff --git a/hw/ip/keymgr/README.md b/hw/ip/keymgr/README.md index d98f85d..f9a54a8 100644 --- a/hw/ip/keymgr/README.md +++ b/hw/ip/keymgr/README.md
@@ -88,11 +88,7 @@ The advancement from `CreatorRootKey` to the `OwnerIntermediateKey` is irreversible during the current power cycle. -While in the CreatorRootKey state, the key from OTP is continuously captured and sensed. -This provides some security benefit as the key is constantly background checked by the OTP. -When an operation begins, the sampling is stopped. -If at the conclusion of the operation the key manager stays in the same state, sampling begins again. -If on the other hand key manager transitions to another state, OTP sampling is stopped until reset. +Keymgr reads the root key from OTP in a single clock cycle. It assumes that when keymgr's internal FSM reaches to this clock cycle, OTP root key is already available (`valid` is set to 1). Otherwise, keymgr skips loading the root key. ### OwnerIntermediateKey
diff --git a/hw/ip/keymgr/dv/env/keymgr_if.sv b/hw/ip/keymgr/dv/env/keymgr_if.sv index 5c81d03..c378479 100644 --- a/hw/ip/keymgr/dv/env/keymgr_if.sv +++ b/hw/ip/keymgr/dv/env/keymgr_if.sv
@@ -555,7 +555,7 @@ `ASSERT(NAME, SEQ, clk, !rst_n || keymgr_en_sync2 != lc_ctrl_pkg::On || !en_chk) `ASSERT_IFF_KEYMGR_LEGAL(CheckKmacKey, is_kmac_key_good && kmac_key_exp.valid -> - kmac_key == kmac_key_exp) + kmac_key[0] ^ kmac_key[1] == kmac_key_exp[0] ^ kmac_key_exp[1]) `ASSERT_IFF_KEYMGR_LEGAL(CheckKmacKeyValid, is_kmac_key_good -> kmac_key_exp.valid == kmac_key.valid)
diff --git a/hw/ip/keymgr/rtl/keymgr_ctrl.sv b/hw/ip/keymgr/rtl/keymgr_ctrl.sv index 7d00ea9..6e55a5b 100644 --- a/hw/ip/keymgr/rtl/keymgr_ctrl.sv +++ b/hw/ip/keymgr/rtl/keymgr_ctrl.sv
@@ -224,12 +224,11 @@ logic wipe_req; logic random_req; logic random_ack; - logic ld_root_key; // wipe and initialize take precedence assign update_sel = wipe_req ? KeyUpdateWipe : random_req ? KeyUpdateRandom : - init_o | ld_root_key ? KeyUpdateRoot : op_update_sel; + init_o ? KeyUpdateRoot : op_update_sel; /////////////////////////// // interaction between main fsm and prng @@ -328,7 +327,9 @@ KeyUpdateRandom: begin for (int i = 0; i < CDIs; i++) begin for (int j = 0; j < Shares; j++) begin - key_state_d[i][j][cnt[EntropyRndWidth-1:0]] = entropy_i[j]; + // Load each share with the same randomness so we can + // later simply XOR root key on them + key_state_d[i][j][cnt[EntropyRndWidth-1:0]] = entropy_i[i]; end end end @@ -337,8 +338,8 @@ if (root_key_valid_q) begin for (int i = 0; i < CDIs; i++) begin if (KmacEnMasking) begin : gen_two_share_key - key_state_d[i][0] = root_key_i.key_share0; - key_state_d[i][1] = root_key_i.key_share1; + key_state_d[i][0] ^= root_key_i.key_share0; + key_state_d[i][1] ^= root_key_i.key_share1; end else begin : gen_one_share_key key_state_d[i][0] = root_key_i.key_share0 ^ root_key_i.key_share1; key_state_d[i][1] = '0; @@ -451,9 +452,6 @@ // Most states are initialized, mark the exceptions initialized = 1'b1; - // during certain states, the otp root key is continuosly loaded - ld_root_key = 1'b0; - // if state is ever faulted, hold on to this indication // until reset. state_intg_err_d = state_intg_err_q; @@ -520,13 +518,8 @@ stage_sel_o = advance_sel ? Creator : Disable; invalid_op = op_start_i & ~(advance_sel | disable_sel); - // as long as an operation is not requested, continously load root key - // if it is valid. - // If an invalidate condition hits, also stop loading key - ld_root_key = ~op_start_i; if (!en_i || inv_state) begin state_d = StCtrlWipe; - ld_root_key = '0; end else if (dis_state) begin state_d = StCtrlDisabled; end else if (adv_state) begin