The ESP32 has two interesting features, secure boot and flash encryption. Let’s have a quick overview of these features.
Typically when a device is shipped, any firmware or data is stored in the SPI flash connected to the ESP32. Since typically flashes are external to the SoC, a sufficiently inclined person could read the contents of this flash if she so desires for their benefit. What’s more, the contents could also be modified or tampered with to affect the flow of execution.
The flash encryption and secure boot features protect from the side-effects of these types of unwanted accesses to the flash.
The eFUSE: One Time Programmable
The eFUSE plays an important role in the functioning of these security features. So let’s quickly look into the eFUSE before we get into the security features.
The ESP32 has a 1024-bit eFUSE, which is a one-time programmable memory. This eFUSE is divided into 4 blocks of 256-bits each.
Of primary interest to us right now are blocks 1 and 2. These blocks store keys for flash encryption and secure boot respectively. Also, once the keys are stored in the eFUSE, it can be configured such that any software running on ESP32 cannot read (or update) these keys (disable software readout). Once enabled, only the ESP32 hardware can read and use these keys for ensuring secure boot and flash encryption.
The secure boot support ensures that when the ESP32 executes any software from flash, that software is trusted and signed by a known entity. If even a single bit in the software bootloader and application firmware is modified, the firmware is not trusted, and the device will refuse to execute this untrusted code.
This is achieved by building a chain of trust from the hardware, to the software bootloader to the application firmware.
Validating the Software Bootloader
We start with the hardware (the ROM and the eFUSE), that is trusted.
The hardware (BootROM) uses the secure boot key in the eFUSE to verify and validate the software bootloader. Only once the software bootloader is validated, does the BootROM execute the software bootloader.
The software bootloader contains 3 things as shown below.
- Software bootloader binary: which is the code that will get executed as the software bootloader
- ECDSA Public Key: which is the public key that we will use for validation in our next step (Validating the Application Firmware)
- AES based digest: A digest that validates that the software bootloader binary and the ECDSA public key are the same as were programmed by the manufacturer
AES-input = Software Bootloader Binary + ECDSA Pub Key
AES-key = secure boot key from eFUSE
AES-based-digest = SHA512(AES(AES-input, AES-key))
This setup ensures that it is not possible for an attacker to create malicious software bootloader binary or a malicious ECDSA public key with a matching AES digest. That’s because the AES key is locked away in the eFUSE and cannot be read or written.
Validating the Application Firmware
Now that the software bootloader is validated, the software bootloader executes. It in turn verifies the application firmware before executing it.
The application firmware contains 2 things as shown below:
- Application Firmware Binary: which is the code that will get executed as the application firmware
- ECDSA Signature: which is the signature of the Application Firmware binary generated using the ECDSA private key. The ECDSA private key is in the possession of the manufacturer and kept secret.
Now the software bootloader uses the ECDSA public key (which is already validated and trusted in the previous step) to validate that the ECDSA signature above is correct. If the signature is correct, it goes ahead and executes the application firmware.
And that’s how secure boot on ESP32 works.
The flash encryption support ensures that any application firmware, that is stored in the flash of the ESP32, stays encrypted. This allows manufacturers to ship encrypted firmware in their devices.
When flash encryption is enabled, all memory-mapped read accesses to flash are transparently, and at-runtime, decrypted. The flash controller uses the AES key stored in the eFUSE to perform the AES decryption. Similarly, any memory-mapped write operation causes the corresponding data to be transparently encrypted before being written to flash.
Because the key is locked into the eFUSE, only the hardware can use it to decrypt the contents of the flash.
If you are looking for network security using TLS (Transport Layer Security), please go to this article: TLS and IoT.