[hmac] Drop the request prior to hash_start

Jon mentioned the case that MSG_FIFO can be back-pressured when the
software writes the message into MSG_FIFO when `hash_start` is not
asserted in issue #1869. It is not desirable behavior as it can lock the
core access. If that happens, core cannot set `hash_start` to flush out
the data.

This commit is to restrict the access from the software. It only allows
the MSG_FIFO (request to packer) from `hash_start` to `hash_process`. If
the software tries to write the message other than the time above, it
drops the request and raises an error with
`SwPushMsgWhenDisallowed(0x5)` error code.

This is related to #1869 #1871

Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/hw/ip/hmac/rtl/hmac.sv b/hw/ip/hmac/rtl/hmac.sv
index 24cce7e..217e700 100644
--- a/hw/ip/hmac/rtl/hmac.sv
+++ b/hw/ip/hmac/rtl/hmac.sv
@@ -101,6 +101,7 @@
 
   hmac_reg2hw_cfg_reg_t cfg_reg;
   logic                 cfg_block;  // Prevent changing config
+  logic                 msg_allowed; // MSG_FIFO from software is allowed
 
   ///////////////////////
   // Connect registers //
@@ -177,6 +178,17 @@
       cfg_reg <= reg2hw.cfg ;
     end
   end
+
+  // Open up the MSG_FIFO from the TL-UL port when it is ready
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      msg_allowed <= '0;
+    end else if (hash_start) begin
+      msg_allowed <= 1'b 1;
+    end else if (packer_flush_done) begin
+      msg_allowed <= 1'b 0;
+    end
+  end
   ////////////////
   // Interrupts //
   ////////////////
@@ -291,7 +303,7 @@
   // TL-UL to MSG_FIFO byte write handling
   logic msg_write;
 
-  assign msg_write = msg_fifo_req & msg_fifo_we & ~hmac_fifo_wsel;
+  assign msg_write = msg_fifo_req & msg_fifo_we & ~hmac_fifo_wsel & msg_allowed;
 
   logic [$clog2(32+1)-1:0] wmask_ones;
 
@@ -426,9 +438,11 @@
   /////////////////////////
   logic msg_push_sha_disabled, hash_start_sha_disabled, update_seckey_inprocess;
   logic hash_start_active;  // `reg_hash_start` set when hash already in active
+  logic msg_push_not_allowed; // Message is received when `hash_start` isn't set
   assign msg_push_sha_disabled = msg_write & ~sha_en;
   assign hash_start_sha_disabled = reg_hash_start & ~sha_en;
   assign hash_start_active = reg_hash_start & cfg_block;
+  assign msg_push_not_allowed = msg_fifo_req & ~msg_allowed;
 
   always_comb begin
     update_seckey_inprocess = 1'b0;
@@ -449,7 +463,8 @@
   // is pending to avoid any race conditions.
   assign err_valid = ~reg2hw.intr_state.hmac_err.q &
                    ( msg_push_sha_disabled | hash_start_sha_disabled
-                   | update_seckey_inprocess | hash_start_active);
+                   | update_seckey_inprocess | hash_start_active
+                   | msg_push_not_allowed );
 
   always_comb begin
     err_code = NoError;
@@ -469,6 +484,10 @@
         err_code = SwHashStartWhenActive;
       end
 
+      msg_push_not_allowed: begin
+        err_code = SwPushMsgWhenDisallowed;
+      end
+
       default: begin
         err_code = NoError;
       end
diff --git a/hw/ip/hmac/rtl/hmac_pkg.sv b/hw/ip/hmac/rtl/hmac_pkg.sv
index 32dd723..c93eae2 100644
--- a/hw/ip/hmac/rtl/hmac_pkg.sv
+++ b/hw/ip/hmac/rtl/hmac_pkg.sv
@@ -96,7 +96,8 @@
     SwPushMsgWhenShaDisabled   = 32'h 0000_0001,
     SwHashStartWhenShaDisabled = 32'h 0000_0002,
     SwUpdateSecretKeyInProcess = 32'h 0000_0003,
-    SwHashStartWhenActive      = 32'h 0000_0004
+    SwHashStartWhenActive      = 32'h 0000_0004,
+    SwPushMsgWhenDisallowed    = 32'h 0000_0005
   } err_code_e;
 
 endpackage : hmac_pkg