Skip to content

Fix early USB security dongle branding detection; refine STATUS/NOTE/INFO logging, fix TPM sealing/counter increment & respawn loop#2094

Draft
tlaurion wants to merge 5 commits intolinuxboot:masterfrom
tlaurion:detect_usb_security_dongle_branding_early
Draft

Fix early USB security dongle branding detection; refine STATUS/NOTE/INFO logging, fix TPM sealing/counter increment & respawn loop#2094
tlaurion wants to merge 5 commits intolinuxboot:masterfrom
tlaurion:detect_usb_security_dongle_branding_early

Conversation

@tlaurion
Copy link
Copy Markdown
Collaborator

@tlaurion tlaurion commented Apr 28, 2026

Closes #2098
Closes #2097
Closes #2096

Summary

Multiple improvements for Heads initrd boot reliability: early USB dongle branding detection by VID, TPM sealing/counter-increment auth retry (TPM1 + TPM2), consistent STATUS/NOTE/INFO/DEBUG logging under /tmp/measuring_trace.log even in quiet mode, and BOOTSCRIPT respawn loop fix in case of DIE killing init.

Changes

1. USB Security Dongle Detection

  • Add sysfs VID polling loop (max 3s, 0.1s sleep, 30-iteration cap) for known dongle VIDs (20a0, 316d, 16d0, 1050) before lsusb branding detection — fixes Nitrokey 3 enumeration race
  • Fix PCR5 regression: don't auto-load USB modules in detect_usb_security_dongle_branding() — callers that need USB (HOTP/GPG/LUKS) must call enable_usb() first. Prevents unnecessary PCR5 extensions at boot that break DUK unseal on non-HOTP boards.
  • Add enable_usb at required call sites: GPG keyring init, HOTP verification, TPM reset flow

2. Logging Refinement

  • Rewrite doc/logging.md with clear INFO/NOTE/WARN/DEBUG usage guidance, table with sleep/blank-line columns
  • Add measuring_trace.log to Quiet mode table
  • Consistent STATUS/STATUS_OK usage across 15+ scripts (cbfs-init, gpg-gui, gui-init, kexec-*, lock_chip, network-init-recovery, oem-factory-reset, qubes-measure-luks, seal-hotpkey, seal-totp, tpmr, unseal-hotp, uefi-init, usb-init, gui_functions)
  • pcrs() formatting fix: filter sha256: header from TPM2 pcrread output
  • Recovery shell: show PCR state on entry

3. TPM Sealing & Counter Increment Fixes

TPM1:

  • Handle exit code 2 from tpm1_seal — QEMU TPM1.2 returns exit code 2 with empty stderr when NVRAM index doesn't exist. Fixed by capturing exit codes in subshells with set +e, checking both exit code and "illegal index" output.
  • Add _tpm1_auth_retry shared helper: re-prompts and retries up to 3 times on authorization failures, eliminating duplicate retry logic between counter create and increment
  • Add tpm1_counter_create, tpm1_counter_read, tpm1_counter_increment wrapper functions
  • Add tpm1_seal NVRAM define+write retry loop (consistent with tpm2_seal)

TPM2:

  • Fix regression from auth-retry rewrite — bare nvincrement (NV index auth) path was lost. Counters created by nvdefine default to empty NV index auth; nvincrement -C o was using owner hierarchy auth instead, causing TPM error 0x149 (AUTH_UNAVAILABLE).
  • Add 0x149 to grep patterns in tpm2_counter_inc and tpm2_counter_create retry logic
  • Document TPM2 error codes with reference to TCG TPM2 Part 2 (Structures) Table 18

4. DEBUG Traces at Boot Chain Decision Points

  • Add DEBUG before/after every decision point across init, gui-init.sh, key-init.sh, seal-hotpkey.sh, kexec-unseal-key.sh, kexec-boot.sh, functions.sh (preflight), and gui_functions.sh
  • Add TPM-reset-required marker flow: check_tpm_counterprompt_update_checksums targeted error message, update_totp menu bypass, show_tpm_totp_hotp_options_menu bypass
  • Handle "out of resources" (0x15) from TPM counter creation with targeted user guidance
  • Add doc/tpm.md and doc/ux-patterns.md

5. Respawn Loop Fix

  • Drop exec from cttyhack in init so the while true respawn loop actually respawns on boot script exit, instead of kernel panicking when PID 1 dies

Screenshots

TPM1 non-HOTP variant, normal boot (quiet mode)

Screenshot_20260501_124731

TPM2 HOTP variant, normal boot (quiet mode)

Screenshot_20260501_125053

TPM2 HOTP variant, normal boot (quiet mode) recovery shell access

Screenshot_20260501_125144

TPM2 HOTP variant, normal boot (quiet mode), less on advertised /tmp/measuring_trace.log

Screenshot_20260501_125317

Tested

  • qemu-coreboot-fbwhiptail-tpm2-hotp (full reset + re-ownership)
  • qemu-coreboot-fbwhiptail-tpm1-hotp (full reset + re-ownership)
  • x230-hotp-maximized, x230-maximized (TPM1)
  • v540tu (TPM2)

Copilot AI review requested due to automatic review settings April 28, 2026 21:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates initrd scripts to detect USB security dongle branding earlier and to refine console logging behavior (especially for quiet mode) by shifting messages among STATUS/STATUS_OK/NOTE/WARN and adding more explicit success milestones.

Changes:

  • Add an early sysfs-based wait in detect_usb_security_dongle_branding() to reduce mis-detection before lsusb is reliable.
  • Rebalance user-visible logging across multiple initrd scripts (more STATUS/STATUS_OK, convert some INFO→NOTE/WARN, add success confirmations).
  • Expand doc/logging.md to clarify intended semantics of INFO/NOTE/WARN and console behavior in quiet/info/debug modes.

Reviewed changes

Copilot reviewed 3 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
initrd/etc/gui_functions.sh Adjust integrity report output; add signing-key status messaging.
initrd/etc/functions.sh Add sysfs VID wait loop before lsusb branding detection.
initrd/bin/unseal-hotp.sh Add STATUS/STATUS_OK around TPM unseal of HOTP secret.
initrd/bin/tpmr.sh Change TPM2 unseal failure log level (INFO→WARN).
initrd/bin/seal-totp.sh Promote PCR-read logging to STATUS; show manual secret via NOTE.
initrd/bin/seal-hotpkey.sh Add STATUS/STATUS_OK around writing HOTP secret to dongle.
initrd/bin/oem-factory-reset.sh Add STATUS_OK milestones; adjust guidance output levels; fix TPM reset error handling block structure.
initrd/bin/network-init-recovery.sh Add STATUS_OK milestones for module load, clock sync, and SSH server start.
initrd/bin/lock_chip.sh Add STATUS_OK after chipset lock command.
initrd/bin/key-init.sh Reword ISO key loading messages and add final STATUS_OK.
initrd/bin/kexec-seal-key.sh Add STATUS_OK milestones for key generation, LUKS slot update, PCR reads.
initrd/bin/gui-init.sh Reduce/shift console output in reseal/TOTP/HOTP flows; add HOTP verification status lines.
initrd/bin/gpg-gui.sh Convert INFO instructions to NOTE.
initrd/bin/cbfs-init.sh Adjust SPI read messaging; add STATUS_OK on flash read success.
doc/logging.md Redefine INFO/NOTE positioning and document console styling/sleep/visibility matrix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread initrd/etc/gui_functions.sh Outdated
Comment thread initrd/etc/functions.sh
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 9361484 to 2a485c5 Compare April 29, 2026 13:27
@tlaurion tlaurion marked this pull request as draft April 29, 2026 13:28
@tlaurion tlaurion requested a review from Copilot April 29, 2026 13:28
Copy link
Copy Markdown

Copilot AI left a comment

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 3 out of 15 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread doc/logging.md Outdated
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 2a485c5 to 5e09ef9 Compare April 29, 2026 13:57
@tlaurion tlaurion requested a review from Copilot April 29, 2026 13:59
Copy link
Copy Markdown

Copilot AI left a comment

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 3 out of 15 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 5e09ef9 to c03366b Compare April 29, 2026 18:20
@tlaurion tlaurion requested a review from Copilot April 29, 2026 18:21
@tlaurion tlaurion changed the title Detect usb security dongle branding early, fixup STATUS STATUS_OK for quiet mode Detect usb security dongle branding early, fixup STATUS+STATUS_OK/INFO for quiet mode Apr 29, 2026
Copy link
Copy Markdown

Copilot AI left a comment

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 4 out of 15 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread initrd/init Outdated
Comment thread doc/logging.md Outdated
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from c03366b to fee4251 Compare April 29, 2026 18:53
@tlaurion tlaurion requested a review from Copilot April 29, 2026 18:55
Copy link
Copy Markdown

Copilot AI left a comment

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 4 out of 16 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread doc/logging.md Outdated
Comment thread initrd/init
Comment thread initrd/init Outdated
Comment thread initrd/init Outdated
Comment thread initrd/etc/functions.sh
@tlaurion tlaurion marked this pull request as ready for review April 29, 2026 19:04
@tlaurion tlaurion changed the title Detect usb security dongle branding early, fixup STATUS+STATUS_OK/INFO for quiet mode Refine STATUS/NOTE/INFO logging for consistent UX and accurate terminology Apr 29, 2026
@tlaurion tlaurion marked this pull request as draft April 29, 2026 19:08
@tlaurion
Copy link
Copy Markdown
Collaborator Author

tlaurion commented May 1, 2026

@filipleple this should be part of downstream release

…ology

- doc/logging.md: Complete rewrite with clear INFO/NOTE/WARN guidance, table
  with sleep/blank-line columns, add measuring_trace.log to Quiet mode table
- initrd/bin/cbfs-init.sh: Add STATUS_OK for flash read, streamline messages
- initrd/bin/gpg-gui.sh: Change INFO to NOTE for GPG instructions
- initrd/bin/gui-init.sh: Remove noisy STATUS pairs, add enable_usb for GPG,
  add STATUS for HOTP verification
- initrd/bin/kexec-insert-key.sh: Improve DUK measuring message
- initrd/bin/kexec-seal-key.sh: Add STATUS_OK for key gen, slot update, PCR read
- initrd/bin/kexec-select-boot.sh: Fix "unsigned boot options" -> "boot options"
- initrd/bin/lock_chip.sh: Add STATUS_OK for chipset lock
- initrd/bin/network-init-recovery.sh: Add STATUS_OK for modules, clock, SSH
- initrd/bin/oem-factory-reset.sh: Many STATUS_OK additions, INFO->NOTE for guidance
- initrd/bin/qubes-measure-luks.sh, uefi-init.sh, usb-init.sh: Improve PCR messages
- initrd/bin/seal-hotpkey.sh: Add STATUS/STATUS_OK for HOTP secret write
- initrd/bin/seal-totp.sh: Change STATUS to NOTE for TOTP secret
- initrd/bin/tpmr.sh: Add STATUS/STATUS_OK, INFO->WARN for unseal, add PCR extend INFO
- initrd/bin/unseal-hotp.sh: Add STATUS/STATUS_OK for unseal
- initrd/etc/functions.sh: PCR5 regression fix (don't auto-load USB), VID wait
  loop fixes (sleep 0.1, iteration cap), pcrs() formatting fix
- initrd/etc/gui_functions.sh: Remove redundant STATUS_OK, add for signing key verification
- initrd/init: echo->STATUS_OK, add measuring_trace.log, fix grammar
- initrd/sbin/insmod.sh: Improve PCR extend message

Signed-off-by: Thierry Laurion <[email protected]>
@tlaurion tlaurion marked this pull request as draft May 1, 2026 17:35
@tlaurion
Copy link
Copy Markdown
Collaborator Author

tlaurion commented May 1, 2026

still issues with tpm1 incrementing after reset only on real hardware :( digging

@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 2d0487a to 90a7fa6 Compare May 2, 2026 03:22
@tlaurion tlaurion requested a review from Copilot May 2, 2026 03:28
Copy link
Copy Markdown

Copilot AI left a comment

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 7 out of 23 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread doc/ux-patterns.md
Comment thread initrd/init Outdated
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 90a7fa6 to 53811ff Compare May 2, 2026 14:23
@tlaurion tlaurion requested a review from Copilot May 2, 2026 14:27
Copy link
Copy Markdown

Copilot AI left a comment

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 7 out of 23 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread initrd/init Outdated
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 53811ff to 891cf0c Compare May 2, 2026 18:05
@tlaurion tlaurion requested a review from Copilot May 2, 2026 18:06
Copy link
Copy Markdown

Copilot AI left a comment

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 7 out of 23 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread initrd/init Outdated
tlaurion added 2 commits May 2, 2026 16:56
TPM1: counter_increment fell through to raw 'exec tpm' with no error
handling — a mistyped owner passphrase killed the signing flow instantly.

TPM2: counter_increment had no retry loop, unlike tpm2_seal and
tpm2_counter_create which already re-prompted on auth failure.

Changes:

initrd/bin/tpmr.sh:
- _tpm1_auth_retry: shared retry helper for TPM1 counter create/increment,
  re-prompts owner passphrase up to 3× on auth failure, reuses cached
  passphrase on first attempt (no double-prompt on happy path)
- tpm1_counter_create / tpm1_counter_increment: thin wrappers around helper
- tpm1_counter_read: named function (was catch-all exec tpm passthrough)
- tpm1_seal: restore define+write retry loop removed by stdout-quirk fix,
  definespace output to /dev/null (ignored, nv_writevalue is the real test)
- tpm2_counter_inc: add retry loop with should_retry flag to distinguish
  index-auth (-pwdc , no retry) from owner-auth (retry up to 3×)
- All shred calls in retry loops: add 2>/dev/null || true guards
- TPM1 dispatch: wire counter_read, counter_increment to named functions
- TPM1/TPM2 extend/reset: improved PCR INFO messages

initrd/bin/gui-init.sh:
- reset_tpm: verify tpmr.sh reset exit code, show error and return to
  menu if reset fails (prevents operations on inconsistent TPM)

initrd/etc/functions.sh:
- increment_tpm_counter: replace misleading outer SINK_LOG with 2>/dev/null
  (DO_WITH_DEBUG already captures command stderr via SINK_LOG internally)
- Document DO_WITH_DEBUG stderr handling in comments

doc/tpm.md: document "out of resources" counter error and recovery flow
doc/ux-patterns.md: UX patterns for TPM error recovery

Signed-off-by: Thierry Laurion <[email protected]>
…rations

Following doc/logging.md, add DEBUG before or after every decision point
and time-consuming operation across the boot chain so debug.log provides
a complete narrative without silent gaps:

- initrd/init: TPM detection, TPM session init, recovery serial, USB
  keyboard, boot keys (r/o), BASIC mode, boot script selection, network
  boot, respawn loop entry, board-init.  Drop `exec` from cttyhack so
  the while-true respawn loop actually respawns on boot script exit.
- initrd/bin/gui-init.sh: enable_usb rationale at all 3 call sites,
  boot device detection, clean_boot_check branches, preflight success,
  HOTP token query/retry/check result, TOTP unseal, HOTP attempt counter.
- initrd/bin/key-init.sh: user/distro key import counts, self-signed key
  export.
- initrd/bin/seal-hotpkey.sh: firmware version query, PIN retry counter
  re-query before show_pin_retries and after default-PIN attempt,
  HOTP token status query.
- initrd/bin/kexec-unseal-key.sh: TOTP display and DUK unseal attempts.
- initrd/bin/kexec-boot.sh: TPM context flush and platform hierarchy lock
  before kexec.
- initrd/etc/functions.sh: preflight_rollback_counter_before_reseal:
  counter_id found in rollback file, prior trust metadata check,
  counter_read failure, TPM2 attribute check branches.
- initrd/etc/gui_functions.sh: document why enable_usb inside
  report_integrity_measurements cannot pollute a fresh seal (only called
  after unseal failure; any subsequent seal requires reboot).

Signed-off-by: Thierry Laurion <[email protected]>
@tlaurion tlaurion force-pushed the detect_usb_security_dongle_branding_early branch from 891cf0c to 5047eb1 Compare May 2, 2026 21:03
@tlaurion tlaurion changed the title Improve USB dongle detection and refine STATUS/NOTE/INFO logging, fix tpm1 seal issue Improve USB dongle detection and refine STATUS/NOTE/INFO logging, fix tpm sealing/counter increment issue May 2, 2026
@tlaurion tlaurion changed the title Improve USB dongle detection and refine STATUS/NOTE/INFO logging, fix tpm sealing/counter increment issue Fix TPM2 counter increment, add DEBUG traces across boot chain, fix respawn loop May 2, 2026
@tlaurion tlaurion changed the title Fix TPM2 counter increment, add DEBUG traces across boot chain, fix respawn loop Fix early USB security dongle branding detection; refine STATUS/NOTE/INFO logging, fix TPM sealing/counter increment & respawn loop May 2, 2026
@tlaurion tlaurion requested a review from Copilot May 2, 2026 22:29
Copy link
Copy Markdown

Copilot AI left a comment

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 7 out of 26 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread initrd/etc/gui_functions.sh Outdated
Comment on lines +256 to +259
# enable_usb extends PCR5, but this function is only called when
# unsealing already failed (or rollback validation failed). Any
# subsequent seal requires a reboot, so stale PCR5 from USB is
# never sealed against.
Comment thread initrd/init Outdated
Comment on lines +274 to +281
DEBUG "Entering boot script respawn loop: $CONFIG_BOOTSCRIPT"
#Never DIE in init, respawn Boot Scripts
while true; do
echo '***** Normal boot:' $CONFIG_BOOTSCRIPT

if [ -x /bin/setsid ] && [ -x /bin/agetty ]; then
for console in $CONFIG_BOOT_EXTRA_TTYS; do
setsid agetty -aroot -l"$CONFIG_BOOTSCRIPT" "$console" linux &
…ments

- gui_functions.sh: Fix inaccurate comment claiming report_integrity_measurements
  is 'only called when unsealing already failed' with description of all three
  call sites (main-menu integrity loops + OEM reset path).

- init: Replace asymmetric init loop (blocking cttyhack + inside-loop agetty)
  with uniform PID-tracked respawn for all consoles.  Each console (main and
  extra) gets a PID file; kill -0 checks liveness; only dead instances restart.
  Uses 'wait' to sleep between respawn checks instead of blocking on one console.
  agetty provides separate session+controlling terminal per extra TTY (talos-2
  only), avoiding shared-ctty GPG issues.  Recovery serial (QEMU, librem_l1um_v2)
  remains a fire-and-forget background process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants