Skip to content

Commit 4510fe3

Browse files
committed
[kmac] Improve handling of manual PRNG reseeding requests
This commit modifies the design to latch manual PRNG reseeding requests and to indicate the status of the PRNG via new bits in the status register. This allows software to verify that a reseed request has indeed been accepted and prevents the accidental dropping of such requests in case they reach the PRNG while the SHA3 engine is busy. Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
1 parent 5332b70 commit 4510fe3

9 files changed

Lines changed: 137 additions & 30 deletions

File tree

hw/ip/kmac/data/kmac.hjson

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@
676676
Software can set this bit to 1 to manually trigger the reseeding of the internal PRNG when running in EDN mode.
677677
This will also clear !!ENTROPY_REFRESH_HASH_CNT.
678678

679-
Note that the hardware may miss the trigger pulse if the module is not idle, or if the module is currently performing a reseed operation.
679+
After setting this bit, the !!STATUS.entropy_ready bit should read as 0 and the !!STATUS.entropy_reseeding bit as 1 indicating that a reseed operation is ongoing.
680680
'''
681681
}
682682
{ bits: "9"
@@ -715,6 +715,17 @@
715715
In this stage, SW can manually run the hashing engine.
716716
'''
717717
}
718+
{ bits: "4"
719+
name: "entropy_ready"
720+
desc: '''If 1, the internal PRNG is ready.
721+
If 0, the internal PRNG is either not configured in EDN mode or software mode, or currently performing a reseed operation via EDN or waiting for software to provide a new seed.
722+
'''
723+
}
724+
{ bits: "5"
725+
name: "entropy_reseeding"
726+
desc: '''If 1, the internal PRNG is currently performing a reseed operation via EDN or waiting for software to provide a new seed.
727+
'''
728+
}
718729
{ bits: "12:8"
719730
name: "fifo_depth"
720731
desc: "Count of occupied entries in the message FIFO."

hw/ip/kmac/doc/programmers_guide.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,11 @@ If the value of [`ENTROPY_REFRESH_HASH_CNT`](registers.md#entropy_refresh_hash_c
9494
1. Ensure that the entropy complex is running.
9595
2. Check that the KMAC module is idle by reading the [`STATUS.sha3_idle`](registers.md#status--sha3_idle) bit.
9696
3. Trigger a manual reseed operation by setting the [`CMD.entropy_req`](registers.md#cmd--entropy_req) bit.
97-
4. Configure the module to process a message in cSHAKE mode (but not in KMAC mode).
98-
More precisely, set [`CFG_SHADOWED.mode`](registers.md#cfg_shadowed--mode) to `0x3` and [`CFG_SHADOWED.kmac_en`](registers.md#cfg_shadowed--kmac_en) to 0.
99-
5. Configure the module to use the PRNG and block any hashing operation if the PRNG is not ready by setting [`CFG_SHADOWED.entropy_fast_process`](registers.md#cfg_shadowed--entropy_fast_process) to 0.
100-
6. Send the `start` command to the [`CMD`](registers.md#cmd) register.
101-
The SHA3 engine will start loading and hashing the function name `N` and the customization string `S` first.
102-
7. Send the `process` command to the [`CMD`](registers.md#cmd) register.
103-
8. Wait for the [`STATUS.sha3_squeeze`](registers.md#status--sha3_squeeze) bit to get set.
104-
Due to the ongoing reseed operation, the [`STATUS.sha3_squeeze`](registers.md#status--sha3_squeeze) bit should remain 0 for an extended period of time.
105-
9. Send the `done` command to the [`CMD`](registers.md#cmd) register to finish processing.
97+
4. Wait for the [`STATUS.entropy_reseeding`](registers.md#status--entropy_reseeding) bit to get set.
98+
Due to the ongoing reseed operation, the [`STATUS.entropy_reseeding`](registers.md#status--entropy_reseeding) bit should remain 1 for an extended period of time.
99+
5. Wait for the [`STATUS.entropy_reseeding`](registers.md#status--entropy_reseeding) bit to get cleared and the [`STATUS.entropy_ready`](registers.md#status--entropy_ready) bit to get set.
106100

107101
The [`ENTROPY_REFRESH_HASH_CNT`](registers.md#entropy_refresh_hash_cnt) register should now read as 0.
108-
Note however that if the manual reseed operation is triggered while the KMAC module is busy, the reseed operation may get skipped despite the hash counter being cleared back to 0.
109102

110103

111104
#### Checking Message FIFO depth before pushing data

hw/ip/kmac/doc/registers.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ Software can set this bit to 1 to manually clear [`ENTROPY_REFRESH_HASH_CNT.`](#
369369
Software can set this bit to 1 to manually trigger the reseeding of the internal PRNG when running in EDN mode.
370370
This will also clear [`ENTROPY_REFRESH_HASH_CNT.`](#entropy_refresh_hash_cnt)
371371

372-
Note that the hardware may miss the trigger pulse if the module is not idle, or if the module is currently performing a reseed operation.
372+
After setting this bit, the [`STATUS.entropy_ready`](#status) bit should read as 0 and the [`STATUS.entropy_reseeding`](#status) bit as 1 indicating that a reseed operation is ongoing.
373373

374374
### CMD . cmd
375375
Issue a command to the KMAC/SHA3 IP. The command is sparse
@@ -389,12 +389,12 @@ Other values are reserved.
389389
KMAC/SHA3 Status register.
390390
- Offset: `0x1c`
391391
- Reset default: `0x4001`
392-
- Reset mask: `0x3df07`
392+
- Reset mask: `0x3df37`
393393

394394
### Fields
395395

396396
```wavejson
397-
{"reg": [{"name": "sha3_idle", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "sha3_absorb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "sha3_squeeze", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 5}, {"name": "fifo_depth", "bits": 5, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "fifo_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "fifo_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ALERT_FATAL_FAULT", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ALERT_RECOV_CTRL_UPDATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 14}], "config": {"lanes": 1, "fontsize": 10, "vspace": 290}}
397+
{"reg": [{"name": "sha3_idle", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "sha3_absorb", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "sha3_squeeze", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "entropy_ready", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "entropy_reseeding", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 2}, {"name": "fifo_depth", "bits": 5, "attr": ["ro"], "rotate": -90}, {"bits": 1}, {"name": "fifo_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "fifo_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ALERT_FATAL_FAULT", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ALERT_RECOV_CTRL_UPDATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 14}], "config": {"lanes": 1, "fontsize": 10, "vspace": 290}}
398398
```
399399

400400
| Bits | Type | Reset | Name |
@@ -406,7 +406,10 @@ KMAC/SHA3 Status register.
406406
| 14 | ro | 0x1 | [fifo_empty](#status--fifo_empty) |
407407
| 13 | | | Reserved |
408408
| 12:8 | ro | x | [fifo_depth](#status--fifo_depth) |
409-
| 7:3 | | | Reserved |
409+
| 7:6 | | | Reserved |
410+
| 5 | ro | x | [entropy_reseeding](#status--entropy_reseeding) |
411+
| 4 | ro | x | [entropy_ready](#status--entropy_ready) |
412+
| 3 | | | Reserved |
410413
| 2 | ro | x | [sha3_squeeze](#status--sha3_squeeze) |
411414
| 1 | ro | x | [sha3_absorb](#status--sha3_absorb) |
412415
| 0 | ro | 0x1 | [sha3_idle](#status--sha3_idle) |
@@ -444,6 +447,13 @@ See the "Message FIFO" section in the spec for the reason.
444447
### STATUS . fifo_depth
445448
Count of occupied entries in the message FIFO.
446449

450+
### STATUS . entropy_reseeding
451+
If 1, the internal PRNG is currently performing a reseed operation via EDN or waiting for software to provide a new seed.
452+
453+
### STATUS . entropy_ready
454+
If 1, the internal PRNG is ready.
455+
If 0, the internal PRNG is either not configured in EDN mode or software mode, or currently performing a reseed operation via EDN or waiting for software to provide a new seed.
456+
447457
### STATUS . sha3_squeeze
448458
If 1, SHA3 completes sponge absorbing stage.
449459
In this stage, SW can manually run the hashing engine.

hw/ip/kmac/dv/env/kmac_env_pkg.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ package kmac_env_pkg;
123123
KmacStatusSha3Idle = 0,
124124
KmacStatusSha3Absorb = 1,
125125
KmacStatusSha3Squeeze = 2,
126+
KmacStatusEntropyReady = 4,
127+
KmacStatusEntropyReseeding = 5,
126128
KmacStatusFifoDepthLSB = 8,
127129
KmacStatusFifoDepthMSB = 12,
128130
KmacStatusFifoEmpty = 14,

hw/ip/kmac/dv/env/kmac_scoreboard.sv

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class kmac_scoreboard extends cip_base_scoreboard #(.CFG_T(kmac_env_cfg),
7979
bit sha3_absorb;
8080
bit sha3_squeeze;
8181

82+
// PRNG status bits
83+
bit status_entropy_ready;
84+
bit status_entropy_reseeding;
85+
8286
// FIFO status bits
8387
bit cmd_process_triggered;
8488
bit msgfifo_access;
@@ -966,6 +970,8 @@ class kmac_scoreboard extends cip_base_scoreboard #(.CFG_T(kmac_env_cfg),
966970
exp_status[KmacStatusSha3Absorb] = sha3_absorb;
967971
exp_status[KmacStatusSha3Squeeze] = sha3_squeeze;
968972

973+
exp_status[KmacStatusEntropyReady] = status_entropy_ready;
974+
exp_status[KmacStatusEntropyReseeding] = status_entropy_reseeding;
969975

970976
void'(ral.status.predict(.value(exp_status), .kind(UVM_PREDICT_READ)));
971977

@@ -1837,9 +1843,15 @@ class kmac_scoreboard extends cip_base_scoreboard #(.CFG_T(kmac_env_cfg),
18371843

18381844
function void set_entropy_fetch(bit val);
18391845
if (val) begin
1840-
if (entropy_mode == EntropyModeEdn) in_edn_fetch = cfg.enable_masking;
1846+
if (entropy_mode == EntropyModeEdn) begin
1847+
in_edn_fetch = cfg.enable_masking;
1848+
status_entropy_reseeding = cfg.enable_masking;
1849+
status_entropy_ready = !cfg.enable_masking;
1850+
end
18411851
end else begin
18421852
in_edn_fetch = 0;
1853+
status_entropy_reseeding = 0;
1854+
status_entropy_ready = 1;
18431855
`uvm_info(`gfn, "dropped in_edn_fetch", UVM_HIGH)
18441856
end
18451857
endfunction

hw/ip/kmac/rtl/kmac.sv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ module kmac
306306

307307
prim_mubi_pkg::mubi4_t entropy_configured;
308308

309+
logic status_entropy_ready;
310+
logic status_entropy_reseeding;
311+
309312
// Message Masking
310313
logic msg_mask_en, cfg_msg_mask;
311314
logic [MsgWidth-1:0] msg_mask;
@@ -465,6 +468,9 @@ module kmac
465468
assign hw2reg.status.sha3_absorb.d = sha3_fsm == sha3_pkg::StAbsorb;
466469
assign hw2reg.status.sha3_squeeze.d = sha3_fsm == sha3_pkg::StSqueeze;
467470

471+
assign hw2reg.status.entropy_ready.d = status_entropy_ready;
472+
assign hw2reg.status.entropy_reseeding.d = status_entropy_reseeding;
473+
468474
// FIFO related status
469475
assign hw2reg.status.fifo_depth.d[MsgFifoDepthW-1:0] = msgfifo_depth;
470476
if ($bits(hw2reg.status.fifo_depth.d) != MsgFifoDepthW) begin : gen_fifo_depth_tie
@@ -1309,6 +1315,9 @@ module kmac
13091315

13101316
.entropy_configured_o (entropy_configured),
13111317

1318+
.entropy_ready_o (status_entropy_ready),
1319+
.entropy_reseeding_o (status_entropy_reseeding),
1320+
13121321
// LC escalation
13131322
.lc_escalate_en_i (lc_escalate_en[5]),
13141323

@@ -1362,6 +1371,8 @@ module kmac
13621371

13631372
// If Masking is off, always entropy configured
13641373
assign entropy_configured = prim_mubi_pkg::MuBi4True;
1374+
assign status_entropy_ready = 1'b 1;
1375+
assign status_entropy_reseeding = 1'b 0;
13651376

13661377
logic unused_edn_clk_rst;
13671378
assign unused_edn_clk_rst = ^{clk_edn_i, rst_edn_ni};

hw/ip/kmac/rtl/kmac_entropy.sv

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ module kmac_entropy
7171

7272
output prim_mubi_pkg::mubi4_t entropy_configured_o,
7373

74+
output logic entropy_ready_o,
75+
output logic entropy_reseeding_o,
76+
7477
// Life cycle
7578
input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i,
7679

@@ -297,7 +300,6 @@ module kmac_entropy
297300

298301
// Hash Counter
299302
logic threshold_hit;
300-
logic threshold_hit_q, threshold_hit_clr; // latched hit
301303

302304
logic hash_progress_d, hash_progress_q;
303305
always_ff @(posedge clk_i or negedge rst_ni) begin
@@ -337,15 +339,29 @@ module kmac_entropy
337339
assign threshold_hit = |hash_threshold_i && (hash_threshold_i <= hash_cnt_o);
338340

339341
always_ff @(posedge clk_i or negedge rst_ni) begin
340-
if (!rst_ni) threshold_hit_q <= 1'b 0;
341-
else if (threshold_hit_clr) threshold_hit_q <= 1'b 0;
342-
else if (threshold_hit) threshold_hit_q <= 1'b 1;
342+
if (!rst_ni) mode_q <= EntropyModeNone;
343+
else if (mode_latch) mode_q <= mode_i;
343344
end
344345

346+
// EDN reseed triggering ====================================================
347+
logic edn_trigger_clr;
348+
logic edn_trigger_d, edn_trigger_q;
349+
350+
// The entropy_refresh_req_i input from software and the threshold_hit signal
351+
// are both pulses. Latch them.
352+
assign edn_trigger_d =
353+
((mode_q == EntropyModeEdn) &&
354+
(entropy_refresh_req_i || threshold_hit)) ? 1'b1 :
355+
edn_trigger_clr ? 1'b0 : edn_trigger_q;
356+
345357
always_ff @(posedge clk_i or negedge rst_ni) begin
346-
if (!rst_ni) mode_q <= EntropyModeNone;
347-
else if (mode_latch) mode_q <= mode_i;
358+
if (!rst_ni) begin
359+
edn_trigger_q <= 1'b0;
360+
end else begin
361+
edn_trigger_q <= edn_trigger_d;
362+
end
348363
end
364+
// EDN reseed triggering ----------------------------------------------------
349365

350366
// PRNG primitive ===========================================================
351367

@@ -497,7 +513,7 @@ module kmac_entropy
497513
timer_enable = 1'b 0;
498514
timer_update = 1'b 0;
499515

500-
threshold_hit_clr = 1'b 0;
516+
edn_trigger_clr = 1'b 0;
501517

502518
// rand is valid when this logic expands the entropy.
503519
// FSM sets the valid signal, the signal is cleared by `consume` signal
@@ -521,6 +537,10 @@ module kmac_entropy
521537
data_update = 1'b 0;
522538
aux_update = 1'b 0;
523539

540+
// Status
541+
entropy_ready_o = 1'b 0;
542+
entropy_reseeding_o = 1'b 0;
543+
524544
// Error
525545
err_o = '{valid: 1'b 0, code: ErrNone, info: '0};
526546

@@ -570,6 +590,8 @@ module kmac_entropy
570590

571591
prng_en = prng_en_rand_q[0];
572592

593+
entropy_ready_o = 1'b 1;
594+
573595
if ((rand_update_i || rand_consumed_i) &&
574596
((fast_process_i && in_keyblock_i) || !fast_process_i)) begin
575597
// If fast_process is set, don't clear the rand valid, even
@@ -586,17 +608,15 @@ module kmac_entropy
586608
end else begin
587609
st_d = StRandReady;
588610
end
589-
end else if ((mode_q == EntropyModeEdn) &&
590-
(entropy_refresh_req_i || threshold_hit_q)) begin
611+
end else if (edn_trigger_q) begin
591612
// Start reseeding the PRNG via EDN.
592613
seed_en = 1'b 1;
593614
st_d = StRandEdn;
594615

595616
// Timer reset
596617
timer_update = 1'b 1;
597618

598-
// Clear the threshold as it refreshes the hash
599-
threshold_hit_clr = 1'b 1;
619+
edn_trigger_clr = 1'b 1;
600620
end else begin
601621
st_d = StRandReady;
602622
end
@@ -609,6 +629,9 @@ module kmac_entropy
609629
// Wait timer
610630
timer_enable = 1'b 1;
611631

632+
// Status
633+
entropy_reseeding_o = 1'b 1;
634+
612635
if (timer_expired && non_zero_wait_timer_limit) begin
613636
// If timer count is non-zero and expired;
614637
st_d = StRandErrWaitExpired;
@@ -648,6 +671,9 @@ module kmac_entropy
648671
// Forward ack driven by software.
649672
seed_ack = seed_req & seed_update_i;
650673

674+
// Status
675+
entropy_reseeding_o = 1'b 1;
676+
651677
if (seed_done) begin
652678
st_d = StRandGenerate;
653679

@@ -678,6 +704,8 @@ module kmac_entropy
678704
rand_valid_set = 1'b 1;
679705
prng_en = prng_en_rand_q[0];
680706

707+
entropy_ready_o = 1'b 1;
708+
681709
st_d = StRandReady;
682710
end
683711

hw/ip/kmac/rtl/kmac_reg_pkg.sv

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ package kmac_reg_pkg;
218218
struct packed {
219219
logic [4:0] d;
220220
} fifo_depth;
221+
struct packed {
222+
logic d;
223+
} entropy_reseeding;
224+
struct packed {
225+
logic d;
226+
} entropy_ready;
221227
struct packed {
222228
logic d;
223229
} sha3_squeeze;
@@ -259,9 +265,9 @@ package kmac_reg_pkg;
259265

260266
// HW -> register type
261267
typedef struct packed {
262-
kmac_hw2reg_intr_state_reg_t intr_state; // [62:57]
263-
kmac_hw2reg_cfg_regwen_reg_t cfg_regwen; // [56:56]
264-
kmac_hw2reg_status_reg_t status; // [55:44]
268+
kmac_hw2reg_intr_state_reg_t intr_state; // [64:59]
269+
kmac_hw2reg_cfg_regwen_reg_t cfg_regwen; // [58:58]
270+
kmac_hw2reg_status_reg_t status; // [57:44]
265271
kmac_hw2reg_entropy_refresh_hash_cnt_reg_t entropy_refresh_hash_cnt; // [43:33]
266272
kmac_hw2reg_err_code_reg_t err_code; // [32:0]
267273
} kmac_hw2reg_t;

hw/ip/kmac/rtl/kmac_reg_top.sv

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ module kmac_reg_top (
254254
logic status_sha3_idle_qs;
255255
logic status_sha3_absorb_qs;
256256
logic status_sha3_squeeze_qs;
257+
logic status_entropy_ready_qs;
258+
logic status_entropy_reseeding_qs;
257259
logic [4:0] status_fifo_depth_qs;
258260
logic status_fifo_empty_qs;
259261
logic status_fifo_full_qs;
@@ -1185,6 +1187,36 @@ module kmac_reg_top (
11851187
.qs (status_sha3_squeeze_qs)
11861188
);
11871189

1190+
// F[entropy_ready]: 4:4
1191+
prim_subreg_ext #(
1192+
.DW (1)
1193+
) u_status_entropy_ready (
1194+
.re (status_re),
1195+
.we (1'b0),
1196+
.wd ('0),
1197+
.d (hw2reg.status.entropy_ready.d),
1198+
.qre (),
1199+
.qe (),
1200+
.q (),
1201+
.ds (),
1202+
.qs (status_entropy_ready_qs)
1203+
);
1204+
1205+
// F[entropy_reseeding]: 5:5
1206+
prim_subreg_ext #(
1207+
.DW (1)
1208+
) u_status_entropy_reseeding (
1209+
.re (status_re),
1210+
.we (1'b0),
1211+
.wd ('0),
1212+
.d (hw2reg.status.entropy_reseeding.d),
1213+
.qre (),
1214+
.qe (),
1215+
.q (),
1216+
.ds (),
1217+
.qs (status_entropy_reseeding_qs)
1218+
);
1219+
11881220
// F[fifo_depth]: 12:8
11891221
prim_subreg_ext #(
11901222
.DW (5)
@@ -3036,6 +3068,8 @@ module kmac_reg_top (
30363068
reg_rdata_next[0] = status_sha3_idle_qs;
30373069
reg_rdata_next[1] = status_sha3_absorb_qs;
30383070
reg_rdata_next[2] = status_sha3_squeeze_qs;
3071+
reg_rdata_next[4] = status_entropy_ready_qs;
3072+
reg_rdata_next[5] = status_entropy_reseeding_qs;
30393073
reg_rdata_next[12:8] = status_fifo_depth_qs;
30403074
reg_rdata_next[14] = status_fifo_empty_qs;
30413075
reg_rdata_next[15] = status_fifo_full_qs;

0 commit comments

Comments
 (0)