The cybersecurity landscape is dynamically changing in recent years. With an increased number of cyber threats and sophisticated vulnerabilities, the need for assuring complete security for the users becomes more and more important for iot device manufacturers. Assuring security for the users of these mass-market iot devices is no longer a feature — it becomes a strict legal requirement.
One of the best ways of thinking about essential security controls is using the basic cybersecurity model known as the CIA triad — meaning Confidentiality, Integrity, and Availability. In this article, we are going to talk about built-in security mechanisms in Espressif ESP32 microcontrollers which help manufacturers achieve complete security and ensure that their firmware meets these requirements: Secure Boot and Flash Encryption.
Cyber Resilience Act and IoT devices
One of the widely discussed upcoming regulatory directives is the Cyber Resilience Act, a EU directive that will fully come into force in December 2027 to ensure compliance across the digital market. While it does not directly refer to the features we are going to cover in this article, it does put strict sbom requirements on protecting the integrity of programs and configuration, especially for embedded software, as well as protecting ‘…the confidentiality of stored, transmitted or otherwise processed data (…) such as by encrypting relevant data at rest or in transit by state of the art mechanism, and by using other technical means’.
In practice, that makes it obligatory to implement the features we will discuss in this article to improve vulnerability detection on IoT devices. Failing to meet these obligations would not allow you to declare compatibility with CRA and place a CE mark on your mass-market iot devices which, in result, would not allow you to sell your products on the EU market.
Secure Boot on ESP32
Secure Boot is a tool that ensures integrity of the firmware on an embedded device. It protects the user from running unauthorized or malicious code on the microcontroller by checking a signature on each part of the software being booted
You can think of it as a gatekeeper protecting access to a data archive. Whenever someone wants to update an entry in that archive, the gatekeeper checks the ID of the incoming person and makes sure if the document is signed by a person that is authorized to make updates to this archive. Similarly, during the boot process of an ESP32 chip by Espressif, the signature of each piece of software is being checked to eliminate vulnerabilities. If any of the signatures is wrong, the boot process is stopped. Here is how it goes:
The first stage bootloader loads the second stage bootloader and verifies its RSA-PSS signature. If verification is successful, the second stage bootloader is executed
The second stage bootloader loads the application image and verifies its RSA-PSS signature. After successful verification the application image is executed
This ensures that no unauthorized code can be started on the microcontroller and forms a ‘chain of trust’. This protects integrity of the software run on the device (making sure it cannot be modified by an unauthorized person) which allows you to meet part of the baseline requirements listed in Cyber Resilience Act mentioned above.
Flash Encryption
The next feature is pretty self-explanatory – its objective is to encrypt the contents of the microcontroller’s memory in order to prevent unauthorized persons from physically reading the contents of flash. When working with the ESP32 platforms by Espressif, flash encryption serves as a foundation for improving bluetooth security and overall device hardening.
Coming back to our previous analogy with a gatekeeper – in this part we are not focusing on checking the ID of a person that wants to see the given document – we know that the document has been prepared in such a way that it will make sense only if the given person has the proper key to decipher the document. For iot device manufacturers producing mass-market iot devices, this represents one of the core security controls needed to achieve complete security.
The easiest way to fully understand why it’s important is to imagine what can happen if you would not have it:
Anyone with physical access to your programmed chip can download your firmware. After that the firmware file may be used for reverse engineering proprietary algorithms used in your code or just to flash on another hardware and create a clone of your device. Both options don’t sound good
If any sensitive data are kept in flash in plain text they might be extracted from sensitive devices. If you keep credentials that allow you e.g. to connect to cloud, extracting them may allow malicious actors to conduct impersonation attacks, impersonate your device, infer personal data, and use these credentials in another attack, leading to identity theft.
Firmware tampering – if secure boot is not enabled, after reverse engineering your code the hacker can modify it, inject malicious code or a backdoor with hidden functionality, and upload it to your device again. Your smart locks or other bluetooth gadgets may be then used in a number of different ways, none of which you would agree too (for example, sending your private data to a third party server or for participating in an attack)
Reverse engineering your code might not only be used for cloning your device, but for detecting weaknesses. The attacker may reverse engineer your firmware to find vulnerabilities and use them for hacking other devices in the field.
Scenarios presented above seem scary, but they are possible and each one of them alone is a good enough reason to add flash encryption to required robust security mechanisms in your application. As mentioned before, in many cases now it may not be your choice and proactive approach, but a legal requirement.
Security Implementation on ESP32
In this section we would like to present how these features are implemented in ESP32 hardware and how to use them safely.
Note: This is intended to present the general overview of enabling the security functions on your processor. Some of these steps may have irreversible consequences for your hardware and you may lock the possibility to update your device (rendering it useless). Make sure to check the details of implementation of the security functions in the esp-idf documentation.
Secure Boot
Secure Boot on ESP32 is used as follows:
you generate the public and private key pair – RSA 3072 or ECDSA 256 (if it’s available for your ESP32 version). Make sure to keep the private key secure on your host machine or your build server. The security of this private key is crucial for assuring the integrity of your device’s firmware.
SHA-256 hash of your private key is stored in the eFuse bits
When you build your firmware, the signature block is appended to the bootloader and firmware binaries. This block contains the SHA256 hash of the image, the full public key, and the image signature generated using the private key.
When you start the device, the ROM code checks the proper eFuse to verify if Secure Boot v2 is enabled
If Secure Boot is not enabled, the application follows normal boot procedure, otherwise it goes as described in the steps below
ROM code verifies correctness of the signature block (checking correctness of first byte and the CRC32)
ROM code verifies the SHA256 of the public key embedded in the signature block with the hash stored in eFuse bits
ROM code generates the SHA256 hash of the bootloader image and compares it against the value from the signature block
If above verification was successful, ROM code runs the bootloader
Bootloader repeats similar steps with application image – checks its signature block, verifies the hash of the public key from the signature block and checks the hash of the application image against the one from the signature block
If above verification is successful, bootloader runs application image
Enabling Secure Boot in esp-idf
In order to enable Secure Boot in your application, engineers should perform security audits on the environment and follow these technical steps:
Generate the signing key: The signing key can be generated using espsecure.py script:
espsecure.py generate_signing_key
However, for production devices it is recommended to generate the key using OpenSSL or other industry standard program on a system with a quality entropy source
open menuconfig->Security features for your application and:
-
set option ‘Enable hardware Secure Boot in bootloader’.
Note: to enable Secure Boot V2 you need to option ‘Minimum Supported ESP32 Revision’ to Rev3
specify the path to the private signing key (relative to project directory)
-
select the proper UART ROM download mode – disabling it locks out the serial bootloader and prevents anyone with physical access to the device from updating the firmware on the device via UART. The only option remaining for updating such a device is via OTA.
Note: some of the ESP32s (e.g. ESP32-S2) offer Secure UART Download mode which does not completely block the option for updating the firmware via UART but significantly limits the amount of available commands (e.g. blocking the attacker from reading out the flash or dumping the memory). If this mode is available in your case determine which of the modes is best suited for your application taking into account threat analysis for your device
Adjust other Secure Boot options according to your application needs, check the esp-idf documentation for detail.
Run idf.py bootloader to build a bootloader with Secure Boot enabled. In the build output you will be able to find prompt for flashing command (starting with esptool.py write_flash).
Run the command mentioned above to flash the bootloader.
Run idf.py flash to build and flash partition table and application image. This image will be signed using the private key you specified before.
Reset ESP32. The software bootloader that you have flashed will enable the Secure Boot. Check the logs from the ESP32 to make sure that Secure Boot is enabled and that there weren’t any issues.
Flash Encryption
With flash encryption enabled, firmware is flashed as plain text and then – at the first boot – data from selected partitions are being encrypted. In result, physical readout of the flash contents is not sufficient to recover contents of the flash. The whole process is summarized below:
when the ESP32 is switched on for the first time, the flash content is un-encrypted
Second stage bootloader is loaded and it reads the eFuse indicating if flash is already encrypted
The second stage bootloader also checks if a valid key has been programmed to eFuse – if there is no such a key it generates a 256 bit AES key using RNG module. The key cannot be accessed by software
Flash contents are being encrypted – second stage bootloader, applications and all partitions marked as encrypted. This process can take up to one minute for larger partitions
Proper eFuse bit is set to indicate that flash contents are encrypted
The device is rebooted and starts executing the encrypted image
Development Mode vs Release Mode
Encrypting the contents of flash might be some impediment during software development. The priorities are completely different when we are performing development tests and when we are performing manufacturing quality tests. During development tests we focus on ease of reconfiguring the device, with quality tests we are focusing on ensuring the best possible security level. ESP32 modules have two modes of flash encryption:
Development Mode – it still enables the user to flash the plaintext firmware – bootloader will encrypt this firmware using the stored key.
Release Mode – flashing plaintext firmware is possible only if the encryption key is known.
Risks
As it was already mentioned, using safety features on ESP32 microcontrollers brings into light some additional points that you need to consider and be aware of:
Some of the steps described in this article are irreversible. It is easy to brick your device – e.g. by disabling the serial bootloader without OTA implemented in the application. It would be recommended to test enabling the secure boot on a devboard (that probably might be less expensive than your target hardware) to make sure you understand the process correctly. Even if something would not go as planned, it’s better to brick the devboard which you can easily replace than brick your test PCB (which usually might be available in limited quantity).
Make sure your private keys are generated using industry standard programs and generated on a system with quality entropy source.
Keep your private keys secure! Even the most expensive and safest lock will not keep your house safe if you keep the key under the doormat.
Summary
In this article we have presented some basic information regarding security functions implemented on ESP32 such as secure boot and flash encryption. In the changing regulatory landscape ensuring confidentiality and integrity of the firmware becomes a matter of utmost importance. Planning to introduce these features in your products in advance can help you to be better prepared for new challenges and make your device more resilient to potential attacks.












