The table below lists other CSRNG signals.
Signal | Direction | Type | Description |
---|---|---|---|
otp_en_csrng_sw_app_read_i | input | otp_en_t | An efuse that will enable firmware to access the NIST CTR_DRBG internal state and genbits through registers. |
lc_hw_debug_en_i | input | lc_tx_t | A life-cycle that will select which diversification value is used for xoring with the seed from ENTROPY_SRC. |
entropy_src_hw_if_o | output | entropy_src_hw_if_req_t | Seed request made to the ENTROPY_SRC module. |
entropy_src_hw_if_i | input | entropy_src_hw_if_rsp_t | Seed response from the ENTROPY_SRC module. |
cs_aes_halt_i | input | cs_aes_halt_req_t | Request to CSRNG from ENTROPY_SRC to halt requests to the AES block for power leveling purposes. |
cs_aes_halt_o | output | cs_aes_halt_rsp_t | Response from CSRNG to ENTROPY_SRC that all requests to AES block are halted. |
csrng_cmd_i | input | csrng_req_t | Application interface request to CSRNG from an EDN block. |
csrng_cmd_o | output | csrng_rsp_t | Application interface response from CSRNG to an EDN block. |
Regarding command processing, all commands process immediately except for the generate command. The command generate length count (glen
) is kept in the cmd_stage
block. When the state_db
block issues an ack to the cmd_stage
block, the cmd_stage
block increments an internal counter. This process repeats until the glen
field value has been matched. Because each request is pipelined, requests from other cmd_stage
blocks can be processed before the original generate command is completely done. This provides some interleaving of commands since a generate command can be programmed to take a very long time.
When sending an unsupported or illegal command, CS_MAIN_SM_ALERT
will be triggered, but there will be no status response or indication of which app the error occurred in.
The CSRNG working state data base (state_db
) contains the current working state for a given DRBG instance. It holds the following values:
The block_encrypt
block is where the aes_cipher_core
block is located. This is the same block used in the AES design. Parameters are selected such that this is the unmasked version.
The software application interface uses a set of TL-UL registers to send commands and receive generated bits. Since the registers are 32-bit words wide, some sequencing will need to be done by firmware to make this interface work properly.
This section describes the application interface, which is required for performing any operations using a CSRNG instance (i.e. instantiation, reseeding, RNG generation, or uninstantiation). Each CSRNG instance corresponds to a unique application interface port, which implements the application interface described here. Any hardware peripherals which require complete control of an instance may connect directly to a dedicated interface port. Meanwhile peripherals without any special requirements (i.e. personalization strings or non-FIPS-approved, fully-deterministic number sequences) may share access to an instance via the entropy distribution network (EDN) IP. The EDNs manage the instantiation and reseeding of CSRNG instances for general use-cases, providing either on-demand or timed-delivery entropy streams to hardware peripherals. Firmware applications can obtain access to random bit sequences directly through application interface port 0, which is directly mapped to a set of TL-UL registers.
The total number of application interface ports (for TL-UL, directly attached peripherals or EDN instances) is determined by the NHwApp
parameter.
The command bus operates like a FIFO, in which a command is pushed into the interface. An optional stream of additional data may follow, such as seed material for an instantiate
application command. For the generate
application command, the obfuscated entropy will be returned on the genbits
bus. This bus also operates like a FIFO, and the receiving module can provide back pressure to the genbits
bus. There is one instance of a firmware application interface, and it uses the TL-UL registers. For more details on how the application interface works, see the Theory of Operations section above.
In general, users of the application interface are either firmware or some hardware module entity. For hardware, a module can either directly control the application interface, or it can connect to an EDN module. Attaching to an EDN module allows for a simpler interface connection to a more layout-friendly distributed-chip network.
The general format for the application interface is a 32-bit command header, optionally followed by additional data, such as a personalization string, typically twelve 32-bit words in length. Depending on the command, these strings are typically required to be 384-bits in length, to match the size of the seed-length when operating with 256-bit security-strength. The exact function of the additional data field depends in the command. However, in general, the additional data can be any length as specified by the command length field. The command header is defined below.
The application interface requires that a 32-bit command header be provided to instruct the CSRNG how to manage the internal working states. Below is a description of the fields of this header:
The command field of the application command header is described in detail in the table below. The actions performed by each command, as well as which flags are supported, are described in this table.
Once a command has been completed, successfully or unsuccessfully, the CSRNG responds with a single cycle pulse on the csrng_rsp_ack
signal associated with the same application interface port. If the command is successful, the csrng_rsp_sts
signal will indicate the value 0 (CSRNG_OK
) in the same cycle. Otherwise the application will receive the value 1 (CSRNG_ERROR
) on the csrng_rsp_sts
signal. A number of exception cases to be considered are enumerated in NIST SP 800-90A, and may include events such as:
hw_exc_sts
register, and a cs_hw_inst_exc
interrupt will be raised.genbits
) InterfaceIn addition to the command response signals there is a bus for returning the generated bits. This 129-bit bus consists of 128-bits, genbits_bus
, for the random bit sequence itself, along with a single bit flag, genbits_fips
, indicating whether the bits were considered fully in accordance with FIPS standards.
There are two cases when the sequence will not be FIPS compliant:
ENTROPY_SRC
generates a seed from the first 384 bits pulled from the noise source. This initial seed is tested to ensure some minimum quality for obfuscation use- cases, but this boot seed is not expected to be full-entropy nor do these health checks meet the 1024-bit requirement for start-up health checks required by NIST 800-90B.flag0
is asserted during instantiation, the resulting DRBG instance will have a fully-deterministic seed, determined only by user input data. Such a seed will be created only using factory-entropy and will lack the physical-entropy required by NIST SP 800-90A, and thus this DRBG instance will not be FIPS compliant.The application command signal csrng_req_bus
is accompanied by a csrng_valid_signal
, which is asserted by the requester when the command is valid. CSRNG may stall incoming commands by de-asserting the csrng_req_ready
signal. A command is considered received whenever both csrng_req_valid
and csrng_req_ready
are asserted in the same clock cycle.
Likewise a requester must only consider data on the genbits
bus to be valid when the genbits_valid
signal is asserted, and should assert genbits_ready
whenever it is ready to accept the genbits
data. The genbits
data is considered successfully transmitted whenever genbits_valid
and genbits_ready
are asserted in the same clock cycle.
A requester must always be ready to receive csrng_req_sts
signals. (There is no “ready” signal for command response messages sent to hardware.)
{signal: [ {name: 'clk' , wave: 'p...............|.....'}, {name: 'csrng_req_valid' , wave: '01............0.|.....'}, {name: 'csrng_req_ready' , wave: '1.............0.|..1..'}, {name: 'csrng_req_bus' , wave: 'x5333333333333x.|.....',data: ['ins','sd1','sd2','sd3','sd4','sd5','sd6','sd7','sd8','sd9','sd10','sd11','sd12']}, {name: 'csrng_rsp_ack' , wave: '0...............|.10..'}, {name: 'csrng_rsp_sts' , wave: 'x...............|.5x..', data: ['ok']}, {}, ]}
{signal: [ {name: 'clk' , wave: 'p...............|.....'}, {name: 'csrng_req_valid' , wave: '01............0.|.....'}, {name: 'csrng_req_ready' , wave: '1.............0.|..1..'}, {name: 'csrng_req_bus' , wave: 'x5333333333333x.|.....',data: ['res','ad1','ad2','ad3','ad4','ad5','ad6','ad7','ad8','ad9','ad10','ad11','ad12']}, {name: 'csrng_rsp_ack' , wave: '0...............|.10..'}, {name: 'csrng_rsp_sts' , wave: 'x...............|.5x..', data: ['ok']}, {}, ]}
{signal: [ {name: 'clk' , wave: 'p...|...|....|....|...'}, {name: 'csrng_req_valid' , wave: '010.|...|....|....|...'}, {name: 'csrng_req_ready' , wave: '1...|...|....|....|...'}, {name: 'csrng_req_bus' , wave: 'x5x.|...|....|....|...',data: ['gen']}, {name: 'csrng_rsp_ack' , wave: '0...|...|....|....|.10'}, {name: 'csrng_rsp_sts' , wave: 'x...|...|....|....|.5x', data: ['ok']}, {name: 'genbits_valid' , wave: '0...|.10|.1.0|.10.|...'}, {name: 'csrng_rsp_fips' , wave: '0...|.10|.1.0|.10.|...'}, {name: 'genbits_bus' , wave: '0...|.40|.4.0|.40.|...', data: ['bits0','bits1','bits2']}, {name: 'genbits_ready' , wave: '1...|...|0.1.|........'}, ]}
{signal: [ {name: 'clk' , wave: 'p...............|.....'}, {name: 'csrng_req_valid' , wave: '01............0.|.....'}, {name: 'csrng_req_ready' , wave: '1.............0.|..1..'}, {name: 'csrng_req_bus' , wave: 'x5333333333333x.|.....',data: ['upd','ad1','ad2','ad3','ad4','ad5','ad6','ad7','ad8','ad9','ad10','ad11','ad12']}, {name: 'csrng_rsp_ack' , wave: '0...............|.10..'}, {name: 'csrng_rsp_sts' , wave: 'x...............|.5x..', data: ['ok']}, {}, ]}
{signal: [ {name: 'clk' , wave: 'p...............|.....'}, {name: 'csrng_req_valid' , wave: '010.............|.....'}, {name: 'csrng_req_ready' , wave: '1.0.............|..1..'}, {name: 'csrng_req_bus' , wave: 'x5x.............|.....',data: ['uni']}, {name: 'csrng_rsp_ack' , wave: '0...............|.10..'}, {name: 'csrng_rsp_sts' , wave: 'x...............|.5x..', data: ['ok']}, {}, ]}
The following waveform shows an example of how the entropy source hardware interface works.
{signal: [ {name: 'clk' , wave: 'p...|.........|.......'}, {name: 'es_req' , wave: '0..1|..01.0..1|.....0.'}, {name: 'es_ack' , wave: '0...|.10.10...|....10.'}, {name: 'es_bus[383:0]' , wave: '0...|.30.30...|....30.', data: ['es0','es1','es2']}, {name: 'es_fips' , wave: '0...|....10...|....10.'}, ]} ]}
The cs_cmd_req_done
interrupt will assert when a CSRNG command has been completed.
The cs_entropy_req
interrupt will assert when CSRNG requests entropy from ENTROPY_SRC.
The cs_hw_inst_exc
interrupt will assert when any of the hardware-controlled CSRNG instances encounters an exception while executing a command, either due to errors on the command sequencing, or an exception within the ENTROPY_SRC
IP.
The cs_fatal_err
interrupt will assert when any of the CSRNG FIFOs has a malfunction. The conditions that cause this to happen are either when there is a push to a full FIFO or a pull from an empty FIFO.
This section discusses how software can interface with CSRNG.
CSRNG may only be enabled if ENTROPY_SRC
is enabled. CSRNG may only be disabled if all EDNs are disabled. Once disabled, CSRNG may only be re-enabled after ENTROPY_SRC
has been disabled and re-enabled.
All CSRNG registers are little-endian.
When providing additional data for an instantiate, reseed or update command the data words have to be written to CMD_REQ
in the correct order. Consider a byte string B1, B2, ..., Bn as defined in Appendix A of NIST's SP 800-90A, i.e., where B1 is the most significant byte and Bn the least significant byte. Providing this sequence as additional data to CSRNG requires software to write the following 32-bit words to CMD_REQ
in the following order:
When reading the internal state from INT_STATE_VAL
, CSRNG returns the bytes of V and Key in the following order:
Finally, when reading a byte string of say 64 bytes (16 words) B1, B2, ..., B64 from GENBITS
as defined in Appendix A of NIST's SP 800-90A, the bytes are returned in the following order. Note that always 4 words return 1 128-bit GENBITS block. Within each block, the least significant bytes are returned first and the most significant bytes are returned last. In particular, the most significant byte B1 of the string is read in Word 4 and the least significant byte B64 of the string is read in Word 13.