Boot Image Verification Caching: Decide When a Previously Checked Result Is Stale
Treat a previous verification result as stale whenever its assumed image, trust policy or protected state can change without invalidating that result. First establish that the implementation actually reuses approval. A marker that says “checked before” is different from fresh authentication of the current bytes.
This guide examines a concrete optional mechanism: MCUboot v2.2.0’s Zephyr single-application-slot validate-once path. The worked profile is ordinary flash execution, not RAM-load or a two-slot swap. It is a source-based qualification review, with no recommendation to enable the option and no target tests performed.
1. Establish the exact optional mechanism
The pinned Kconfig defaults primary-slot validation on every boot. Its validate-once option instead depends on single-application-slot mode and the every-boot option being disabled. The help explicitly warns that caching in the magic area lowers security.
The configuration mapping selects MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE, and the build logic selects the single-slot loader. Verify both in the final build before applying this article.
Do not infer this behavior from a fast boot time or the existence of trailer flags. A product using another loader may have no such cache, a different cache, or an independently protected mechanism.

2. Read the reuse predicate
In boot_image_validate_once(), GOOD magic together with SET image-ok returns success without calling full image validation. Otherwise it validates, writes missing magic if needed and writes image-ok. State-read, validation and marker-write errors return failure.
The reuse predicate contains no image digest or explicit trust-policy version comparison. It is therefore necessary to examine everything that can change while those marker states survive. The source observation concerns this optional implementation, not any claim that a deployed product is affected.
The surrounding boot path still loads header information and performs its configured work. Saying full image validation is skipped does not mean no bytes are read or that every other boot check disappears.
3. Define the evidence that approval depends on
Create a dependency ledger with current image identity, accepted signer policy, relevant validation configuration, rollback requirements and the integrity of the approval marker itself. Add downstream policy inputs actually consumed by the product.
| Change while marker remains reusable | Question the release review must answer |
|---|---|
| Payload or protected metadata changes | What forces current bytes through full validation again? |
| Trusted signer set changes | What prevents old approval from standing in for the new policy? |
| Validation code or algorithm policy changes | Was the old result produced under an equivalent acceptance contract? |
| Required rollback state changes | Which actual path applies the new requirement on every relevant boot? |
| Marker restored from an older storage copy | Is its provenance still valid for the current image and policy? |
| Untrusted writer can alter image or marker | Does the product have independent, qualified protection? |
These questions define the acceptance obligations; they do not imply that the scoped cache implements automatic invalidation for each row. If the product cannot answer them, prior approval is insufficient evidence for the claimed current-boot property.
4. Distinguish marker state from application confirmation
Here, the validate-once routine writes image-ok following successful validation. Do not import a scratch-swap trial interpretation in which the same familiar field name represents a later application confirmation decision.
Keep the consuming function and boot mode attached to every decoded state. A support tool displaying only “image-ok: set” cannot tell a reviewer which policy created the marker or whether full validation ran on this boot.
Likewise, cache reuse says nothing by itself about application readiness. Authentication, installed-state bookkeeping and operational health require separate result fields.
5. Build a branch-and-invalidation fixture matrix
Use an isolated storage model or instrumented single-loader harness with synthetic bytes and recorded function calls. The first objective is to establish whether full validation was invoked, without modifying production flash.
| Proposed fixture | Expected scoped branch | Evidence boundary |
|---|---|---|
| Magic not GOOD or image-ok not SET | Invoke full validation | Positive validation and marker-write behavior |
| GOOD magic and SET image-ok | Reuse result without full validation | Actual reuse branch confirmed |
| Changed payload with reusable marker | Same reuse predicate | Demonstrates lack of digest binding in that predicate, not a safe boot |
| Changed trust policy with reusable marker | Same reuse predicate | Requires independent policy-invalidation evidence |
| Trailer read failure | Fail | Unavailable state is not approval |
| Validation or marker-write failure | Fail | No successful result claimed from incomplete work |
These fixtures have not been executed. Capture branch entry and return rather than accepting a generic “boot succeeded” line. Keep a valid control and distinguish the marker model from actual flash durability and access protection.
Any later target tests need disposable storage, original artifacts and verified restoration. Do not clear or forge markers on a live device, and do not execute deliberately unauthenticated code merely to illustrate the issue.
Hypothetical service restoration
A fictional service process restores an old slot snapshot containing reusable markers, then replaces only part of the image through another approved maintenance path. The review finds no evidence that the historical result is tied to the new content.
The correct release conclusion is that current-image authentication has not been established by that marker. Review the actual configured validation policy and restoration workflow through the authorized process; do not report the old marker as a fresh verification result.
6. Decide from the required security property
If requirements call for authentication of current bytes on each boot, demonstrate that property directly on the intended build. A timing optimization that omits the check cannot be credited with the same evidence merely because a previous boot passed.
If a product proposes relying on independently protected immutable state, require exact platform and lifecycle evidence, including service and recovery paths. This article supplies none of that hardware evidence.
Retain the loader binary, option resolution, marker provenance, dependency ledger and observed branch results. Revisit the decision after content, trust, validation or maintenance changes. No boot-time improvement or complete security assurance is claimed here.