Programmer’s Guide
This section discusses how software can interface with CSRNG.
Module enable and disable
CSRNG may only be disabled if all EDNs are disabled.
The recommended enable sequence for the entropy complex is to first enable ENTROPY_SRC, then CSRNG, and finally the EDNs.
Running CSRNG with ENTROPY_SRC disabled
Once the entropy complex has been enabled and all configured CSRNG instances have been seeded with entropy, software can again disable ENTROPY_SRC (and the PTRNG noise source to e.g. save power) while CSRNG and the EDNs remain running to keep serving entropy to consumers.
Depending on the mode in which the CSRNG instance is running, software can use a different mechanism to efficiently operate the entropy complex without having the ENTROPY_SRC continuously running:
Regular, non-deterministic mode
If a CSRNG instance is running in regular, non-deterministic mode (flag0 being false, see Generated Bits (genbits) Interface for details), the cs_entropy_req interrupt will assert whenever the instance requests entropy from ENTROPY_SRC.
Once software observes the interrupt, it has to enable ENTROPY_SRC.
The ENTROPY_SRC block will then perform the startup health testing and eventually deliver a new seed to the CSRNG instance.
Note that the startup health testing may take a non-negligible time (see Startup Health Testing during which the CSRNG instance is blocked.
Thus, it is recommended that software tracks the age of the seed currently in use via the corresponding RESEED_COUNTER register to re-enable ENTROPY_SRC ahead of the cs_entropy_req interrupt firing.
Fully deterministic mode
For CSRNG instances running in fully deterministic mode (flag0 being true, see Generated Bits (genbits) Interface for details), software has to provide entropy for instantiation and reseeding via the additional data field of the instantiate and reseed command, respectively.
If no additional data is provided, CSRNG will use an all-zero seed.
Additional entropy can be provided via the additional data field of every generate command.
The entropy to be provided to these commands can for example be generated by running the ENTROPY_SRC block in a dedicated mode, see Reading Entropy Output for details.
Software is recommended to manage a buffer of seeds which is filled whenever it enables ENTROPY_SRC in this mode to reduce the duty cycle of ENTROPY_SRC (and the PTRNG noise source) thereby improving power efficiency and latency.
Endianness and Known-Answer Tests
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:
| Word Index | Byte Indices of Additional Data |
|---|---|
| 1 | 0xBn-3Bn-2Bn-1Bn |
| ... | ... |
| n/4-1 | 0xB5B6B8B8 |
| n/4 | 0xB1B2B3B4 |
When reading the internal state of an instance from INT_STATE_VAL (see Internal-State Save and Restore below), CSRNG returns 26 words: the reseed counter, the bytes of V and Key, the additional data of a Generate command paused mid-sequence, and finally the status and Generate command state, in the following order:
| Word Index | Contents |
|---|---|
| 1 | Reseed counter |
| 2 | 0xV13V14V15V16 |
| ... | ... |
| 5 | 0xV01V02V03V04 |
| 6 | 0xKey29Key30Key31Key32 |
| ... | ... |
| 12 | 0xKey05Key06Key07Key08 |
| 13 | 0xKey01Key02Key03Key04 |
| 14 | Generate additional data, least significant word |
| ... | ... |
| 25 | Generate additional data, most significant word |
| 26 | Bit 0: instantiated, bit 1: FIPS, bits 2-13: remaining Generate blocks, bit 14: Generate command in progress, bit 15: Generate additional data valid, bits 16-31: reserved (read as 0) |
Internal-State Save and Restore
CSRNG supports pausing a single instance via INT_STATE_HALT, reading out (or overwriting) its full internal DRBG state via INT_STATE_VAL, and resuming it:
- Select the target instance by writing its index to
INT_STATE_NUM. - Set
INT_STATE_HALTtokMultiBitBool4True. The halt applies to the instance selected byINT_STATE_NUM, so only one instance can be halted at a time. - Wait for the instance to quiesce, either by polling
INT_STATE_STSor by waiting for thecs_cmd_req_doneinterrupt. - Read all 26 words of the internal state through
INT_STATE_VALto save it, or write all 26 words to restore it. Reserved bits are ignored on writes and read as 0. The internal state includes the state of a Generate command paused mid-sequence, which continues once the instance is resumed. Every read and every write advances the word pointer. Switching from reads to writes, or from writes to reads, restarts the sequence at the first word. WritingINT_STATE_NUMalso resets the word pointer to the first word. - Set
INT_STATE_HALTtokMultiBitBool4Falseto let the instance continue processing commands.
INT_STATE_VAL can be read independent of whether or not the instance is halted.
Restoring a state by writing INT_STATE_VAL is only allowed while the instance is halted, i.e., while INT_STATE_STS.HALTED is set.
If CSRNG internally updates the state of the selected instance while a read sequence is in progress, i.e., while the word pointer is advanced, the saved state may be inconsistent and RECOV_ALERT_STS.INT_STATE_OVERWRITE_ALERT is raised.
Halting the instance first prevents this.
Reading requires CTRL.READ_INT_STATE to be set to kMultiBitBool4True and the selected instance’s bit in INT_STATE_READ_ENABLE to be set.
Writing requires CTRL.WRITE_INT_STATE to be set to kMultiBitBool4True and the selected instance’s bit in INT_STATE_WRITE_ENABLE to be set.
Otherwise, INT_STATE_VAL reads as 0, writes are dropped, and the word pointer does not advance.
Disabling read access while reading, or write access while writing, resets the word pointer to the first word.
Halting requires the selected instance’s bit in INT_STATE_HALT_ENABLE to be set.
Otherwise, setting INT_STATE_HALT has no effect on the instance and INT_STATE_STS.HALTED remains 0.
After reset, reading, writing and halting are enabled for all instances.
Each of these settings can be locked via INT_STATE_READ_ENABLE_REGWEN, INT_STATE_WRITE_ENABLE_REGWEN and INT_STATE_HALT_ENABLE_REGWEN, respectively.
If INT_STATE_HALT is set while the instance is processing a Generate command, the instance halts as soon as the block currently being generated is complete, provided that further blocks of the command remain to be generated.
The application does not need to read out the generated block first.
The remaining blocks are generated after the instance is resumed.
If the generation of the final block of the command has already started, the instance only halts after the application has read out the final block and the command has been acknowledged.
Any other command in progress completes before the instance halts.
Commands that have been received for the instance but not yet started are also processed before it halts.
While halted, the instance accepts no new commands: requests from an EDN are back-pressured until the instance is resumed, and SW_CMD_STS.CMD_RDY stays low for the software instance.
Hence, no command is pending while the instance is halted, and any command issued afterwards is processed against the restored state once the instance is resumed.
Halting does not stop an EDN in auto mode: it continues its Generate/Reseed sequence as soon as the instance is resumed.
When restoring the state of an instance serving an EDN, software must ensure that the EDN can continue without errors.
The EDN might expect the instance to be instantiated, and the restored reseed counter needs to leave enough headroom for the Generate commands the EDN may issue before its next Reseed, as the EDN tracks MAX_NUM_REQS_BETWEEN_RESEEDS independently of CSRNG.
Otherwise, CSRNG rejects one of the EDN’s subsequent commands and the EDN stops serving entropy until software disables and re-enables it.
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.
| Word Index | Byte Indices of Generated Bits |
|---|---|
| 1 | 0xB13B14B15B16 |
| 2 | 0xB09B10B11B12 |
| 3 | 0xB05B06B07B08 |
| 4 | 0xB01B02B03B04 |
| 5 | 0xB29B30B31B32 |
| 6 | 0xB25B26B27B28 |
| 7 | 0xB21B22B23B24 |
| 8 | 0xB17B18B19B20 |
| ... | ... |
| 13 | 0xB61B62B63B64 |
| 14 | 0xB57B58B59B60 |
| 15 | 0xB53B54B55B56 |
| 16 | 0xB49B50B51B52 |