Let me describe something I've seen more than once.
A manufacturer ships a connected device. The OTA update mechanism works - firmware gets delivered, the update applies, everything looks fine. Then someone points out that the device accepts any firmware image delivered through the update channel. No signature check. No integrity verification.
The "working OTA update" is actually an attack vector.
Unsigned firmware updates are one of the most common IoT security failures. Here's what a correct architecture looks like.
What goes wrong without image signing
Firmware replacement. An attacker who compromises your update server or intercepts the delivery can substitute their own image. The device has no way to tell the difference. It flashes whatever arrives.
Image tampering. Even without replacing the image entirely, an attacker can modify it in transit - insert a backdoor, change config values, patch out a security check. Without a cryptographic signature, the device can't detect it.
Rollback attacks. Without anti-rollback protection, an attacker can push an old firmware version with known vulnerabilities back onto devices you've already patched.
Fake update server. A device that doesn't verify server identity can be redirected to an attacker-controlled endpoint. It thinks it's updating from your infrastructure. It's not.
What a secure OTA architecture looks like
- Sign the image at build time. As part of your build pipeline, the final binary gets signed with your private key. The signature is embedded in the firmware package along with a version number for anti-rollback. The private key never leaves your build infrastructure.
- Store the public key securely on-device. The device holds the public key used to verify signatures. Where it lives matters - OTP memory, a secure element, or a hardware key management unit. A public key that can be overwritten by an attacker undermines everything. On STM32, the public key hash goes into Option Bytes (which must be locked in production). On nRF, it goes into UICR or the KMU depending on the series.
- Verify before you flash. The bootloader verifies the signature before writing anything to flash. This is not optional and not "add it later" - it's in the critical path. Verification fails → update rejected → existing firmware stays → event logged.
- Enforce anti-rollback. A monotonic counter in non-volatile memory tracks the minimum acceptable firmware version. The device rejects any update with a lower version number. Once you patch a vulnerability, it stays patched.
- Use TLS for delivery too. TLS doesn't replace image signing - if your update server is compromised, TLS doesn't help. But defense in depth means you don't rely on a single control. Use both.
MCUboot in practice
MCUboot is the go-to open source bootloader for secure OTA on Cortex-M targets (nRF Connect SDK, STM32, Zephyr).
On Nordic nRF: MCUboot is integrated as the default secure bootloader. Images are signed with imgtool using ECDSA-P256 keys. The public key is compiled into the MCUboot binary during its own build. Anti-rollback uses the security counter in the image header.
For a stronger trust chain, nRF also supports NSIB (nRF Secure Immutable Bootloader) as a first-stage bootloader: hardware root → NSIB → MCUboot → application.
On STM32 (L5, U5, H5): ST provides SBSFU and newer series have STiROT in ROM. For direct MCUboot use, the signing flow is identical - imgtool signs the image, the public key is embedded in MCUboot, verification happens before the application runs. Critical step: lock Option Bytes in production.
In both environments, the build pipeline is where teams have the most gaps. Signing needs to be automatic, not a manual step someone might forget.
OTA signing ≠ secure boot (you need both)
These are separate controls that work together.
Secure boot verifies firmware at every power-on - ensures the device only runs signed firmware from flash.
OTA signing verifies firmware before it's written to flash - ensures only authorized updates get applied.
A device with secure boot but without OTA signing will reject a modified image at boot, but it might still write the malicious image to flash - bricking the device or causing a boot loop. Denial of service achieved.
A device with OTA signing but without secure boot verifies updates correctly, but an attacker with flash access bypasses the OTA mechanism entirely and writes directly to the firmware partition.
The correct architecture has both, sharing the same root of trust and the same key infrastructure.
Top comments (0)