lowRISC / opentitan

OpenTitan: Open source silicon root of trust
https://www.opentitan.org
Apache License 2.0
2.44k stars 730 forks source link

[edn, doc, rom] EDN documentation requires updates #22366

Open vsukhoml opened 3 months ago

vsukhoml commented 3 months ago

Description

Boot-time Request Mode doc states: "In boot-time request mode, the command sequence is fully hardware-controlled and no command customization is possible. In this mode, the EDN automatically issues a special reduced-latency instantiate command followed by the default generate commands. This means, for instance, that no personalization strings or additional data may be passed to the CSRNG application interface port in this mode. On exiting, the EDN issues an uninstantiate command to destroy the associated CSRNG instance."

  1. Does it mean that after boot mode is completed, nothing is using EDN unless explicitly requested? and as such,
  2. Can EDN be left completely disabled after boot-time to reduce power consumption? Any implications of it?
  3. What HW is using EDN and in what cases?
  4. What would happen if CSRNG is disabled, but EDN is enabled in violation to module enable and disable. I suppose EDN won't receive acknowledgment, but how to recover? Disable it, enable CSRNG, enable EDN?
  5. What specifically ROM does in regards to EDN use, and any guidance/assumptions for what ROM_EXT should do.
  6. Why Auto Request Mode is not a default? It seems that EDN can function with minimal control from firmware.
  7. Why would firmware prefer to use GENERATE_CMD when it seems that EDN will issue these commands as needed in auto request mode? How many commands shall be written and why?
  8. Overall Programmers guide requires more details .

@vogelpi , @h-filali ?

vogelpi commented 3 months ago

Description

Boot-time Request Mode doc states: "In boot-time request mode, the command sequence is fully hardware-controlled and no command customization is possible. In this mode, the EDN automatically issues a special reduced-latency instantiate command followed by the default generate commands. This means, for instance, that no personalization strings or additional data may be passed to the CSRNG application interface port in this mode. On exiting, the EDN issues an uninstantiate command to destroy the associated CSRNG instance."

1. Does it mean that after boot mode is completed, nothing is using EDN unless explicitly requested?  and as such,
2. Can EDN be left completely disabled after boot-time to reduce power consumption? Any implications of it?

No. It means after the fixed amount of entropy has been consumed, EDN won't deliver any further entropy to hardware consumers. They will just stall. How much entropy can be delivered is a hardware parameter tuned such that boot-time mode is sufficient for the system to run through ROM. Once in ROM_ext, software has to set up auto mode with the parameters deemed suitable by ROM_ext.

I don't know how much power can be saved by leaving it disabled. In comparison to ENTROPY_SRC and RNG it will be small. It's important to note that whenever an IP requests entropy from EDN while EDN is disabled, the IP will sooner or later hang.

3. What HW is using EDN and in what cases?

Please take a look here to get insight on the different EDN end points / entropy consumers.

4. What would happen if CSRNG is disabled, but EDN is enabled in violation to [module enable and disable](https://opentitan.org/book/hw/ip/edn/doc/programmers_guide.html#module-enable-and-disable). I suppose EDN won't receive acknowledgment, but how to recover? Disable it, enable CSRNG, enable EDN?

Yes, that should work! It's designed such that there is safe sequence to bring things back to operation again.

5. What specifically ROM does in regards to EDN use, and any guidance/assumptions for what ROM_EXT should do.

ROM_ext should set up EDN in auto-request mode early on. More precisely, it should restart the whole entropy complex and set it the different blocks up in the respective modes where they can deliver entropy continuously.

6. Why [Auto Request Mode](https://opentitan.org/book/hw/ip/edn/doc/theory_of_operation.html#auto-request-mode) is not a default? It seems that EDN can function with minimal control from firmware.

CTR_DRBG and as such EDN is highly configurable. What would reasonable parameters for the default auto-request mode be? Because no one can/could answer this in the past, the rational was to set up a minimal mode sufficient for ROM and then let firmware take over and tune parameters as suitable.

7. Why would firmware prefer to use [GENERATE_CMD](https://opentitan.org/book/hw/ip/edn/doc/registers.html#generate_cmd--generate_cmd) when it seems that EDN will issue these commands as needed in auto request mode? How many commands shall be written and why?

The Generate command itself is highly configurable (as per definition of CTR_DRBG) and EDN will send the very command in auto-request mode that firmware writes to the GENERATE_CMD register.

8. Overall [Programmers guide](https://opentitan.org/book/hw/ip/edn/doc/programmers_guide.html) requires more details .

I acknowledge that the programmers guide is not very useful as it is now. But I fear no one really has time right now to extend it. What I recommend instead is to have a look at the EDN SiVal testplan and the corresponding test implementations to get a better idea of what we have been testing at the top level and how firmware can set up these modes.

@vogelpi , @h-filali ?

vsukhoml commented 3 months ago

@vogelpi , thank you for detailed answer. So it seems we need to maintain EDN running, but have to make sure:

  1. It is in auto-request mode
  2. It never sends reseeding, so entropy source can be left disabled

CTR_DRBG and as such EDN is highly configurable. What would reasonable parameters for the default auto-request mode be? Because no one can/could answer this in the past, the rational was to set up a minimal mode sufficient for ROM and then let firmware take over and tune parameters as suitable.

To answer this question it is worth to understand the rate of requests to EDN from hw peripherals. NIST for CTR_DRBG allows up to 2^48 requests w/o reseeding. Practically, if no reseeds are configured, or some very high number like 2^32-1, then I'd expect it can't be reached over the lifetime. But if generate requests are frequent, then we need to periodically enable entropy source for CSRNG to withdraw fresh entropy, and to do that we need to know status of EDN instance - how many requests were made since last reseeding. I don't see that register exposed, but it clearly exists internally.

So, default would be to instantiate CSRNG in Only entropy source seed is used mode with zero reseeding, generate command to produce whatever number of blocks are needed internally with no additional data provided. I'm not sure what are the over options to configure.

The Generate command itself is highly configurable (as per definition of CTR_DRBG) and EDN will send the very command in auto-request mode that firmware writes to the GENERATE_CMD register.

This seems to be not covered by current documentation. I only see number of blocks to generate and additional data.

What I recommend instead is to have a look at the EDN SiVal testplan

Thanks! Links are super useful.

vogelpi commented 3 months ago

The 2^48 requests w/o reseeding is not tracked directly in the hardware. Note that this is just an upper bound and that it doesn't tell you how many bits can be requested. Edit: the hardware has a 32-bit counter counting the number of Generate requests since the last reseed (not the bits generated). I've also updated the text below.

Instead how this is handled in EDN / CSRNG is as follows:

You can track the number of requests by reading the state_db in CSRNG or instead of tracking the number of requests, you can observe the entropy_req interrupt of CSRNG. This will go high whenever CSRNG needs new seed material from ENTROPY_SRC. Firmware can then re-enable ENTROPY_SRC to unblock CSRNG. So you don't need to keep track of the Generate requests.

This seems to be not covered by current documentation. I only see number of blocks to generate and additional data.

What you probably missed is the Application Command Header doc which is part of the CSRNG doc.

vsukhoml commented 3 months ago

@vogelpi, thank you! So, CSRNG counting bits generated is quite different from number of requests which may have 128-bits or multiple of it. What would happen if this counter overflows? Will CSRNG continue to work? If not, this value actually sets the maximum period between reseeds.

NIST 800-90A limits single request to 2^19 bits, which is totally ok with generate command limited to 4095 bits, so everything is ok here.

How many bits EDN typically requests from CSRNG in a single request? Looking at module diagram it looks like 128, but could it be more? And if more bits are requested - how they would be used? Can firmware ask EDN to request 128*4095 bits in one command? I'm trying to understand what are the options with generate command customization.

vogelpi commented 3 months ago

I believe overflows in the counting inside CSRNG are currently not detected but I am not 100%. We also don't know what exactly is going to happen if that happens :-/ There is an issue to verify this for the tapeout. So we are on it though :-)

How many bits are typically requested per single request is really up to firmware. We have different tests in the tree but they are not really representative of how this should be done in practice. I think the best point to look for inspiration is inside cryptolib.

To get a certain number of bits you can either (this is inline with the CTR_DRBG Generate Process, Page 56 of the spec):

  1. Do many Generates with few bits per Generate, or
  2. Do few Generates with many bits per Generate.

Option 1 will be slower because for every Generate, one Update is performed which runs 3 AES blocks (independently of the number of bits you request) and then 1 AES block per 128 bits of requested entropy. Option 2 will just run fewer Update operations. So to save power, use Option 2. To make heavier use of the AES (whitening / better diffusion between returned 128-bit blocks) use Option 1.

I think in practice, you will wan to use Option 1 combined with a low MAX_NUM_REQS_BETWEEN_RESEEDS value for OTBN RND (EDN1) and Option 2 with a high MAX_NUM_REQS_BETWEEN_RESEEDS for EDN0.

vsukhoml commented 3 months ago

How many bits are typically requested per single request is really up to firmware.

Here I meant when requested by EDN from CSRNG. EDN issues a command written by firmware. In auto-request mode would there be any practical difference if generate command will result in 1x128 bit block (Option 1), or, say, 4x128 (Option 2)? Will EDN be able to take advantage of Option 2?

I think in practice, you will want to use Option 1 combined with a low MAX_NUM_REQS_BETWEEN_RESEEDS value for OTBN

I'm not sure this is true - I might prefer to also use high MAX_NUM_REQS_BETWEENRESEEDS for EDN1 and just manually send reseed though EDN before use. For active use of CSRNG it would make sense to set reseed counts such that $MAX\textunderscore NUM\textunderscore REQS\textunderscore BETWEEN\textunderscore RESEEDS = \frac{T{entropy\textunderscore block}}{T_{CSRNG\textunderscore generate}}$, so that entropy source will have enough time to generate 384 bits by condensing 2048 bits of entropy. And this number can be pretty large.

Also, we seriously consider disabling ENTROPY_SRC after initial seeding and run solely on CSRNG while possible, this would suggest maxing MAX_NUM_REQS_BETWEEN_RESEEDS, and probably monitoring CSRNG interrupt to enable enable ENTROPY_SRC when needed (if this can't be avoided). I'd really prefer to have some sentinel value

Another consideration - deterministic key gen suggests no reseeds.