Digital Signatures for Security

No, see my note above - it only prevents access to backup SRAM (this is the 4kB AON block, not the 128kB main block). If you can fit all your critical workspace & stack into 4kB then you’re safe :wink:

The F215 does not have encrypted SRAM either. These devices just have an encryption peripheral block (hardware AES) - actually the F205 has this too but it zeros out all the results… if you set it up and drive it, the encryption/decryption takes the right amount of time but the output is all zero. Boo, marketing de-feature! But yeah, this isn’t “secure ram” or anything, it’s just an encryption block which you can use instead of software crypto.

Hang on, still a bit confused about the flash dumping code part. I understand that the SRAM is secure from JTAG in RDP1 and that the main RAM is not (ie, main RAM can be viewed/modified). But in RDP1, it seems like both the flash memory & SRAM cannot be accessed if you try to upload “flash dumping code” into the RAM and boot from the RAM. So that would mean that the flash memory is secure, correct? This would mean the private key is also secure since its stored in flash?

In terms of preventing seeing the inner workings of the code, yea it would make sense to move all critical workspace into the SRAM if possible.

It’s a bit confusing here as both the backup SRAM and main RAM are both SRAM (static RAM) :slight_smile:

When they say flash memory & secure SRAM cannot be accessed from “boot from RAM”, they are referring to the bootmode selection with both BOOT0 & BOOT1 high (see RM0033 programmers reference) - ie RAM as opposed to flash or system memory (DFU) mode.

What I’m saying is that if you can manipulate RAM via JTAG, you don’t need to boot from RAM - you just manipulate stacks (which have to be in RAM) to cause RAM to be executed without a reboot - just connect, change RAM, load code, and then continue execution. As noted before, I’ve not tried this exploit myself but they don’t imply that it’s prevented in the RDP docs.

Thanks for all this info! Im sure this thread will be helpful to many. It seems like the only safe option left is to go full RDP2 and rely completely on cloud uploads for safety. Thats pretty much the same decision you came to on the Imp, right?

In terms of RAM on these microcontrollers, what exactly is pulled into RAM during runtime? Doesn’t the code on Flash run directly from Flash? If so, even if you are tinkering with RAM, aren’t you simply just tinkering with instantiated variables and their values? I don’t know too much about this type of hardware hacking and curious about the damage that can be done by just having access to RAM.

On Cortex ARMs, one can compile/build to run portions of or all code in RAM. Rarely done, for speed reasons.

RDP2 is as good as it gets on the STM32, and yes that’s why we picked it. For other chips we have different approaches eg the '005 boots from an external SPI flash (there’s no on-die flash) and so everything is loaded into internal RAM and only run if the image is signed with the right key. All the parameter storage - also off-chip - is AES-GCM+AEAD protected with device-unique keys.

What goes into RAM depends a lot on your code; stacks are the main interesting thing - but also note that during (eg) key exchange, a significant amount of valuable information will be in there.

@stevech usually on these MCUs RAM is faster than flash; on the STM32 flash is 128 bits wide and feeds what is essentially a small cache in order to get flash execution near to RAM speed. The flash also gets significantly slower at lower voltages whereas the RAM doesn’t - you can run the F205 at full clock even at 1.8v, but you go from (as I remember) 3 to 7 wait-states for the flash.

1 Like

“One of the steps in the setup of a new device is essentially sending or identifying the public key of device to the cloud so the negotiation can happen correctly.”

How do you do this step specifically from within firmware ? What’s the appropriate function call ?

Also - how does the device decrypt information that’s been encrypted using the device’s public key ?

How do you do this step specifically from within firmware ? What’s the appropriate function call ?

Thanks,
Dhaval

“One of the steps in the setup of a new device is essentially sending or identifying the public key of device to the cloud so the negotiation can happen correctly.”

This is not anything that is under user firmware control. It's handled entirely by the Device OS and happens whenever a cloud connection is made where re-authentication is required.

1 Like

I have enabled RPD Level 2 on a P0 device. However, it seems as though I can still enter DFU mode (as indicated by the LED).

Does this mean that the user firmware is still exposed to possible read-out via DFU? Do I also need to disable DFU via the bootloader code, in order to protect the user firmware?

Yes, RDP only prevents readout using JTAG. You also need to disable DFU mode, which can only be done currently by making a modified version of the bootloader.

That is described here:

However then you also need to find a way to disable listening mode, because otherwise while in listening mode you could flash a bootloader with DFU enabled. You’ll probably need to disable or modify safe mode as well.

2 Likes

Thank you very much for your quick reply. It is greatly appreciated, since we are trying to finalize firmware for a product release.

I have checked your notes on how to disable listening mode via the bootloader code. In order to disable listening mode and safe mode, can we make a similar modification to the bootloader code? Or, do we need to make this modification in the user firmware?

I haven’t verified for sure that this will work, but I don’t think you really need to disable listening mode and safe mode. Plus, disabling safe mode would make it difficult to upgrade system firmware.

The trick I think will be to intercept the call to OTA_Flash_Reset() in the bootloader main file if the file is the bootloader. In other words, instead of trying to prevent downloading a replacement bootloader, you just prevent it from installing. This also has the benefit of only requiring a bootloader change, which you already need to be doing anyway, as well. There shouldn’t be a need to modify system or user firmware if you do that.

Thanks @rickkas7. I think I understand what you are saying.

So, we will need to:
(1) Comment out “HAL_DFU_USB_Init();” to disable DFU
(2) Comment out “OTA_Flash_Reset();” after we have already flashed our desired user firmware, which will be locked down

Please correct me if I am misunderstanding anything.

That seems right. I can’t guarantee it will work as I’ve never tried it, but it seems promising.

@rickkas7

It may have worked! (but not 100% sure yet)

I think my P0 now has a modified bootloader (bootloader_noDFU.bin), which has DFU disabled, and OTA_Flash_Reset() disabled.

However, I can still write the original bootloader to 0x08000000. But I am pretty sure the P0 is not actually using the original bootloader. I think the P0 is still using bootloader_noDFU.bin, even though the original bootloader gets written to 0x08000000. Does that make any sense?

What happens when OTA_Flash_Reset() is called?

In particular, what happens after the bootloader is written to 0x08000000?

Unfortunately, I don’t think disabling “OTA_Flash_Reset();” achieved the desired affect. It was worth a shot.

So, I guess my best solution is to disable DFU mode, disable SAFE mode, and automatically exit LISTENING mode as soon as it is detected. Then, I will also enable RDP level 2. Do you think this will be sufficient to protect against the read-out of user firmware?

Yes, that will probably work. I think the problem is that flashing the bootloader might be a special case. Normally parts are written to the OTA sector then moved into their correct place at boot, but now that I think about it, that would be a problem for the bootloader because the bootloader can’t replace itself because the STM32 does XIP (execute-in-place). That’s also why you can’t write the bootloader in DFU mode.

So the STM32 has an internal root of trust for verifying the bootloader. Are particles bootloaders cryptographically signed so they can be verified? Are firmware images (DeviceOS and User parts) that come in via OTA signed against the STM32 root of trust?

No, the STM32 has no internal root of trust; there is no mask ROM that verifies a first stage loader in flash is correct before executing. The main security feature on STM’s is that flash is on-die, so hard (not impossible) to disturb as long as all the security features are enabled such as RDP2.

It is possible to glitch RDP2 devices into RDP1 (see https://chip.fail ) which doesn’t give code readout but does enable JTAG and allow RAM contents at the time of reset to be read; the gitch just needs to flip a single bit in the flash config register to do this. Whilst in theory you could glitch it into RDP0 with the same trick, you need to flip multiple bits just the right way… exponentially harder.

In RDP2 mode, the system ROM DFU mode is disabled as is JTAG/SWD. However, code running on the device can still jump to the system ROM DFU code and hence enable it, but this sounds like particle behavior not inherent to the STM32.

Note that there is generally no way back from RDP2, which means if a device ever got to a point where it required particle doctor when in RDP2, it’d be a brick and unrecoverable. When you use RDP2 you need to be really, really sure that you’re never ever going to need DFU or JTAG ever again.

I don’t believe particle images are signed, though they are sent over the encrypted channel. On electric imp devices, OS upgrades are both AES encrypted and RSA signed, with the private key being stored in a FIPS140-2 HSM that requires multifactor physical authentication to perform a signing. Some imp devices like the imp005 do validate encrypted boot images using mask ROM code, but STM32-based ones are using RDP2 and a bootloader to validate OTA upgrades as they are applied because there aren’t any other ways to do it.

Security is hard!