[kmac] Randomly advance the PRNG if its output not used

This commit adds some logic to randomly advance the PRNG in clock
cycles where it's output is not used. This has two advantages:
- The 800-bit wide PRNG can serve as an integrated noise source.
- As KMAC outputs the state in 2 shares it would theoretically be
  be possible (although difficult) to predict the PRNG state and exploit
  that for attacks. By randomizing how many times the PRNG is updated
  we can further aggravate such attacks.

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/ip/kmac/rtl/kmac_entropy.sv b/hw/ip/kmac/rtl/kmac_entropy.sv
index 1ac5442..c5c307a 100644
--- a/hw/ip/kmac/rtl/kmac_entropy.sv
+++ b/hw/ip/kmac/rtl/kmac_entropy.sv
@@ -203,6 +203,10 @@
   logic aux_rand_d, aux_rand_q;
   logic aux_update;
 
+  // Randomness for controlling PRNG updates. This only matters for clock cycles
+  // where the PRNG output is not actually used.
+  logic [3:0] lfsr_en_rand_d, lfsr_en_rand_q;
+
   // Entropy valid signal
   // FSM set and clear the valid signal, rand_consume signal clear the valid
   // signal. Split the set, clear to make entropy valid while FSM is processing
@@ -443,6 +447,21 @@
 
   // Auxiliary randomness -----------------------------------------------------
 
+  // LFSR enable randomness ===================================================
+  assign lfsr_en_rand_d =
+      aux_update ? lfsr_data_permuted[EntropyLfsrW - 2 -: 4] : // refresh
+                   {1'b0, lfsr_en_rand_q[3:1]};                // shift out
+
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      lfsr_en_rand_q <= '0;
+    end else begin
+      lfsr_en_rand_q <= lfsr_en_rand_d;
+    end
+  end
+
+  // LFSR enable randomness ---------------------------------------------------
+
   // Randomness outputs =======================================================
   assign rand_data_o = lfsr_data_permuted;
   assign rand_aux_o = aux_rand_q;
@@ -561,6 +580,8 @@
       StRandReady: begin
         timer_enable = 1'b 1; // If limit is zero, timer won't work
 
+        lfsr_en = lfsr_en_rand_q[0];
+
         if (rand_consumed_i &&
             ((fast_process_i && in_keyblock_i) || !fast_process_i)) begin
           // If fast_process is set, don't clear the rand valid, even