[csrng/rtl] sw port data attack check added
For the software port only, the returned genbits will have a repeated data check before genbits are returned to the register interface.
Signed-off-by: Mark Branstad <mark.branstad@wdc.com>
diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson
index 905e554..bdaf73a 100644
--- a/hw/ip/csrng/data/csrng.hjson
+++ b/hw/ip/csrng/data/csrng.hjson
@@ -316,6 +316,14 @@
Writing a zero resets this status bit.
'''
}
+ { bits: "12",
+ name: "CS_BUS_CMP_ALERT",
+ desc: '''
+ This bit is set when the software application port genbits bus value is equal
+ to the prior valid value on the bus, indicating a possible attack.
+ Writing a zero resets this status bit.
+ '''
+ }
]
},
{
diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv
index d41656e..c826b30 100644
--- a/hw/ip/csrng/rtl/csrng_core.sv
+++ b/hw/ip/csrng/rtl/csrng_core.sv
@@ -336,6 +336,9 @@
logic [7:0] track_sm[16];
logic [1:0] sel_track_sm_grp;
+ logic cs_rdata_capt_vld;
+ logic cs_bus_cmp_alert;
+
logic unused_err_code_test_bit;
logic unused_reg2hw_genbits;
logic unused_int_state_val;
@@ -353,6 +356,8 @@
logic cs_aes_halt_q, cs_aes_halt_d;
logic [SeedLen-1:0] entropy_src_seed_q, entropy_src_seed_d;
logic entropy_src_fips_q, entropy_src_fips_d;
+ logic [63:0] cs_rdata_capt_q, cs_rdata_capt_d;
+ logic cs_rdata_capt_vld_q, cs_rdata_capt_vld_d;
always_ff @(posedge clk_i or negedge rst_ni)
if (!rst_ni) begin
@@ -368,6 +373,8 @@
cs_aes_halt_q <= '0;
entropy_src_seed_q <= '0;
entropy_src_fips_q <= '0;
+ cs_rdata_capt_q <= '0;
+ cs_rdata_capt_vld_q <= '0;
end else begin
acmd_q <= acmd_d;
shid_q <= shid_d;
@@ -381,6 +388,8 @@
cs_aes_halt_q <= cs_aes_halt_d;
entropy_src_seed_q <= entropy_src_seed_d;
entropy_src_fips_q <= entropy_src_fips_d;
+ cs_rdata_capt_q <= cs_rdata_capt_d;
+ cs_rdata_capt_vld_q <= cs_rdata_capt_vld_d;
end
//--------------------------------------------
@@ -676,7 +685,10 @@
};
- assign recov_alert_event = cs_enable_pfa || sw_app_enable_pfa || read_int_state_pfa;
+ assign recov_alert_event = cs_enable_pfa ||
+ sw_app_enable_pfa ||
+ read_int_state_pfa ||
+ cs_bus_cmp_alert;
assign recov_alert_o = recov_alert_event;
@@ -804,6 +816,32 @@
assign genbits_stage_fips_sw = genbits_stage_fips_sw_q;
+
+ //--------------------------------------------
+ // data path integrity check
+ // - a counter measure to software genbits bus tampering
+ // - checks to make sure repeated data sets off
+ // an alert for sw to handle
+ //--------------------------------------------
+
+ // capture a copy of the genbits data
+ assign cs_rdata_capt_vld = (genbits_stage_vld[NApps-1] && genbits_stage_rdy[NApps-1]);
+
+ assign cs_rdata_capt_d = cs_rdata_capt_vld ? genbits_stage_bus[NApps-1][63:0] : cs_rdata_capt_q;
+
+ assign cs_rdata_capt_vld_d =
+ !cs_enable ? 1'b0 :
+ cs_rdata_capt_vld ? 1'b1 :
+ cs_rdata_capt_vld_q;
+
+ // continuous compare of the entropy data for sw port
+ assign cs_bus_cmp_alert = cs_rdata_capt_vld && cs_rdata_capt_vld_q &&
+ (cs_rdata_capt_q == genbits_stage_bus[NApps-1][63:0]); // only look at 64 bits
+
+ assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.de = cs_bus_cmp_alert;
+ assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.d = cs_bus_cmp_alert;
+
+
// HW interface connections (up to 16, numbered 0-14)
for (genvar hai = 0; hai < (NApps-1); hai = hai+1) begin : gen_app_if
// cmd req
diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
index 777d48d..400066b 100644
--- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
@@ -182,6 +182,10 @@
logic d;
logic de;
} read_int_state_field_alert;
+ struct packed {
+ logic d;
+ logic de;
+ } cs_bus_cmp_alert;
} csrng_hw2reg_recov_alert_sts_reg_t;
typedef struct packed {
@@ -327,13 +331,13 @@
// HW -> register type
typedef struct packed {
- csrng_hw2reg_intr_state_reg_t intr_state; // [187:180]
- csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [179:176]
- csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [175:174]
- csrng_hw2reg_genbits_reg_t genbits; // [173:142]
- csrng_hw2reg_int_state_val_reg_t int_state_val; // [141:110]
- csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [109:94]
- csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [93:88]
+ csrng_hw2reg_intr_state_reg_t intr_state; // [189:182]
+ csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [181:178]
+ csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [177:176]
+ csrng_hw2reg_genbits_reg_t genbits; // [175:144]
+ csrng_hw2reg_int_state_val_reg_t int_state_val; // [143:112]
+ csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [111:96]
+ csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [95:88]
csrng_hw2reg_err_code_reg_t err_code; // [87:36]
csrng_hw2reg_tracking_sm_obs_reg_t tracking_sm_obs; // [35:0]
} csrng_hw2reg_t;
@@ -408,7 +412,7 @@
4'b 0001, // index[10] CSRNG_INT_STATE_NUM
4'b 1111, // index[11] CSRNG_INT_STATE_VAL
4'b 0011, // index[12] CSRNG_HW_EXC_STS
- 4'b 0001, // index[13] CSRNG_RECOV_ALERT_STS
+ 4'b 0011, // index[13] CSRNG_RECOV_ALERT_STS
4'b 1111, // index[14] CSRNG_ERR_CODE
4'b 0001, // index[15] CSRNG_ERR_CODE_TEST
4'b 0001, // index[16] CSRNG_SEL_TRACKING_SM
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index cee589c..96c4861 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -168,6 +168,8 @@
logic recov_alert_sts_sw_app_enable_field_alert_wd;
logic recov_alert_sts_read_int_state_field_alert_qs;
logic recov_alert_sts_read_int_state_field_alert_wd;
+ logic recov_alert_sts_cs_bus_cmp_alert_qs;
+ logic recov_alert_sts_cs_bus_cmp_alert_wd;
logic err_code_sfifo_cmd_err_qs;
logic err_code_sfifo_genbits_err_qs;
logic err_code_sfifo_cmdreq_err_qs;
@@ -866,6 +868,31 @@
.qs (recov_alert_sts_read_int_state_field_alert_qs)
);
+ // F[cs_bus_cmp_alert]: 12:12
+ prim_subreg #(
+ .DW (1),
+ .SwAccess(prim_subreg_pkg::SwAccessW0C),
+ .RESVAL (1'h0)
+ ) u_recov_alert_sts_cs_bus_cmp_alert (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (recov_alert_sts_we),
+ .wd (recov_alert_sts_cs_bus_cmp_alert_wd),
+
+ // from internal hardware
+ .de (hw2reg.recov_alert_sts.cs_bus_cmp_alert.de),
+ .d (hw2reg.recov_alert_sts.cs_bus_cmp_alert.d),
+
+ // to internal hardware
+ .qe (),
+ .q (),
+
+ // to register interface (read)
+ .qs (recov_alert_sts_cs_bus_cmp_alert_qs)
+ );
+
// R[err_code]: V(False)
// F[sfifo_cmd_err]: 0:0
@@ -1782,6 +1809,8 @@
assign recov_alert_sts_sw_app_enable_field_alert_wd = reg_wdata[1];
assign recov_alert_sts_read_int_state_field_alert_wd = reg_wdata[2];
+
+ assign recov_alert_sts_cs_bus_cmp_alert_wd = reg_wdata[12];
assign err_code_test_we = addr_hit[15] & reg_we & !reg_error;
assign err_code_test_wd = reg_wdata[4:0];
@@ -1863,6 +1892,7 @@
reg_rdata_next[0] = recov_alert_sts_enable_field_alert_qs;
reg_rdata_next[1] = recov_alert_sts_sw_app_enable_field_alert_qs;
reg_rdata_next[2] = recov_alert_sts_read_int_state_field_alert_qs;
+ reg_rdata_next[12] = recov_alert_sts_cs_bus_cmp_alert_qs;
end
addr_hit[14]: begin