Skip to content

Commit

Permalink
[entropy_src/doc] Document behavior of SHA3 conditioner engine
Browse files Browse the repository at this point in the history
Previously, the documentation and comments in the RTL suggested that
the number of bits the conditioner takes to produce a single 384-bit
seed would be fixed to 2048 bits. However, this is not true. In a
nutshell, the number of bits consumed is equal to the configured health
test window size. This commit clarifies this in the documentation as
well as in the RTL.

In addition, this commit also documents in the RTL when the SHA3
conditioner block is actually active. So far, this the assumption was
the conditioner was only active if explicitly triggered by the main
state machine upon finishing checking the next health test window.
However, the SHA3 engine is also active whenever 832 bits have been
received. This condition is not tracked by the main state machine which
is the reason for the CS AES Halt interface currently being broken.

See also #17941.

Signed-off-by: Pirmin Vogel <[email protected]>
  • Loading branch information
vogelpi committed Feb 8, 2024
1 parent 8618394 commit 809ba9c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 8 deletions.
5 changes: 3 additions & 2 deletions hw/ip/entropy_src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@ These tests include:
- Optional Vendor Specific tests, which allow silicon creators to extend the health checks by adding a top-level block external to this IP.

The Repetition Count and Adaptive Proportion test are specifically recommended by SP 800-90B, and are implemented in accordance with those recommendations.
In FIPS/CC-compliance mode, all checks except the Repetition Count test are performed on fixed window of data, typically consisting of 2048 bits each.
In FIPS/CC-compliance mode, all checks except the Repetition Count test are performed on a fixed window of data of configurable size, by default consisting of 2048 bits each.
Per the definition in SP 800-90B, the Repetition Count test does not operate on a fixed window.
The repetition count test fails if any sequence of bits continuously asserts the same value for too many samples, as determined by the programmable threshold, regardless of whether that sequence crosses any window boundaries.
The thresholds for these tests should be chosen to achieve a low false-positive rate (&alpha;) given a conservative estimate of the manufacturing tolerances of the PTRNG noise source.
The combined choice of threshold and window size then determine the false-negative rate (&beta;), or the probability of missing statistical defects at any particular magnitude.

When the IP is disabled by clearing the [`MODULE_ENABLE`](./doc/registers.md#MODULE_ENABLE) register, all health checks are disabled and all counters internal to the health checks are reset.

In order to compensate for the fact our tests (like *all* realistic statistical tests) have finite resolution for detecting defects, we conservatively use 2048 bits of PTRNG noise source to construct each 384 bit conditioned entropy sample.
In order to compensate for the fact our tests (like *all* realistic statistical tests) have finite resolution for detecting defects, we conservatively use 2048 bits of PTRNG noise source to construct each 384 bit conditioned entropy sample by default.
The effectively used number of bits is equal to the configured health test window size.
When passed through the conditioning block, the resultant entropy stream will be full entropy unless the PTRNG noise source has encountered some statistical defect serious enough to reduce the raw min-entropy to a level below 0.375 bits of entropy per output bit.
We choose this level as our definition of "non-tolerable statistical defects" for the purposes of evaluating this system under AIS31.
Given this definition of "non-tolerable defects", the health-checks as implemented for this block will almost certainly detect any of the previously mentioned defects in a single iteration of the health checks (i.e. such serious defects will be detected with very low &beta;).
Expand Down
8 changes: 8 additions & 0 deletions hw/ip/entropy_src/data/entropy_src.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,14 @@
This is the window size for all health tests.
This value is used when entropy is being tested in FIPS/CC compliance mode (for simplicity referred to as FIPS mode).
The default value is (2048 bits * 1 clock/4 bits);

Note that the number of tested bits taken by the conditioner to produce a seed is equal to the window size x 4.
The only exception is the startup seed which is produced using the bits of two subsequent windows, i.e., 2 x window size x 4 tested bits.
The factor of 4 relates to the number of noise source channels (i.e. symbol size) and applies both in single-channel and multi-channel mode (see !!ENTROPY_SRC.RNG_BIT_ENABLE).

Note that NIST SP 800-90B (Table 2) requires the adaptive proportion test to be run on 1024 or 512 samples in single-channel or multi-channel mode, respectively (see !!ENTROPY_SRC.RNG_BIT_ENABLE).
The startup tests must be run on at least 1024 consecutive samples (see Section 4.3 Requirements for Health Tests of NIST SP 800-90B) and this block always uses two subsequent windows for startup health testing.
The use of window sizes below 512 samples is thus not recommended as this may not comply with NIST SP 800-90B.
'''
resval: "0x0200"
}
Expand Down
8 changes: 8 additions & 0 deletions hw/ip/entropy_src/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,14 @@ This is the window size for all health tests.
This value is used when entropy is being tested in FIPS/CC compliance mode (for simplicity referred to as FIPS mode).
The default value is (2048 bits * 1 clock/4 bits);

Note that the number of tested bits taken by the conditioner to produce a seed is equal to the window size x 4.
The only exception is the startup seed which is produced using the bits of two subsequent windows, i.e., 2 x window size x 4 tested bits.
The factor of 4 relates to the number of noise source channels (i.e. symbol size) and applies both in single-channel and multi-channel mode (see [`ENTROPY_SRC.RNG_BIT_ENABLE`](#entropy_src)).

Note that NIST SP 800-90B (Table 2) requires the adaptive proportion test to be run on 1024 or 512 samples in single-channel or multi-channel mode, respectively (see [`ENTROPY_SRC.RNG_BIT_ENABLE`](#entropy_src)).
The startup tests must be run on at least 1024 consecutive samples (see Section 4.3 Requirements for Health Tests of NIST SP 800-90B) and this block always uses two subsequent windows for startup health testing.
The use of window sizes below 512 samples is thus not recommended as this may not comply with NIST SP 800-90B.

## REPCNT_THRESHOLDS
Repetition count test thresholds register
- Offset: `0x34`
Expand Down
6 changes: 5 additions & 1 deletion hw/ip/entropy_src/doc/theory_of_operation.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ When entropy is delivered to the downstream hardware block, a signal will indica
Once the initial boot-time mode phase has completed, the ENTROPY_SRC block can be switched to FIPS/CC compliant mode (for simplicity referred to as FIPS mode) by setting the `FIPS_ENABLE` field in the [`CONF`](registers.md#conf) register to `kMultiBitBool4True`.
In this mode, once the raw entropy has been health checked, it will be passed into a conditioner block.
This block will compress the bits such that the entropy bits/physical bits, or min-entropy value, should be improved over the raw data source min-entropy value.
The compression operation, by default, will compress every 2048 tested bits into 384 full-entropy bits.
The compression operation will compress every [`HEALTH_TEST_WINDOWS.FIPS_WINDOW`](registers.md#health_test_windows--fips_window) x 4 tested bits into 384 full-entropy bits.
By default, 2048 tested bits are used.

Note that after enabling the ENTROPY_SRC block, the health tests need to pass for two subsequent windows of [`HEALTH_TEST_WINDOWS.FIPS_WINDOW`](registers.md#health_test_windows--fips_window) x 4 tested bits (startup health testing).
By default, 1024 samples of 4 bits (4096 1-bit samples when running in single-channel mode), i.e., 4096 tested bits, are used for producing the startup seed.

The hardware conditioning can also be bypassed and replaced in normal operation with a firmware-defined conditioning algorithm.
This firmware conditioning algorithm can be disabled on boot for security purposes.
Expand Down
23 changes: 19 additions & 4 deletions hw/ip/entropy_src/rtl/entropy_src_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2455,10 +2455,25 @@ module entropy_src_core import entropy_src_pkg::*; #(
//--------------------------------------------
// entropy conditioner
//--------------------------------------------
// This block will take in raw entropy from the noise source block
// and compress it such that a perfect entropy source is created
// This block will take in 2048 (by default setting) bits to create 384 bits.

// This block takes in either post-health test entropy bits (when running in FIPS/CC compliant
// mode) or entropy injected by software (when running in Firmware Override: Extract & Insert
// mode).
// The amount of entropy consumed to generate a 384-bit seed depends on the mode of operation:
// - In FIPS/CC compliant mode, HEALTH_TEST_WINDOWS.FIPS_WINDOW x 4 bits (by default 2048 bits)
// are required to produce one 384-bit seed. For the first seed after start up, the number of
// bits consumed is doubled to align with the required 1024 samples of 4 bits for startup
// health testing.
// For windows which fail a health test, the entropy is still absorbed by the SHA3 engine
// but no seed is produced. In order for the SHA3 engine to produce a seed, the last window it
// absorbed must have passed the health tests.
// - In Firmware Override: Extract & Insert mode, the operation of the SHA3 engine is software
// defined.
//
// Note that the final absorption operation of the SHA3 engine is triggered by the main state
// machine (upon receiving the health-test done pulse). The SHA3 engine is also triggered
// internally by the padding logic whenever 832 bits (= the rate or block size of SHA3-384) have
// been received.
//
// Note on backpressure from the SHA block:
// If we use the full sha3_msgfifo_ready signal, we create a combinational logic
// loop. However, the SHA3 seems to have a hiccup by which it some times
Expand Down
19 changes: 18 additions & 1 deletion hw/ip/entropy_src/rtl/entropy_src_main_sm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ module entropy_src_main_sm
if (ht_fail_pulse_i) begin
state_d = StartupFail1;
end else begin
// Passed two consecutive tests
// We've now passed two consecutive test windows of the configured window length.
// Next, we're going to compress the collected entropy to produce a single seed.
state_d = Sha3Prep;
rst_alert_cntr_o = 1'b1;
end
Expand All @@ -186,6 +187,16 @@ module entropy_src_main_sm
if (!enable_i) begin
state_d = Idle;
end else begin
// Send the Start trigger to the SHA3 engine. After this point, collected raw entropy is
// going to be moved into the conditioner in chunks of 64 bits. The SHA3 engine itself
// will hash the received raw entropy whenever either of the following two conditions are
// met:
// 1) 13 64-bit chunks have been received (13 x 64 = 832 = the rate or block size of
// the employed SHA3-384 engine). This condition is checked internally to the SHA3
// engine.
// 2) The total amount of received entropy is equal to the configured health test window
// size. This condition is checked by this FSM which then triggers the SHA3 engine
// using the sha3_process_o signal.
sha3_start_o = 1'b1;
state_d = ContHTRunning;
end
Expand All @@ -195,9 +206,12 @@ module entropy_src_main_sm
state_d = Idle;
end else begin
if (ht_done_pulse_i) begin
// We've finished testing the current window and all the collected and tested entropy
// has been forwarded to the SHA3 engine and has at least partially been absorbed.
if (alert_thresh_fail_i) begin
state_d = AlertState;
end else if (!ht_fail_pulse_i) begin
// Move forward and get the conditioner ready to finish the absorption process.
state_d = Sha3Prep;
rst_alert_cntr_o = 1'b1;
end
Expand Down Expand Up @@ -226,6 +240,7 @@ module entropy_src_main_sm
end
end
Sha3Process: begin
// Trigger the final absorption operation of the SHA3 engine.
cs_aes_halt_req_o = 1'b1;
sha3_process_o = 1'b1;
state_d = Sha3Valid;
Expand All @@ -242,6 +257,8 @@ module entropy_src_main_sm
state_d = Sha3MsgDone;
end else begin
if (main_stage_rdy_i) begin
// Push the digest produced by the SHA3 engine into the final FIFO and clear the
// internal state of the SHA3 engine to start from scratch for the next seed.
sha3_done_o = prim_mubi_pkg::MuBi4True;
main_stage_push_o = 1'b1;
state_d = Sha3MsgDone;
Expand Down

0 comments on commit 809ba9c

Please sign in to comment.