[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