Accept an update only when authenticated metadata says it is for this hardware, is at least the protected minimum version and has the expected digest. Write it to the inactive slot while the working image stays bootable, boot it as a trial with limited attempts, and confirm it only after health checks. Advance the anti-rollback counter after confirmation, never before. Keep a recovery path that the new floor still permits, and publish how long updates will last.
- A valid signature is necessary but not sufficient: model, version, digest and freshness must also be in signed metadata.
- Keep one confirmed image bootable until the new one has passed its trial boot and health checks.
- Advance an irreversible anti-rollback floor only after confirmation, or a failed trial strands the device.
- Use an established design: MCUboot for microcontrollers, RAUC, SWUpdate or Mender for embedded Linux, TUF or Uptane for repository trust.
- Plan key rotation, recovery images and the end of support before the first device ships.
- The EU Cyber Resilience Act requires a support period of at least five years, unless the product is expected to be used for less time.
| Setting | Value | Note | Source |
|---|---|---|---|
| MCUboot signing | imgtool sign --version <x.y.z> --security-counter <n> with an ECDSA P-256 or Ed25519 key kept offline or in an HSM | — | MCUboot imgtool documentation |
| MCUboot anti-rollback | MCUBOOT_HW_ROLLBACK_PROT with the security counter in protected storage, or MCUBOOT_DOWNGRADE_PREVENTION, which compares image versions | The design page still limits MCUBOOT_DOWNGRADE_PREVENTION to overwrite-only updates; MCUboot 1.10.0 added it for the swap modes. | MCUboot design documentation; MCUboot release notes |
| Trial boot | Test swap with revert: Zephyr boot_request_upgrade(BOOT_UPGRADE_TEST), then boot_write_img_confirmed() after health checks | — | Zephyr MCUboot API |
| Repository trust | TUF roles and thresholds; Uptane for vehicles with primary and secondary ECUs | — | TUF specification; Uptane standard |
| EU support period | At least five years, or the expected use time if shorter; the end month and year shown at purchase | Cyber Resilience Act Article 13, applicable from 11 December 2027. | Regulation (EU) 2024/2847 |
| UK minimum update period | Published before sale for consumer connectable products, with no universal default passwords and a vulnerability reporting route | In force since 29 April 2024. | UK PSTI product security regime |
- Feed the updater a valid image for another model, an older signed image, a digest mismatch and expired metadata; each must be refused before any slot is erased.
- Cut power at each durable step, from the slot write to the floor update, and record which image boots next.
- Fail the health check on every trial attempt and confirm the device returns to the last confirmed image.
- Run
imgtool verifyon every release artifact and confirm the version and security counter in the signed TLVs. - Rotate the release key in a test fleet that skips several releases and confirm devices still accept the next update.
- Applies to
Signed firmware updates and recovery. Device flash behavior and power-loss recovery require hardware-specific testing.
- Part of
- Workflow: Review a design
Tested fixes: the vulnerable code, the fix, a plausible fix that still fails, and the regression tests that tell them apart.
Learning goals and prerequisites
What you will learn
- Distinguish signature, target binding, integrity and freshness.
- Design update and recovery state transitions together.
- Verify power-loss behavior before advancing irreversible state.
Before you start
Firmware and embedded Linux engineers who build update and boot paths, and product security reviewers assessing them.
- Identify the device trust anchor, boot path, update package and rollback state.
Refresh first: Verify artifact signatures against an explicit trust policy
Go to the guided practiceSecure boot asks whether the code selected for execution satisfies the device's boot trust policy. An update mechanism must also decide whether a candidate is intended for this hardware, is fresh enough, has the expected bytes and can be installed without destroying recoverability. A valid signature alone cannot answer all of those questions. An old signed image may restore a known vulnerability, and a correctly signed image for another model can make a device unusable.
Consider a device with active slot A at firmware version 12 and inactive slot B. The update policy requires the approved model M2, image digest matching authenticated metadata, version at least 12 and an authorized release signature. Before erasing a slot, the updater verifies metadata and establishes these conditions. Version and model fields must be inside the authenticated information; checking an unsigned version string gives an attacker control over the rollback decision.
Use a maintained update framework or platform facility that handles trusted keys, signed metadata, target digests and freshness. TUF separates roles and metadata responsibilities to limit several repository and key-compromise risks; adopting only a signature check does not reproduce its complete design. Verify the trust chain from a configured root, threshold and role policy as applicable. NIST SP 800-193 puts the signature check before the update's non-volatile storage completes, for example by writing the update to a region of flash, verifying it there and only then selecting that region as active (section 4.2.1.1). A key embedded in an untrusted download cannot authorize that same download.
Bind the expected image length and digest, device model and compatible hardware revision to the verified metadata. Enforce rollback policy with protected state that an old image cannot simply reset. Metadata expiry creates an availability tradeoff for devices offline for long periods; define a safe recovery and trusted-time approach rather than ignoring expiration globally. Key rotation and revocation need authenticated transitions and testing before an emergency. Recovery keys and normal release keys may have different authority and storage controls.
Download and verify into the inactive slot while the confirmed slot remains bootable. After writing, verify the installed bytes, then atomically mark the candidate for a trial boot. The bootloader records limited attempts. The new firmware confirms success only after meaningful health checks; otherwise the device returns to the last confirmed image according to its rollback policy. The sequence must survive power loss at every durable-state boundary.
Do not overwrite the only working image and hope installation finishes. Also avoid advancing an irreversible anti-rollback counter before the recovery design can still boot a permitted image. A/B slots, boot metadata and rollback protection must be designed together: if the counter jumps to 13 before an unsuccessful version 13 trial, the confirmed version 12 fallback may become forbidden. One approach delays the irreversible floor update until successful confirmation while controlling the trial state; Android Verified Boot does this, updating its stored rollback indexes only from slots marked successful, on the first boot after the slot succeeded. The exact mechanism depends on the platform's protected storage and boot architecture.
STATE MACHINE (concept)
confirmed A: v12, rollback floor 12
-> download v13 into B; A remains bootable
-> verify B bytes and metadata
-> trial B: v13, attempts <= 2; floor remains 12
-> if health check fails: boot confirmed A: v12
-> if health check succeeds: confirm B, then advance protected floor to 13
After floor 13: an ordinary update to v12 is rejected.
Recovery path must provide authenticated code permitted by the new floor.On microcontrollers, MCUboot implements this state machine. Its image header carries the version, and its protected TLV area can carry a security counter; both are covered by the signature, so an attacker cannot relabel an old image as new without the release key. With MCUBOOT_HW_ROLLBACK_PROT, the bootloader compares the image's security counter with a counter in protected storage; MCUBOOT_DOWNGRADE_PREVENTION compares image versions instead; the design page still says it needs overwrite-only updates, but MCUboot 1.10.0 added it for the swap modes. In Zephyr, the application requests a trial with boot_request_upgrade(BOOT_UPGRADE_TEST), and the new image calls boot_write_img_confirmed() only after its health checks; an unconfirmed image is reverted on the next reset.
The script below signs release 13 with imgtool. In a test with imgtool 2.4.0, the signed image verified with the release key and carried security counter 13 in TLV 0x50, while a copy whose header was relabelled 1.12.0, a copy with one firmware byte changed and a check against a different key all failed verification. Keep the private key offline or in a hardware security module; anyone who holds it can sign a downgrade with a higher counter. The artifact-policy browser lab at /labs/artifact-policy/ practices the release-side check: rejecting a correctly signed release from the wrong producer.
#!/bin/sh
# sign-release.sh: sign firmware 13 for MCUboot with imgtool 2.x.
# The version and security counter sit in the image header and protected TLVs, which the
# signature covers, so nobody can relabel an old image as new without the release key.
set -eu
imgtool sign --key release-key.pem \
--version 1.13.0 --security-counter 13 \
--header-size 0x200 --pad-header --align 4 --slot-size 0x60000 \
zephyr.bin firmware-1.13.0.signed.bin
imgtool verify --key release-key.pem firmware-1.13.0.signed.binReuse a reviewed design rather than inventing one. For embedded Linux, RAUC, SWUpdate and Mender provide A/B installation with signed bundles and a confirm step. TUF protects the repository side: separate root, targets, snapshot and timestamp roles limit what one stolen key can do. Uptane extends TUF for vehicles, with a director repository that assigns images to specific electronic control units and verification by secondaries that cannot reach the network themselves. The IETF SUIT work describes the same problem for constrained devices: RFC 9019 sets out the architecture, RFC 9124 the information model a manifest must carry, and the CBOR manifest format itself, draft-ietf-suit-manifest, was still an Internet-Draft in the RFC Editor queue in October 2026. RFC 9124's manifest elements map directly onto the checks above: a monotonic sequence number that devices must not let go backwards (REQ.SEC.SEQUENCE), vendor and class IDs (REQ.SEC.COMPATIBLE), and the payload digest and size.
For each stage, simulate interruption and state the image expected at the next boot. Check that a partial inactive-slot image is never selected as confirmed and that repeated trial failures terminate in a known recovery state. Test a valid signature with the wrong model, a stale version, a digest mismatch and an expired metadata record. These cases exercise different decisions and should not be collapsed into one 'signature failed' category. The firmware-ab-recovery project below runs these cases, power loss at every flash write, a trial image that never confirms and a device whose slots both fail, against a simulated A/B device, and writes an evidence file of each failure and the boot that followed.
Fleet operations need device version, update stage, failure category and last successful contact, with a rollout pause if failures cluster by hardware revision. A nominally successful download is not a confirmed boot. Keep diagnostic data minimal and authenticated so a device cannot falsely claim every other device updated. Plan the final supported update and secure retirement: remove user credentials, disable abandoned service access and explain what remains operable after support ends. Recovery and key maintenance are ongoing product capabilities, not one-time manufacturing settings.
How long devices receive security updates is now a legal commitment in some markets. Under Article 13 of the EU Cyber Resilience Act, which applies from 11 December 2027, a manufacturer must set a support period that reflects how long the product is expected to be used: at least five years, unless the expected use time is shorter. It must handle vulnerabilities throughout that period and state its end, at least the month and year, at the time of purchase. Its Article 14 duty to report actively exploited vulnerabilities has applied since 11 September 2026. In the United Kingdom, the product security regime under the PSTI Act has required since 29 April 2024 that consumer connectable products have no universal default passwords, publish a way to report vulnerabilities and state a minimum security update period. /frameworks/product-security-obligations/ maps these and related duties by market.
Engineering has to make the published period possible: keep signing keys, build environments and recovery images usable for the whole window, budget update storage for the last release as well as the first, and decide what the device does after support ends, for example disabling cloud features that would stay exposed without fixes.
CVE-2020-10713 (BootHole) was a buffer overflow in the GRUB2 bootloader's configuration parser that let an attacker bypass UEFI Secure Boot and run unsigned code before the operating system. The missing control was treating the bootloader's own input as untrusted and signing the whole boot chain.
An updater that accepts only today's release key can become impossible to maintain when that key expires or is compromised. An updater that accepts any new key embedded in downloaded metadata lets an attacker authorize their own image. Key rotation therefore needs an authenticated transition from the currently trusted root or another explicitly provisioned authority, with role and threshold rules supplied by the chosen framework. Test the transition on devices that skip several releases as well as devices updated every week.
Recovery is also an authorized capability. A physical recovery mode that ignores all image authentication may restore availability while granting an attacker permanent control. A recovery image should satisfy a documented trust policy, and the device should protect user secrets or erase them when a recovery path changes the trust state. The exact design depends on the hardware and product threat model; the important review question is which authority can install what code under which conditions.
Extend the state machine with a device that has confirmed version 13 and floor 13 but cannot boot either ordinary slot. Its recovery image must be permitted by the post-confirmation policy. Keeping only a factory image at version 1 is insufficient if the protected floor correctly rejects it. Maintain and test a compatible recovery path before advancing the floor across a fleet. This connects cryptographic policy to physical recoverability: each can work as implemented while their combination leaves a device stranded.
Guided practice
Evaluate candidate firmware and power-loss schedules under a complete training policy.
Supplied scenario material
Device model=M2; confirmed slotA=v12; slotB empty; protected floor=12. Candidate allowed only if authorized signature, matching model, matching digest and version>=floor.
C1: v13,M2,signature valid,digest matches.
C2: v11,M2,signature valid,digest matches.
C3: v13,M3,signature valid,digest matches.
C4: v13,M2,signature valid,digest mismatch.
Install C1: write B; verify B; set trial B with max 2 attempts; health check; confirm B; then floor 13.
Power loss P1: halfway through B write. P2: after trial flag, before health confirmation. P3: after B confirmed and floor 13.
Trial health failure consumes an attempt; after 2 failures fall back to confirmed A while floor is still 12.1. Separate candidate checks
Classify C1–C4 and identify the failed condition.
Expected result and reasoning
C1 qualifies. C2 fails rollback floor despite a valid signature. C3 fails hardware model. C4 fails byte integrity. None of C2–C4 should erase the confirmed image or become a boot candidate.
2. Recover from incomplete writing
Evaluate P1 and specify the next safe boot target.
Expected result and reasoning
Boot confirmed
A:v12. B is partial and unconfirmed; verification and candidate selection have not completed. A remains intact, so interrupted download does not require running corrupt B.3. Bound trial failure
Evaluate P2 followed by two unsuccessful health checks.
Expected result and reasoning
Trial B is attempted under the bounded policy, then the device returns to confirmed
A:v12. Floor 12 permits that fallback. Do not mark B successful merely because the processor started executing it.4. Apply irreversible advancement
Evaluate P3 and a later request to install v12. Explain the unsafe alternative of setting floor 13 before trial.
Expected result and reasoning
B:v13is confirmed and the ordinary v12 update is rejected. If floor 13 had advanced before a failed trial,A:v12could no longer be a permitted fallback. Recovery must be designed to satisfy the protected floor after confirmation.
Paper exercise: candidates, power-loss points and the policy are supplied. sign-release.sh above shows how a real MCUboot image carries the version and security counter that the policy checks; the firmware-ab-recovery project below executes the same decisions.
Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.
No draft saved on this device yet.
Run a local project
Download and unzip a starter with failing tests and a step-by-step README, edit the named exercise file, and run the tests until they pass. The reference solution is a separate download, so you can attempt the repair before you see it.
Recover from failed firmware updates with A/B slots
Repair the update client and bootloader of a simulated dual-slot device: Ed25519-signed manifests, a monotonic anti-rollback floor, writes to the inactive slot, trial boots with automatic fallback and authenticated recovery. The tests inject bad signatures, signed rollbacks, power loss at every flash write and images that never confirm, and write an evidence file of each failure and the boot that followed.
In the extracted folder, run:
node demo.mjs
node --test exercise.test.mjs13 regression tests · The starter intentionally fails some cases.
Opens in a dev container (VS Code Dev Containers or GitHub Codespaces) with a pinned image.
Real Ed25519 signatures and SHA-256 digests over simulated flash with injected power loss and a simulated protected counter. It models the decisions a bootloader and update client make; page sizes, erase behavior and the counter hardware must be tested on the device itself.
Sources & further reading
The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.
- NIST SP 800-193 firmware resiliency. May 2018.
- The Update Framework specification. Version 1.0.37.
- MCUboot design: image format, swap and downgrade prevention
- RFC 9019: a firmware update architecture for the Internet of Things. April 2021.
- RFC 9124: an information model for firmware updates in IoT devices. January 2022.
- Uptane standard. Uptane Standard 2.1.0.
- Regulation (EU) 2024/2847, the Cyber Resilience Act. OJ L, 20 November 2024.
- UK government: the product security regime (PSTI)
- NVD: CVE-2020-10713, GRUB2 Secure Boot bypass (BootHole)
- MCUboot release notes (1.10.0: downgrade prevention for swap modes)
- IETF datatracker: draft-ietf-suit-manifest. draft 37, RFC Editor queue.
- Android: A/B (seamless) system updates
- Android Verified Boot: updating stored rollback indexes
- U-Boot: boot count limit
Reference information
- SDLC phase
- DevelopmentRelease