From 7f84f7cdb836718b7e2605fe628c537309bb527f Mon Sep 17 00:00:00 2001 From: Hakim Filali Date: Tue, 30 Apr 2024 16:50:40 +0000 Subject: [PATCH] [csrng/rtl] Add reseed interval status error This commit adds a new status error response, that is triggered whenever the number of generates between reseeds exceeds the reseed_interval. Signed-off-by: Hakim Filali --- hw/ip/csrng/data/csrng.hjson | 36 ++++- hw/ip/csrng/doc/registers.md | 109 ++++++++----- hw/ip/csrng/dv/env/csrng_scoreboard.sv | 6 +- hw/ip/csrng/rtl/csrng_cmd_stage.sv | 45 ++++-- hw/ip/csrng/rtl/csrng_core.sv | 25 ++- hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv | 4 +- hw/ip/csrng/rtl/csrng_pkg.sv | 3 +- hw/ip/csrng/rtl/csrng_reg_pkg.sv | 83 +++++----- hw/ip/csrng/rtl/csrng_reg_top.sv | 171 +++++++++++++++------ hw/ip/edn/data/edn.hjson | 4 +- hw/ip/edn/doc/registers.md | 16 +- hw/ip/edn/rtl/edn_reg_pkg.sv | 10 +- hw/ip/edn/rtl/edn_reg_top.sv | 20 +-- sw/device/lib/crypto/drivers/entropy_kat.c | 4 +- sw/device/lib/dif/dif_csrng.h | 13 +- sw/device/lib/dif/dif_csrng_unittest.cc | 2 +- sw/device/lib/testing/aes_testutils.c | 6 +- sw/device/lib/testing/csrng_testutils.c | 4 +- 18 files changed, 391 insertions(+), 170 deletions(-) diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson index 829cbd3679cc2..fe19326e6725c 100644 --- a/hw/ip/csrng/data/csrng.hjson +++ b/hw/ip/csrng/data/csrng.hjson @@ -317,6 +317,29 @@ } ] }, + { name: "RESEED_INTERVAL", + desc: "CSRNG maximum number of generate requests allowed between reseeds register", + swaccess: "rw", + hwaccess: "hro", + hwqe: "true", + fields: [ + { bits: "31:0", + name: "RESEED_INTERVAL", + desc: ''' + Setting this field will set the number of generate requests that can be + made to CSRNG before a reseed request needs to be made. + This register supports a maximum of 2^32 requests between reseeds. + This register will be compared to a counter, which counts the number of + generate commands between reseed or instantiate commands. + If the counter reaches the value of this register, the violating command + will be acknowledged with a status error. + If the violating command was issued by a HW instance, an interrupt will + be triggered. + ''' + resval: 0xffff_ffff + } + ] + }, { name: "SW_CMD_STS", desc: "Application interface command status register", @@ -346,7 +369,7 @@ ''' resval: "0" } - { bits: "4:3", + { bits: "5:3", name: "CMD_STS", desc: ''' This field represents the status code returned with the application command ack. @@ -364,6 +387,8 @@ 0x3: This error indicates that the last command was issued out of sequence. This happens when a command other than instantiate was issued without sending an instantiate command first. This can also happen when an uninstantiate command is sent without instantiating first. + 0x4: This error indicates that the number of generate commands between reseeds exceeded the maximum number allowed. + This happens only for generate commands. ''' resval: "0" } @@ -541,6 +566,15 @@ Writing a zero resets this status bit. ''' } + { bits: "15", + name: "CMD_STAGE_RESEED_CNT_ALERT", + desc: ''' + This bit is set when the maximum number of generate requests between reseeds is + exceeded. + The invalid generate command is ignored and CSRNG continues to operate. + Writing a zero resets this status bit. + ''' + } ] }, { diff --git a/hw/ip/csrng/doc/registers.md b/hw/ip/csrng/doc/registers.md index 4cbee03f72ee0..84864d6770d6b 100644 --- a/hw/ip/csrng/doc/registers.md +++ b/hw/ip/csrng/doc/registers.md @@ -3,25 +3,26 @@ ## Summary -| Name | Offset | Length | Description | -|:--------------------------------------------|:---------|---------:|:-------------------------------------------------------| -| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | -| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | -| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | -| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x1c | 4 | Application interface command status register | -| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x20 | 4 | Generate bits returned valid register | -| csrng.[`GENBITS`](#genbits) | 0x24 | 4 | Generate bits returned register | -| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x28 | 4 | Internal state number register | -| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x2c | 4 | Internal state read access register | -| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x30 | 4 | Hardware instance exception status register | -| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x34 | 4 | Recoverable alert status register | -| csrng.[`ERR_CODE`](#err_code) | 0x38 | 4 | Hardware detection of error conditions status register | -| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x3c | 4 | Test error conditions register | -| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x40 | 4 | Main state machine state debug register | +| Name | Offset | Length | Description | +|:--------------------------------------------|:---------|---------:|:---------------------------------------------------------------------------| +| csrng.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | +| csrng.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | +| csrng.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | +| csrng.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | +| csrng.[`REGWEN`](#regwen) | 0x10 | 4 | Register write enable for all control registers | +| csrng.[`CTRL`](#ctrl) | 0x14 | 4 | Control register | +| csrng.[`CMD_REQ`](#cmd_req) | 0x18 | 4 | Command request register | +| csrng.[`RESEED_INTERVAL`](#reseed_interval) | 0x1c | 4 | CSRNG maximum number of generate requests allowed between reseeds register | +| csrng.[`SW_CMD_STS`](#sw_cmd_sts) | 0x20 | 4 | Application interface command status register | +| csrng.[`GENBITS_VLD`](#genbits_vld) | 0x24 | 4 | Generate bits returned valid register | +| csrng.[`GENBITS`](#genbits) | 0x28 | 4 | Generate bits returned register | +| csrng.[`INT_STATE_NUM`](#int_state_num) | 0x2c | 4 | Internal state number register | +| csrng.[`INT_STATE_VAL`](#int_state_val) | 0x30 | 4 | Internal state read access register | +| csrng.[`HW_EXC_STS`](#hw_exc_sts) | 0x34 | 4 | Hardware instance exception status register | +| csrng.[`RECOV_ALERT_STS`](#recov_alert_sts) | 0x38 | 4 | Recoverable alert status register | +| csrng.[`ERR_CODE`](#err_code) | 0x3c | 4 | Hardware detection of error conditions status register | +| csrng.[`ERR_CODE_TEST`](#err_code_test) | 0x40 | 4 | Test error conditions register | +| csrng.[`MAIN_SM_STATE`](#main_sm_state) | 0x44 | 4 | Main state machine state debug register | ## INTR_STATE Interrupt State Register @@ -154,22 +155,49 @@ Command request register |:------:|:------:|:-------:|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 31:0 | wo | 0x0 | CMD_REQ | Writing this request with defined CSRNG commands will initiate all possible CSRNG actions. The application interface must wait for the "ack" to return before issuing new commands. | +## RESEED_INTERVAL +CSRNG maximum number of generate requests allowed between reseeds register +- Offset: `0x1c` +- Reset default: `0xffffffff` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "RESEED_INTERVAL", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:----------:|:-----------------------------------------------------| +| 31:0 | rw | 0xffffffff | [RESEED_INTERVAL](#reseed_interval--reseed_interval) | + +### RESEED_INTERVAL . RESEED_INTERVAL +Setting this field will set the number of generate requests that can be +made to CSRNG before a reseed request needs to be made. +This register supports a maximum of 2^32 requests between reseeds. +This register will be compared to a counter, which counts the number of +generate commands between reseed or instantiate commands. +If the counter reaches the value of this register, the violating command +will be acknowledged with a status error. +If the violating command was issued by a HW instance, an interrupt will +be triggered. + ## SW_CMD_STS Application interface command status register -- Offset: `0x1c` +- Offset: `0x20` - Reset default: `0x0` -- Reset mask: `0x1e` +- Reset mask: `0x3e` ### Fields ```wavejson -{"reg": [{"bits": 1}, {"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 2, "attr": ["ro"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 90}} +{"reg": [{"bits": 1}, {"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 3, "attr": ["ro"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 90}} ``` | Bits | Type | Reset | Name | |:------:|:------:|:-------:|:--------------------------------| -| 31:5 | | | Reserved | -| 4:3 | ro | 0x0 | [CMD_STS](#sw_cmd_sts--cmd_sts) | +| 31:6 | | | Reserved | +| 5:3 | ro | 0x0 | [CMD_STS](#sw_cmd_sts--cmd_sts) | | 2 | ro | 0x0 | [CMD_ACK](#sw_cmd_sts--cmd_ack) | | 1 | ro | 0x0 | [CMD_RDY](#sw_cmd_sts--cmd_rdy) | @@ -189,6 +217,8 @@ To check whether a command was succesful, wait for [`INTR_STATE.CS_CMD_REQ_DONE` 0x3: This error indicates that the last command was issued out of sequence. This happens when a command other than instantiate was issued without sending an instantiate command first. This can also happen when an uninstantiate command is sent without instantiating first. +0x4: This error indicates that the number of generate commands between reseeds exceeded the maximum number allowed. + This happens only for generate commands. ### SW_CMD_STS . CMD_ACK This one bit field indicates when a SW command has been acknowledged by the CSRNG. @@ -205,7 +235,7 @@ Before starting to write a new command to [`SW_CMD_REQ`](#sw_cmd_req), this fiel ## GENBITS_VLD Generate bits returned valid register -- Offset: `0x20` +- Offset: `0x24` - Reset default: `0x0` - Reset mask: `0x3` @@ -223,7 +253,7 @@ Generate bits returned valid register ## GENBITS Generate bits returned register -- Offset: `0x24` +- Offset: `0x28` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -249,7 +279,7 @@ Otherwise, the register reads as 0. ## INT_STATE_NUM Internal state number register -- Offset: `0x28` +- Offset: `0x2c` - Reset default: `0x0` - Reset mask: `0xf` @@ -277,7 +307,7 @@ that the [`INT_STATE_VAL`](#int_state_val) read back is accurate. ## INT_STATE_VAL Internal state read access register -- Offset: `0x2c` +- Offset: `0x30` - Reset default: `0x0` - Reset mask: `0xffffffff` @@ -304,7 +334,7 @@ Otherwise, the register reads as 0. ## HW_EXC_STS Hardware instance exception status register -- Offset: `0x30` +- Offset: `0x34` - Reset default: `0x0` - Reset mask: `0xffff` @@ -329,19 +359,20 @@ resets the status bits. ## RECOV_ALERT_STS Recoverable alert status register -- Offset: `0x34` +- Offset: `0x38` - Reset default: `0x0` -- Reset mask: `0x700f` +- Reset mask: `0xf00f` ### Fields ```wavejson -{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 17}], "config": {"lanes": 1, "fontsize": 10, "vspace": 280}} +{"reg": [{"name": "ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "SW_APP_ENABLE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "READ_INT_STATE_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "ACMD_FLAG0_FIELD_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 8}, {"name": "CS_BUS_CMP_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CS_MAIN_SM_INVALID_CMD_SEQ", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CMD_STAGE_RESEED_CNT_ALERT", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 280}} ``` | Bits | Type | Reset | Name | |:------:|:------:|:-------:|:---------------------------------------------------------------------------| -| 31:15 | | | Reserved | +| 31:16 | | | Reserved | +| 15 | rw0c | 0x0 | [CMD_STAGE_RESEED_CNT_ALERT](#recov_alert_sts--cmd_stage_reseed_cnt_alert) | | 14 | rw0c | 0x0 | [CS_MAIN_SM_INVALID_CMD_SEQ](#recov_alert_sts--cs_main_sm_invalid_cmd_seq) | | 13 | rw0c | 0x0 | [CS_MAIN_SM_ALERT](#recov_alert_sts--cs_main_sm_alert) | | 12 | rw0c | 0x0 | [CS_BUS_CMP_ALERT](#recov_alert_sts--cs_bus_cmp_alert) | @@ -351,6 +382,12 @@ Recoverable alert status register | 1 | rw0c | 0x0 | [SW_APP_ENABLE_FIELD_ALERT](#recov_alert_sts--sw_app_enable_field_alert) | | 0 | rw0c | 0x0 | [ENABLE_FIELD_ALERT](#recov_alert_sts--enable_field_alert) | +### RECOV_ALERT_STS . CMD_STAGE_RESEED_CNT_ALERT +This bit is set when the maximum number of generate requests between reseeds is +exceeded. +The invalid generate command is ignored and CSRNG continues to operate. +Writing a zero resets this status bit. + ### RECOV_ALERT_STS . CS_MAIN_SM_INVALID_CMD_SEQ This bit is set when an out of order command is received by the main state machine. This happens when an instantiate command is sent for a state that was already @@ -392,7 +429,7 @@ Writing a zero resets this status bit. ## ERR_CODE Hardware detection of error conditions status register -- Offset: `0x38` +- Offset: `0x3c` - Reset default: `0x0` - Reset mask: `0x77f0ffff` @@ -593,7 +630,7 @@ This bit will stay set until the next reset. ## ERR_CODE_TEST Test error conditions register -- Offset: `0x3c` +- Offset: `0x40` - Reset default: `0x0` - Reset mask: `0x1f` - Register enable: [`REGWEN`](#regwen) @@ -619,7 +656,7 @@ an interrupt or an alert. ## MAIN_SM_STATE Main state machine state debug register -- Offset: `0x40` +- Offset: `0x44` - Reset default: `0x4e` - Reset mask: `0xff` diff --git a/hw/ip/csrng/dv/env/csrng_scoreboard.sv b/hw/ip/csrng/dv/env/csrng_scoreboard.sv index c48b038eab993..ee9ce06f12915 100644 --- a/hw/ip/csrng/dv/env/csrng_scoreboard.sv +++ b/hw/ip/csrng/dv/env/csrng_scoreboard.sv @@ -266,6 +266,8 @@ class csrng_scoreboard extends cip_base_scoreboard #( end end end + "reseed_interval": begin + end "sw_cmd_sts": begin do_read_check = 1'b0; end @@ -447,7 +449,7 @@ class csrng_scoreboard extends cip_base_scoreboard #( cfg.key[app] = 'h0; cfg.v[app] = 'h0; ctr_drbg_update(app, seed_material); - cfg.reseed_counter[app] = 1'b1; + cfg.reseed_counter[app] = 1'b0; cfg.compliance[app] = fips; cfg.status[app] = 1'b1; cov_vif.cg_csrng_state_db_sample(cfg.compliance[app], compliance_previous, app); @@ -464,7 +466,7 @@ class csrng_scoreboard extends cip_base_scoreboard #( `uvm_info(`gfn, $sformatf("Reseed of app %0d", app), UVM_MEDIUM) seed_material = entropy_input ^ additional_input; ctr_drbg_update(app, seed_material); - cfg.reseed_counter[app] = 1'b1; + cfg.reseed_counter[app] = 1'b0; cfg.compliance[app] = fips; cov_vif.cg_csrng_state_db_sample(cfg.compliance[app], compliance_previous, app); endfunction diff --git a/hw/ip/csrng/rtl/csrng_cmd_stage.sv b/hw/ip/csrng/rtl/csrng_cmd_stage.sv index d69ac8c894254..2dcfaba1abd79 100644 --- a/hw/ip/csrng/rtl/csrng_cmd_stage.sv +++ b/hw/ip/csrng/rtl/csrng_cmd_stage.sv @@ -18,6 +18,9 @@ module csrng_cmd_stage import csrng_pkg::*; #( input logic [StateId-1:0] cmd_stage_shid_i, input logic [CmdFifoWidth-1:0] cmd_stage_bus_i, output logic cmd_stage_rdy_o, + // Command checking interface. + input logic reseed_cnt_reached_i, + output logic reseed_cnt_alert_o, // Command to arbiter. output logic cmd_arb_req_o, output logic cmd_arb_sop_o, @@ -72,16 +75,19 @@ module csrng_cmd_stage import csrng_pkg::*; #( logic sfifo_genbits_not_empty; // Command signals. - logic [3:0] cmd_len; - logic cmd_fifo_zero; - logic cmd_fifo_pop; - logic cmd_len_dec; - logic cmd_gen_cnt_dec; - logic cmd_gen_1st_req; - logic cmd_gen_inc_req; - logic cmd_gen_cnt_last; - logic cmd_final_ack; + logic [3:0] cmd_len; + logic cmd_fifo_zero; + logic cmd_fifo_pop; + logic cmd_len_dec; + logic cmd_gen_cnt_dec; + logic cmd_gen_1st_req; + logic cmd_gen_inc_req; + logic cmd_gen_cnt_last; + logic cmd_final_ack; + logic cmd_err_ack; logic [GenBitsCntrWidth-1:0] cmd_gen_cnt; + csrng_cmd_sts_e err_sts; + logic reseed_cnt_exceeded; // Flops. logic cmd_ack_q, cmd_ack_d; @@ -255,6 +261,8 @@ module csrng_cmd_stage import csrng_pkg::*; #( cmd_arb_mop_o = 1'b0; cmd_arb_eop_o = 1'b0; cmd_stage_sm_err_o = 1'b0; + cmd_err_ack = 1'b0; + reseed_cnt_exceeded = 1'b0; if (state_q == Error) begin // In case we are in the Error state we must ignore the local escalate and enable signals. @@ -272,7 +280,15 @@ module csrng_cmd_stage import csrng_pkg::*; #( Idle: begin // Because of the if statement above we won't leave idle if enable is low. if (!cmd_fifo_zero) begin - state_d = ArbGnt; + // If the issued command is GEN and the reseed count has already been reached, send an + // ack with an error status response. + if ((sfifo_cmd_rdata[2:0] == GEN) && reseed_cnt_reached_i) begin + cmd_err_ack = 1'b1; + reseed_cnt_exceeded = 1'b1; + state_d = Idle; + end else begin + state_d = ArbGnt; + end end end ArbGnt: begin @@ -310,7 +326,7 @@ module csrng_cmd_stage import csrng_pkg::*; #( end GenCmdChk: begin if (cmd_gen_flag_q) begin - cmd_gen_cnt_dec= 1'b1; + cmd_gen_cnt_dec = 1'b1; end state_d = CmdAck; end @@ -429,17 +445,22 @@ module csrng_cmd_stage import csrng_pkg::*; #( assign cmd_ack_d = (!cs_enable_i) ? '0 : - cmd_final_ack; + cmd_final_ack || cmd_err_ack; assign cmd_stage_ack_o = cmd_ack_q; + assign err_sts = reseed_cnt_exceeded ? CMD_STS_RESEED_CNT_EXCEEDED : CMD_STS_SUCCESS; + assign cmd_ack_sts_d = (!cs_enable_i) ? CMD_STS_SUCCESS : + cmd_err_ack ? err_sts : cmd_final_ack ? cmd_ack_sts_i : cmd_ack_sts_q; assign cmd_stage_ack_sts_o = cmd_ack_sts_q; + assign reseed_cnt_alert_o = reseed_cnt_exceeded; + // Make sure that the state machine has a stable error state. This means that after the error // state is entered it will not exit it unless a reset signal is received. `ASSERT(CsrngCmdStageErrorStStable_A, state_q == Error |=> $stable(state_q)) diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv index 7283e50a4f717..21f5c0812bb18 100644 --- a/hw/ip/csrng/rtl/csrng_core.sv +++ b/hw/ip/csrng/rtl/csrng_core.sv @@ -349,12 +349,14 @@ module csrng_core import csrng_pkg::*; #( logic cs_rdata_capt_vld; logic cs_bus_cmp_alert; logic cmd_rdy; + logic [NApps-1:0] reseed_cnt_alert; logic sw_sts_ack; logic [1:0] efuse_sw_app_enable; logic unused_err_code_test_bit; logic unused_reg2hw_genbits; logic unused_int_state_val; + logic unused_reseed_interval; prim_mubi_pkg::mubi8_t [1:0] en_csrng_sw_app_read; prim_mubi_pkg::mubi4_t [CsEnableCopies-1:0] mubi_cs_enable_fanout; @@ -377,6 +379,7 @@ module csrng_core import csrng_pkg::*; #( logic cs_rdata_capt_vld_q, cs_rdata_capt_vld_d; logic sw_rdy_sts_q, sw_rdy_sts_d; logic sw_sts_ack_q, sw_sts_ack_d; + logic [NApps-1:0] reseed_cnt_reached_q, reseed_cnt_reached_d; always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin @@ -396,6 +399,7 @@ module csrng_core import csrng_pkg::*; #( cs_rdata_capt_vld_q <= '0; sw_rdy_sts_q <= '0; sw_sts_ack_q <= '0; + reseed_cnt_reached_q <= '0; end else begin acmd_q <= acmd_d; shid_q <= shid_d; @@ -413,6 +417,7 @@ module csrng_core import csrng_pkg::*; #( cs_rdata_capt_vld_q <= cs_rdata_capt_vld_d; sw_rdy_sts_q <= sw_rdy_sts_d; sw_sts_ack_q <= sw_sts_ack_d; + reseed_cnt_reached_q <= reseed_cnt_reached_d; end end @@ -739,6 +744,7 @@ module csrng_core import csrng_pkg::*; #( acmd_flag0_pfa || cs_main_sm_alert || cs_main_sm_invalid_cmd_seq || + |reseed_cnt_alert || cs_bus_cmp_alert; @@ -845,6 +851,8 @@ module csrng_core import csrng_pkg::*; #( .cmd_stage_shid_i (cmd_stage_shid[ai]), .cmd_stage_bus_i (cmd_stage_bus[ai]), .cmd_stage_rdy_o (cmd_stage_rdy[ai]), + .reseed_cnt_reached_i (reseed_cnt_reached_q[ai]), + .reseed_cnt_alert_o (reseed_cnt_alert[ai]), .cmd_arb_req_o (cmd_arb_req[ai]), .cmd_arb_sop_o (cmd_arb_sop[ai]), .cmd_arb_mop_o (cmd_arb_mop[ai]), @@ -868,6 +876,13 @@ module csrng_core import csrng_pkg::*; #( .cmd_stage_sm_err_o (cmd_stage_sm_err[ai]) ); + // Set reseed_cnt_reached_d to true if the max number of generate requests between reseeds + // has been reached for the respective counter. + assign reseed_cnt_reached_d[ai] = + state_db_wr_req && state_db_wr_req_rdy && (state_db_wr_inst_id == ai) ? + (state_db_wr_rc >= reg2hw.reseed_interval.q) : + reseed_cnt_reached_q[ai]; + end : gen_cmd_stage // SW interface connection (only 1, and must be present) @@ -979,6 +994,9 @@ module csrng_core import csrng_pkg::*; #( assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.de = cs_main_sm_invalid_cmd_seq; assign hw2reg.recov_alert_sts.cs_main_sm_invalid_cmd_seq.d = cs_main_sm_invalid_cmd_seq; + assign hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.de = |reseed_cnt_alert; + assign hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.d = |reseed_cnt_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 @@ -990,9 +1008,9 @@ module csrng_core import csrng_pkg::*; #( assign csrng_cmd_o[hai].csrng_rsp_ack = cmd_stage_ack[hai] || ((cs_main_sm_alert || cs_main_sm_invalid_cmd_seq) && (shid_q == StateId'(hai))); assign csrng_cmd_o[hai].csrng_rsp_sts = - (cs_main_sm_alert && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_ACMD : - (cs_main_sm_invalid_cmd_seq && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_CMD_SEQ : - cmd_stage_ack_sts[hai]; + (cs_main_sm_alert && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_ACMD : + (cs_main_sm_invalid_cmd_seq && (shid_q == StateId'(hai))) ? CMD_STS_INVALID_CMD_SEQ : + cmd_stage_ack_sts[hai]; // genbits assign csrng_cmd_o[hai].genbits_valid = genbits_stage_vld[hai]; assign csrng_cmd_o[hai].genbits_fips = genbits_stage_fips[hai]; @@ -1683,6 +1701,7 @@ module csrng_core import csrng_pkg::*; #( assign unused_err_code_test_bit = (|err_code_test_bit[19:16]) || (|err_code_test_bit[27:26]); assign unused_reg2hw_genbits = (|reg2hw.genbits.q); assign unused_int_state_val = (|reg2hw.int_state_val.q); + assign unused_reseed_interval = reg2hw.reseed_interval.qe; //-------------------------------------------- // Assertions diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv index bc8b395242691..65862bcbe7f87 100644 --- a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv +++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv @@ -213,8 +213,8 @@ module csrng_ctr_drbg_cmd import csrng_pkg::*; #( '0; assign prep_rc = - (cmdreq_ccmd == INS) ? {{(CtrLen-1){1'b0}},1'b1} : - (cmdreq_ccmd == RES) ? {{(CtrLen-1){1'b0}},1'b1} : + (cmdreq_ccmd == INS) ? {{(CtrLen-1){1'b0}},1'b0} : + (cmdreq_ccmd == RES) ? {{(CtrLen-1){1'b0}},1'b0} : (cmdreq_ccmd == GEN) ? cmdreq_rc : (cmdreq_ccmd == UPD) ? cmdreq_rc : '0; diff --git a/hw/ip/csrng/rtl/csrng_pkg.sv b/hw/ip/csrng/rtl/csrng_pkg.sv index 0a6b4f521456a..c042aa2379a60 100644 --- a/hw/ip/csrng/rtl/csrng_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_pkg.sv @@ -14,7 +14,7 @@ package csrng_pkg; parameter int unsigned FIPS_GENBITS_BUS_WIDTH = entropy_src_pkg::FIPS_BUS_WIDTH + GENBITS_BUS_WIDTH; parameter int unsigned MainSmStateWidth = 8; - parameter int unsigned CSRNG_CMD_STS_WIDTH = 2; + parameter int unsigned CSRNG_CMD_STS_WIDTH = 3; // instantiation interface typedef struct packed { @@ -28,6 +28,7 @@ package csrng_pkg; CMD_STS_INVALID_ACMD = 'h1, CMD_STS_INVALID_GEN_CMD = 'h2, CMD_STS_INVALID_CMD_SEQ = 'h3, + CMD_STS_RESEED_CNT_EXCEEDED = 'h4, CMD_STS_UNDRIVEN = 'z } csrng_cmd_sts_e; diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv index 043c1b743fd3e..49196f980670b 100644 --- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv +++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv @@ -93,6 +93,11 @@ package csrng_reg_pkg; logic qe; } csrng_reg2hw_cmd_req_reg_t; + typedef struct packed { + logic [31:0] q; + logic qe; + } csrng_reg2hw_reseed_interval_reg_t; + typedef struct packed { logic [31:0] q; logic re; @@ -142,7 +147,7 @@ package csrng_reg_pkg; logic de; } cmd_ack; struct packed { - logic [1:0] d; + logic [2:0] d; logic de; } cmd_sts; } csrng_hw2reg_sw_cmd_sts_reg_t; @@ -198,6 +203,10 @@ package csrng_reg_pkg; logic d; logic de; } cs_main_sm_invalid_cmd_seq; + struct packed { + logic d; + logic de; + } cmd_stage_reseed_cnt_alert; } csrng_hw2reg_recov_alert_sts_reg_t; typedef struct packed { @@ -314,12 +323,13 @@ package csrng_reg_pkg; // Register -> HW type typedef struct packed { - csrng_reg2hw_intr_state_reg_t intr_state; // [141:138] - csrng_reg2hw_intr_enable_reg_t intr_enable; // [137:134] - csrng_reg2hw_intr_test_reg_t intr_test; // [133:126] - csrng_reg2hw_alert_test_reg_t alert_test; // [125:122] - csrng_reg2hw_ctrl_reg_t ctrl; // [121:110] - csrng_reg2hw_cmd_req_reg_t cmd_req; // [109:77] + csrng_reg2hw_intr_state_reg_t intr_state; // [174:171] + csrng_reg2hw_intr_enable_reg_t intr_enable; // [170:167] + csrng_reg2hw_intr_test_reg_t intr_test; // [166:159] + csrng_reg2hw_alert_test_reg_t alert_test; // [158:155] + csrng_reg2hw_ctrl_reg_t ctrl; // [154:143] + csrng_reg2hw_cmd_req_reg_t cmd_req; // [142:110] + csrng_reg2hw_reseed_interval_reg_t reseed_interval; // [109:77] csrng_reg2hw_genbits_reg_t genbits; // [76:44] csrng_reg2hw_int_state_num_reg_t int_state_num; // [43:39] csrng_reg2hw_int_state_val_reg_t int_state_val; // [38:6] @@ -328,13 +338,13 @@ package csrng_reg_pkg; // HW -> register type typedef struct packed { - csrng_hw2reg_intr_state_reg_t intr_state; // [172:165] - csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [164:158] - csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [157:156] - csrng_hw2reg_genbits_reg_t genbits; // [155:124] - csrng_hw2reg_int_state_val_reg_t int_state_val; // [123:92] - csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [91:75] - csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [74:61] + csrng_hw2reg_intr_state_reg_t intr_state; // [175:168] + csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [167:160] + csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [159:158] + csrng_hw2reg_genbits_reg_t genbits; // [157:126] + csrng_hw2reg_int_state_val_reg_t int_state_val; // [125:94] + csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [93:77] + csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [76:61] csrng_hw2reg_err_code_reg_t err_code; // [60:9] csrng_hw2reg_main_sm_state_reg_t main_sm_state; // [8:0] } csrng_hw2reg_t; @@ -347,16 +357,17 @@ package csrng_reg_pkg; parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 7'h 10; parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 7'h 14; parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 7'h 18; - parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 1c; - parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 20; - parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 24; - parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 28; - parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 2c; - parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 30; - parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 34; - parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 38; - parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 3c; - parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STATE_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CSRNG_RESEED_INTERVAL_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STATE_OFFSET = 7'h 44; // Reset values for hwext registers and their fields parameter logic [3:0] CSRNG_INTR_TEST_RESVAL = 4'h 0; @@ -380,6 +391,7 @@ package csrng_reg_pkg; CSRNG_REGWEN, CSRNG_CTRL, CSRNG_CMD_REQ, + CSRNG_RESEED_INTERVAL, CSRNG_SW_CMD_STS, CSRNG_GENBITS_VLD, CSRNG_GENBITS, @@ -393,7 +405,7 @@ package csrng_reg_pkg; } csrng_id_e; // Register width information to check illegal writes - parameter logic [3:0] CSRNG_PERMIT [17] = '{ + parameter logic [3:0] CSRNG_PERMIT [18] = '{ 4'b 0001, // index[ 0] CSRNG_INTR_STATE 4'b 0001, // index[ 1] CSRNG_INTR_ENABLE 4'b 0001, // index[ 2] CSRNG_INTR_TEST @@ -401,16 +413,17 @@ package csrng_reg_pkg; 4'b 0001, // index[ 4] CSRNG_REGWEN 4'b 0011, // index[ 5] CSRNG_CTRL 4'b 1111, // index[ 6] CSRNG_CMD_REQ - 4'b 0001, // index[ 7] CSRNG_SW_CMD_STS - 4'b 0001, // index[ 8] CSRNG_GENBITS_VLD - 4'b 1111, // index[ 9] CSRNG_GENBITS - 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 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_MAIN_SM_STATE + 4'b 1111, // index[ 7] CSRNG_RESEED_INTERVAL + 4'b 0001, // index[ 8] CSRNG_SW_CMD_STS + 4'b 0001, // index[ 9] CSRNG_GENBITS_VLD + 4'b 1111, // index[10] CSRNG_GENBITS + 4'b 0001, // index[11] CSRNG_INT_STATE_NUM + 4'b 1111, // index[12] CSRNG_INT_STATE_VAL + 4'b 0011, // index[13] CSRNG_HW_EXC_STS + 4'b 0011, // index[14] CSRNG_RECOV_ALERT_STS + 4'b 1111, // index[15] CSRNG_ERR_CODE + 4'b 0001, // index[16] CSRNG_ERR_CODE_TEST + 4'b 0001 // index[17] CSRNG_MAIN_SM_STATE }; endpackage diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv index ec816b4d19b0c..a7a92bf34b422 100644 --- a/hw/ip/csrng/rtl/csrng_reg_top.sv +++ b/hw/ip/csrng/rtl/csrng_reg_top.sv @@ -52,9 +52,9 @@ module csrng_reg_top ( // also check for spurious write enables logic reg_we_err; - logic [16:0] reg_we_check; + logic [17:0] reg_we_check; prim_reg_we_check #( - .OneHotWidth(17) + .OneHotWidth(18) ) u_prim_reg_we_check ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -159,9 +159,12 @@ module csrng_reg_top ( logic [3:0] ctrl_read_int_state_wd; logic cmd_req_we; logic [31:0] cmd_req_wd; + logic reseed_interval_we; + logic [31:0] reseed_interval_qs; + logic [31:0] reseed_interval_wd; logic sw_cmd_sts_cmd_rdy_qs; logic sw_cmd_sts_cmd_ack_qs; - logic [1:0] sw_cmd_sts_cmd_sts_qs; + logic [2:0] sw_cmd_sts_cmd_sts_qs; logic genbits_vld_re; logic genbits_vld_genbits_vld_qs; logic genbits_vld_genbits_fips_qs; @@ -190,6 +193,8 @@ module csrng_reg_top ( logic recov_alert_sts_cs_main_sm_alert_wd; logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs; logic recov_alert_sts_cs_main_sm_invalid_cmd_seq_wd; + logic recov_alert_sts_cmd_stage_reseed_cnt_alert_qs; + logic recov_alert_sts_cmd_stage_reseed_cnt_alert_wd; logic err_code_sfifo_cmd_err_qs; logic err_code_sfifo_genbits_err_qs; logic err_code_sfifo_cmdreq_err_qs; @@ -702,6 +707,46 @@ module csrng_reg_top ( assign reg2hw.cmd_req.qe = cmd_req_qe; + // R[reseed_interval]: V(False) + logic reseed_interval_qe; + logic [0:0] reseed_interval_flds_we; + prim_flop #( + .Width(1), + .ResetValue(0) + ) u_reseed_interval0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&reseed_interval_flds_we), + .q_o(reseed_interval_qe) + ); + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hffffffff), + .Mubi (1'b0) + ) u_reseed_interval ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (reseed_interval_we), + .wd (reseed_interval_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (reseed_interval_flds_we[0]), + .q (reg2hw.reseed_interval.q), + .ds (), + + // to register interface (read) + .qs (reseed_interval_qs) + ); + assign reg2hw.reseed_interval.qe = reseed_interval_qe; + + // R[sw_cmd_sts]: V(False) // F[cmd_rdy]: 1:1 prim_subreg #( @@ -757,11 +802,11 @@ module csrng_reg_top ( .qs (sw_cmd_sts_cmd_ack_qs) ); - // F[cmd_sts]: 4:3 + // F[cmd_sts]: 5:3 prim_subreg #( - .DW (2), + .DW (3), .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (2'h0), + .RESVAL (3'h0), .Mubi (1'b0) ) u_sw_cmd_sts_cmd_sts ( .clk_i (clk_i), @@ -1107,6 +1152,33 @@ module csrng_reg_top ( .qs (recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs) ); + // F[cmd_stage_reseed_cnt_alert]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cmd_stage_reseed_cnt_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cmd_stage_reseed_cnt_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.de), + .d (hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cmd_stage_reseed_cnt_alert_qs) + ); + // R[err_code]: V(False) // F[sfifo_cmd_err]: 0:0 @@ -1884,7 +1956,7 @@ module csrng_reg_top ( - logic [16:0] addr_hit; + logic [17:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == CSRNG_INTR_STATE_OFFSET); @@ -1894,16 +1966,17 @@ module csrng_reg_top ( addr_hit[ 4] = (reg_addr == CSRNG_REGWEN_OFFSET); addr_hit[ 5] = (reg_addr == CSRNG_CTRL_OFFSET); addr_hit[ 6] = (reg_addr == CSRNG_CMD_REQ_OFFSET); - addr_hit[ 7] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET); - addr_hit[ 8] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET); - addr_hit[ 9] = (reg_addr == CSRNG_GENBITS_OFFSET); - addr_hit[10] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET); - addr_hit[11] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET); - addr_hit[12] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET); - addr_hit[13] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET); - addr_hit[14] = (reg_addr == CSRNG_ERR_CODE_OFFSET); - addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET); - addr_hit[16] = (reg_addr == CSRNG_MAIN_SM_STATE_OFFSET); + addr_hit[ 7] = (reg_addr == CSRNG_RESEED_INTERVAL_OFFSET); + addr_hit[ 8] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET); + addr_hit[ 9] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET); + addr_hit[10] = (reg_addr == CSRNG_GENBITS_OFFSET); + addr_hit[11] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET); + addr_hit[12] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET); + addr_hit[13] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET); + addr_hit[14] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET); + addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_OFFSET); + addr_hit[16] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET); + addr_hit[17] = (reg_addr == CSRNG_MAIN_SM_STATE_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1927,7 +2000,8 @@ module csrng_reg_top ( (addr_hit[13] & (|(CSRNG_PERMIT[13] & ~reg_be))) | (addr_hit[14] & (|(CSRNG_PERMIT[14] & ~reg_be))) | (addr_hit[15] & (|(CSRNG_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))))); + (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(CSRNG_PERMIT[17] & ~reg_be))))); end // Generate write-enables @@ -1976,16 +2050,19 @@ module csrng_reg_top ( assign cmd_req_we = addr_hit[6] & reg_we & !reg_error; assign cmd_req_wd = reg_wdata[31:0]; - assign genbits_vld_re = addr_hit[8] & reg_re & !reg_error; - assign genbits_re = addr_hit[9] & reg_re & !reg_error; - assign int_state_num_we = addr_hit[10] & reg_we & !reg_error; + assign reseed_interval_we = addr_hit[7] & reg_we & !reg_error; + + assign reseed_interval_wd = reg_wdata[31:0]; + assign genbits_vld_re = addr_hit[9] & reg_re & !reg_error; + assign genbits_re = addr_hit[10] & reg_re & !reg_error; + assign int_state_num_we = addr_hit[11] & reg_we & !reg_error; assign int_state_num_wd = reg_wdata[3:0]; - assign int_state_val_re = addr_hit[11] & reg_re & !reg_error; - assign hw_exc_sts_we = addr_hit[12] & reg_we & !reg_error; + assign int_state_val_re = addr_hit[12] & reg_re & !reg_error; + assign hw_exc_sts_we = addr_hit[13] & reg_we & !reg_error; assign hw_exc_sts_wd = reg_wdata[15:0]; - assign recov_alert_sts_we = addr_hit[13] & reg_we & !reg_error; + assign recov_alert_sts_we = addr_hit[14] & reg_we & !reg_error; assign recov_alert_sts_enable_field_alert_wd = reg_wdata[0]; @@ -2000,7 +2077,9 @@ module csrng_reg_top ( assign recov_alert_sts_cs_main_sm_alert_wd = reg_wdata[13]; assign recov_alert_sts_cs_main_sm_invalid_cmd_seq_wd = reg_wdata[14]; - assign err_code_test_we = addr_hit[15] & reg_we & !reg_error; + + assign recov_alert_sts_cmd_stage_reseed_cnt_alert_wd = reg_wdata[15]; + assign err_code_test_we = addr_hit[16] & reg_we & !reg_error; assign err_code_test_wd = reg_wdata[4:0]; @@ -2014,16 +2093,17 @@ module csrng_reg_top ( reg_we_check[4] = regwen_we; reg_we_check[5] = ctrl_gated_we; reg_we_check[6] = cmd_req_we; - reg_we_check[7] = 1'b0; + reg_we_check[7] = reseed_interval_we; reg_we_check[8] = 1'b0; reg_we_check[9] = 1'b0; - reg_we_check[10] = int_state_num_we; - reg_we_check[11] = 1'b0; - reg_we_check[12] = hw_exc_sts_we; - reg_we_check[13] = recov_alert_sts_we; - reg_we_check[14] = 1'b0; - reg_we_check[15] = err_code_test_gated_we; - reg_we_check[16] = 1'b0; + reg_we_check[10] = 1'b0; + reg_we_check[11] = int_state_num_we; + reg_we_check[12] = 1'b0; + reg_we_check[13] = hw_exc_sts_we; + reg_we_check[14] = recov_alert_sts_we; + reg_we_check[15] = 1'b0; + reg_we_check[16] = err_code_test_gated_we; + reg_we_check[17] = 1'b0; end // Read data return @@ -2071,33 +2151,37 @@ module csrng_reg_top ( end addr_hit[7]: begin + reg_rdata_next[31:0] = reseed_interval_qs; + end + + addr_hit[8]: begin reg_rdata_next[1] = sw_cmd_sts_cmd_rdy_qs; reg_rdata_next[2] = sw_cmd_sts_cmd_ack_qs; - reg_rdata_next[4:3] = sw_cmd_sts_cmd_sts_qs; + reg_rdata_next[5:3] = sw_cmd_sts_cmd_sts_qs; end - addr_hit[8]: begin + addr_hit[9]: begin reg_rdata_next[0] = genbits_vld_genbits_vld_qs; reg_rdata_next[1] = genbits_vld_genbits_fips_qs; end - addr_hit[9]: begin + addr_hit[10]: begin reg_rdata_next[31:0] = genbits_qs; end - addr_hit[10]: begin + addr_hit[11]: begin reg_rdata_next[3:0] = int_state_num_qs; end - addr_hit[11]: begin + addr_hit[12]: begin reg_rdata_next[31:0] = int_state_val_qs; end - addr_hit[12]: begin + addr_hit[13]: begin reg_rdata_next[15:0] = hw_exc_sts_qs; end - addr_hit[13]: begin + addr_hit[14]: begin 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; @@ -2105,9 +2189,10 @@ module csrng_reg_top ( reg_rdata_next[12] = recov_alert_sts_cs_bus_cmp_alert_qs; reg_rdata_next[13] = recov_alert_sts_cs_main_sm_alert_qs; reg_rdata_next[14] = recov_alert_sts_cs_main_sm_invalid_cmd_seq_qs; + reg_rdata_next[15] = recov_alert_sts_cmd_stage_reseed_cnt_alert_qs; end - addr_hit[14]: begin + addr_hit[15]: begin reg_rdata_next[0] = err_code_sfifo_cmd_err_qs; reg_rdata_next[1] = err_code_sfifo_genbits_err_qs; reg_rdata_next[2] = err_code_sfifo_cmdreq_err_qs; @@ -2136,11 +2221,11 @@ module csrng_reg_top ( reg_rdata_next[30] = err_code_fifo_state_err_qs; end - addr_hit[15]: begin + addr_hit[16]: begin reg_rdata_next[4:0] = err_code_test_qs; end - addr_hit[16]: begin + addr_hit[17]: begin reg_rdata_next[7:0] = main_sm_state_qs; end diff --git a/hw/ip/edn/data/edn.hjson b/hw/ip/edn/data/edn.hjson index f346f05d61406..8d1a253da273e 100644 --- a/hw/ip/edn/data/edn.hjson +++ b/hw/ip/edn/data/edn.hjson @@ -342,7 +342,7 @@ ''' resval: "0" } - { bits: "4:3", + { bits: "5:3", name: "CMD_STS", desc: ''' This field represents the status code returned with the CSRNG application command ack. @@ -401,7 +401,7 @@ ''' resval: "0" } - { bits: "8:7", + { bits: "9:7", name: "CMD_STS", desc: ''' This field represents the status code returned with the CSRNG application command ack. diff --git a/hw/ip/edn/doc/registers.md b/hw/ip/edn/doc/registers.md index 249a763c6bfaa..6cdfc44eec92d 100644 --- a/hw/ip/edn/doc/registers.md +++ b/hw/ip/edn/doc/registers.md @@ -227,18 +227,18 @@ in the CSRNG documentation. EDN software command status register - Offset: `0x24` - Reset default: `0x0` -- Reset mask: `0x1f` +- Reset mask: `0x3f` ### Fields ```wavejson -{"reg": [{"name": "CMD_REG_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 2, "attr": ["ro"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +{"reg": [{"name": "CMD_REG_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 3, "attr": ["ro"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} ``` | Bits | Type | Reset | Name | |:------:|:------:|:-------:|:----------------------------------------| -| 31:5 | | | Reserved | -| 4:3 | ro | 0x0 | [CMD_STS](#sw_cmd_sts--cmd_sts) | +| 31:6 | | | Reserved | +| 5:3 | ro | 0x0 | [CMD_STS](#sw_cmd_sts--cmd_sts) | | 2 | ro | 0x0 | [CMD_ACK](#sw_cmd_sts--cmd_ack) | | 1 | ro | 0x0 | [CMD_RDY](#sw_cmd_sts--cmd_rdy) | | 0 | ro | 0x0 | [CMD_REG_RDY](#sw_cmd_sts--cmd_reg_rdy) | @@ -273,18 +273,18 @@ This bit has to be polled before each word of a command is written to [`SW_CMD_R EDN hardware command status register - Offset: `0x28` - Reset default: `0x0` -- Reset mask: `0x1ff` +- Reset mask: `0x3ff` ### Fields ```wavejson -{"reg": [{"name": "BOOT_MODE", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "AUTO_MODE", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_TYPE", "bits": 4, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 2, "attr": ["ro"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}} +{"reg": [{"name": "BOOT_MODE", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "AUTO_MODE", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_TYPE", "bits": 4, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 3, "attr": ["ro"], "rotate": -90}, {"bits": 22}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}} ``` | Bits | Type | Reset | Name | |:------:|:------:|:-------:|:------------------------------------| -| 31:9 | | | Reserved | -| 8:7 | ro | 0x0 | [CMD_STS](#hw_cmd_sts--cmd_sts) | +| 31:10 | | | Reserved | +| 9:7 | ro | 0x0 | [CMD_STS](#hw_cmd_sts--cmd_sts) | | 6 | ro | 0x0 | [CMD_ACK](#hw_cmd_sts--cmd_ack) | | 5:2 | ro | 0x0 | [CMD_TYPE](#hw_cmd_sts--cmd_type) | | 1 | ro | 0x0 | [AUTO_MODE](#hw_cmd_sts--auto_mode) | diff --git a/hw/ip/edn/rtl/edn_reg_pkg.sv b/hw/ip/edn/rtl/edn_reg_pkg.sv index b807d8be7fe67..808a704bbe56b 100644 --- a/hw/ip/edn/rtl/edn_reg_pkg.sv +++ b/hw/ip/edn/rtl/edn_reg_pkg.sv @@ -133,7 +133,7 @@ package edn_reg_pkg; logic de; } cmd_ack; struct packed { - logic [1:0] d; + logic [2:0] d; logic de; } cmd_sts; } edn_hw2reg_sw_cmd_sts_reg_t; @@ -156,7 +156,7 @@ package edn_reg_pkg; logic de; } cmd_ack; struct packed { - logic [1:0] d; + logic [2:0] d; logic de; } cmd_sts; } edn_hw2reg_hw_cmd_sts_reg_t; @@ -246,9 +246,9 @@ package edn_reg_pkg; // HW -> register type typedef struct packed { - edn_hw2reg_intr_state_reg_t intr_state; // [64:61] - edn_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [60:52] - edn_hw2reg_hw_cmd_sts_reg_t hw_cmd_sts; // [51:38] + edn_hw2reg_intr_state_reg_t intr_state; // [66:63] + edn_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [62:53] + edn_hw2reg_hw_cmd_sts_reg_t hw_cmd_sts; // [52:38] edn_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [37:26] edn_hw2reg_err_code_reg_t err_code; // [25:10] edn_hw2reg_main_sm_state_reg_t main_sm_state; // [9:0] diff --git a/hw/ip/edn/rtl/edn_reg_top.sv b/hw/ip/edn/rtl/edn_reg_top.sv index 5915528b23c0b..fc418b861b6dd 100644 --- a/hw/ip/edn/rtl/edn_reg_top.sv +++ b/hw/ip/edn/rtl/edn_reg_top.sv @@ -160,12 +160,12 @@ module edn_reg_top ( logic sw_cmd_sts_cmd_reg_rdy_qs; logic sw_cmd_sts_cmd_rdy_qs; logic sw_cmd_sts_cmd_ack_qs; - logic [1:0] sw_cmd_sts_cmd_sts_qs; + logic [2:0] sw_cmd_sts_cmd_sts_qs; logic hw_cmd_sts_boot_mode_qs; logic hw_cmd_sts_auto_mode_qs; logic [3:0] hw_cmd_sts_cmd_type_qs; logic hw_cmd_sts_cmd_ack_qs; - logic [1:0] hw_cmd_sts_cmd_sts_qs; + logic [2:0] hw_cmd_sts_cmd_sts_qs; logic reseed_cmd_we; logic [31:0] reseed_cmd_wd; logic generate_cmd_we; @@ -685,11 +685,11 @@ module edn_reg_top ( .qs (sw_cmd_sts_cmd_ack_qs) ); - // F[cmd_sts]: 4:3 + // F[cmd_sts]: 5:3 prim_subreg #( - .DW (2), + .DW (3), .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (2'h0), + .RESVAL (3'h0), .Mubi (1'b0) ) u_sw_cmd_sts_cmd_sts ( .clk_i (clk_i), @@ -822,11 +822,11 @@ module edn_reg_top ( .qs (hw_cmd_sts_cmd_ack_qs) ); - // F[cmd_sts]: 8:7 + // F[cmd_sts]: 9:7 prim_subreg #( - .DW (2), + .DW (3), .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (2'h0), + .RESVAL (3'h0), .Mubi (1'b0) ) u_hw_cmd_sts_cmd_sts ( .clk_i (clk_i), @@ -1571,7 +1571,7 @@ module edn_reg_top ( reg_rdata_next[0] = sw_cmd_sts_cmd_reg_rdy_qs; reg_rdata_next[1] = sw_cmd_sts_cmd_rdy_qs; reg_rdata_next[2] = sw_cmd_sts_cmd_ack_qs; - reg_rdata_next[4:3] = sw_cmd_sts_cmd_sts_qs; + reg_rdata_next[5:3] = sw_cmd_sts_cmd_sts_qs; end addr_hit[10]: begin @@ -1579,7 +1579,7 @@ module edn_reg_top ( reg_rdata_next[1] = hw_cmd_sts_auto_mode_qs; reg_rdata_next[5:2] = hw_cmd_sts_cmd_type_qs; reg_rdata_next[6] = hw_cmd_sts_cmd_ack_qs; - reg_rdata_next[8:7] = hw_cmd_sts_cmd_sts_qs; + reg_rdata_next[9:7] = hw_cmd_sts_cmd_sts_qs; end addr_hit[11]: begin diff --git a/sw/device/lib/crypto/drivers/entropy_kat.c b/sw/device/lib/crypto/drivers/entropy_kat.c index fbc83b7aa2ed4..0b20f88ef7746 100644 --- a/sw/device/lib/crypto/drivers/entropy_kat.c +++ b/sw/device/lib/crypto/drivers/entropy_kat.c @@ -126,7 +126,7 @@ status_t entropy_csrng_kat(void) { /*disable_trng_input=*/kHardenedBoolTrue, &kEntropyInput)); const entropy_csrng_internal_state_t kExpectedStateInstantiate = { - .reseed_counter = 1, + .reseed_counter = 0, .v = {0x06b8f59e, 0x43c0b2c2, 0x21052502, 0x217b5214}, .key = {0x941709fd, 0xd8a25860, 0x861aecf3, 0x98a701a1, 0x0eb2c33b, 0x74c08fad, 0x632d5227, 0x8c52f901}, @@ -146,7 +146,7 @@ status_t entropy_csrng_kat(void) { /*fips_check=*/kHardenedBoolFalse)); const entropy_csrng_internal_state_t kExpectedStateGenerate = { - .reseed_counter = 3, + .reseed_counter = 2, .v = {0xe73e3392, 0x7d2e92b1, 0x1a0bac9d, 0x53c78ac6}, .key = {0x66d1b85a, 0xc19d4dfd, 0x053b73e3, 0xe9dc0f90, 0x3f015bc8, diff --git a/sw/device/lib/dif/dif_csrng.h b/sw/device/lib/dif/dif_csrng.h index 1aa9eb8a1e4f2..2606e2e79f622 100644 --- a/sw/device/lib/dif/dif_csrng.h +++ b/sw/device/lib/dif/dif_csrng.h @@ -339,11 +339,20 @@ typedef enum dif_csrng_recoverable_alert { kDifCsrngRecoverableAlertRepeatedGenBits = 1U << CSRNG_RECOV_ALERT_STS_CS_BUS_CMP_ALERT_BIT, /** - * Indicates an unsupported CSRNG command is being processed, causing the main - * FSM to hang unless the module enable field is set to the disabled state. + * Indicates an unsupported CSRNG command was issued. */ kDifCsrngRecoverableAlertBadCsrngCmd = 1U << CSRNG_RECOV_ALERT_STS_CS_MAIN_SM_ALERT_BIT, + /** + * Indicates a supported CSRNG command was issued out of sequence. + */ + kDifCsrngRecoverableAlertBadCsrngCmdSeq = + 1U << CSRNG_RECOV_ALERT_STS_CS_MAIN_SM_INVALID_CMD_SEQ_BIT, + /** + * Indicates that too many generate commands were issued in a row. + */ + kDifCsrngRecoverableAlertMaxReseedsExceeded = + 1U << CSRNG_RECOV_ALERT_STS_CMD_STAGE_RESEED_CNT_ALERT_BIT, } dif_csrng_recoverable_alert_t; /** diff --git a/sw/device/lib/dif/dif_csrng_unittest.cc b/sw/device/lib/dif/dif_csrng_unittest.cc index 4d47cd2d671c5..52186280fca70 100644 --- a/sw/device/lib/dif/dif_csrng_unittest.cc +++ b/sw/device/lib/dif/dif_csrng_unittest.cc @@ -348,7 +348,7 @@ TEST_F(GetInternalStateTest, GetInternalStateOk) { }); dif_csrng_internal_state_t expected = { - .reseed_counter = 1, + .reseed_counter = 0, .v = {1, 2, 3, 4}, .key = {1, 2, 3, 4, 5, 6, 7, 8}, .instantiated = true, diff --git a/sw/device/lib/testing/aes_testutils.c b/sw/device/lib/testing/aes_testutils.c index 20f2a5a3c883a..2e375dbd71a1d 100644 --- a/sw/device/lib/testing/aes_testutils.c +++ b/sw/device/lib/testing/aes_testutils.c @@ -163,7 +163,7 @@ status_t aes_testutils_csrng_kat(void) { memcpy(seed_material_instantiate.seed_material, kEdnSeedMaterialInstantiate, sizeof(kEdnSeedMaterialInstantiate)); dif_csrng_internal_state_t expected_state_instantiate = { - .reseed_counter = 1, + .reseed_counter = 0, .instantiated = true, .fips_compliance = false, }; @@ -177,7 +177,7 @@ status_t aes_testutils_csrng_kat(void) { // Generate one block containing the required seed for the AES masking PRNG // to output an all-zero vector. dif_csrng_internal_state_t expected_state_generate = { - .reseed_counter = 2, + .reseed_counter = 1, .instantiated = true, .fips_compliance = false, }; @@ -196,7 +196,7 @@ status_t aes_testutils_csrng_kat(void) { memcpy(seed_material_reseed.seed_material, kEdnSeedMaterialReseed, sizeof(kEdnSeedMaterialReseed)); dif_csrng_internal_state_t expected_state_reseed = { - .reseed_counter = 1, + .reseed_counter = 0, .instantiated = true, .fips_compliance = false, }; diff --git a/sw/device/lib/testing/csrng_testutils.c b/sw/device/lib/testing/csrng_testutils.c index d058b5f5dd75d..0dfcab17f3f63 100644 --- a/sw/device/lib/testing/csrng_testutils.c +++ b/sw/device/lib/testing/csrng_testutils.c @@ -150,7 +150,7 @@ status_t csrng_testutils_fips_instantiate_kat(const dif_csrng_t *csrng, .seed_material_len = 12, }; const dif_csrng_internal_state_t kExpectedState = { - .reseed_counter = 1, + .reseed_counter = 0, .v = {0x06b8f59e, 0x43c0b2c2, 0x21052502, 0x217b5214}, .key = {0x941709fd, 0xd8a25860, 0x861aecf3, 0x98a701a1, 0x0eb2c33b, 0x74c08fad, 0x632d5227, 0x8c52f901}, @@ -174,7 +174,7 @@ status_t csrng_testutils_fips_generate_kat(const dif_csrng_t *csrng) { 0x793e01c5, 0x87b107ae, 0xdb17514c, 0xa43c41b7, }; const dif_csrng_internal_state_t kExpectedState = { - .reseed_counter = 3, + .reseed_counter = 2, .v = {0xe73e3392, 0x7d2e92b1, 0x1a0bac9d, 0x53c78ac6}, .key = {0x66d1b85a, 0xc19d4dfd, 0x053b73e3, 0xe9dc0f90, 0x3f015bc8, 0x4436e5fd, 0x1cccc697, 0x1a1c6e5f},