Skip to content

v0.2.7 — at-rest pre-OTP seed remnant scrub#13

Merged
TheMaxMur merged 2 commits into
mainfrom
develop
Jun 21, 2026
Merged

v0.2.7 — at-rest pre-OTP seed remnant scrub#13
TheMaxMur merged 2 commits into
mainfrom
develop

Conversation

@TheMaxMur

Copy link
Copy Markdown
Owner

v0.2.7 — at-rest pre-OTP seed remnant scrub

Security fix

The OTP-burn migration re-seals the FIDO seed from the chip-serial root to the
fused OTP root, but sequential-storage's log is append-only: the superseded
chip-serial-sealed copy lingers in flash, recoverable from a raw dump plus
the chip id — bypassing the OTP hardening — until natural compaction
reclaims its page (rare on the cold credential partition). Same class as the
upstream pico-fido/pico-keys-sdk flash_clear_file finding.

Fix: the first boot with the OTP key present runs a one-shot Fs::compact
— a full GC lap over the credential partition that migrates live records
forward and sector-erases every page, physically destroying the superseded
pre-OTP copies. Gated by an EF_HARDENED flash marker (runs once, before USB
attach, crash-safe — an interrupted lap re-runs next boot). A device
provisioned OTP-first never creates the remnant.

Verification

  • Host proof on the real sequential-storage + mock-flash stack:
    fuzz/tests/churn_compaction.rs scans raw flash to confirm the remnant is
    present before the lap and gone after — mutation-checked (a no-op compaction
    fails the assert).
  • HW-verified on a board that carried a real 0x01 remnant: scrubbed
    (378 stale keydev copies → 1, 92% of the partition rewritten), all applets
    intact. Full device test sweep green (tests/ + third_party/pico-fido +
    openpgp-card), no regressions.
  • Local gate green: fmt, clippy (embedded + host + fips firmware), all host
    tests, both firmware builds, gitleaks, flake.lock in sync.

Also

  • production.md recommends burning OTP before enrolling; documents the
    hardening pass.
  • threat-model.md / limitations.md corrected — the "moot against anything
    but a fused-key compromise" caveat held only for the already-fused soft-lock
    remnant, not this one.
  • rsk otp burn notes the post-burn hardening pass.

bcdDevice 0x077E → 0x077F.

🤖 Generated with Claude Code

TheMaxMur and others added 2 commits June 21, 2026 19:10
The OTP-burn migration re-seals the FIDO seed from the chip-serial root to
the fused OTP root, but sequential-storage's log is append-only: an overwrite
leaves the prior value in place and remove_item only flips a header CRC, so
the superseded *chip-serial-sealed* copy lingers in flash, recoverable from a
raw dump plus the chip id — bypassing the OTP hardening — until natural
compaction reclaims its page (rare on the cold credential partition). This is
the same class as the upstream pico-fido/pico-keys-sdk flash_clear_file
finding; here the device-root seal is the only thing that kept the steady
state safe, and the migration strands a weaker-sealed copy.

The first boot with the OTP key present now runs a one-shot Fs::compact: a
full garbage-collection lap over the credential partition that drives the ring
head all the way around, migrating live records forward and sector-erasing
every page, physically destroying the superseded pre-OTP copies. It is gated
by a new EF_HARDENED flash marker (runs once, before USB attach, crash-safe —
an interrupted lap leaves the marker unset and re-runs next boot). A device
provisioned OTP-first never creates the remnant and the pass finds nothing to
scrub.

A host proof on the real sequential-storage + mock-flash stack scans raw flash
to confirm the remnant is present before the lap and gone after
(fuzz/tests/churn_compaction.rs, mutation-checked). production.md now
documents the pass and recommends burning OTP before enrolling; the
threat-model/limitations caveats are corrected ("moot against anything but a
fused-key compromise" held only for the already-fused soft-lock remnant, not
this one).

HW-verified: a board carrying a real 0x01 remnant had it scrubbed (378 stale
keydev copies -> 1, 92% of the partition rewritten), applets intact; full
device test sweep green with no regressions.

bcdDevice 0x077E -> 0x077F.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…emnant scrub) + readme version

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@TheMaxMur TheMaxMur merged commit d07cd4a into main Jun 21, 2026
12 checks passed
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.

1 participant