Digital Signatures for Security


Hello Particle Team,

I was wondering how to best protect my end product against reprogramming or abuse. I understand that even if I don’t expose JTAG or USB to the outside, the product can always be opened and reprogrammed.

I would like to ensure that any new code pushed to the chip are coming from an authorized firmware provider. Is there any implementation of digital signatures currently in place and how would that work in terms of offline flashing and OTA flashing? What is the common practices that can be used to maintain the security of the products in the field to prevent unsigned code flashing?

Thank you!

Reseting SparkCore or Photon

Hi @sdinnu

The cloud connection for over-the-air updates and everything else is negotiated using public key crypto with keys that are placed into the device at the factory (or replaced later by you if you like). The result of the negotiation is a session key for AES that is used for all cloud communications, including code updates, for the current session. This has round-about the same security as a SSL/TLS connection widely used on the net today.

Every device has a copy of the cloud’s public key and every device has it’s own private key stored. 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.

There are system events that your code on the device can listen for and one event is (or will be soon) the update event. You are (or will soon be) free to decline the update. I am not sure where development stands of that feature right now, but it is planned.

With physical access to the device, there is very little that cannot be done, so if your threat model includes that type of access, you will need to think about hardened packaging or detection methods, but these devices are not really designed against that type of threat.


Great to hear! It seems like the defenses when it comes to cloud OTA updating is pretty solid with the public/private key setup.

In terms of physical access of the device, what are the best practices that can be done to prevent reprogramming the IC? I know that if you expose JTAG, you are essentially powerless since any debugger will be able to commandeer the chip. If only the USB pins are exposed on the PCB, at least we limit to DFU reprogramming of the device (which we will need to flash the device at manufacturing anyway).

Isn’t this the place where digital firmware signatures could help since it would prevent any user trying to flash new firmware if the signature didn’t match?

Also if we use the P1 module, then at least all the pins that we don’t break out are quite well hidden (bottom of the pcb module).


If you have anything that gives you whole-chip access (DFU or JTAG) then you can’t enforce signature checking (because you could just replace the code which verifies the signature - all of it lives in flash); you also can’t keep the private key private, because anyone can connect and retrieve it. The internal rom of the STM32 doesn’t include cryptographic protections.

The STM32 has flash protection modes (RDP levels) which prevent flash access. There are 3 RDP levels:

  • RDP level 0: no readback protection, JTAG enabled, DFU enabled (default state). Here anyone with physical access can access the keys and hence perform impersonation attacks, reverse-engineer your code, and so on.

  • RDP level 1: readback protection. JTAG cannot access flash, DFU enabled. Here, when you connect via DFU, you can move back to RDP level 0 but the entire flash contents will be erased. You can’t read the contents (so if you store secure keys in flash, they can’t be read back - but you’d need to reprogram them to re-enable the device). JTAG can still access RAM, which can be a serious weakness - interrupting the processor during key exchange would yield some interesting information, for example, plus obviously your application’s workspace is an open book.

  • RDP level 2: readback protection, JTAG permanently disabled (you simply cannot connect), DFU disabled. There is no way to leave RDP 2 mode: entering it is a permanent operation. The MCU must upgrade itself in this mode: DFU does not exist - if it gets into a state where your code can’t recover itself, you have to throw it away (this is the mode the imp uses).

More info is in the STM32 appnote:

…in summary: RDP level 1 is a good tradeoff until your system is stable enough that you can 100% forever trust the boot process and protections.


Looks like I have a flaw in my knowledge!

I didnt know that DFU gave whole chip access? I thought that the DFU process was going through some bootloader process since its going through the USB pins. I assumed that in that bootloader part, we would be able to add digital signature verification, but I guess not.

Where in a normal flashing process would a digital signature verification system sit? Am I mistaken that it would most likely be in the bootloader?

In terms of protection, it seems like using RDP level 1 and only exposing the USB pins for DFU and not breaking out the JTAG pins may be the most secure. (By breaking out I am referring to the P1 where the pins are on the bottom of the pcb and fairly difficult to reach). Then even the RAM cannot be accessed by an outsider.

What did you mean by:

In what scenario would you need to reprogram the keys to “re-enable” the device?


DFU is provided by the on-chip bootrom (mask rom), which comes from ST. Yes, it’s possible to have a second level bootloader (which can indeed also be a USB loader, and could also implement the DFU protocol), but you can always bypass this by pulling the external BOOT1 pin on the chip high which forces entry to the mask rom bootloader.

Yes, RDP 1 and not breaking out JTAG is a good first step, though it doesn’t protect against anyone with a hot air gun, obviously.

If you needed to re-flash a device in RDP level 1 via DFU, then you first have to move to RDP level 0, which erases all flash on the chip - including any secure keys that might be in the flash (as I understand it, every P0/P1 has keys pre-programmed into flash). You can store keys in OTP if you wanted, but then RDP 1 doesn’t provide any protection - they will just be sitting there when you move to RDP level 0.


Which pin is this on the P1? I cannot find reference to it. Is it even a pad on the P1 module?

This is accurate! I guess if someone is trying to pry the P1 off then its going to be fairly hard to protect much. What could you really do to protect yourself at that level? Wouldn’t this issue apply to all microcontrollers?

At least they shouldn’t be able to rip the code/keys off the chip if its in RDP level 1 correct? Any other protections or security features you think could be implemented to best protect end products on the field from tampering?


BOOT1 is available on a test header under the can of the module (alongside the PB10/PB11 DFU mode UART), so actually you don’t need to remove the module at all to get to it. The point I’m making here is that hiding or not connecting test points/JTAG isn’t actually preventing anyone who is even slightly motivated.

Protection against this is RDP level 2, but as noted it’s not to be taken lightly as once enabled, it can never be disabled.

RDP level 1 is, in theory, decent protection, though if RAM is writable you could load some flash dumping code into it then patch a return address on an active stack frame to branch to your exploit when you set the device running again - the protection is against JTAG reading flash, code running on the MCU can obviously read flash at any time. It’s a little more effort but not exactly rocket science (note: I’ve never tried this but according to the ST appnote, only backup SRAM - the 4kB AON block - is protected).


Thanks for all this information! Seems like protecting the hardware is going to be fairly difficult.

How are you getting the information about what the pins are under the can of the module? It would help to know what test points are broken out and easily accessible to snoopers.

Could you expand on this? Are you saying that even in RDP 1 that since the JTAG pins are accessible under the can of the P1 module, that someone could go in, and update the RAM with flash dumping code? If so, they would be able to make the MCU output the private key also right?

In RDP level 2, can the P1 still be updated over the air or would all firmware updates be locked out?


I have a (non-particle) USI module here back from when we were looking at them as a possible manufacturer. Could be that the design has changed since then, but externally it has the same part number. Our module production line flow used to use DFU mode, hence we needed that pin exposed.

As I said, I’ve not tried anything but reading RAM in RDP level 1 using JTAG (and I can confirm that works), but if you can write RAM then you should be able to dump out flash contents with the method described. I believe the private key is in flash so yes, that would be vulnerable in that case too.

In RDP 2 OTA updates will work, yes, it’s only DFU/JTAG updates that are no longer possible.


Level 1: memory read protection.
It is the default read protection level after option byte erase. The read protection Level
1 is activated by writing any value (except for 0xAA and 0xCC used to set Level 0 and
Level 2, respectively) into the RDP option byte. When the read protection Level 1 is set:
No access (read, erase, program) to Flash memory or backup SRAM can be
performed while the debug feature is connected or while booting from RAM or
system memory bootloader. A bus error is generated in case of read request.
– When booting from Flash memory, accesses (read, erase, program) to Flash
memory and backup SRAM from user code are allowed.
When Level 1 is active, programming the protection option byte (RDP) to Level 0
causes the Flash memory and the backup SRAM to be mass-erased. As a result the
user code area is cleared before the read protection is removed. The mass erase only
erases the user code area. The other option bytes including write protections remain
unchanged from before the mass-erase operation. The OTP area is not affected by
mass erase and remains unchanged.

Does this contradict what you were saying about writing flash dumping code into the RAM? It seems like when you have RDP1 you still cannot read Flash from the system bootloader nor from booting from RAM. Would your technique be considered “booting from RAM”?

Seems like the STM32F215 series have encrypted RAM but the F205 series does not. So regardless, someone would be able to peek/modify the RAM during runtime which would not be ideal.


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.


“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 ?



“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.


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?