Skip to content

Conversation

@glaserf
Copy link
Contributor

@glaserf glaserf commented Nov 21, 2025

Note: This PR will be kept as the current individual commits for eased review and auditing. However, once approved, the merge to master will be done as a single, self-contained commit.

Motivation

While previous PRs (#28428, #28633, #28611) managed to significantly reduce the circuit area of the CSRNG, there is still quite some area locked in FIFOs that cannot be removed due to circular handshake dependencies between the three modules that together implement the CTR_DRBG algorithm as per NIST SP800-90A. Furthermore, the interconnect and resource sharing between these modules and the block_encrypt unit incur additional area and complexity in csrng_core through required arbiters and muxes.

Therefore, a larger reorganization of the CTR_DRBG data path is unavoidable to unlock the remaining area and complexity savings.

Main Changes

This PR replaces the csrng_ctr_drbg_{cmd, upd, gen} modules with a single, unified csrng_ctr_drbg module that implements the complete data path as per NIST. It combines all required elements from the aforementioned previous modules (often de-duplicating and/or refactoring/restructuring them) with a newly designed FSM to control everything. More details about the new data path unit can be found in the commit message of the first commit. In addition, ample commentary for better understanding of the inner workings of the CTR_DRBG data path was kept in mind during the creation.

This unlocks the following benefits:

  • Additional 13kGE or 10% of area reduction for a cumulative area reduction of roughly 45%
  • Complexity reduction: Control of the data path by a single instead of four FSMs; uses only a single redundant prim_count for handling v instead of two
  • Code complexity reduction: Reduction of three RTL source files to one, net reduction of about 1000 LOC of RTL
  • DV complexity reduction: Fewer error reporting mechanism to test, especially in regards to fault injection
  • Addresses several open points and TODOs in [csrng] List of requested changes and improvements #28153

This change requires an update to the block diagram and the manual part of the documentation, both of which will be implemented as soon as this PR has seen general approval.

This commit adds the unified csrng_ctr_drbg module which replaces the
csrng_ctr_drbg_{cmd, gen, upd} modules. It combines all required data
path elements from the aforementioned modules and introduces a newly
designed FSM which creates all necessary control- and handshake signals.

This step allows for significant reduction of both circuit area and
design complexity. The unified module splits the response ports up:
Previously, writes to the state db, the genbits FIFOs in the command
stages, and signalling commands as completed to main and command stages
FSM were done on a single handshake channel. This is now done with three
independent channels which allows for a more streamlined data path and
does away with buffering and pipeline stages previously required.

Note that some of the response handshake channels do not feature a ready
signal, since the respective responders (state db, genbits FIFOs) are
always ready by construction.

Furthermore, csrng_ctr_drbg reworks the v-counter logic to perform all
v-increments inside the hardened prim_count. Before, when loading v from
the state db, the first increment was done outside of the prim_count as
part of its `set` value, potentially harming the overall hardening of v.

Signed-off-by: Florian Glaser <[email protected]>
This commit instantiates the unified csrng_ctr_drbg data path module in
csrng_core and removes the csrng_ctr_drbg_{cmd,gen,upd} modules from the
code base. This either requires or enables the following steps as well:

- Remove several assertions that reference removed parts of the design
- Remove/tweak data types from csrng_pkg
- Remove the flopped status_ack interface from the state db
- Remove the no longer needed cmdid FIFO from csrng_block_encrypt
- Remove all arbiters and muxes associated with the previous data path
  organization from csrng_core
- Remove a sizable amount of signals from csrng_core
- Restructure and clean up the handling of the various error signals in
  csrng_core (the amount of error sources is also further reduced)

Signed-off-by: Florian Glaser <[email protected]>
@glaserf
Copy link
Contributor Author

glaserf commented Nov 21, 2025

Regression results:

CSRNG Simulation Results

Friday November 21 2025 16:36:23 UTC

GitHub Revision: b2ba4738d9

Branch: csrng_archi_pr

Testplan

Simulator: XCELIUM

Test Results

Stage Name Tests Max Job Runtime Simulated Time Passing Total Pass Rate
V1 smoke csrng_smoke 3.000s 122.144us 50 50 100.00 %
V1 csr_hw_reset csrng_csr_hw_reset 1.000s 27.677us 5 5 100.00 %
V1 csr_rw csrng_csr_rw 1.000s 29.168us 20 20 100.00 %
V1 csr_bit_bash csrng_csr_bit_bash 8.000s 1.071ms 5 5 100.00 %
V1 csr_aliasing csrng_csr_aliasing 3.000s 442.599us 5 5 100.00 %
V1 csr_mem_rw_with_rand_reset csrng_csr_mem_rw_with_rand_reset 1.000s 97.666us 20 20 100.00 %
V1 regwen_csr_and_corresponding_lockable_csr csrng_csr_rw 1.000s 29.168us 20 20 100.00 %
csrng_csr_aliasing 3.000s 442.599us 5 5 100.00 %
V1 TOTAL 105 105 100.00 %
V2 interrupts csrng_intr 8.000s 1.394ms 200 200 100.00 %
V2 alerts csrng_alert 17.000s 3.392ms 500 500 100.00 %
V2 err csrng_err 3.000s 20.481us 500 500 100.00 %
V2 cmds csrng_cmds 3.333m 18.348ms 50 50 100.00 %
V2 life cycle csrng_cmds 3.333m 18.348ms 50 50 100.00 %
V2 stress_all csrng_stress_all 9.467m 111.730ms 49 50 98.00 %
V2 intr_test csrng_intr_test 1.000s 24.103us 50 50 100.00 %
V2 alert_test csrng_alert_test 2.000s 17.343us 50 50 100.00 %
V2 tl_d_oob_addr_access csrng_tl_errors 5.000s 627.706us 20 20 100.00 %
V2 tl_d_illegal_access csrng_tl_errors 5.000s 627.706us 20 20 100.00 %
V2 tl_d_outstanding_access csrng_csr_hw_reset 1.000s 27.677us 5 5 100.00 %
csrng_csr_rw 1.000s 29.168us 20 20 100.00 %
csrng_csr_aliasing 3.000s 442.599us 5 5 100.00 %
csrng_same_csr_outstanding 2.000s 290.117us 20 20 100.00 %
V2 tl_d_partial_access csrng_csr_hw_reset 1.000s 27.677us 5 5 100.00 %
csrng_csr_rw 1.000s 29.168us 20 20 100.00 %
csrng_csr_aliasing 3.000s 442.599us 5 5 100.00 %
csrng_same_csr_outstanding 2.000s 290.117us 20 20 100.00 %
V2 TOTAL 1439 1440 99.93 %
V2S tl_intg_err csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
csrng_tl_intg_err 8.000s 1.756ms 20 20 100.00 %
V2S sec_cm_config_regwen csrng_regwen 2.000s 78.276us 50 50 100.00 %
csrng_csr_rw 1.000s 29.168us 20 20 100.00 %
V2S sec_cm_config_mubi csrng_alert 17.000s 3.392ms 500 500 100.00 %
V2S sec_cm_intersig_mubi csrng_stress_all 9.467m 111.730ms 49 50 98.00 %
V2S sec_cm_main_sm_fsm_sparse csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_ctr_drbg_fsm_sparse csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_drbg_ctr_redun csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_gen_cmd_ctr_redun csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_ctrl_mubi csrng_alert 17.000s 3.392ms 500 500 100.00 %
V2S sec_cm_main_sm_ctr_local_esc csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
V2S sec_cm_constants_lc_gated csrng_stress_all 9.467m 111.730ms 49 50 98.00 %
V2S sec_cm_sw_genbits_bus_consistency csrng_alert 17.000s 3.392ms 500 500 100.00 %
V2S sec_cm_tile_link_bus_integrity csrng_tl_intg_err 8.000s 1.756ms 20 20 100.00 %
V2S sec_cm_aes_cipher_fsm_sparse csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_aes_cipher_fsm_redun csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
V2S sec_cm_aes_cipher_ctrl_sparse csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
V2S sec_cm_aes_cipher_fsm_local_esc csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
V2S sec_cm_aes_cipher_ctr_redun csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
csrng_sec_cm 5.000s 353.205us 5 5 100.00 %
V2S sec_cm_aes_cipher_data_reg_local_esc csrng_intr 8.000s 1.394ms 200 200 100.00 %
csrng_err 3.000s 20.481us 500 500 100.00 %
V2S TOTAL 75 75 100.00 %
V3 stress_all_with_rand_reset csrng_stress_all_with_rand_reset 2.600m 13.679ms 10 10 100.00 %
V3 TOTAL 10 10 100.00 %
TOTAL 1629 1630 99.94 %

Coverage Results

Coverage Dashboard

Score Block Branch Statement Expression Toggle Fsm Assertion CoverGroup
97.51 % 98.60 % 96.50 % 99.47 % 96.72 % 93.65 % 85.19 % 95.85 % 91.24 %

Failure Buckets

  • UVM_ERROR (csrng_scoreboard.sv:166) [scoreboard] Check failed intr_pins[i] === (intr_en[i] & item.d_data[i]) (* [*] vs * [*]) Interrupt_pin: EntropyReq has 1 failures:
    • Test csrng_stress_all has 1 failures.
      • 41.csrng_stress_all.97134871003220988528998910511999303650552284180187364491311040752061904021854
        Line 148, in log /scratch/glaserf/opentitan/scratch/csrng_archi_pr/csrng-sim-xcelium/41.csrng_stress_all/latest/run.log

          UVM_ERROR @  88108260 ps: (csrng_scoreboard.sv:166) [uvm_test_top.env.scoreboard] Check failed intr_pins[i] === (intr_en[i] & item.d_data[i]) (0x1 [1] vs 0x0 [0]) Interrupt_pin: EntropyReq
          UVM_INFO @  88108260 ps: (uvm_report_catcher.svh:705) [UVM/REPORT/CATCHER]
          --- UVM Report catcher Summary ---
        

INFO: [FlowCfg] [scratch_path]: [csrng] [/scratch/glaserf/opentitan/scratch/csrng_archi_pr/csrng-sim-xcelium]
ERROR: [dvsim] Errors were encountered in this run.

          [   legend    ]: [Q: queued, D: dispatched, P: passed, F: failed, K: killed, T: total]                                                                                                                                     
00:01:03  [    build    ]: [Q: 0, D: 0, P: 2, F: 0, K: 0, T: 2] 100%                                                                                                                                                                 
00:19:27  [     run     ]: [Q: 0, D: 0, P: 1629, F: 1, K: 0, T: 1630] 100%                                                                                                                                                           
00:19:57  [  cov_merge  ]: [Q: 0, D: 0, P: 1, F: 0, K: 0, T: 1] 100%                                                                                                                                                                 
00:20:01  [ cov_report  ]: [Q: 0, D: 0, P: 1, F: 0, K: 0, T: 1] 100%

This commit removes all now unused error reporting bits from the regfile
and documentation as well as the dummy-assigns in csrng_core.

It also changes the misleadingly named `CMD_GEN_CNT_ERR` bit to
`CTR_ERR` which reflects its meaning (collective reporting if _any_
hardened counter in CSRNG has reported an error).

Finally, it aligns the SEC_CM annotations in RTL to match the IP hjson
and moves some of the labels closer to where the actual counter measure
is implemented.

Signed-off-by: Florian Glaser <[email protected]>
This commit removes all dv functionality related to the FIFOs, hardened
counters and FSMs that got removed during the data path simplification.
It also streamlines parts of the dv environment after having removed a
significant amount of the possible errors to probe/test.

It also removes the no longer used `GENU` and `GENB` command codes from
csrng_pkg, which affects a sizable amount of dv files, especially
coverage related ones.

Signed-off-by: Florian Glaser <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant