Fix early USB security dongle branding detection; refine STATUS/NOTE/INFO logging, fix TPM sealing/counter increment & respawn loop#2094
Conversation
There was a problem hiding this comment.
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 beforelsusbis reliable. - Rebalance user-visible logging across multiple initrd scripts (more STATUS/STATUS_OK, convert some INFO→NOTE/WARN, add success confirmations).
- Expand
doc/logging.mdto 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.
9361484 to
2a485c5
Compare
There was a problem hiding this comment.
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.
2a485c5 to
5e09ef9
Compare
There was a problem hiding this comment.
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.
5e09ef9 to
c03366b
Compare
There was a problem hiding this comment.
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.
c03366b to
fee4251
Compare
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
90a7fa6 to
53811ff
Compare
There was a problem hiding this comment.
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.
53811ff to
891cf0c
Compare
There was a problem hiding this comment.
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.
891cf0c to
5047eb1
Compare
There was a problem hiding this comment.
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.
|
Splitted tpm1 issues in pr #2099 with refactoring to unify tpm1/tmp2 worflow. will rebase this pr once merged |
Delay branding detection until a known USB security dongle vendor ID appears in sysfs, then run lsusb matching. - Add bounded VID polling in detect_usb_security_dongle_branding() - Keep branding fallback path when no known VID appears - Initialize USB in integrity report path before branding detection Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Normalize user-visible logging across initrd scripts and documentation so output levels are applied consistently. - Align STATUS/STATUS_OK usage for action start and success - Reserve NOTE for user guidance requiring attention - Keep WARN/ERROR messaging actionable and consistent - Update doc/logging.md to match runtime behavior Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Relative to origin/master (c2fb345): - Introduces wait_for_usb_security_dongle_vid() with visible countdown. - Adds user-cancel path during wait (keyboard/serial). Current state: - Wait exits early once a known VID appears. - Wait times out after 15 seconds to avoid indefinite boot stall. - Branding fallback path remains unchanged. Signed-off-by: Thierry Laurion <insurgo@riseup.net> initrd/etc/functions.sh: harden recovery shell handoff Relative to origin/master (c2fb345): - Aligns pause_recovery() with hardened recovery checks. - Drains serial input queue before launching recovery shell. Current state: - Buffered serial bytes are no longer interpreted as shell commands. - PCR extension/auth path is preserved before shell handoff. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Relative to origin/master (c2fb345): - Replaces asymmetric script handling with PID-tracked respawn loop. - Tracks process ids per console path and restarts only when dead. Current state: - Main and auxiliary consoles respawn predictably without tight loops. - Existing cttyhack/agetty split is preserved. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Relative to origin/master (c2fb345): - Reintroduces DEBUG lines for critical startup branching decisions. - Covers TPM/USB gating, recovery paths, and boot flow selection. Current state: - Early-boot decision points are observable in debug logs. - Runtime behavior is unchanged; this is diagnostics-only. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Relative to origin/master (c2fb345): - GIT_BRANCH-derived token used in artifact names is sanitized. - Slashes/whitespace in branch names no longer create invalid output paths. Current state: - Artifact basenames remain traceable to branch context. - Build copy/install steps no longer fail on branch names like feature/foo. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Correct DUK documentation from "128 characters" to "128 bytes" in runtime status/error messages and security/TPM docs. Add explicit notation of the brute-force space (2^1024) to clarify entropy magnitude. The DUK is 128 bytes from /dev/urandom (1024 bits of entropy). Brute-force time grows exponentially with entropy: a 128-byte random secret has 2^1024 possible values, requiring an attacker to try about 2^1023 guesses on average. Using the formula time ≈ 2^(H-1)/R (where H is entropy in bits, R is guesses/second): - At 10^12 guesses/second, expected time is ~2^1023/10^12 seconds - This is unimaginably longer than the age of the universe (~4×10^17 seconds) - Every bit of entropy doubles the search space, making exponential growth the key property For practical comparison: 80 Diceware words provide ~1032 bits of entropy, roughly comparable to 128 random bytes. Every attack rate is dominated by the exponential requirement. Important caveat: this protection applies only to offline brute-force against a correctly stored secret. Online rate limits or poor storage would override these estimates. Signed-off-by: Thierry Laurion <insurgo@riseup.net> initrd: address unresolved Copilot review feedback Signed-off-by: Thierry Laurion <insurgo@riseup.net> initrd: align dongle wait console output with logging policy Signed-off-by: Thierry Laurion <insurgo@riseup.net>
The squash lost the enable_usb call that initializes USB and triggers the 15-second dongle VID wait. This caused the wait to never execute when USB wasn't pre-enabled at boot, breaking dongle detection on first boot. Restore the unconditional enable_usb call followed by wait_for_usb_devices only if USB wasn't previously enabled, matching the original flow. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
| # Child scripts can inherit DONGLE_BRAND while _USB_ENABLED resets, so always | ||
| # initialize USB unless the fast path above was taken. | ||
| enable_usb | ||
| [ "$usb_was_enabled" != "y" ] && wait_for_usb_devices |
| if [ "$is_serial" = "1" ]; then | ||
| STATUS "Waiting up to 15s for USB security dongle detection (press Enter to skip)" | ||
| else | ||
| STATUS "Waiting up to 15s for USB security dongle detection (press Esc to skip)" |
| # Re-detect TTY so INPUT uses the correct device | ||
| detect_heads_tty | ||
|
|
||
| if [ "$CONFIG_TPM" = "y" ]; then | ||
| INFO "TPM: Extending PCR[4] with content of string 'recovery' to prevent further secret unsealing" | ||
| tpmr.sh extend -ix 4 -ic recovery | ||
| fi | ||
|
|
||
| gpg_auth | ||
|
|
||
| if [ -n "$*" ]; then | ||
| WARN "$*" | ||
| fi | ||
|
|
||
| if [ "$CONFIG_TPM" = "y" ]; then | ||
| INFO "TPM: PCR state on entering recovery shell:" | ||
| pcrs | while IFS= read -r line; do | ||
| INFO "$line" | ||
| done | ||
| fi | ||
|
|
||
| # Drain any queued serial input before starting the interactive shell. | ||
| # This avoids stale bytes being interpreted as bash commands on entry. | ||
| if [ -n "$RECOVERY_TTY" ]; then | ||
| while IFS= read -r -t 0 -n 1 _junk <"$RECOVERY_TTY" 2>/dev/null; do :; done | ||
| else | ||
| while IFS= read -r -t 0 -n 1 _junk 2>/dev/null; do :; done | ||
| fi | ||
|
|
||
| STATUS "Starting recovery shell" | ||
|
|
||
| if [ -n "$RECOVERY_TTY" ]; then | ||
| setsid /bin/bash <>"$RECOVERY_TTY" >&0 2>&0 | ||
| elif [ -x /bin/setsid ]; then | ||
| /bin/setsid -c /bin/bash | ||
| else | ||
| /bin/bash | ||
| fi |
Closes #2098
Closes #2097
Closes #2096previouslly fixed in #2103Summary
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
detect_usb_security_dongle_branding()— callers that need USB (HOTP/GPG/LUKS) must callenable_usb()first. Prevents unnecessary PCR5 extensions at boot that break DUK unseal on non-HOTP boards.enable_usbat required call sites: GPG keyring init, HOTP verification, TPM reset flow2. Logging Refinement
doc/logging.mdwith clear INFO/NOTE/WARN/DEBUG usage guidance, table with sleep/blank-line columnsmeasuring_trace.logto Quiet mode tablepcrs()formatting fix: filtersha256:header from TPM2 pcrread output3. TPM Sealing & Counter Increment Fixes
TPM1:
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 withset +e, checking both exit code and "illegal index" output._tpm1_auth_retryshared helper: re-prompts and retries up to 3 times on authorization failures, eliminating duplicate retry logic between counter create and incrementtpm1_counter_create,tpm1_counter_read,tpm1_counter_incrementwrapper functionstpm1_sealNVRAM define+write retry loop (consistent withtpm2_seal)TPM2:
nvincrement(NV index auth) path was lost. Counters created bynvdefinedefault to empty NV index auth;nvincrement -C owas using owner hierarchy auth instead, causing TPM error 0x149 (AUTH_UNAVAILABLE).tpm2_counter_incandtpm2_counter_createretry logic4. DEBUG Traces at Boot Chain Decision Points
init,gui-init.sh,key-init.sh,seal-hotpkey.sh,kexec-unseal-key.sh,kexec-boot.sh,functions.sh(preflight), andgui_functions.shcheck_tpm_counter→prompt_update_checksumstargeted error message,update_totpmenu bypass,show_tpm_totp_hotp_options_menubypassdoc/tpm.mdanddoc/ux-patterns.md5. Respawn Loop Fix
execfromcttyhackininitso thewhile truerespawn loop actually respawns on boot script exit, instead of kernel panicking when PID 1 diesScreenshots
TPM1 non-HOTP variant, normal boot (quiet mode)
TPM2 HOTP variant, normal boot (quiet mode)
TPM2 HOTP variant, normal boot (quiet mode) recovery shell access
TPM2 HOTP variant, normal boot (quiet mode), less on advertised /tmp/measuring_trace.log
Tested