Skip to content

Correct the verification claims in the hardened-boot i.MX93 note - #477

Open
jetm wants to merge 4 commits into
mainfrom
field-notes/hardened-boot-imx93-claims
Open

Correct the verification claims in the hardened-boot i.MX93 note#477
jetm wants to merge 4 commits into
mainfrom
field-notes/hardened-boot-imx93-claims

Conversation

@jetm

@jetm jetm commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Problem

The published field note 2026-06-24-hardened-boot-imx93.mdx states in its Coverage table that LUKS2 /var, phase-2 TPM2 sealing, dm-verity, IMA/EVM and module signing are all Verified on avocado-imx93-frdm hardware. None of that holds.

  • The implementing PRs are still open: meta-avocado #232 and #236.
  • The hardware validation step has never been run.
  • Avocado could not boot on this board at all on the BSP those PRs target. The 6.6.36 SPL stalls before Normal Boot on Rev1.2 silicon, from any medium; the board first booted after the meta-imx pin moved to 6.18.20. The note was published 2026-06-24; the board came up 2026-08-05.

The proxy column was wrong in the other direction: it named five harness assertions, of which three exist and only on the #232 branch (so they gate nothing on scarthgap), and two do not exist anywhere in the repo.

This matters because the page is public and Secure Boot is an open ask from several accounts.

Solution

Correct the verification status and leave the design content alone. The technical write-up is sound; only the claims about what has been proven were false. A status admonition near the top states plainly what is and is not verified and links both open PRs, so the page stays useful rather than reading as retracted.

Key changes

  • Coverage table rebuilt: hardware column is Not yet run throughout; proxy column reports what the qemuarm64 run actually produced
  • TestStatus targets and tested_against no longer claim the hardware target
  • Verify it and Reproduce it reframed from results obtained into checks the hardware pass owes
  • Two proxy findings the original omitted are recorded as open questions: TPM2 unseal fails on reboot and falls back to Argon2, and dm-verity is not active on that target
  • The first-boot wedge is documented: a boot interrupted after the LUKS format but before the filesystem is created strands the device in emergency mode permanently, and re-provisioning does not clear it

Reviewer notes

The unseal-on-reboot failure is the open question worth attention. It is plausibly a QEMU artifact, since PCR 7 has no real Secure Boot state to measure under the OP-TEE fTPM, and equally plausibly the design sealing to a PCR that will not be stable. Only the hardware pass settles it, and that pass is starting now against a wrynose-based port of the two PRs.

npm run build exits 0. This page is not a draft, so the production build genuinely compiles it, and I checked the rendered banner and table in a browser.

The Coverage table said every control was Verified on i.MX93 FRDM
hardware. None of it was. The implementing PRs (meta-avocado #232, #236)
are still open, the hardware validation task has never been run, and
Avocado could not boot on this board at all on the BSP those PRs target
until the meta-imx pin moved - the 6.6.36 SPL stalls before Normal Boot
on Rev1.2 silicon, from any medium. The page asserted a finished
hardware pass for a board that could not run the OS when it was written.

The proxy column was wrong in the other direction. It named five
harness assertions; three exist and only on the #232 branch, so they
gate nothing on scarthgap, and the two for IMA and module signing do not
exist anywhere.

Both columns now say what actually holds, and the two proxy results the
original omitted are stated as the open questions they are: TPM2 unseal
fails on reboot and falls back to Argon2, and dm-verity is not active on
that target. The unseal failure is the one that matters, because it is
plausibly a QEMU artifact and equally plausibly the design sealing to a
PCR that will not be stable - only the board settles it.

The design content is unchanged and still correct; it was the
verification status that was false. Verify-it and Reproduce-it are
reframed from results into the checks the hardware pass owes, and the
first-boot wedge found on the proxy is recorded, since it strands a
device in emergency mode permanently and re-provisioning does not clear
it.

Signed-off-by: Javier Tia <javier@peridio.com>
Copilot AI lite review requested due to automatic review settings August 10, 2026 22:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR corrects overstated verification claims in the “hardened-boot i.MX93” field note, clearly separating what has been observed in the QEMU proxy run from what is still pending hardware validation on the i.MX93 FRDM.

Changes:

  • Updates tested_against metadata and the TestStatus targets to remove the implied hardware validation.
  • Adds a prominent verification-status caution banner and reframes “Verify it” / “Reproduce it” as hardware-pass checks rather than completed results.
  • Rebuilds the coverage table and open-questions section to reflect current proxy findings and explicitly mark hardware status as “Not yet run”.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/field-notes/2026-06-24-hardened-boot-imx93.mdx Outdated
Comment thread src/field-notes/2026-06-24-hardened-boot-imx93.mdx Outdated
Comment thread src/field-notes/2026-06-24-hardened-boot-imx93.mdx Outdated
The note contradicted itself on which TPM the qemuarm64 proxy runs: the
Coverage paragraph said QEMU swtpm while the open-questions bullet said
OP-TEE fTPM. The layer settles which half is wrong.
meta-avocado-qemu/conf/machine/avocado-qemuarm64.conf sets
MACHINE_FEATURES += " optee-ftpm", and its own comment on the /var mapper
change says the key is sealed to the OP-TEE fTPM rather than swtpm - swtpm
is the qemux86-64 path. So the Coverage paragraph was the wrong half, and
reconciling the bullet against it would have replaced a correct statement
with an incorrect one.

Correcting that cost the bullet its stated cause, which had blamed
unstable PCR 7 measurement under the emulator. That was a guess, and
optee-ftpm-init.bb already documents the mechanism: the QEMU virt machine
has no RPMB, so OP-TEE cannot commit its secure-storage rollback counter,
does not trust the fTPM's saved state, and the fTPM re-derives its seed on
the next boot. Using the documented cause instead of the guess also
sharpens the note's own thesis, because it means the proxy structurally
cannot demonstrate reboot survival rather than merely having failed to.

The admonition moves to the space-delimited title form the other 22
admonitions on the site use, so the one bracketed instance stops being a
second convention nobody else follows. The Verify it lead-in becomes two
sentences because "not output it has produced" parsed two ways as one.

Prettier's italic and table-padding normalisation lands here too. Those
lines are this branch's own additions, not a drive-by: scripts/checks.sh
was already failing on them before this commit.

Signed-off-by: Javier Tia <javier@peridio.com>
Copilot AI review requested due to automatic review settings August 12, 2026 22:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:183

  • In the "Verify it" intro and expected output, the text reads awkwardly ("not output a board has already produced"), and the systemd-cryptenroll --list expectation is overly specific/inconsistent with the earlier section that describes Argon2id as slot 0 and TPM2 as slot 1. Consider tightening the intro sentence and making the expectation describe the condition (Argon2id slot removed; TPM2 slot present) without hard-coding a slot number.
These are the checks the hardware pass still has to run. The output below is what they should produce, not output a board has already produced. Run them on the board after boot:

```bash
# /var is LUKS2 and mounted from the mapped device
cryptsetup status /dev/mapper/var

…d not cover

The note has been carrying "not yet run" against every hardware row since
the claims correction. The board pass ran on 2026-08-12, so the LUKS2 row
can be filled in - but only that row, and the reason the rest stay open
is worth more to a reader than the tick mark.

Three defects had to be fixed before the board could unlock /var at all,
and all three were invisible on the qemuarm64 proxy because that machine
carries an override imx93 lacked: DM_CRYPT silently demoted to =m by
kconfig, AVOCADO_VAR_PART_DEV unset so fstab pointed at the raw
partition, and a key provider reading a secret no recipe creates. Each is
recorded with what it looked like rather than just that it was fixed,
because the pattern - proxy passes, board cannot - is the transferable
part.

Phase-2 TPM2 changes from "not yet run" to "not possible on this board
yet", which is a different claim. There is no TPM on the FRDM-IMX93 to
seal to: no discrete part on the board, and the i.MX9 route to a TPM 2.0
interface is a firmware TPM on OP-TEE that is currently built for
qemuarm64 only. So the open question about the TPM2 slot reopening /var
is now pinned precisely: the proxy cannot show it for want of RPMB, and
the board cannot show it for want of a TPM. Half of it - that /var
reopens at all from an existing container across a reboot - the board did
show.

The security-properties section needed the sharpest correction. It claims
two independent factors; on this board today there is one, and it is
weaker than "passphrase" implies. The key derives from the SoC UID, which
binds the volume to one board but is not a secret - anyone who can read
it from a running system can rederive the key. Device binding is a real
property and worth claiming; confidentiality against an attacker who has
had code execution on the device is not, and the note said otherwise.

Adds a reproduce section, since none of this is reachable without knowing
that the image ships root login disabled, that the board boots from eMMC
by default so an SD image needs the switches moved, and that the default
flash task rewrites var.

Verified: npm run build succeeds, static files generated.
Signed-off-by: Javier Tia <javier@peridio.com>
Copilot AI review requested due to automatic review settings August 13, 2026 00:10
@jetm

jetm commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

The hardware pass this note was waiting on ran today, so the LUKS2 row is filled in - c10139a.

What the board showed. FRDM-IMX93 on the wrynose BSP (meta-avocado#271): /var is a LUKS2 container on /dev/mmcblk1p8, aes-xts-plain64, 512-bit, mounted from /dev/mapper/var, with dmsetup targets listing crypt v1.28.0. First boot ran open -> no filesystem -> create -> ready; a second boot exercised the unlock path and /var reopened with the same filesystem UUID across a reboot confirmed by a changed boot_id.

Three defects had to be fixed before any of that worked, and each was invisible on the proxy because avocado-qemuarm64 carries a machine override imx93 lacked: DM_CRYPT silently demoted to =m by kconfig, AVOCADO_VAR_PART_DEV unset so fstab pointed at the raw partition, and a key provider reading /var/private/var-key-secret - a file on the volume being unlocked that nothing in the tree creates.

Phase-2 TPM2 moves from "not yet run" to "not possible on this board yet", which is a different claim and I think the more useful one. There is no TPM on the FRDM-IMX93 to seal to - no discrete part (UM12181, and the schematic BOMs for the i.MX95 siblings), and the i.MX9 route to a TPM 2.0 interface is a firmware TPM on OP-TEE that optee-ftpm-init currently builds for avocado-qemuarm64 only. So the open question about the TPM2 slot reopening /var is now pinned from both sides: the proxy cannot show it for want of RPMB, the board cannot show it for want of a TPM.

The security-properties section needed the sharpest edit. It claimed two independent factors. On this board today there is one, and it is weaker than "passphrase" implies: the key derives from the SoC UID, which binds the volume to one board but is not a secret, since anyone who can read it from a running system can rederive it. Device binding is real and worth claiming; confidentiality against an attacker who has already had code execution on the device is not, and the note said otherwise.

Also adds a reproduce section - none of this is reachable without knowing that the stock image ships root login disabled (root:*:), that the board boots from eMMC by default so an SD image needs SW1[3:0] moved to 0011, and that the default flash task rewrites var.

npm run build passes, static files generated.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (5)

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:294

  • There are two top-level sections titled “## Reproduce it” (one around build/flash steps and one for adversarial tests). Duplicate headings create duplicate anchors and make the ToC ambiguous; rename one of them (e.g., the adversarial section) to a distinct heading.
## Reproduce it

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:236

  • PR description says the coverage table’s hardware column is “Not yet run throughout”, but this table marks hardware as Verified for LUKS2 /var (and the frontmatter also claims validation on 2026-08-12). Either the PR description needs updating or the table/frontmatter should be adjusted so they match, because reviewers will otherwise read the change as contradicting the stated intent.
| Control        | `avocado-qemuarm64` (proxy)                     | `avocado-imx93-frdm` (hardware)                    |
| :------------- | :---------------------------------------------- | :------------------------------------------------- |
| LUKS2 `/var`   | Verified on first boot                          | **Verified**, first boot and reboot (2026-08-12)   |
| Phase-2 TPM2   | Enrollment verified; unseal on reboot **fails** | **Not possible on this board yet** - see below     |

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:45

  • The caution admonition says “What is not verified: any of it on the i.MX93 FRDM board”, but later the page claims LUKS2 /var was validated on hardware (frontmatter tested_against, coverage table, and “The hardware pass (2026-08-12)”). This reads as self-contradictory and undermines the corrected verification messaging. Rephrase this paragraph to reflect that only LUKS2 /var has been verified on hardware so far, while the rest remains proxy-only/not yet run.

This issue also appears on line 233 of the same file.

What is not verified: any of it on the i.MX93 FRDM board. The implementation is still
in review ([meta-avocado #232](https://github.com/avocado-linux/meta-avocado/pull/232)
and [#236](https://github.com/avocado-linux/meta-avocado/pull/236) are open), and two
results from the proxy run are open questions rather than details: TPM2 unseal on
_reboot_ fails there and falls back to the Argon2 slot, and dm-verity is not active on

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:204

  • This paragraph is still grammatically incorrect/ambiguous (“not output anything has produced yet”). It also mixes “output a board has produced” with “checks that should produce output” in one sentence. Consider rephrasing so it clearly distinguishes verified command output from expected output for not-yet-run checks.

This issue also appears on line 294 of the same file.

## Verify it

Everything under LUKS2 below is output a board has produced. The TPM2, dm-verity, IMA/EVM and module-signing checks are what they should produce, not output anything has produced yet - see the coverage table.

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:288

  • The page gives conflicting guidance on whether a re-flash clears /var: earlier it says fwup -t complete rewrites the whole medium including var (line 199), but here it says re-provisioning doesn’t clear the wedge because fwup -t complete does not touch var. These two statements can’t both be true; please verify the actual fwup behavior and make the doc consistent so readers don’t brick devices based on incorrect recovery steps.
- **An interrupted first boot wedges the device permanently.** `cryptsetup-var.sh` only runs `mkfs.btrfs` in its first-boot branch. A first boot that dies after `luksFormat` but before `mkfs.btrfs` leaves a LUKS2 header with no filesystem inside, so every later boot takes the open-existing branch, never creates the filesystem, and drops to emergency forever. Re-provisioning does not clear it, because `fwup -t complete` does not touch the `var` partition; recovery means zeroing the LUKS header by hand. The fix is either to detect "header present, no filesystem on the opened mapper" and re-`mkfs`, or to make format-plus-mkfs atomic behind a completion marker.

… never written

The build-flow snippet showed a fourth SRC_URI gate pulling file://ima.cfg
on the ima DISTRO_FEATURE, and the source-layout tree listed an ima-policy
recipe with a policy file and a public cert. None of it exists: ima.cfg is
absent from scarthgap and from both secure-boot branches, no recipe or kas
feature references ima, and the board confirms it - no /sys/kernel/security/ima,
no ima_policy on the cmdline. A reader following the snippet greps for a file
nobody ever wrote and concludes the docs are stale rather than the control is
missing.

The earlier pass on this note corrected the coverage table while leaving the
snippet asserting the wiring exists, so the two halves disagreed. Replace the
snippet with the three gates the bbappend actually carries - including the
encrypted-var one it omitted - and say plainly that the IMA gate is design.
Correcting the snippet meant reading the surrounding block against the tree,
which surfaced the same defect in the fragment paths and packagegroup names;
those are fixed here rather than left knowingly wrong in a block being rewritten.

Signed-off-by: Javier Tia <javier@peridio.com>
Copilot AI review requested due to automatic review settings August 13, 2026 00:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:182

  • There are now two sections titled “Reproduce it” (this one and another later in the note). Duplicate headings create ambiguous anchors and make the document harder to navigate; consider renaming this earlier section to reflect that it’s the build/flash steps.
## Reproduce it

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:208

  • Minor wording/grammar: “output a board has produced” / “not output anything has produced yet” reads awkwardly. Rephrase so it’s clear what output is confirmed vs expected.
Everything under LUKS2 below is output a board has produced. The TPM2, dm-verity, IMA/EVM and module-signing checks are what they should produce, not output anything has produced yet - see the coverage table.

src/field-notes/2026-06-24-hardened-boot-imx93.mdx:50

  • The admonition contradicts the rest of the note: it says nothing is verified on i.MX93 hardware, but the frontmatter and Coverage table state LUKS2 /var was validated on avocado-imx93-frdm (2026-08-12). Update the admonition title/body so it accurately reflects partial hardware verification (LUKS2 only) and that the remaining controls are still proxy-only / design-only.

This issue also appears in the following locations of the same file:

  • line 182
  • line 208
What is verified, on `avocado-qemuarm64` standing in for the board: LUKS2 `/var`
formatted on first boot, and the two-phase enrollment landing an Argon2 recovery
keyslot alongside a TPM2 keyslot sealed to PCR 7.

What is not verified: any of it on the i.MX93 FRDM board. The implementation is still

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants