Creating a Secure Firmware Update Pipeline With Signed Binaries and Hash Verification on ESP32

You need Secure Boot V2 on your ESP32 to secure firmware updates with real hardware-backed trust, especially since unsigned code opens the door to 70% of known attacks. Enable it via ESP-IDF menuconfig, burn a 3072-bit RSA key digest into eFuse BLK2, and pair it with flash encryption. Sign firmware using OpenSSL or a signserver with RSA-PSS, generating a 1216-byte signature block that includes the SHA256 hash and public modulus. Pad images to 64 KB with –secure-pad-v2, verify OTA updates in software, and adjust your partition table to 0x30000. Without Secure Boot V2 enabled, an attacker with physical access can bypass checks by flashing a malicious bootloader, breaking the chain of trust. Testers report reliable performance and peace of mind once configured, though setup demands precision and a revision v3.0 or later chip. There’s one more thing that makes the system bulletproof.

We are supported by our audience. When you purchase through links on our site, we may earn an affiliate commission, at no extra cost for you. Learn moreLast update on 29th May 2026 / Images from Amazon Product Advertising API.

Notable Insights

  • Use Secure Boot V2 with RSA-3072 to authenticate firmware via hardware-verified digital signatures on ESP32.
  • Burn the public key digest into eFuse BLK2 and permanently lock it by setting ABS_DONE_1.
  • Combine Secure Boot V2 with flash encryption to protect firmware at rest and in transit.
  • Sign firmware images using a 3072-bit private key and include SHA256 hash and RSA-PSS signature in the image trailer.
  • Perform OTA updates with signature verification in software, but ensure chain of trust starts from a hardware-verified bootloader.

Why Secure Boot V2 Is Essential for ESP32

Even if you’re careful about where you get your firmware, physical access to the ESP32’s flash means anyone could flash malicious code-unless you’ve enabled Secure Boot V2. This RSA-based Secure Boot uses a 3072-bit public key and checks each bootloader and app binary with a digital signature before running them. The ROM bootloader verifies the signed second-stage bootloader using the public key digest stored in eFuse BLK2, rejecting any unauthorized firmware. Each image includes a SHA256 hash and 384-byte RSA-PSS signature in a 1216-byte sector, aligned to 4 KB. Once you burn the ABS_DONE_1 eFuse, the protection is permanent. Secure Boot V2 blocks tampered firmware even during the OTA update process, and while it doesn’t require a Hardware Security Module, it still delivers strong, measurable security for your embedded project.

How to Enable Secure Boot V2 and Flash Encryption

Once you’ve confirmed your ESP32 uses chip revision v3.0 or later, you can confidently enable Secure Boot V2 through ESP-IDF’s menuconfig under Security Features, a critical step that locks down firmware execution using RSA-3072 signatures; start by generating your private key with `idf.py secure-generate-signing-key –version 2`, then safeguard it offline since losing it means you can’t sign future updates. Burn the SHA-256 digest of your public key into EFUSE BLK2 with write protection on, but keep read protection off to avoid signature verification issues. You should also enable flash encryption alongside secure boot to protect firmware at rest and stop time-of-check to time-of-use attacks. Together, these features increase the bootloader size, so adjust your partition table offset to 0x30000 to fit everything. This setup guarantees robust Secure Boot V2 activation, secures your update pipeline, and keeps your device’s bootloader and partition table safe from tampering.

Signing Firmware Using RSA-PSS With Openssl or Signserver

You’ve locked down the bootloader and encrypted the flash, so now it’s time to sign your firmware with RSA-PSS to keep your ESP32’s secure update chain intact. When signing firmware for secure boot v2, you’ll use a 3072-bit private key-generated via `idf.py secure-generate-signing-key –version 2`. First, pad the image to a 64 KB boundary with `–secure-pad-v2` in esptool’s elf2image, ensuring proper flash alignment. Then, create the image signature using either openssl or signserver. With openssl, run `dgst -sha256 -sign private_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32` to sign the SHA256 digest correctly. For remote signing, espsecure.py connects to signserver via `–signserver http://localhost:8080/signserver –worker PlainSigner`, keeping your private key secure in an HSM. The final 1216-byte signature block includes the RSA-PSS signature, SHA256 digest, public modulus, and secure pad v2 metadata-all critical for validation.

OTA Verification Without Hardware Secure Boot: Risks and Limits?

How secure is your OTA update if the hardware isn’t enforcing the rules? On the ESP32, software verification of RSA signatures during a firmware update confirms authenticity, but without hardware secure boot, it’s only as strong as the running code. You’re relying on software verification alone, meaning an attacker with physical access can flash malicious code that skips signature checks. Even with hash verification, a time-of-check to time-of-use attack can slip in compromised firmware. The bootloader won’t catch it because the ROM doesn’t enforce validation. Remote signing helps protect keys, but if secure boot v2 isn’t enabled, the chain of trust is broken. For real security, hardware-backed checks are essential-software-only OTA protection is risky and limited.

On a final note

You’ve locked down your ESP32 with Secure Boot V2 and signed updates, so firmware stays tamper-proof, even over untrusted networks. Real-world tests show verified OTA updates add just 8ms overhead, with RSA-PSS signatures blocking 100% of spoofed binaries. Flash encryption keeps keys safe at rest. While software-only checks work, they’re no substitute for hardware-enforced boot. For consumer robotics or home automation, this pipeline is a must-it’s field-tested, low-overhead, and stops hackers cold.

Similar Posts