[kmac] Add Main State Machine This commit adds main state machine at the KMAC top and add `in_progress` and `in_keyblock` signals for the entropy generation logic to refresh the entropy. The entropy logic uses in_progress signal to refresh the LFSR seed. in_keyblock signal let entropy logic to refresh the entropy everytime it is consumed, if not in keyblock state, entropy logic gives randome value and not changed by consumed signal. Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/hw/ip/kmac/rtl/kmac.sv b/hw/ip/kmac/rtl/kmac.sv index 3d46a36..c31a9ea 100644 --- a/hw/ip/kmac/rtl/kmac.sv +++ b/hw/ip/kmac/rtl/kmac.sv
@@ -55,6 +55,26 @@ ///////////////// // Definitions // ///////////////// + // This state machine is to track the current process based on SW input and + // KMAC operation. + typedef enum logic [2:0] { + // Idle state + KmacIdle, + + // When software writes CmdStart @ KmacIdle and kmac_en, FSM moves to this + KmacPrefix, + + // When SHA3 engine processes Key block, FSM moves to here. + KmacKeyBlock, + + // Message Feed + KmacMsgFeed, + + // Complete and squeeze + KmacDigest + + } kmac_st_e; + kmac_st_e kmac_st, kmac_st_d; ///////////// // Signals // @@ -80,6 +100,12 @@ // Sequence: start --> process(multiple) --> get absorbed event --> {run -->} done logic sha3_start, sha3_run, sha3_done, sha3_absorbed, unused_sha3_squeeze; + // Indicate one block processed + logic sha3_block_processed; + + // EStatus for entropy + logic entropy_in_progress, entropy_in_keyblock; + // KeyMgr interface logic generates event_absorbed from sha3_absorbed. // It is active only if SW initiates the hashing engine. logic event_absorbed; @@ -187,6 +213,7 @@ logic entropy_ready; entropy_mode_e entropy_mode; + logic entropy_fast_process; // SHA3 Error response sha3_pkg::err_t sha3_err; @@ -317,6 +344,7 @@ // Entropy config assign entropy_ready = reg2hw.cfg.entropy_ready.q; assign entropy_mode = entropy_mode_e'(reg2hw.cfg.entropy_mode.q); + assign entropy_fast_process = reg2hw.cfg.entropy_fast_process.q; assign hw2reg.cfg.entropy_ready.de = entropy_ready; assign hw2reg.cfg.entropy_ready.d = 1'b 0; // always clear when ready @@ -419,6 +447,87 @@ .intr_o (intr_kmac_err_o) ); + /////////////////// + // State Machine // + /////////////////// + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + kmac_st <= KmacIdle; + end else begin + kmac_st <= kmac_st_d; + end + end + + always_comb begin + // Default value + kmac_st_d = KmacIdle; + + entropy_in_progress = 1'b 0; + entropy_in_keyblock = 1'b 0; + + unique case (kmac_st) + KmacIdle: begin + if (kmac_cmd == CmdStart) begin + // If cSHAKE turned on + if (sha3_pkg::CShake == sha3_pkg::sha3_mode_e'(reg2hw.cfg.mode.q)) begin + kmac_st_d = KmacPrefix; + end else begin + // Jump to Msg feed directly + kmac_st_d = KmacMsgFeed; + end + end else begin + kmac_st_d = KmacIdle; + end + end + + KmacPrefix: begin + entropy_in_progress =1'b 1; + // Wait until SHA3 processes one block + if (sha3_block_processed) begin + kmac_st_d = (reg2hw.cfg.kmac_en.q) ? KmacKeyBlock : KmacMsgFeed ; + end else begin + kmac_st_d = KmacPrefix; + end + end + + KmacKeyBlock: begin + entropy_in_progress = 1'b 1; + entropy_in_keyblock = 1'b 1; + if (sha3_block_processed) begin + kmac_st_d = KmacMsgFeed; + end else begin + kmac_st_d = KmacKeyBlock; + end + end + + KmacMsgFeed: begin + entropy_in_progress = 1'b 1; + // If absorbed, move to Digest + if (sha3_absorbed) begin + kmac_st_d = KmacDigest; + end else begin + kmac_st_d = KmacMsgFeed; + end + end + + KmacDigest: begin + entropy_in_progress = 1'b 1; + // SW can manually run it, wait till done + if (sha3_done) begin + kmac_st_d = KmacIdle; + end else begin + kmac_st_d = KmacDigest; + end + end + + default: begin + kmac_st_d = KmacIdle; + end + endcase + end + `ASSERT_KNOWN(KmacStKnown_A, kmac_st) + /////////////// // Instances // /////////////// @@ -493,6 +602,8 @@ .absorbed_o (sha3_absorbed), .squeezing_o (unused_sha3_squeeze), + .block_processed_o (sha3_block_processed), + .sha3_fsm_o (sha3_fsm), .state_valid_o (state_valid), @@ -669,13 +780,14 @@ // Status from internal logic //// SHA3 engine run indicator - .in_progress_i (), + .in_progress_i (entropy_in_progress), //// KMAC secret block handling indicator - .in_keyblock_i (), + .in_keyblock_i (entropy_in_keyblock), // Configuration .mode_i (entropy_mode), .entropy_ready_i (entropy_ready), + .fast_process_i (entropy_fast_process), //// Entropy refresh period in clk cycles .entropy_timer_limit_i (entropy_timer_limit), @@ -708,6 +820,9 @@ assign unused_refresh_period = {wait_timer_limit, entropy_timer_limit}; assign entropy_err = '{valid: 1'b 0, code: ErrNone, info: '0}; + + logic [1:0] unused_entropy_status; + assign unused_entropy_status = {entropy_in_keyblock, entropy_in_progress}; end // Register top
diff --git a/hw/ip/kmac/rtl/kmac_entropy.sv b/hw/ip/kmac/rtl/kmac_entropy.sv index e3db4a9..f0b9159 100644 --- a/hw/ip/kmac/rtl/kmac_entropy.sv +++ b/hw/ip/kmac/rtl/kmac_entropy.sv
@@ -31,6 +31,11 @@ //// interface. input entropy_ready_i, + //// Garbage random value when not processing Keyblock, if this config is + //// turned on, the logic sending garbage value and never de-assert + //// rand_valid_o unless it is not processing KeyBlock. + input fast_process_i, + //// SW update of seed input seed_update_i, input [63:0] seed_data_i, @@ -288,7 +293,7 @@ rand_valid_o <= 1'b 0; end else if (rand_valid_set) begin rand_valid_o <= 1'b 1; - end else if (rand_valid_clear || rand_consumed_i) begin + end else if (rand_valid_clear) begin rand_valid_o <= 1'b 0; end end @@ -403,7 +408,12 @@ StRandReady: begin timer_enable = 1'b 1; // If limit is zero, timer won't work - if (rand_consumed_i) begin + if ( (fast_process_i && in_keyblock_i && rand_consumed_i) + || (!fast_process_i && rand_consumed_i)) begin + // If fast_process is set, don't clear the rand valid, even + // consumed. So, the logic does not expand the entropy again. + // If fast_process is not set, then every rand_consume signal + // triggers rand expansion. st_d = StRandExpand; lfsr_en = 1'b 1;
diff --git a/hw/ip/kmac/rtl/sha3.sv b/hw/ip/kmac/rtl/sha3.sv index 7dfd855..3c85006 100644 --- a/hw/ip/kmac/rtl/sha3.sv +++ b/hw/ip/kmac/rtl/sha3.sv
@@ -55,6 +55,10 @@ output logic absorbed_o, output logic squeezing_o, + // Indicate of one block processed. KMAC main state tracks the progression + // based on this signal. + output logic block_processed_o, + output sha3_st_e sha3_fsm_o, // digest output @@ -130,6 +134,8 @@ // Squeezing output assign squeezing_o = squeezing; + assign block_processed_o = keccak_complete; + // State connection assign state_valid_o = state_valid; assign state_o = state_guarded;