[aes] Hold EDN request until acknowledgment in case of fatal alerts
Previously, AES would drop a potentially asserted EDN request signal in
case of a fatal alert which could leave the EDN interface including CDC
in a weird state. With this commit, the request signal is always kept
asserted until acknowledgment which is similar to what other entropy
consumers do.
This is related to lowRISC/OpenTitan#10991.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/ip/aes/rtl/aes.sv b/hw/ip/aes/rtl/aes.sv
index f46a05a..28defc5 100644
--- a/hw/ip/aes/rtl/aes.sv
+++ b/hw/ip/aes/rtl/aes.sv
@@ -71,15 +71,16 @@
aes_hw2reg_t hw2reg;
logic [NumAlerts-1:0] alert;
- lc_ctrl_pkg::lc_tx_t [1:0] lc_escalate_en;
+ lc_ctrl_pkg::lc_tx_t lc_escalate_en;
+ logic edn_req_int;
+ logic edn_req_hold_d, edn_req_hold_q;
logic edn_req;
logic edn_ack;
logic [EntropyWidth-1:0] edn_data;
logic unused_edn_fips;
logic entropy_clearing_req, entropy_masking_req;
logic entropy_clearing_ack, entropy_masking_ack;
- logic edn_req_chk;
////////////
// Inputs //
@@ -106,7 +107,7 @@
// SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI
// Synchronize life cycle input
prim_lc_sync #(
- .NumCopies (2)
+ .NumCopies (1)
) u_prim_lc_sync (
.clk_i,
.rst_ni,
@@ -114,9 +115,33 @@
.lc_en_o ( {lc_escalate_en} )
);
+ ///////////////////
+ // EDN Interface //
+ ///////////////////
+
+ // Internally, we have up to two PRNGs that share the EDN interface for reseeding. Here, we just
+ // arbitrate the requests. Upsizing of the entropy to the correct width is performed inside the
+ // PRNGs.
+ // Reseed operations for the clearing PRNG are initiated by software. Reseed operations for the
+ // masking PRNG can also be automatically initiated.
+ assign edn_req_int = entropy_clearing_req | entropy_masking_req;
+ // Only forward ACK to PRNG currently requesting entropy. Give higher priority to clearing PRNG.
+ assign entropy_clearing_ack = entropy_clearing_req & edn_ack;
+ assign entropy_masking_ack = ~entropy_clearing_req & entropy_masking_req & edn_ack;
+
// Upon escalation or detection of a fatal alert, an EDN request signal can be dropped before
- // getting acknowledged. This is okay as the module will need to be reset anyway.
- assign edn_req_chk = (lc_escalate_en[0] == lc_ctrl_pkg::Off) & ~alert[1];
+ // getting acknowledged. This is okay with respect to AES as the module will need to be reset
+ // anyway. However, to not leave EDN in a strange state, we hold the request until it's actually
+ // acknowledged.
+ assign edn_req = edn_req_int | edn_req_hold_q;
+ assign edn_req_hold_d = (edn_req_hold_q | edn_req) & ~edn_ack;
+ always_ff @(posedge clk_i or negedge rst_ni) begin : edn_req_reg
+ if (!rst_ni) begin
+ edn_req_hold_q <= '0;
+ end else begin
+ edn_req_hold_q <= edn_req_hold_d;
+ end
+ end
// Synchronize EDN interface
prim_sync_reqack_data #(
@@ -128,7 +153,7 @@
.rst_src_ni ( rst_ni ),
.clk_dst_i ( clk_edn_i ),
.rst_dst_ni ( rst_edn_ni ),
- .req_chk_i ( edn_req_chk ),
+ .req_chk_i ( 1'b1 ),
.src_req_i ( edn_req ),
.src_ack_o ( edn_ack ),
.dst_req_o ( edn_o.edn_req ),
@@ -143,18 +168,6 @@
// Core //
//////////
- // Entropy distribution
- // Internally, we have up to two PRNGs that share the EDN interface for reseeding. Here, we just
- // arbitrate the requests. Upsizing of the entropy to the correct width is performed inside the
- // PRNGs.
- // Reseed operations for the clearing PRNG are initiated by software. Reseed operations for the
- // masking PRNG are automatically initiated. Reseeding operations of the two PRNGs are not
- // expected to take place simultaneously.
- assign edn_req = entropy_clearing_req | entropy_masking_req;
- // Only forward ACK to PRNG currently requesting entropy. Give higher priority to clearing PRNG.
- assign entropy_clearing_ack = entropy_clearing_req & edn_ack;
- assign entropy_masking_ack = ~entropy_clearing_req & entropy_masking_req & edn_ack;
-
// AES core
aes_core #(
.AES192Enable ( AES192Enable ),
@@ -182,7 +195,7 @@
.keymgr_key_i ( keymgr_key_i ),
- .lc_escalate_en_i ( lc_escalate_en[1] ),
+ .lc_escalate_en_i ( lc_escalate_en ),
.intg_err_alert_i ( intg_err_alert ),
.alert_recov_o ( alert[0] ),