lowRISC / opentitan

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

[ROM] The Retention Sram initialization does not follow the steps in the manual. #22492

Open radnvlad opened 5 months ago

radnvlad commented 5 months ago

Description

Hello, looking in the retention SRAM initialization process in the rom I can see that the initialization just calls the retention_sram_init function.

https://github.com/lowRISC/opentitan/blob/a6780fbdcfd7eec55030ccad3b63195918d17650/sw/device/silicon_creator/rom/rom.c#L181

https://github.com/lowRISC/opentitan/blob/master/sw/device/silicon_creator/lib/drivers/retention_sram.c#L3

That initializes the retention sram but does not get a scrambling key, and although the scrambling function that does the initialization is present as well, just below it, it is not used. This would pose some problems to the silicon owner since that means he either has to live with the unscrambled ram ( well, here my understanding is fuzzy but I believe that technically, it is scrambled, but with a default key, without randomness seeded), or reinit the retention ram, and that would mean he has to backup the creator section and then restore it after init in order to avoid losing the data.

If the intention is for the silicon creator ROM to init the sram, then likely the intention would be a scrambled and fully validated key to be present. I would have expected the init called to follow the process outlined in the documentation:

https://opentitan.org/book/hw/ip/sram_ctrl/doc/programmers_guide.html

Also, it seems the intention is that the retention sram to store data to be communicated to the user SW, but certain pieces of data don't really make sense to be stored there. For example, the reset reason could be located in normal RAM as well, since it changes across resets, and the property or rram to keep data across resets does not make sense here.

I see in the existing code the intention for the creator ROM to use half of the rram and the device owner to use the other half, but I feel that should be documented in order to avoid confusion. I'm also not sure what the threat model is when crossing creator ROM execution boundries and if you want to still trust the RRAM data after the user code has executed.

jwnrt commented 4 months ago

I agree this is an issue. Correct me if I'm misunderstanding, but it's as if the ROM / ROM_EXT treat the creator and owner partitions of the retention SRAM to have separate scrambling keys.

The ROM_EXT will only boot if the ret SRAM contains a valid version with the default scrambling key. If the scramble the SRAM, isn't there a risk the owner could overwrite this version and prevent the chip booting again?

CC @cfrantz

a-will commented 4 months ago

I'll note that these lines have since been changed to always write the version in the ROM, even after waking from deep sleep:

https://github.com/lowRISC/opentitan/blob/4d6504eb2948e1c00c42f490cd2e5ff06693e441/sw/device/silicon_creator/rom/rom.c#L204-L211

ROM also does not change the scrambling key after waking from deep sleep, so long as the OTP setting doesn't require it.

jwnrt commented 4 months ago

Thanks Alex, I had forgotten that ROM leaves the new scrambling key alone after waking from deep sleep.

cfrantz commented 4 months ago

That initializes the retention sram but does not get a scrambling key, and although the scrambling function that does the initialization is present as well, just below it, it is not used. This would pose some problems to the silicon owner since that means he either has to live with the unscrambled ram ( well, here my understanding is fuzzy but I believe that technically, it is scrambled, but with a default key, without randomness seeded),

Retention RAM is meant to persist across resets, whereas the normal RAM is not. Unless the reset is a power-on reset, we cannot request a new scrambling key for RET-RAM.

My recollection is that we chose not to request a scrambling key for RET-RAM because there are no secrets stored there, nor any data critical to the ROM or ROM_EXT boot processes.

We could consider adding another OTP configuration word that specifies whether or not to request a scrambling key for RET-RAM for power-on resets.

I see in the existing code the intention for the creator ROM to use half of the rram and the device owner to use the other half, but I feel that should be documented in order to avoid confusion. I'm also not sure what the threat model is when crossing creator ROM execution boundries and if you want to still trust the RRAM data after the user code has executed.

The bulk of the creator half of RET-RAM is "write only" from the ROM/ROM_EXT perspective. It is used to communicate boot information from creator code to owner code. The exception is a block of creator RET-RAM used for communicating "boot services" messages from the owner to creator code. This segment of RET-RAM is validated with a sha256 over the contents and the various command words all use high hamming-weight values.

radnvlad commented 3 months ago

@cfrantz

Unless the reset is a power-on reset, we cannot request a new scrambling key for RET-RAM.

Are we unable to at the HW level or is it simply inadvisable since you lose everything? My understanding is that we could if we are willing to pay the price of erasing the retention ram. I think I also did some experiments where I re-initialized it.

Retention RAM is meant to persist across resets, whereas the normal RAM is not.

Right, hence my point that if we have data that is always overwritten on startup ( eg. reset reason) then it makes little sense to store it in rram as opposed to regular ram. Retention Ram is a more scarce resource. It's possible one will not hit the limit of this, but I suspect it's hard to foresee what choice the end user will make and what their needs will me. It's not a big deal, but rather just an observation from my side.

My recollection is that we chose not to request a scrambling key for RET-RAM because there are no secrets stored there, nor any data critical to the ROM or ROM_EXT boot processes.

Again, this might be true for the ROM or ROM_EXT, but the end-user might have other needs and they might decide, for some reason to store some sort of secret there.. The other thing is that if you have a hw mechanism (scrambling key provisioning) that you can't really use because of the way ROM is set up, is there any point to the mechanism itself?

We could consider adding another OTP configuration word that specifies whether or not to request a scrambling key for RET-RAM for power-on resets.

i guess this works, but I would suggest to just requesting the scrambling key anyway without a config option. Consider that the scrambling is happening anyway for the retention ram, the regular RAM I presume is initialized with a proper request for the scrambling key so the entropy source is already active and we just need to get enough entropy for the scrambling key. This looks like it's a small cost and just doing it instead of having it as a configuration option is just simpler. I don't see it as a meaningful cost that one is paying for this initialization and I don't imagine what reason could someone possible have to need the retention ram to be scrambled with the default key instead of a proper one from the entropy source. Might just be a failure of my imagination, so I'm curious what you think about this.

The bulk of the creator half of RET-RAM is "write only" from the ROM/ROM_EXT perspective. It is used to communicate boot information from creator code to owner code

Ok, if you don't process input from it this looks fine.

The exception is a block of creator RET-RAM used for communicating "boot services" messages from the owner to creator code.

Do you know where I can see these "boot service" message processing? Just for my better understanding.

This segment of RET-RAM is validated with a sha256 over the contents and the various command words all use high hamming-weight values.

I will just note, that, if I understand this correctly, this will safeguard against accidental writes, not against intentional but malicious writes. So sanitization of this data and treating it with gloves still seems needed. I guess that if some one has arbitrary code execution on that level on the target it doesn't matter a whole lot though, you're already pwned?

@jwnrt

I agree this is an issue. Correct me if I'm misunderstanding, but it's as if the ROM / ROM_EXT treat the creator and owner partitions of the retention SRAM to have separate scrambling keys.

My understanding is that the whole retention SRAM has the same scrambling keys ( they have to, in order to pass data from one entity to the other) and it's the same scrambling HW block, it just seems a convention at the the ROM/ROM_EXT level that the creator "owns" or writes data in the first 2kb and the user owns the last 2kb. The initialization happens on Power On Reset only in the ROM and then the various entities can write and use data from these sections, data that would survive further resets and sleep. It would only be lost on Power On Reset again, (or maybe some sort of completely destructive reset? This is just a speculation from my side. )

radnvlad commented 1 month ago

Retention RAM is meant to persist across resets, whereas the normal RAM is not. Unless the reset is a power-on reset, we cannot request a new scrambling key for RET-RAM.

@cfrantz I think I understand your point better now. The RET_RAM circuitry seems to lose data if we init it with the scrambling key requested. This is because, I believe, the scrambling mechanism does NOT survive resets and you lose the ephemeral scrambling key.

Thus, it seems that the RET_RAM is unable to function with the random scrambling key. Not sure if this is intended or a known limitation, but... probably useful to have it documented or explicitly stated.