Interrupted Anti-Rollback Counter Updates: Test the Commit Order Before Release
Test the durable image state and the durable rollback floor together. Advancing a minimum counter before a recoverable new image exists can remove the old recovery path. Failing to preserve an advanced floor can restore acceptance of a release that policy meant to retire.
This article pins MCUboot v2.2.0 hardware rollback-protection call sites and its counter-interface contract. It also inspects one exact repository backend to demonstrate a limitation. No production counter implementation is qualified here, no power cuts were performed, and no irreversible programming instructions are provided.
1. Establish that the backend really persists a counter
Identify the function implementation actually linked into the deployed bootloader, its storage location, protection owner, error behavior and reset semantics. A symbol named boot_nv_security_counter_update() does not prove nonvolatile storage.
For a concrete warning, the v2.2.0 repository file under boot/cypress/MCUBootApp returns a fixed value of 30 from its getter. Its update function ignores the supplied values and returns success. That exact file supplies no persistent advancement evidence.
This is a source-level observation about a repository implementation, not a claim that a particular Cypress or Infineon product deploys it. A downstream product may provide a different backend. Until the final linked implementation is identified, stop the production qualification claim at “counter calls located.”
2. Separate API success from the storage contract
The MCUboot counter interface requires fail-safe handling of asynchronous power loss: interrupted advancement must be resumable or recover a previous consistent counter state, and a stable completed value must not decrease because of later power failure.
Translate that interface into backend-specific evidence. Identify its commit point, any intermediate representation, how startup detects an incomplete operation and whether a read can return uncertainty. If the implementation relies on a hardware property, obtain the exact device specification and qualify the actual integration before claiming it.
Do not assume a successful C return means the physical write is durable. Nor should a failed call be interpreted as proof that no change occurred. Preserve and reconcile the stored state after reset according to the backend’s documented recovery behavior.

3. Pin the image mode and the counter call site
The tagged loader does not use one universal advancement point. A TEST swap delays the active-image counter update until a later boot observes confirmation, preserving the ability to revert an unconfirmed trial. A permanent swap updates after the image upgrade. The overwrite path calls the counter update after copying the new image.
Direct-XIP with revert has its own confirmation-conditioned update path. These distinctions are implementation-specific. Record the actual mode, request type, image-ok state and function path rather than applying a generic “counter after first boot” rule.
Keep normal application health confirmation separate from cryptographic image validation. Permanent installation does not become a trial merely because the application has not yet run. If a product needs a recoverable trial, its configured update semantics must provide that behavior.
4. Build a reset-visible state table
Consider a hypothetical TEST-swap product with old image counter 4, new image counter 5 and an initial stored floor of 4. The table describes the counter gate only; image validity, swap recovery and other boot policy still apply.
| Interruption boundary | State to establish after recovery | Counter-gate consequence |
|---|---|---|
| Before a valid new image is ready | Old supported recovery path and floor 4 remain coherent | Image 4 must not be excluded by premature advancement |
| New trial installed, not confirmed | Mode-specific trial/revert metadata; floor remains 4 | Counter policy still permits old 4 and new 5 |
| Confirmation durable, advancement not yet committed | Confirmation and floor 4 identified as distinct facts | Do not report the minimum as 5 yet |
| During backend advancement | Resume or recover a consistent state under the backend contract | Do not boot from an unreadable or fabricated counter value |
| Floor 5 stably committed | Every later reset preserves at least 5 | Old image 4 fails this gate even if its bytes remain intact |
The validation path rejects a lower image counter and a failed stored-counter read. The table does not authorize a new fallback rule that substitutes zero or the image’s own value when the backend cannot report its state.
5. Qualify interruptions without risking service devices
- Preserve the original boot media, images, metadata and approved restoration procedure.
- Use a device reserved for interruption qualification, with customer data removed or recoverably backed up and actuators disconnected.
- Instrument image writes, confirmation persistence, counter update entry, physical commit and recovery completion without logging secrets.
- Choose interruption points from the actual implementation’s state transitions, including just before and after durable commits.
- After restart, record image identities, confirmation state, counter read result and the set of candidates accepted by the counter gate.
- Repeat stable-floor resets and failure-recovery paths under the documented device conditions.
Begin with an isolated backend model where useful, but label its limits. A simulated success return cannot demonstrate physical persistence, power-failure atomicity or protection against unauthorized writes. Use actual hardware evidence before making those claims.
Do not program real fuses or consume finite counter resources for an illustrative test. Such operations require a device-specific, separately approved qualification plan and provisioning authority.
6. Interpret mismatches before changing order
If the floor advances while only the old usable image remains, investigate the image/counter ordering and recovery path. If a stable floor later decreases, investigate backend durability and state selection. If update calls succeed but the read value never changes, confirm that a placeholder or unintended implementation was not linked.
If old bytes remain physically present but their lower counter is rejected, that can be the intended retirement outcome. A recovery document must not promise booting those bytes after the floor has advanced.
Close with the exact binary and backend revisions, mode-specific call trace, reset-state table and interruption observations. Without an identified persistent backend and target evidence, the result remains a review plan, not proof of power-loss-safe rollback protection.