NK3: use device-specific branding and PIN labels consistently across codebase

The NK3 uses 'Secrets app' terminology and has 8 PIN retry attempts (vs 3 for
older devices), but the codebase had inconsistent UX messaging that referred to
'GPG Admin PIN', 'USB security dongle', 'TOKEN', etc. instead of the actual
brand and PIN type.

Fix 1: PIN label - $prompt_message is used in all user-facing strings (status,
prompts, error messages, reminder note) with correct value: 'Secrets app' for NK3,
'GPG Admin' for older devices.

Fix 2: Dynamic attempt counting - after the default PIN trial consumes an attempt,
re-read the counter and limit user attempts to min(retries-1, 3). If the counter
read is unreliable (0 or 1), fall back to 3 attempts so the user is never
blocked from sealing. Documented with example outcomes for NK3 (8 retries) and
pre-NK3 (3 retries).

Fix 3: NK3-specific error message now references 'Secrets app PIN' instead of
'GPG Admin PIN' in the PIN reset instructions.

Fix 4: Use $DONGLE_BRAND consistently in all USB security dongle messaging
(STATUS, prompts, dialog titles, guidance strings, integrity report, DEBUG
logs, error messages, NOTES) instead of hardcoded 'USB security dongle',
'OpenPGP signing card', 'GPG security dongle', 'dongle', 'signing card',
'Dongle key'. Also replaces 'TOKEN' in hotp_state/hotp_display with
$DONGLE_BRAND so integrity report shows actual brand (e.g. 'Nitrokey 3
PRESENT' instead of 'TOKEN PRESENT').

Fix 5: Centralize branding detection in standalone script entry points:
  - gui-init.sh: already detects at boot flow entry (line ~965)
  - oem-factory-reset.sh: added detection at script start (was missing)
  - confirm_gpg_card: detects for gpg-gui.sh and kexec-sign-config.sh
  - report_integrity_measurements: detects for hotp/gpg flow
  - seal-hotpkey.sh: has its own detection at script start

Fix 6: detect_usb_security_dongle_branding now guards against redundant
re-detection while preserving USB init safety: it skips USB re-init and lsusb
re-scan only when a specific DONGLE_BRAND is already set and _USB_ENABLED=y in
the current process. In child scripts that inherit DONGLE_BRAND but reset
_USB_ENABLED, it still runs enable_usb, then returns without re-scan if
branding is already specific.

Fix 7: Comment casing fix in oem-factory-reset.sh (Secrets App -> Secrets app)
to match user-facing strings and hotp_verification output.

Fix 8: Remove duplicate show_pin_retries call before PIN entry loop in
seal-hotpkey.sh. The function was being called twice before the first prompt
(once before the loop, once at loop start), showing 'Nitrokey 3 Secrets app
PIN retries remaining: 8' twice.

Fix 9: Clarify and enforce fast-path behavior for
detect_usb_security_dongle_branding in mixed parent/child script contexts:
avoid redundant module loads and scans in the same process, but do not skip USB
initialization when only branding is inherited.

Fix 10: detect_usb_security_dongle_branding now reuses wait_for_usb_devices
after enable_usb only when USB was not already initialized in the current
process. This avoids early lsusb enumeration races without regressing the
no-redundant-load/no-re-scan fast path.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion
2026-04-16 23:15:42 -04:00
parent 98249ebcc2
commit bd0f786c4d
5 changed files with 122 additions and 54 deletions
+9 -9
View File
@@ -249,17 +249,17 @@ gate_reseal_with_integrity_report() {
# starting the NK3 CCID teardown. This safety call covers the
# case where scdaemon was restarted between then and now.
release_scdaemon
STATUS "Checking USB security dongle presence before sealing"
STATUS "Checking $DONGLE_BRAND presence before sealing"
DEBUG "gate_reseal_with_integrity_report: checking HOTP token presence"
if hotp_verification info >/dev/null 2>&1; then
token_ok="y"
STATUS_OK "USB security dongle present and accessible"
STATUS_OK "$DONGLE_BRAND present and accessible"
break
fi
DEBUG "gate_reseal_with_integrity_report: HOTP token not accessible"
if ! whiptail_warning --title "USB Security Dongle Required" \
if ! whiptail_warning --title "$DONGLE_BRAND Required" \
--yes-button "Retry" --no-button "Abort" \
--yesno "Your USB security dongle must be present before sealing new secrets.\n\nInsert the dongle and choose Retry, or Abort." 0 80; then
--yesno "Your $DONGLE_BRAND must be present before sealing new secrets.\n\nInsert the dongle and choose Retry, or Abort." 0 80; then
return 1
fi
done
@@ -292,7 +292,7 @@ generate_totp_hotp() {
if [ -x /bin/hotp_verification ]; then
# If we have a TPM and a HOTP USB Security dongle
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then
INPUT "Once you have scanned the QR code, press Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)"
INPUT "Once you have scanned the QR code, press Enter to configure your $DONGLE_BRAND"
fi
TRACE_FUNC
/bin/seal-hotpkey.sh || DIE "Failed to generate HOTP secret"
@@ -314,11 +314,11 @@ prompt_missing_gpg_key_action() {
TRACE_FUNC
local retry_label retry_msg
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" = "y" ]; then
retry_label=' Retry (insert signing card or backup USB drive)'
retry_msg="Cannot sign /boot because no private GPG signing key is available (card not inserted, wiped, or key not set up).\n\nInsert your signing card or backup USB drive and retry.\n\nHow would you like to proceed?"
retry_label=" Retry (insert $DONGLE_BRAND or backup USB drive)"
retry_msg="Cannot sign /boot because no private GPG signing key is available ($DONGLE_BRAND not inserted, wiped, or key not set up).\n\nInsert your $DONGLE_BRAND or backup USB drive and retry.\n\nHow would you like to proceed?"
else
retry_label=' Retry (after connecting the correct signing card)'
retry_msg="Cannot sign /boot because no private GPG signing key is available (card not inserted, wiped, or key not set up).\n\nIf you have the correct signing card, insert it and retry.\n\nHow would you like to proceed?"
retry_label=" Retry (after connecting $DONGLE_BRAND)"
retry_msg="Cannot sign /boot because no private GPG signing key is available ($DONGLE_BRAND not inserted, wiped, or key not set up).\n\nInsert your $DONGLE_BRAND and retry.\n\nHow would you like to proceed?"
fi
whiptail_error --title "ERROR: GPG signing key unavailable" \
--menu "$retry_msg" 0 80 4 \
+10 -6
View File
@@ -23,6 +23,10 @@ rm -f /tmp/hotpkey_fw_shown
TRACE_FUNC
# Enable USB and detect branding early — $DONGLE_BRAND is used throughout this script.
enable_usb
detect_usb_security_dongle_branding
# use TERM to exit on error
trap "exit 1" TERM
export TOP_PID=$$
@@ -180,7 +184,7 @@ reset_nk3_secret_app() {
else
error_code=$?
if [ $error_code -eq 3 ] && [ $attempt -lt 3 ]; then
whiptail_warning --msgbox "Nitrokey 3 requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "Nk3 secrets app reset attempt: $attempt/3"
whiptail_warning --msgbox "$DONGLE_BRAND requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "$DONGLE_BRAND secrets app reset attempt: $attempt/3"
else
whiptail_error_die "Nitrokey 3's Secrets app reset failed with error:$error_code. Contact Nitrokey support"
fi
@@ -1043,7 +1047,7 @@ usb_security_token_capabilities_check() {
DONGLE_FW_VERSION="$(echo "$hotp_token_info" | grep "Firmware:" | sed 's/.*: *//')"
case "$DONGLE_FW_VERSION" in v*) ;; *) DONGLE_FW_VERSION="v$DONGLE_FW_VERSION" ;; esac
fi
DEBUG "Dongle firmware version: $DONGLE_FW_VERSION"
DEBUG "$DONGLE_BRAND firmware version: $DONGLE_FW_VERSION"
fi
fi
}
@@ -1222,7 +1226,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
INPUT "Enter desired NK3 Secrets app PIN / GPG Admin PIN (6-${MAX_HOTP_GPG_PIN_LENGTH} chars):" -r ADMIN_PIN
done
else
NOTE "GPG Admin PIN: management tasks on USB Security dongle, seal measurements under HOTP. 3 attempts max, locks Admin out. DO NOT FORGET. Recommended: 2 words"
NOTE "GPG Admin PIN: management tasks on $DONGLE_BRAND, seal measurements under HOTP. 3 attempts max, locks Admin out. DO NOT FORGET. Recommended: 2 words"
while [[ ${#ADMIN_PIN} -lt 6 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do
INPUT "Enter desired GPG Admin PIN (6-${MAX_HOTP_GPG_PIN_LENGTH} chars):" -r ADMIN_PIN
done
@@ -1320,10 +1324,10 @@ fi
if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then
enable_usb
if ! gpg --card-status >/dev/null 2>&1; then
local_whiptail_error "Can't access USB Security dongle; \nPlease remove and reinsert, then press Enter."
local_whiptail_error "Can't access $DONGLE_BRAND; \nPlease remove and reinsert, then press Enter."
if ! gpg --card-status >/dev/null 2>/tmp/error; then
ERROR=$(tail -n 1 /tmp/error | fold -s)
whiptail_error_die "Unable to detect USB Security dongle:\n\n${ERROR}"
whiptail_error_die "Unable to detect $DONGLE_BRAND:\n\n${ERROR}"
fi
fi
@@ -1605,7 +1609,7 @@ if [ "$CONFIG_TPM" = "y" ]; then
passphrases+="TPM Owner Passphrase: ${TPM_PASS}\n"
fi
#if nk3 detected, we add the NK3 Secrets App PIN
#if nk3 detected, we add the NK3 Secrets app PIN
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
passphrases+="Nitrokey 3 Secrets app PIN: ${ADMIN_PIN}\n"
fi
+56 -12
View File
@@ -88,7 +88,8 @@ DEBUG "Signature key was created at $(date -d "@$gpg_key_create_time")"
now_date="$(date '+%s')"
# Get the number of HOTP related PIN retry attempts remaining.
# NK3 uses "Secrets app PIN counter"; all pre-NK3 devices use "Card counters: Admin".
# NK3 uses "Secrets app PIN counter" (factory default: 8 attempts);
# all pre-NK3 devices use "Card counters: Admin" (factory default: 3 attempts).
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
admin_pin_retries=$(echo "$hotp_token_info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ')
prompt_message="Secrets app"
@@ -103,6 +104,8 @@ DEBUG "HOTP related PIN retry counter is $admin_pin_retries"
hotpkey_fw_display "$hotp_token_info" "$DONGLE_BRAND"
# Re-query and display the current PIN retry counter before each manual prompt.
# Updates the global $admin_pin_retries (no local keyword) so callers can use
# the fresh value for decisions (e.g. max_attempts calculation below).
# prompt_message is already set for the device type (NK3 vs older), reuse it.
show_pin_retries() {
local info
@@ -113,7 +116,7 @@ show_pin_retries() {
admin_pin_retries=$(echo "$info" | grep "Card counters: Admin" | grep -o 'Admin [0-9]*' | grep -o '[0-9]*')
fi
admin_pin_retries="${admin_pin_retries:-0}"
STATUS "$DONGLE_BRAND GPG Admin PIN retries remaining: $(pin_color "$admin_pin_retries")${admin_pin_retries}\033[0m"
STATUS "$DONGLE_BRAND ${prompt_message} PIN retries remaining: $(pin_color "$admin_pin_retries")${admin_pin_retries}\033[0m"
}
# Try using factory default admin PIN for 1 month following OEM reset to ease
@@ -131,7 +134,7 @@ if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then
elif [ "$admin_pin_retries" -lt 3 ]; then
DEBUG "Not trying default PIN ($admin_pin): only $admin_pin_retries attempt(s) left"
else
STATUS "Trying GPG Admin PIN to seal HOTP secret on $DONGLE_BRAND"
STATUS "Trying ${prompt_message} PIN to seal HOTP secret on $DONGLE_BRAND"
# NK3 requires physical touch confirmation for the initialize operation
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
NOTE "Nitrokey 3 requires physical presence: touch the dongle when prompted"
@@ -144,30 +147,71 @@ fi
if [ "$admin_pin_status" -ne 0 ]; then
# If the default PIN was tried and failed, we consumed 1 attempt.
# Re-read the counter and limit user attempts accordingly.
# Leave at least 1 attempt unconsumed to avoid accidental lockout.
#
# max_attempts calculation:
# - Read current retry counter (may be lower if default PIN consumed 1)
# - Subtract 1 to preserve one final attempt for the user
# - Cap at 3 to match the pre-NK3 factory default, so the user experience
# is consistent regardless of device.
# - If the counter read is unreliable (0 or 1), fall back to 3 attempts
# so the user is never blocked from sealing.
#
# Example outcomes for NK3 (factory default: 8):
# Default PIN skipped (key >1 month old) -> max_attempts = min(8-1, 3) = 3
# Default PIN tried & failed (8 -> 7 remaining) -> max_attempts = min(7-1, 3) = 3
# Default PIN tried & failed (4 -> 3 remaining) -> max_attempts = min(3-1, 3) = 2
# Default PIN tried & failed (2 -> 1 remaining) -> max_attempts = 3 (fallback, don't block)
# Counter read failed (0 or empty) -> max_attempts = 3 (fallback, don't block)
#
# Example outcomes for pre-NK3 (factory default: 3):
# Default PIN skipped (key >1 month old) -> max_attempts = min(3-1, 3) = 2
# Default PIN tried & failed (3 -> 2 remaining) -> max_attempts = min(2-1, 3) = 1
# Counter read failed (0 or empty) -> max_attempts = 3 (fallback, don't block)
# Re-read counter without displaying (loop will show it)
info="$(hotp_verification info 2>/dev/null)" || true
if [ "$DONGLE_BRAND" = "Nitrokey 3" ]; then
admin_pin_retries=$(echo "$info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ')
else
admin_pin_retries=$(echo "$info" | grep "Card counters: Admin" | grep -o 'Admin [0-9]*' | grep -o '[0-9]*')
fi
admin_pin_retries="${admin_pin_retries:-0}"
if [ "$admin_pin_retries" -ge 2 ]; then
max_attempts=$((admin_pin_retries - 1))
[ "$max_attempts" -gt 3 ] && max_attempts=3
else
max_attempts=3
fi
# prompt user for PIN; re-query counter before each attempt so the user
# sees the decremented count after a wrong PIN (same pattern as kexec-sign-config.sh)
for tries in 1 2 3; do
for tries in $(seq 1 $max_attempts); do
show_pin_retries
if [ "$tries" -eq 1 ]; then
INPUT "Enter your $DONGLE_BRAND GPG Admin PIN (attempt $tries/3):" -r -s admin_pin
INPUT "Enter your $DONGLE_BRAND ${prompt_message} PIN (attempt $tries/$max_attempts):" -r -s admin_pin
else
INPUT "Wrong PIN - re-enter your $DONGLE_BRAND GPG Admin PIN (attempt $tries/3):" -r -s admin_pin
INPUT "Wrong PIN - re-enter your $DONGLE_BRAND ${prompt_message} PIN (attempt $tries/$max_attempts):" -r -s admin_pin
fi
if hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$DONGLE_BRAND"; then
break
fi
if [ "$tries" -eq 3 ]; then
if [ "$tries" -eq "$max_attempts" ]; then
# don't leak key on failure
shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null
case "$DONGLE_BRAND" in
"Nitrokey Pro" | "Nitrokey Storage" | "Nitrokey 3")
DIE "Setting HOTP secret on $DONGLE_BRAND failed after 3 attempts. To reset GPG Admin PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
"Nitrokey 3")
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset ${prompt_message} PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
;;
"Nitrokey Pro" | "Nitrokey Storage")
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset GPG Admin PIN: redo Re-Ownership, or use Nitrokey App 2, or contact Nitrokey support."
;;
"Librem Key")
DIE "Setting HOTP secret on $DONGLE_BRAND failed after 3 attempts. To reset GPG Admin PIN: redo Re-Ownership or contact Purism support."
DIE "Setting HOTP secret on $DONGLE_BRAND failed after $max_attempts attempts. To reset GPG Admin PIN: redo Re-Ownership or contact Purism support."
;;
*)
DIE "Setting HOTP secret failed after 3 attempts"
DIE "Setting HOTP secret failed after $max_attempts attempts"
;;
esac
fi
@@ -175,7 +219,7 @@ if [ "$admin_pin_status" -ne 0 ]; then
else
# Default PIN was accepted — security reminder, not a fatal error.
# NOTE prints blank lines before/after and is always visible; no INPUT needed.
NOTE "Default GPG Admin PIN detected. Change it via Options --> OEM Factory Reset / Re-Ownership."
NOTE "Default ${prompt_message} PIN detected. Change it via Options --> OEM Factory Reset / Re-Ownership."
fi
# HOTP key no longer needed
+19 -1
View File
@@ -500,6 +500,22 @@ pin_color() {
# 1050:0404 Yubikey 5 (FIDO+CCID)
detect_usb_security_dongle_branding() {
TRACE_FUNC
local usb_was_enabled="${_USB_ENABLED:-n}"
# Fast path: avoid USB re-init and lsusb scan when branding is already known
# and USB has already been initialized in this process.
if [ "$DONGLE_BRAND" != "USB Security dongle" ] \
&& [ -n "$DONGLE_BRAND" ] \
&& [ "$usb_was_enabled" = "y" ]; then
return
fi
# 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 branding is already specific, USB is now ready and no re-scan is needed.
[ "$DONGLE_BRAND" != "USB Security dongle" ] && [ -n "$DONGLE_BRAND" ] && return
local lsusb_out
lsusb_out="$(lsusb)"
DEBUG "lsusb output: $lsusb_out"
@@ -644,7 +660,7 @@ cache_gpg_signing_pin() {
# keystrokes from previous prompts cannot silently satisfy this read.
local card_confirm=""
if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then
INPUT "Use your GPG security dongle (Enter/y) or backup thumb drive (b)? [Y/b]:" -n 1 -r card_confirm
INPUT "Use your $DONGLE_BRAND (Enter/y) or backup thumb drive (b)? [Y/b]:" -n 1 -r card_confirm
while [ "$card_confirm" != "y" \
-a "$card_confirm" != "Y" \
-a "$card_confirm" != "b" \
@@ -831,6 +847,8 @@ cache_gpg_signing_pin() {
}
confirm_gpg_card() {
enable_usb
detect_usb_security_dongle_branding
cache_gpg_signing_pin "$@"
}
+28 -26
View File
@@ -253,6 +253,10 @@ report_integrity_measurements() {
DEBUG "integrity report generated at $date_now"
STATUS "Preparing Measured Integrity Report - hashing and verifying /boot"
# Detect branding and initialize USB (detect_usb_security_dongle_branding calls
# enable_usb internally and guards against redundant re-detection).
detect_usb_security_dongle_branding
if [ "$CONFIG_TPM" = "y" ]; then
totp_state="UNAVAILABLE"
if [ "$CONFIG_TPM2_TOOLS" != "y" ] || [ -f /tmp/secret/primary.handle ]; then
@@ -271,21 +275,19 @@ report_integrity_measurements() {
fi
if [ -x /bin/hotp_verification ]; then
enable_usb
STATUS "Checking USB security dongle presence"
local _dongle_brand _hotp_info
_dongle_brand="$(detect_usb_security_dongle_branding)"
STATUS "Checking $DONGLE_BRAND presence"
local _hotp_info
DEBUG "report_integrity_measurements: querying HOTP token info"
if _hotp_info="$(hotp_verification info 2>/dev/null)"; then
hotp_state="TOKEN PRESENT"
STATUS_OK "USB security dongle detected"
hotpkey_fw_display "$_hotp_info" "$_dongle_brand"
elif [ "$_dongle_brand" != "USB Security dongle" ]; then
hotp_state="TOKEN INCOMPATIBLE"
DEBUG "report_integrity_measurements: $_dongle_brand detected but HOTP verification failed"
hotp_state="$DONGLE_BRAND PRESENT"
STATUS_OK "$DONGLE_BRAND detected"
hotpkey_fw_display "$_hotp_info" "$DONGLE_BRAND"
elif [ "$DONGLE_BRAND" != "USB Security dongle" ]; then
hotp_state="$DONGLE_BRAND INCOMPATIBLE"
DEBUG "report_integrity_measurements: $DONGLE_BRAND detected but HOTP verification failed"
else
hotp_state="TOKEN MISSING"
DEBUG "report_integrity_measurements: hotp_verification info failed, hotp_state=TOKEN MISSING"
hotp_state="$DONGLE_BRAND MISSING"
DEBUG "report_integrity_measurements: hotp_verification info failed, hotp_state=$hotp_state"
fi
fi
@@ -351,7 +353,7 @@ report_integrity_measurements() {
# Check signing key: try card immediately (USB already up); only prompt if not accessible.
# wait_for_gpg_card sets global gpg_output to the card-status output on success.
STATUS "Verifying OpenPGP signing key on USB security dongle"
STATUS "Verifying signing key on $DONGLE_BRAND"
enable_usb
gpg_output=""
local _card_detected=0
@@ -359,7 +361,7 @@ report_integrity_measurements() {
_card_detected=1
else
whiptail_type "$BG_COLOR_MAIN_MENU" --title 'Signing Card Check' \
--msgbox "Please insert your OpenPGP signing card (USB security key), then press OK." 0 80
--msgbox "Please insert your $DONGLE_BRAND and press OK." 0 80
if wait_for_gpg_card 2>/dev/null; then
_card_detected=1
fi
@@ -368,14 +370,14 @@ report_integrity_measurements() {
# Determine signing key state from card-status output (gpg_output set by wait_for_gpg_card).
local _card_sig_fpr _rom_fprs signing_key_guidance
if [ "$_card_detected" -eq 0 ]; then
signing_key_state="NO DONGLE DETECTED"
signing_key_guidance="No USB security dongle detected. Insert the correct dongle and retry, or perform OEM Factory Reset / Re-Ownership."
signing_key_state="NO $DONGLE_BRAND DETECTED"
signing_key_guidance="No $DONGLE_BRAND detected. Insert the correct dongle and retry, or perform OEM Factory Reset / Re-Ownership."
else
_card_sig_fpr=$(echo "$gpg_output" |
awk -F: '/Signature key/ {gsub(/[[:space:]]/,"",$2); print $2; exit}')
if [ -z "$_card_sig_fpr" ] || [ "$_card_sig_fpr" = "[none]" ]; then
signing_key_state="DONGLE NOT PROVISIONED"
signing_key_guidance="USB security dongle is connected but has no signing key (unprovisioned or wiped). Provision the dongle with the signing subkey, or perform OEM Factory Reset / Re-Ownership to start fresh with a new key."
signing_key_guidance="$DONGLE_BRAND is connected but has no signing key (unprovisioned or wiped). Provision the dongle with the signing subkey, or perform OEM Factory Reset / Re-Ownership to start fresh with a new key."
else
_rom_fprs=$(gpg --with-colons --list-keys 2>/dev/null |
awk -F: '/^fpr/ {print $10}')
@@ -384,7 +386,7 @@ report_integrity_measurements() {
signing_key_guidance=""
else
signing_key_state="DONGLE KEY NOT ROM-TRUSTED"
signing_key_guidance="USB security dongle has a signing key that does not match this firmware's trusted key. OEM Factory Reset / Re-Ownership is required to establish new trusted ownership."
signing_key_guidance="$DONGLE_BRAND has a signing key that does not match this firmware's trusted key. OEM Factory Reset / Re-Ownership is required to establish new trusted ownership."
fi
fi
fi
@@ -404,14 +406,14 @@ report_integrity_measurements() {
;;
esac
case "$hotp_state" in
"TOKEN MISSING")
hotp_display="TOKEN NOT CONNECTED"
*"MISSING")
hotp_display="$DONGLE_BRAND NOT CONNECTED"
;;
"TOKEN PRESENT")
hotp_display="TOKEN CONNECTED (presence confirmed)"
*"PRESENT")
hotp_display="$DONGLE_BRAND CONNECTED (presence confirmed)"
;;
"TOKEN INCOMPATIBLE")
hotp_display="TOKEN INCOMPATIBLE ($_dongle_brand does not support HOTP)"
*"INCOMPATIBLE")
hotp_display="$DONGLE_BRAND INCOMPATIBLE ($DONGLE_BRAND does not support HOTP)"
;;
*)
hotp_display="$hotp_state"
@@ -424,7 +426,7 @@ report_integrity_measurements() {
else
action_guidance="$sig_guidance"
fi
report_body="Date: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\nDongle key: $signing_key_state\n\nAction: $action_guidance"
report_body="Date: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\n$DONGLE_BRAND key: $signing_key_state\n\nAction: $action_guidance"
if [ "$hash_state" != "OK" ]; then
report_body="$report_body\n\nIf /boot integrity is not OK, investigate before sealing new secrets or performing TPM reset or re-ownership."
fi
@@ -438,7 +440,7 @@ report_integrity_measurements() {
fi
msg="Measured Integrity Report\n\n$report_body"
# menu_msg omits the guidance paragraphs to keep the dialog within terminal height
menu_msg="Measured Integrity Report\n\nDate: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\nDongle key: $signing_key_state\n\nChoose an action:"
menu_msg="Measured Integrity Report\n\nDate: $date_now\nTOTP: $totp_display\nHOTP: $hotp_display\n\nBoot signature (/boot/kexec.sig): $signature_state\n$sig_detail\nBoot files: $hash_state\n$DONGLE_BRAND key: $signing_key_state\n\nChoose an action:"
if [ "$hash_state" = "OK" ] && [ "$signing_key_state" = "DONGLE MATCHES ROM-TRUSTED KEY" ]; then
whiptail_type $BG_COLOR_MAIN_MENU --title 'Measured Integrity Report' \