[otbn] Keep URND reseed request high until acknowledged
Prior to this change, the OTBN-internal URND reseed request signal was
high for a single cycle to communicate a request. This could be
counter-glitched to suppress a reseed request.
To harden against this glitch, the URND reseed request signal now
remains high until the reseed has been acknowledged.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
diff --git a/hw/ip/otbn/rtl/otbn_core.sv b/hw/ip/otbn/rtl/otbn_core.sv
index 99062a8..b1b6b30 100644
--- a/hw/ip/otbn/rtl/otbn_core.sv
+++ b/hw/ip/otbn/rtl/otbn_core.sv
@@ -206,7 +206,7 @@
logic rnd_fips_err;
logic urnd_reseed_req;
- logic urnd_reseed_busy;
+ logic urnd_reseed_ack;
logic urnd_advance;
logic urnd_advance_start_stop_control;
logic [WLEN-1:0] urnd_data;
@@ -262,7 +262,7 @@
.controller_start_o(controller_start),
.urnd_reseed_req_o (urnd_reseed_req),
- .urnd_reseed_busy_i(urnd_reseed_busy),
+ .urnd_reseed_ack_i (urnd_reseed_ack),
.urnd_advance_o (urnd_advance_start_stop_control),
.start_secure_wipe_i (start_secure_wipe),
@@ -795,7 +795,7 @@
.rnd_fips_err_o (rnd_fips_err),
.urnd_reseed_req_i (urnd_reseed_req),
- .urnd_reseed_busy_o(urnd_reseed_busy),
+ .urnd_reseed_ack_o (urnd_reseed_ack),
.urnd_advance_i (urnd_advance),
.urnd_data_o (urnd_data),
.urnd_all_zero_o (urnd_all_zero),
diff --git a/hw/ip/otbn/rtl/otbn_rnd.sv b/hw/ip/otbn/rtl/otbn_rnd.sv
index e85e87f..61071ce 100644
--- a/hw/ip/otbn/rtl/otbn_rnd.sv
+++ b/hw/ip/otbn/rtl/otbn_rnd.sv
@@ -38,8 +38,8 @@
// Request URND PRNG reseed from the EDN
input logic urnd_reseed_req_i,
- // Remains asserted whilst reseed is in progress
- output logic urnd_reseed_busy_o,
+ // Acknowledge URND PRNG reseed from the EDN
+ output logic urnd_reseed_ack_o,
// When asserted PRNG state advances. It is permissible to advance the state whilst
// reseeding.
input logic urnd_advance_i,
@@ -165,10 +165,13 @@
logic edn_urnd_req_q, edn_urnd_req_d;
assign edn_urnd_req_complete = edn_urnd_req_o & edn_urnd_ack_i;
+
+ // Keep EDN URND request high even if input URND reseed request goes low before the reseed has
+ // completed.
assign edn_urnd_req_d = (edn_urnd_req_q | urnd_reseed_req_i) & ~edn_urnd_req_complete;
assign edn_urnd_req_o = edn_urnd_req_q;
- assign urnd_reseed_busy_o = edn_urnd_req_q;
+ assign urnd_reseed_ack_o = edn_urnd_ack_i;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
diff --git a/hw/ip/otbn/rtl/otbn_start_stop_control.sv b/hw/ip/otbn/rtl/otbn_start_stop_control.sv
index 0e3a23d..1757a50 100644
--- a/hw/ip/otbn/rtl/otbn_start_stop_control.sv
+++ b/hw/ip/otbn/rtl/otbn_start_stop_control.sv
@@ -38,7 +38,7 @@
output logic controller_start_o,
output logic urnd_reseed_req_o,
- input logic urnd_reseed_busy_i,
+ input logic urnd_reseed_ack_i,
output logic urnd_advance_o,
input logic start_secure_wipe_i,
@@ -118,9 +118,10 @@
end
end
OtbnStartStopStateUrndRefresh: begin
+ urnd_reseed_req_o = 1'b1;
if (stop) begin
state_d = OtbnStartStopStateLocked;
- end else if (!urnd_reseed_busy_i) begin
+ end else if (urnd_reseed_ack_i) begin
state_d = OtbnStartStopStateRunning;
end
end
@@ -194,7 +195,7 @@
end
// Logic separate from main FSM code to avoid false combinational loop warning from verilator
- assign controller_start_o = (state_q == OtbnStartStopStateUrndRefresh) & !urnd_reseed_busy_i;
+ assign controller_start_o = (state_q == OtbnStartStopStateUrndRefresh) & urnd_reseed_ack_i;
assign done_o = ((state_q == OtbnStartStopSecureWipeComplete) ||
(stop && (state_q == OtbnStartStopStateUrndRefresh)));