[keymgr] Add second version of internal key

- Expand software binding to sealing and attestation
- For generate operations, software must select one of the CDI's

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/keymgr/rtl/keymgr_ctrl.sv b/hw/ip/keymgr/rtl/keymgr_ctrl.sv
index f172930..34ac4c8 100644
--- a/hw/ip/keymgr/rtl/keymgr_ctrl.sv
+++ b/hw/ip/keymgr/rtl/keymgr_ctrl.sv
@@ -7,7 +7,7 @@
 
 `include "prim_assert.sv"
 
-module keymgr_ctrl import keymgr_pkg::*;(
+module keymgr_ctrl import keymgr_pkg::*; (
   input clk_i,
   input rst_ni,
 
@@ -17,6 +17,7 @@
   // Software interface
   input op_start_i,
   input keymgr_ops_e op_i,
+  input [CdiWidth-1:0] op_cdi_sel_i,
   output logic op_done_o,
   output keymgr_op_status_e status_o,
   output logic [ErrLastPos-1:0] error_o,
@@ -31,6 +32,7 @@
   input  otp_ctrl_pkg::otp_keymgr_key_t root_key_i,
   output keymgr_gen_out_e hw_sel_o,
   output keymgr_stage_e stage_sel_o,
+  output logic [CdiWidth-1:0] cdi_sel_o,
 
   // KMAC ctrl interface
   output logic adv_en_o,
@@ -54,9 +56,7 @@
   localparam int EntropyWidth = LfsrWidth / 2;
   localparam int EntropyRounds = KeyWidth / EntropyWidth;
   localparam int EntropyRndWidth = prim_util_pkg::vbits(EntropyRounds);
-  localparam int VersionWidth = prim_util_pkg::vbits(Versions);
-  localparam int CntMax = EntropyRounds > Versions ? EntropyRounds : Versions;
-  localparam int CntWidth = prim_util_pkg::vbits(CntMax);
+  localparam int CntWidth = EntropyRounds > CDIs ? EntropyRndWidth : CdiWidth;
 
   // Enumeration for working state
   typedef enum logic [3:0] {
@@ -88,10 +88,9 @@
   // There are two versions of the key state, one for sealing one for attestation
   // Among each version, there are multiple shares
   // Each share is a fixed multiple of the entropy width
-  logic [VersionWidth-1:0] key_sel;
-  logic [Versions-1:0][Shares-1:0][EntropyRounds-1:0][EntropyWidth-1:0] key_state_q, key_state_d;
+  logic [CDIs-1:0][Shares-1:0][EntropyRounds-1:0][EntropyWidth-1:0] key_state_q, key_state_d;
   logic [CntWidth-1:0] cnt;
-  logic [VersionWidth-1:0] version_cnt;
+  logic [CdiWidth-1:0] cdi_cnt;
 
   logic key_update;
   logic data_update;
@@ -176,14 +175,13 @@
   //   state.
   // - when there are no operations, the key state also should be exposed.
   assign key_o.valid = op_req;
-  // TODO, hook-up extra command info from registers
-  assign key_sel = '0;
+  assign cdi_sel_o = advance_sel ? cdi_cnt : op_cdi_sel_i;
   assign key_o.key_share0 = stage_sel_o == Disable ?
                             {EntropyRounds{entropy_i[0]}} :
-                            key_state_q[cnt[key_sel]][0];
+                            key_state_q[cnt[cdi_sel_o]][0];
   assign key_o.key_share1 = stage_sel_o == Disable ?
                             {EntropyRounds{entropy_i[1]}} :
-                            key_state_q[cnt[key_sel]][1];
+                            key_state_q[cnt[cdi_sel_o]][1];
 
   // key state is intentionally not reset
   always_ff @(posedge clk_i) begin
@@ -208,8 +206,7 @@
   assign update_sel = wipe_req ? KeyUpdateWipe :
                       init_o   ? KeyUpdateRoot : op_update_sel;
 
-  //assign version_cnt = cnt[VersionWidth-1:0];
-  assign version_cnt = cnt[VersionWidth-1:0];
+  assign cdi_cnt = cnt[CdiWidth-1:0];
 
   always_comb begin
     key_state_d = key_state_q;
@@ -223,7 +220,7 @@
 
     unique case (update_sel)
       KeyUpdateRandom: begin
-        for (int i = 0; i < Versions; i++) 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];
           end
@@ -232,7 +229,7 @@
 
       KeyUpdateRoot: begin
         if (root_key_valid_q) begin
-          for (int i = 0; i < Versions; i++) begin
+          for (int i = 0; i < CDIs; i++) begin
             key_state_d[i][0] = root_key_i.key_share0;
             key_state_d[i][1] = root_key_i.key_share1;
           end
@@ -242,18 +239,18 @@
       KeyUpdateKmac: begin
         data_valid_o = data_update & ~fault_err & ~op_err;
         key_update_vld = key_update & ~fault_err & ~op_err;
-        key_state_d[version_cnt] = key_update_vld ? kmac_data_i : key_state_q;
+        key_state_d[cdi_sel_o] = key_update_vld ? kmac_data_i : key_state_q[cdi_sel_o];
       end
 
       KeyUpdateInvalid: begin
         data_valid_o = data_update;
         key_update_vld = key_update;
-        key_state_d[version_cnt] = key_update_vld ? kmac_data_i : key_state_q;
+        key_state_d[cdi_sel_o] = key_update_vld ? kmac_data_i : key_state_q[cdi_sel_o];
       end
 
       KeyUpdateWipe: begin
         wipe_key_o = 1'b1;
-        for (int i = 0; i < Versions; i++) begin
+        for (int i = 0; i < CDIs; i++) begin
           for (int j = 0; j < Shares; j++) begin
             key_state_d[i][j] = {EntropyRounds{entropy_i[j]}};
           end
@@ -499,7 +496,7 @@
     endcase // unique case (state_q)
   end
 
-  // if working over multiple versions, a fault of any version
+  // if working over multiple CDIs, a fault of any
   // is considered an overall fault
   logic clr_err;
 
@@ -560,10 +557,10 @@
       StAdv: begin
         adv_en_o = 1'b1;
 
-        if (kmac_done_i && (version_cnt == Versions-1)) begin
+        if (kmac_done_i && (cdi_cnt == CDIs-1)) begin
           op_ack = 1'b1;
           op_state_d = StIdle;
-        end else if (kmac_done_i && (version_cnt < Versions-1)) begin
+        end else if (kmac_done_i && (cdi_cnt < CDIs-1)) begin
           op_update = 1'b1;
           op_state_d = StAdvAck;
         end