[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