From 496d93031ec61f03f1e18109bd617c121868655c Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 27 Nov 2024 11:54:58 -0500 Subject: [PATCH 01/81] qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet board: addition of board containing 'export CONFIG_QUIET_MODE=y' for output comparison between debug, prod and quiet mode Signed-off-by: Thierry Laurion --- ...oot-fbwhiptail-tpm2-hotp-prod_quiet.config | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config new file mode 100644 index 000000000..cf8491f58 --- /dev/null +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config @@ -0,0 +1,99 @@ +# Configuration for building a coreboot ROM that works in +# the qemu emulator in graphical mode thanks to FBWhiptail +# This version requires a supported HOTP Security dongle (Nitrokey Pro/Storage or Librem Key) +# +# TPM can be used with a qemu software TPM (TIS, 2.0). +export CONFIG_COREBOOT=y +export CONFIG_COREBOOT_VERSION=24.02.01 +export CONFIG_LINUX_VERSION=6.1.8 + +CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm2-prod.config +CONFIG_LINUX_CONFIG=config/linux-qemu.config + +#Enable only one RESTRICTED/BASIC boot modes below to test them manually (we cannot inject config under QEMU (no internal flashing) +#export CONFIG_RESTRICTED_BOOT=y +#export CONFIG_BASIC=y + +#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) +#export CONFIG_HAVE_GPG_KEY_BACKUP=y + +#Enable DEBUG output +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=y + +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y + +#On-demand hardware support (modules.cpio) +CONFIG_LINUX_USB=y +CONFIG_LINUX_E1000=y +#CONFIG_MOBILE_TETHERING=y +#Runtime on-demand additional hardware support (modules.cpio) +export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y + + + +#Modules packed into tools.cpio +ifeq "$(CONFIG_UROOT)" "y" +CONFIG_BUSYBOX=n +else +#Modules packed into tools.cpio +CONFIG_CRYPTSETUP2=y +CONFIG_FLASHPROG=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +#Runtime tools to write to MSR +CONFIG_MSRTOOLS=y +#Remote attestation support +# TPM2 requirements +CONFIG_TPM2_TSS=y +CONFIG_OPENSSL=y +#Remote Attestation common tools +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y +#HOTP based remote attestation for supported USB Security dongle +#With/Without TPM support +CONFIG_HOTPKEY=y +#Nitrokey Storage admin tool (deprecated) +#CONFIG_NKSTORECLI=n +#GUI Support +#Console based Whiptail support(Console based, no FB): +#CONFIG_SLANG=y +#CONFIG_NEWT=y +#FBWhiptail based (Graphical): +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y +#Additional tools (tools.cpio): +#SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) +CONFIG_DROPBEAR=y +endif + +#Runtime configuration +#Automatically boot if HOTP is valid +export CONFIG_AUTO_BOOT_TIMEOUT=5 +#TPM2 requirements +export CONFIG_TPM2_TOOLS=y +export CONFIG_PRIMARY_KEY_TYPE=ecc +#TPM1 requirements +#export CONFIG_TPM=y +export CONFIG_BOOTSCRIPT=/bin/gui-init +#text-based original init: +#export CONFIG_BOOTSCRIPT=/bin/generic-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_RECOVERY_SERIAL="/dev/ttyS0" +export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" +export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" +export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2-hotp" +#export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" +export CONFIG_AUTO_BOOT_TIMEOUT=5 + +BOARD_TARGETS := qemu From 1f029123e9a501a513352b6b97351251e405085a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 27 Nov 2024 10:38:37 -0500 Subject: [PATCH 02/81] initrd bin/* sbin/insmod + /etc/ash_functions: TPM extend operations now all passed to LOG (quiet mode doesn't show them and logs them to /tmp/debug.log) Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 6 ++---- initrd/bin/kexec-insert-key | 2 +- initrd/bin/kexec-select-boot | 2 +- initrd/bin/qubes-measure-luks | 2 +- initrd/bin/tpmr | 6 +++--- initrd/etc/ash_functions | 13 +++++++++++-- initrd/sbin/insmod | 6 +++--- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index c54991f41..d89effe5e 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -17,12 +17,12 @@ for cbfsname in `echo $cbfsfiles`; do if [ ! -z "$filename" ]; then mkdir -p `dirname $filename` \ || die "$filename: mkdir failed" - echo "Extracting CBFS file $cbfsname into $filename" + LOG "Extracting CBFS file $cbfsname into $filename" cbfs -t 50 $CBFS_ARG -r $cbfsname > "$filename" \ || die "$filename: cbfs file read failed" if [ "$CONFIG_TPM" = "y" ]; then TRACE_FUNC - echo "TPM: Extending PCR[$CONFIG_PCR] with $filename" + LOG "TPM: Extending PCR[$CONFIG_PCR] with filename $filename and then its content" # Measure both the filename and its content. This # ensures that renaming files or pivoting file content # will still affect the resulting PCR measurement. @@ -32,5 +32,3 @@ for cbfsname in `echo $cbfsfiles`; do fi fi done - -# TODO: copy CBFS file named "heads/initrd.tgz" to /tmp, measure and extract diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 0028e348e..ca5db6a57 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -66,7 +66,7 @@ fi # Override PCR 4 so that user can't read the key TRACE_FUNC -echo "TPM: Extending PCR[4] to prevent any future secret unsealing" +LOG "TPM: Extending PCR[4] to prevent any future secret unsealing" tpmr extend -ix 4 -ic generic || die 'Unable to scramble PCR' diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index b3b55c302..bdda8aaf8 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -385,7 +385,7 @@ while true; do if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible TRACE_FUNC - DEBUG "TPM: Extending PCR[4] to prevent further secret unsealing" + LOG "TPM: Extending PCR[4] to prevent further secret unsealing" tpmr extend -ix 4 -ic generic || die "Failed to extend TPM PCR[4]" fi diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index bef6fb102..cc94c9c81 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -20,6 +20,6 @@ DEBUG "Removing /tmp/lukshdr-*" rm /tmp/lukshdr-* TRACE_FUNC -echo "TPM: Extending PCR[6] with hash of LUKS headers from /tmp/luksDump.txt" +LOG "TPM: Extending PCR[6] with hash of LUKS headers from /tmp/luksDump.txt" tpmr extend -ix 6 -if /tmp/luksDump.txt || die "Unable to extend PCR" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 78b71ea1f..5adb48253 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -258,7 +258,7 @@ tpm2_extend() { esac done tpm2 pcrextend "$index:sha256=$hash" - tpm2 pcrread "sha256:$index" + LOG $(tpm2 pcrread "sha256:$index" 2>&1) TRACE_FUNC DEBUG "TPM: Extended PCR[$index] with hash $hash" @@ -786,7 +786,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then fi TRACE_FUNC - DEBUG "TPM: Extending PCR[$3] with hash $hash" + LOG "TPM: Extending PCR[$3] with hash $hash" DO_WITH_DEBUG exec tpm "$@" ;; seal) @@ -828,7 +828,7 @@ calcfuturepcr) ;; extend) TRACE_FUNC - DEBUG "TPM: Extending PCR[$2] with $4" + LOG "TPM: Extending PCR[$2] with $4" tpm2_extend "$@" ;; counter_read) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index bf2e32896..735c8760c 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -39,7 +39,16 @@ TRACE() { # Write directly to the debug log (but not kmsg), never appears on console LOG() { - echo "LOG: $*" >>/tmp/debug.log + # if not CONFIG_QUIET_MODE=y, output to console. If not, output to debug.log + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + DEBUG "$*" + elif [ "$CONFIG_QUIET_MODE" = "y" ]; then + # if in quiet mode, output solely to debug.log + echo "$*" >> /tmp/debug.log + else + # if not in quiet mode, output to console + echo "$*" + fi } fw_version() { @@ -241,7 +250,7 @@ recovery() { DEBUG "Board $CONFIG_BOARD - version $(fw_version)" if [ "$CONFIG_TPM" = "y" ]; then - echo "TPM: Extending PCR[4] to prevent any further secret unsealing" + LOG "TPM: Extending PCR[4] to prevent any further secret unsealing" tpmr extend -ix 4 -ic recovery fi diff --git a/initrd/sbin/insmod b/initrd/sbin/insmod index 359bf68f6..95e2303c6 100755 --- a/initrd/sbin/insmod +++ b/initrd/sbin/insmod @@ -39,19 +39,19 @@ if [ ! -r /sys/class/tpm/tpm0/pcrs -o ! -x /bin/tpm ]; then fi if [ -z "$tpm_missing" ]; then - echo "TPM: Extending PCR[$MODULE_PCR] with $MODULE and parameters '$*' before loading" + LOG "TPM: Extending PCR[$MODULE_PCR] with $MODULE and parameters '$*' before loading" # Extend with the module parameters (even if they are empty) and the # module. Changing the parameters or the module content will result in a # different PCR measurement. if [ -n "$*" ]; then TRACE_FUNC - DEBUG "Extending with module parameters and the module's content" + LOG "Extending with module parameters and the module's content" tpmr extend -ix "$MODULE_PCR" -ic "$*" tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ || die "$MODULE: tpm extend failed" else TRACE_FUNC - DEBUG "No module parameters, extending only with the module's content" + LOG "No module parameters, extending only with the module's content" tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ || die "$MODULE: tpm extend failed" fi From 9cd4757e4a36d2450f7280f1d77f01c9b6fb671d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 27 Nov 2024 13:17:56 -0500 Subject: [PATCH 03/81] init: suppress /etc/config.user not existing on grep calls Signed-off-by: Thierry Laurion --- initrd/init | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/initrd/init b/initrd/init index 55a894a79..6959424e3 100755 --- a/initrd/init +++ b/initrd/init @@ -125,6 +125,7 @@ if [ "$CONFIG_LINUXBOOT" = "y" ]; then fi # Set GPG_TTY before calling gpg in key-init +#TODO: do better then this; on dual console gpg only interacts with main console (affects Talos-2 and all whiptail variants) export GPG_TTY=/dev/console # Initialize gpnupg with distro/user keys and setup the keyrings @@ -144,10 +145,10 @@ fi # changing the value for the rest of the scripts which source /tmp/config. #Only set CONFIG_TPM and CONFIG_TPM2_TOOLS if they are not already set in /etc/config.user -if ! grep -q 'CONFIG_TPM=' /etc/config.user; then +if ! grep -q 'CONFIG_TPM=' /etc/config.user 2>/dev/null; then echo "export CONFIG_TPM=\"$CONFIG_TPM\"" >> /etc/config.user fi -if ! grep -q 'CONFIG_TPM2_TOOLS=' /etc/config.user; then +if ! grep -q 'CONFIG_TPM2_TOOLS=' /etc/config.user 2> /dev/null; then echo "export CONFIG_TPM2_TOOLS=\"$CONFIG_TPM2_TOOLS\"" >> /etc/config.user fi From e03a7906495ae1a466b0e8817c0b4e22b50c6838 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 27 Nov 2024 13:27:13 -0500 Subject: [PATCH 04/81] init: inform user that running in quiet mode, tell user that technical information can be seen running 'cat /tmp/debug.log' from Recovery Shell Signed-off-by: Thierry Laurion --- initrd/init | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/initrd/init b/initrd/init index 6959424e3..83ea659cf 100755 --- a/initrd/init +++ b/initrd/init @@ -59,6 +59,11 @@ hwclock -l -s . /etc/ash_functions . /etc/config +# report if we are in quiet mode, tell logs available under /tmp/debug.log +if [ "$CONFIG_QUIET_MODE" = "y" ]; then + echo "Quiet mode enabled. To see technical output, do 'cat /tmp/debug.log' from Recovery Shell!" > /dev/tty0 +fi + # Board config had CONFIG_DEBUG_OUTPUT=y defined. # Note that boards's coreboot config kernel command line "debug" option only will have all kernel messages output on console prior of this point if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then From 48807de2223e315701adb0cab56c76f175043146 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 3 Dec 2024 11:22:03 -0500 Subject: [PATCH 05/81] codebase: silence dd output while capturing output in variables when needed Signed-off-by: Thierry Laurion --- initrd/bin/inject_firmware.sh | 2 +- initrd/bin/tpmr | 8 ++++---- initrd/bin/unpack_initramfs.sh | 2 +- initrd/mount-boot | 2 +- targets/qemu.mk | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/initrd/bin/inject_firmware.sh b/initrd/bin/inject_firmware.sh index 0de9e33c1..f9e6556e6 100755 --- a/initrd/bin/inject_firmware.sh +++ b/initrd/bin/inject_firmware.sh @@ -96,7 +96,7 @@ chmod a+x "$INITRD_ROOT/init" # Linux ignores zeros between archive segments, so any extra padding is not # harmful. FW_INITRD="/tmp/inject_firmware_initrd.cpio.gz" -dd if="$ORIG_INITRD" of="$FW_INITRD" bs=512 conv=sync status=none +dd if="$ORIG_INITRD" of="$FW_INITRD" bs=512 conv=sync status=none > /dev/null 2>&1 # Pack up the new contents and append to the initrd. Don't spend time # compressing this. (cd "$INITRD_ROOT"; find . | cpio -o -H newc) >>"$FW_INITRD" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 5adb48253..5d8a59531 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -332,7 +332,7 @@ tpm2_counter_create() { esac done prompt_tpm_owner_password - rand_index="1$(dd if=/dev/urandom bs=1 count=3 | xxd -pc3)" + rand_index="1$(dd if=/dev/urandom bs=1 count=3 2>/dev/null | xxd -pc3)" tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \ -P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/console || { @@ -412,7 +412,7 @@ tpm1_destroy() { index="$1" # Index of the sealed file size="$2" # Size of zeroes to overwrite for TPM1 - dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero + dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero > /dev/null 2>&1 tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero || die "Unable to wipe sealed secret from TPM NVRAM" } @@ -690,7 +690,7 @@ tpm2_reset() { # The default lockout password is empty, so we must set this, and we # don't need to provide any auth (use the default empty password). tpm2 changeauth -Q -c lockout \ - "hex:$(dd if=/dev/urandom bs=32 count=1 status=none | xxd -p | tr -d ' \n')" + "hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" } tpm1_reset() { TRACE_FUNC @@ -729,7 +729,7 @@ tpm2_kexec_finalize() { # being cleared in the OS. # This passphrase is only effective before the next boot. echo "Locking TPM2 platform hierarchy..." - randpass=$(dd if=/dev/urandom bs=4 count=1 status=none | xxd -p) + randpass=$(dd if=/dev/urandom bs=4 count=1 status=none 2>/dev/null | xxd -p) tpm2 changeauth -c platform "$randpass" || warn "Failed to lock platform hierarchy of TPM2" } diff --git a/initrd/bin/unpack_initramfs.sh b/initrd/bin/unpack_initramfs.sh index 772131188..4fff52f60 100755 --- a/initrd/bin/unpack_initramfs.sh +++ b/initrd/bin/unpack_initramfs.sh @@ -61,7 +61,7 @@ unpack_first_segment() { mkdir -p "$dest_dir" # peek the beginning of the file to determine what type of content is next - magic="$(dd if="$unpack_archive" bs=6 count=1 status=none | xxd -p)" + magic="$(dd if="$unpack_archive" bs=6 count=1 status=none 2>/dev/null | xxd -p)" # read this segment of the archive, then write the rest to the next file ( diff --git a/initrd/mount-boot b/initrd/mount-boot index 42e4c9ae5..be02e08d8 100755 --- a/initrd/mount-boot +++ b/initrd/mount-boot @@ -36,7 +36,7 @@ dev_blocks=`cat "$dev_size_file"` # # Extract the signed file from the hard disk image # -if ! dd if="$dev" of="$cmd_sig" bs=512 skip="`expr $dev_blocks - 1`"; then +if ! dd if="$dev" of="$cmd_sig" bs=512 skip="`expr $dev_blocks - 1`" > /dev/null 2>&1; then echo >&2 '!!!!!' echo >&2 '!!!!! Boot block extraction failed' echo >&2 '!!!!! Dropping to recovery shell' diff --git a/targets/qemu.mk b/targets/qemu.mk index d5d7dc018..5520ebcdf 100644 --- a/targets/qemu.mk +++ b/targets/qemu.mk @@ -45,7 +45,7 @@ $(MEMORY_SIZE_FILE): @echo "$(QEMU_MEMORY_SIZE)" >"$(MEMORY_SIZE_FILE)" USB_FD_IMG=$(build)/$(BOARD)/usb_fd.raw $(USB_FD_IMG): - dd if=/dev/zero bs=1M of="$(USB_FD_IMG)" bs=1M count=256 + dd if=/dev/zero bs=1M of="$(USB_FD_IMG)" bs=1M count=256 >/dev/null 2>&1 # Debian obnoxiously does not include /usr/sbin in PATH for non-root, even # though it is meaningful to use mkfs.vfat (etc.) as non-root MKFS_VFAT=mkfs.vfat; \ From 3726e9083fba7538e0fc08ce73d759c0bb83a628 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 3 Dec 2024 12:20:21 -0500 Subject: [PATCH 06/81] initrd/bin/tmpr: silence tpm reset console output, LOG instead Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 5d8a59531..65ecbe534 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -650,15 +650,15 @@ tpm2_reset() { # output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" - tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy" - tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" - tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" + tpm2 clear -c platform > /dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy" + tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change owner password" + tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change endorsement password" tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \ - -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" + -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to create primary key" tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \ - -P "$(tpm2_password_hex "$tpm_owner_password")" - shred -u "$SECRET_DIR/primary.ctx" - tpm2_startsession + -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to evict primary key" + shred -u "$SECRET_DIR/primary.ctx" > /dev/null 2>&1 + tpm2_startsession > /dev/null 2>&1 || LOG "Unable to start session" # Set the dictionary attack parameters. TPM2 defaults vary widely, we # want consistent behavior on any TPM. @@ -681,7 +681,7 @@ tpm2_reset() { --max-tries=10 \ --recovery-time=3600 \ --lockout-recovery-time=0 \ - --auth="session:$ENC_SESSION_FILE" + --auth="session:$ENC_SESSION_FILE" > /dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters" # Set a random DA lockout password, so the DA lockout can't be cleared # with a password. Heads doesn't offer dictionary attach reset, instead @@ -690,7 +690,7 @@ tpm2_reset() { # The default lockout password is empty, so we must set this, and we # don't need to provide any auth (use the default empty password). tpm2 changeauth -Q -c lockout \ - "hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" + "hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" > /dev/null 2>&1 || LOG "Unable to set lockout password" } tpm1_reset() { TRACE_FUNC @@ -700,17 +700,17 @@ tpm1_reset() { DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" # Make sure the TPM is ready to be reset - tpm physicalpresence -s - tpm physicalenable - tpm physicalsetdeactivated -c - tpm forceclear - tpm physicalenable - tpm takeown -pwdo "$tpm_owner_password" + tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence" + tpm physicalenable > /dev/null 2>&1 || >LOG "Unable to enable TPM" + tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM" + tpm forceclear -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to clear TPM" + tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM" + tpm takeown -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to take ownership of TPM" # And now turn it all back on - tpm physicalpresence -s - tpm physicalenable - tpm physicalsetdeactivated -c + tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence" + tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM" + tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM" } # Perform final cleanup before boot and lock the platform heirarchy. From d57a1209129461e6a2c58cca3c326d4260ccdb12 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 3 Dec 2024 12:48:32 -0500 Subject: [PATCH 07/81] initrd/etc/ash_functions: add GPG Admin/User PIN output grabbing on confirm_gpg_card presence call, echo for now, warn to input GPG User PIN when asked to unlock GPG card Mitigate misunderstands and show GPG User/Admin PIN counts until proper output exists under hotp_verification info to reduce global confusion Add TODO under initrd/bin/seal-hotpkey to not foget to fix output since now outputting counter of 8 for Admin PIN which makes no sense at all under hotp_verification 1.6 https://github.com/Nitrokey/nitrokey-hotp-verification/issues/38 Signed-off-by: Thierry Laurion --- initrd/bin/seal-hotpkey | 1 + initrd/etc/ash_functions | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 3f91edcc9..957b94240 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -105,6 +105,7 @@ awk_get_admin_counter="$awk_admin_counter_regex"' { print gensub('"$awk_admin_co admin_pin_retries="$(echo "$hotp_token_info" | awk "$awk_get_admin_counter")" admin_pin_retries="${admin_pin_retries:-0}" DEBUG "Admin PIN retry counter is $admin_pin_retries" +#TODO: as per hotp_verification 1.6: this is 8 for nk3 and wrong. FIX # Try using factory default admin PIN for 1 month following OEM reset to ease # initial setup. But don't do it forever to encourage changing the PIN and diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 735c8760c..c0182002a 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -154,7 +154,7 @@ confirm_gpg_card() { # ensure we don't exit without retrying errexit=$(set -o | grep errexit | awk '{print $2}') set +e - gpg --card-status >/dev/null + gpg_output=$(gpg --card-status 2>&1) if [ $? -ne 0 ]; then # prompt for reinsertion and try a second time read -n1 -r -p \ @@ -165,13 +165,26 @@ confirm_gpg_card() { set -e fi # retry card status - gpg --card-status >/dev/null || + gpg_output=$(gpg --card-status 2>&1) || die "gpg card read failed" fi # restore prev errexit state if [ "$errexit" = "on" ]; then set -e fi + + # Extract and display GPG PIN retry counters + # output excerpt: "PIN retry counter : 3 0 3" + pin_retry_counters=$(echo "$gpg_output" | grep 'PIN retry counter' | awk -F': ' '{print $2}') + user_pin_retries=$(echo "$pin_retry_counters" | awk '{print $1}') + admin_pin_retries=$(echo "$pin_retry_counters" | awk '{print $3}') + + echo "" + echo "GPG User PIN retry attempts left before becoming locked: $user_pin_retries" + echo "GPG Admin PIN retry attempts left before becoming locked: $admin_pin_retries" + echo "" + warn "Your GPG User PIN, followed by Enter key will be required for input at: 'Please unlock the card' next prompt" + echo "" } gpg_auth() { From befef09b7f02330e5cbdc0bea1f3bcbbebfe34fe Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 15 Nov 2024 15:46:51 -0500 Subject: [PATCH 08/81] diceware: add short list v2, requiring 4 dices and providing longer words then short list v1 for easier to remember passphrases This lists comes from https://www.eff.org/files/2016/09/08/eff_short_wordlist_2_0.txt Refered in article: https://www.eff.org/dice Signed-off-by: Thierry Laurion --- .../eff_short_wordlist_2_0.txt | 1296 +++++++++++++++++ 1 file changed, 1296 insertions(+) create mode 100644 initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt diff --git a/initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt b/initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt new file mode 100644 index 000000000..ae09babe4 --- /dev/null +++ b/initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt @@ -0,0 +1,1296 @@ +1111 aardvark +1112 abandoned +1113 abbreviate +1114 abdomen +1115 abhorrence +1116 abiding +1121 abnormal +1122 abrasion +1123 absorbing +1124 abundant +1125 abyss +1126 academy +1131 accountant +1132 acetone +1133 achiness +1134 acid +1135 acoustics +1136 acquire +1141 acrobat +1142 actress +1143 acuteness +1144 aerosol +1145 aesthetic +1146 affidavit +1151 afloat +1152 afraid +1153 aftershave +1154 again +1155 agency +1156 aggressor +1161 aghast +1162 agitate +1163 agnostic +1164 agonizing +1165 agreeing +1166 aidless +1211 aimlessly +1212 ajar +1213 alarmclock +1214 albatross +1215 alchemy +1216 alfalfa +1221 algae +1222 aliens +1223 alkaline +1224 almanac +1225 alongside +1226 alphabet +1231 already +1232 also +1233 altitude +1234 aluminum +1235 always +1236 amazingly +1241 ambulance +1242 amendment +1243 amiable +1244 ammunition +1245 amnesty +1246 amoeba +1251 amplifier +1252 amuser +1253 anagram +1254 anchor +1255 android +1256 anesthesia +1261 angelfish +1262 animal +1263 anklet +1264 announcer +1265 anonymous +1266 answer +1311 antelope +1312 anxiety +1313 anyplace +1314 aorta +1315 apartment +1316 apnea +1321 apostrophe +1322 apple +1323 apricot +1324 aquamarine +1325 arachnid +1326 arbitrate +1331 ardently +1332 arena +1333 argument +1334 aristocrat +1335 armchair +1336 aromatic +1341 arrowhead +1342 arsonist +1343 artichoke +1344 asbestos +1345 ascend +1346 aseptic +1351 ashamed +1352 asinine +1353 asleep +1354 asocial +1355 asparagus +1356 astronaut +1361 asymmetric +1362 atlas +1363 atmosphere +1364 atom +1365 atrocious +1366 attic +1411 atypical +1412 auctioneer +1413 auditorium +1414 augmented +1415 auspicious +1416 automobile +1421 auxiliary +1422 avalanche +1423 avenue +1424 aviator +1425 avocado +1426 awareness +1431 awhile +1432 awkward +1433 awning +1434 awoke +1435 axially +1436 azalea +1441 babbling +1442 backpack +1443 badass +1444 bagpipe +1445 bakery +1446 balancing +1451 bamboo +1452 banana +1453 barracuda +1454 basket +1455 bathrobe +1456 bazooka +1461 blade +1462 blender +1463 blimp +1464 blouse +1465 blurred +1466 boatyard +1511 bobcat +1512 body +1513 bogusness +1514 bohemian +1515 boiler +1516 bonnet +1521 boots +1522 borough +1523 bossiness +1524 bottle +1525 bouquet +1526 boxlike +1531 breath +1532 briefcase +1533 broom +1534 brushes +1535 bubblegum +1536 buckle +1541 buddhist +1542 buffalo +1543 bullfrog +1544 bunny +1545 busboy +1546 buzzard +1551 cabin +1552 cactus +1553 cadillac +1554 cafeteria +1555 cage +1556 cahoots +1561 cajoling +1562 cakewalk +1563 calculator +1564 camera +1565 canister +1566 capsule +1611 carrot +1612 cashew +1613 cathedral +1614 caucasian +1615 caviar +1616 ceasefire +1621 cedar +1622 celery +1623 cement +1624 census +1625 ceramics +1626 cesspool +1631 chalkboard +1632 cheesecake +1633 chimney +1634 chlorine +1635 chopsticks +1636 chrome +1641 chute +1642 cilantro +1643 cinnamon +1644 circle +1645 cityscape +1646 civilian +1651 clay +1652 clergyman +1653 clipboard +1654 clock +1655 clubhouse +1656 coathanger +1661 cobweb +1662 coconut +1663 codeword +1664 coexistent +1665 coffeecake +1666 cognitive +2111 cohabitate +2112 collarbone +2113 computer +2114 confetti +2115 copier +2116 cornea +2121 cosmetics +2122 cotton +2123 couch +2124 coverless +2125 coyote +2126 coziness +2131 crawfish +2132 crewmember +2133 crib +2134 croissant +2135 crumble +2136 crystal +2141 cubical +2142 cucumber +2143 cuddly +2144 cufflink +2145 cuisine +2146 culprit +2151 cup +2152 curry +2153 cushion +2154 cuticle +2155 cybernetic +2156 cyclist +2161 cylinder +2162 cymbal +2163 cynicism +2164 cypress +2165 cytoplasm +2166 dachshund +2211 daffodil +2212 dagger +2213 dairy +2214 dalmatian +2215 dandelion +2216 dartboard +2221 dastardly +2222 datebook +2223 daughter +2224 dawn +2225 daytime +2226 dazzler +2231 dealer +2232 debris +2233 decal +2234 dedicate +2235 deepness +2236 defrost +2241 degree +2242 dehydrator +2243 deliverer +2244 democrat +2245 dentist +2246 deodorant +2251 depot +2252 deranged +2253 desktop +2254 detergent +2255 device +2256 dexterity +2261 diamond +2262 dibs +2263 dictionary +2264 diffuser +2265 digit +2266 dilated +2311 dimple +2312 dinnerware +2313 dioxide +2314 diploma +2315 directory +2316 dishcloth +2321 ditto +2322 dividers +2323 dizziness +2324 doctor +2325 dodge +2326 doll +2331 dominoes +2332 donut +2333 doorstep +2334 dorsal +2335 double +2336 downstairs +2341 dozed +2342 drainpipe +2343 dresser +2344 driftwood +2345 droppings +2346 drum +2351 dryer +2352 dubiously +2353 duckling +2354 duffel +2355 dugout +2356 dumpster +2361 duplex +2362 durable +2363 dustpan +2364 dutiful +2365 duvet +2366 dwarfism +2411 dwelling +2412 dwindling +2413 dynamite +2414 dyslexia +2415 eagerness +2416 earlobe +2421 easel +2422 eavesdrop +2423 ebook +2424 eccentric +2425 echoless +2426 eclipse +2431 ecosystem +2432 ecstasy +2433 edged +2434 editor +2435 educator +2436 eelworm +2441 eerie +2442 effects +2443 eggnog +2444 egomaniac +2445 ejection +2446 elastic +2451 elbow +2452 elderly +2453 elephant +2454 elfishly +2455 eliminator +2456 elk +2461 elliptical +2462 elongated +2463 elsewhere +2464 elusive +2465 elves +2466 emancipate +2511 embroidery +2512 emcee +2513 emerald +2514 emission +2515 emoticon +2516 emperor +2521 emulate +2522 enactment +2523 enchilada +2524 endorphin +2525 energy +2526 enforcer +2531 engine +2532 enhance +2533 enigmatic +2534 enjoyably +2535 enlarged +2536 enormous +2541 enquirer +2542 enrollment +2543 ensemble +2544 entryway +2545 enunciate +2546 envoy +2551 enzyme +2552 epidemic +2553 equipment +2554 erasable +2555 ergonomic +2556 erratic +2561 eruption +2562 escalator +2563 eskimo +2564 esophagus +2565 espresso +2566 essay +2611 estrogen +2612 etching +2613 eternal +2614 ethics +2615 etiquette +2616 eucalyptus +2621 eulogy +2622 euphemism +2623 euthanize +2624 evacuation +2625 evergreen +2626 evidence +2631 evolution +2632 exam +2633 excerpt +2634 exerciser +2635 exfoliate +2636 exhale +2641 exist +2642 exorcist +2643 explode +2644 exquisite +2645 exterior +2646 exuberant +2651 fabric +2652 factory +2653 faded +2654 failsafe +2655 falcon +2656 family +2661 fanfare +2662 fasten +2663 faucet +2664 favorite +2665 feasibly +2666 february +3111 federal +3112 feedback +3113 feigned +3114 feline +3115 femur +3116 fence +3121 ferret +3122 festival +3123 fettuccine +3124 feudalist +3125 feverish +3126 fiberglass +3131 fictitious +3132 fiddle +3133 figurine +3134 fillet +3135 finalist +3136 fiscally +3141 fixture +3142 flashlight +3143 fleshiness +3144 flight +3145 florist +3146 flypaper +3151 foamless +3152 focus +3153 foggy +3154 folksong +3155 fondue +3156 footpath +3161 fossil +3162 fountain +3163 fox +3164 fragment +3165 freeway +3166 fridge +3211 frosting +3212 fruit +3213 fryingpan +3214 gadget +3215 gainfully +3216 gallstone +3221 gamekeeper +3222 gangway +3223 garlic +3224 gaslight +3225 gathering +3226 gauntlet +3231 gearbox +3232 gecko +3233 gem +3234 generator +3235 geographer +3236 gerbil +3241 gesture +3242 getaway +3243 geyser +3244 ghoulishly +3245 gibberish +3246 giddiness +3251 giftshop +3252 gigabyte +3253 gimmick +3254 giraffe +3255 giveaway +3256 gizmo +3261 glasses +3262 gleeful +3263 glisten +3264 glove +3265 glucose +3266 glycerin +3311 gnarly +3312 gnomish +3313 goatskin +3314 goggles +3315 goldfish +3316 gong +3321 gooey +3322 gorgeous +3323 gosling +3324 gothic +3325 gourmet +3326 governor +3331 grape +3332 greyhound +3333 grill +3334 groundhog +3335 grumbling +3336 guacamole +3341 guerrilla +3342 guitar +3343 gullible +3344 gumdrop +3345 gurgling +3346 gusto +3351 gutless +3352 gymnast +3353 gynecology +3354 gyration +3355 habitat +3356 hacking +3361 haggard +3362 haiku +3363 halogen +3364 hamburger +3365 handgun +3366 happiness +3411 hardhat +3412 hastily +3413 hatchling +3414 haughty +3415 hazelnut +3416 headband +3421 hedgehog +3422 hefty +3423 heinously +3424 helmet +3425 hemoglobin +3426 henceforth +3431 herbs +3432 hesitation +3433 hexagon +3434 hubcap +3435 huddling +3436 huff +3441 hugeness +3442 hullabaloo +3443 human +3444 hunter +3445 hurricane +3446 hushing +3451 hyacinth +3452 hybrid +3453 hydrant +3454 hygienist +3455 hypnotist +3456 ibuprofen +3461 icepack +3462 icing +3463 iconic +3464 identical +3465 idiocy +3466 idly +3511 igloo +3512 ignition +3513 iguana +3514 illuminate +3515 imaging +3516 imbecile +3521 imitator +3522 immigrant +3523 imprint +3524 iodine +3525 ionosphere +3526 ipad +3531 iphone +3532 iridescent +3533 irksome +3534 iron +3535 irrigation +3536 island +3541 isotope +3542 issueless +3543 italicize +3544 itemizer +3545 itinerary +3546 itunes +3551 ivory +3552 jabbering +3553 jackrabbit +3554 jaguar +3555 jailhouse +3556 jalapeno +3561 jamboree +3562 janitor +3563 jarring +3564 jasmine +3565 jaundice +3566 jawbreaker +3611 jaywalker +3612 jazz +3613 jealous +3614 jeep +3615 jelly +3616 jeopardize +3621 jersey +3622 jetski +3623 jezebel +3624 jiffy +3625 jigsaw +3626 jingling +3631 jobholder +3632 jockstrap +3633 jogging +3634 john +3635 joinable +3636 jokingly +3641 journal +3642 jovial +3643 joystick +3644 jubilant +3645 judiciary +3646 juggle +3651 juice +3652 jujitsu +3653 jukebox +3654 jumpiness +3655 junkyard +3656 juror +3661 justifying +3662 juvenile +3663 kabob +3664 kamikaze +3665 kangaroo +3666 karate +4111 kayak +4112 keepsake +4113 kennel +4114 kerosene +4115 ketchup +4116 khaki +4121 kickstand +4122 kilogram +4123 kimono +4124 kingdom +4125 kiosk +4126 kissing +4131 kite +4132 kleenex +4133 knapsack +4134 kneecap +4135 knickers +4136 koala +4141 krypton +4142 laboratory +4143 ladder +4144 lakefront +4145 lantern +4146 laptop +4151 laryngitis +4152 lasagna +4153 latch +4154 laundry +4155 lavender +4156 laxative +4161 lazybones +4162 lecturer +4163 leftover +4164 leggings +4165 leisure +4166 lemon +4211 length +4212 leopard +4213 leprechaun +4214 lettuce +4215 leukemia +4216 levers +4221 lewdness +4222 liability +4223 library +4224 licorice +4225 lifeboat +4226 lightbulb +4231 likewise +4232 lilac +4233 limousine +4234 lint +4235 lioness +4236 lipstick +4241 liquid +4242 listless +4243 litter +4244 liverwurst +4245 lizard +4246 llama +4251 luau +4252 lubricant +4253 lucidity +4254 ludicrous +4255 luggage +4256 lukewarm +4261 lullaby +4262 lumberjack +4263 lunchbox +4264 luridness +4265 luscious +4266 luxurious +4311 lyrics +4312 macaroni +4313 maestro +4314 magazine +4315 mahogany +4316 maimed +4321 majority +4322 makeover +4323 malformed +4324 mammal +4325 mango +4326 mapmaker +4331 marbles +4332 massager +4333 matchstick +4334 maverick +4335 maximum +4336 mayonnaise +4341 moaning +4342 mobilize +4343 moccasin +4344 modify +4345 moisture +4346 molecule +4351 momentum +4352 monastery +4353 moonshine +4354 mortuary +4355 mosquito +4356 motorcycle +4361 mousetrap +4362 movie +4363 mower +4364 mozzarella +4365 muckiness +4366 mudflow +4411 mugshot +4412 mule +4413 mummy +4414 mundane +4415 muppet +4416 mural +4421 mustard +4422 mutation +4423 myriad +4424 myspace +4425 myth +4426 nail +4431 namesake +4432 nanosecond +4433 napkin +4434 narrator +4435 nastiness +4436 natives +4441 nautically +4442 navigate +4443 nearest +4444 nebula +4445 nectar +4446 nefarious +4451 negotiator +4452 neither +4453 nemesis +4454 neoliberal +4455 nephew +4456 nervously +4461 nest +4462 netting +4463 neuron +4464 nevermore +4465 nextdoor +4466 nicotine +4511 niece +4512 nimbleness +4513 nintendo +4514 nirvana +4515 nuclear +4516 nugget +4521 nuisance +4522 nullify +4523 numbing +4524 nuptials +4525 nursery +4526 nutcracker +4531 nylon +4532 oasis +4533 oat +4534 obediently +4535 obituary +4536 object +4541 obliterate +4542 obnoxious +4543 observer +4544 obtain +4545 obvious +4546 occupation +4551 oceanic +4552 octopus +4553 ocular +4554 office +4555 oftentimes +4556 oiliness +4561 ointment +4562 older +4563 olympics +4564 omissible +4565 omnivorous +4566 oncoming +4611 onion +4612 onlooker +4613 onstage +4614 onward +4615 onyx +4616 oomph +4621 opaquely +4622 opera +4623 opium +4624 opossum +4625 opponent +4626 optical +4631 opulently +4632 oscillator +4633 osmosis +4634 ostrich +4635 otherwise +4636 ought +4641 outhouse +4642 ovation +4643 oven +4644 owlish +4645 oxford +4646 oxidize +4651 oxygen +4652 oyster +4653 ozone +4654 pacemaker +4655 padlock +4656 pageant +4661 pajamas +4662 palm +4663 pamphlet +4664 pantyhose +4665 paprika +4666 parakeet +5111 passport +5112 patio +5113 pauper +5114 pavement +5115 payphone +5116 pebble +5121 peculiarly +5122 pedometer +5123 pegboard +5124 pelican +5125 penguin +5126 peony +5131 pepperoni +5132 peroxide +5133 pesticide +5134 petroleum +5135 pewter +5136 pharmacy +5141 pheasant +5142 phonebook +5143 phrasing +5144 physician +5145 plank +5146 pledge +5151 plotted +5152 plug +5153 plywood +5154 pneumonia +5155 podiatrist +5156 poetic +5161 pogo +5162 poison +5163 poking +5164 policeman +5165 poncho +5166 popcorn +5211 porcupine +5212 postcard +5213 poultry +5214 powerboat +5215 prairie +5216 pretzel +5221 princess +5222 propeller +5223 prune +5224 pry +5225 pseudo +5226 psychopath +5231 publisher +5232 pucker +5233 pueblo +5234 pulley +5235 pumpkin +5236 punchbowl +5241 puppy +5242 purse +5243 pushup +5244 putt +5245 puzzle +5246 pyramid +5251 python +5252 quarters +5253 quesadilla +5254 quilt +5255 quote +5256 racoon +5261 radish +5262 ragweed +5263 railroad +5264 rampantly +5265 rancidity +5266 rarity +5311 raspberry +5312 ravishing +5313 rearrange +5314 rebuilt +5315 receipt +5316 reentry +5321 refinery +5322 register +5323 rehydrate +5324 reimburse +5325 rejoicing +5326 rekindle +5331 relic +5332 remote +5333 renovator +5334 reopen +5335 reporter +5336 request +5341 rerun +5342 reservoir +5343 retriever +5344 reunion +5345 revolver +5346 rewrite +5351 rhapsody +5352 rhetoric +5353 rhino +5354 rhubarb +5355 rhyme +5356 ribbon +5361 riches +5362 ridden +5363 rigidness +5364 rimmed +5365 riptide +5366 riskily +5411 ritzy +5412 riverboat +5413 roamer +5414 robe +5415 rocket +5416 romancer +5421 ropelike +5422 rotisserie +5423 roundtable +5424 royal +5425 rubber +5426 rudderless +5431 rugby +5432 ruined +5433 rulebook +5434 rummage +5435 running +5436 rupture +5441 rustproof +5442 sabotage +5443 sacrifice +5444 saddlebag +5445 saffron +5446 sainthood +5451 saltshaker +5452 samurai +5453 sandworm +5454 sapphire +5455 sardine +5456 sassy +5461 satchel +5462 sauna +5463 savage +5464 saxophone +5465 scarf +5466 scenario +5511 schoolbook +5512 scientist +5513 scooter +5514 scrapbook +5515 sculpture +5516 scythe +5521 secretary +5522 sedative +5523 segregator +5524 seismology +5525 selected +5526 semicolon +5531 senator +5532 septum +5533 sequence +5534 serpent +5535 sesame +5536 settler +5541 severely +5542 shack +5543 shelf +5544 shirt +5545 shovel +5546 shrimp +5551 shuttle +5552 shyness +5553 siamese +5554 sibling +5555 siesta +5556 silicon +5561 simmering +5562 singles +5563 sisterhood +5564 sitcom +5565 sixfold +5566 sizable +5611 skateboard +5612 skeleton +5613 skies +5614 skulk +5615 skylight +5616 slapping +5621 sled +5622 slingshot +5623 sloth +5624 slumbering +5625 smartphone +5626 smelliness +5631 smitten +5632 smokestack +5633 smudge +5634 snapshot +5635 sneezing +5636 sniff +5641 snowsuit +5642 snugness +5643 speakers +5644 sphinx +5645 spider +5646 splashing +5651 sponge +5652 sprout +5653 spur +5654 spyglass +5655 squirrel +5656 statue +5661 steamboat +5662 stingray +5663 stopwatch +5664 strawberry +5665 student +5666 stylus +6111 suave +6112 subway +6113 suction +6114 suds +6115 suffocate +6116 sugar +6121 suitcase +6122 sulphur +6123 superstore +6124 surfer +6125 sushi +6126 swan +6131 sweatshirt +6132 swimwear +6133 sword +6134 sycamore +6135 syllable +6136 symphony +6141 synagogue +6142 syringes +6143 systemize +6144 tablespoon +6145 taco +6146 tadpole +6151 taekwondo +6152 tagalong +6153 takeout +6154 tallness +6155 tamale +6156 tanned +6161 tapestry +6162 tarantula +6163 tastebud +6164 tattoo +6165 tavern +6166 thaw +6211 theater +6212 thimble +6213 thorn +6214 throat +6215 thumb +6216 thwarting +6221 tiara +6222 tidbit +6223 tiebreaker +6224 tiger +6225 timid +6226 tinsel +6231 tiptoeing +6232 tirade +6233 tissue +6234 tractor +6235 tree +6236 tripod +6241 trousers +6242 trucks +6243 tryout +6244 tubeless +6245 tuesday +6246 tugboat +6251 tulip +6252 tumbleweed +6253 tupperware +6254 turtle +6255 tusk +6256 tutorial +6261 tuxedo +6262 tweezers +6263 twins +6264 tyrannical +6265 ultrasound +6266 umbrella +6311 umpire +6312 unarmored +6313 unbuttoned +6314 uncle +6315 underwear +6316 unevenness +6321 unflavored +6322 ungloved +6323 unhinge +6324 unicycle +6325 unjustly +6326 unknown +6331 unlocking +6332 unmarked +6333 unnoticed +6334 unopened +6335 unpaved +6336 unquenched +6341 unroll +6342 unscrewing +6343 untied +6344 unusual +6345 unveiled +6346 unwrinkled +6351 unyielding +6352 unzip +6353 upbeat +6354 upcountry +6355 update +6356 upfront +6361 upgrade +6362 upholstery +6363 upkeep +6364 upload +6365 uppercut +6366 upright +6411 upstairs +6412 uptown +6413 upwind +6414 uranium +6415 urban +6416 urchin +6421 urethane +6422 urgent +6423 urologist +6424 username +6425 usher +6426 utensil +6431 utility +6432 utmost +6433 utopia +6434 utterance +6435 vacuum +6436 vagrancy +6441 valuables +6442 vanquished +6443 vaporizer +6444 varied +6445 vaseline +6446 vegetable +6451 vehicle +6452 velcro +6453 vendor +6454 vertebrae +6455 vestibule +6456 veteran +6461 vexingly +6462 vicinity +6463 videogame +6464 viewfinder +6465 vigilante +6466 village +6511 vinegar +6512 violin +6513 viperfish +6514 virus +6515 visor +6516 vitamins +6521 vivacious +6522 vixen +6523 vocalist +6524 vogue +6525 voicemail +6526 volleyball +6531 voucher +6532 voyage +6533 vulnerable +6534 waffle +6535 wagon +6536 wakeup +6541 walrus +6542 wanderer +6543 wasp +6544 water +6545 waving +6546 wheat +6551 whisper +6552 wholesaler +6553 wick +6554 widow +6555 wielder +6556 wifeless +6561 wikipedia +6562 wildcat +6563 windmill +6564 wipeout +6565 wired +6566 wishbone +6611 wizardry +6612 wobbliness +6613 wolverine +6614 womb +6615 woolworker +6616 workbasket +6621 wound +6622 wrangle +6623 wreckage +6624 wristwatch +6625 wrongdoing +6626 xerox +6631 xylophone +6632 yacht +6633 yahoo +6634 yard +6635 yearbook +6636 yesterday +6641 yiddish +6642 yield +6643 yo-yo +6644 yodel +6645 yogurt +6646 yuppie +6651 zealot +6652 zebra +6653 zeppelin +6654 zestfully +6655 zigzagged +6656 zillion +6661 zipping +6662 zirconium +6663 zodiac +6664 zombie +6665 zookeeper +6666 zucchini From 1da511958495c5512758d01cd3a974dfcff10251 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 15 Nov 2024 13:25:43 -0500 Subject: [PATCH 09/81] initrd/etc/functions: add generate_passphrase logic Nothing uses it for the moment, needs to be called from recovery shell: bash, source /etc/functions. generate_passphrase - parses dictionary to check how many dice rolls needed on first entry, defaults to EFF short list v2 (bigger words easier to remember, 4 dices roll instead of 5) - defaults to using initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt, parametrable - make sure format of dictionary is 'digit word' and fail early otherwise: we expect EFF diceware format dictionaries - enforces max length of 256 chars, parametrable, reduces number of words to fit if not override - enforces default 3 words passphrase, parametrable - enforces captialization of first letter, lowercase parametrable - read multiple bytes from /dev/urandom to fit number of dice rolls Unrelated: uniformize format of file Signed-off-by: Thierry Laurion --- initrd/etc/functions | 162 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 148 insertions(+), 14 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 3c4b092c7..6a89dc60a 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -25,7 +25,10 @@ SINK_LOG() { # last (unterminated) line. Add a line break with echo to ensure we # don't lose any input. Buffer up to one blank line so we can avoid # emitting a final (or only) blank line. - (cat; echo) | while IFS= read -r line; do + ( + cat + echo + ) | while IFS= read -r line; do [[ -n "$haveblank" ]] && DEBUG "$name: " # Emit buffered blank line if [[ -z "$line" ]]; then haveblank=y @@ -129,10 +132,10 @@ TRACE_FUNC() { DEBUG_STACK() { local FRAMES FRAMES="${#FUNCNAME[@]}" - DEBUG "call stack: ($((FRAMES-1)) frames)" + DEBUG "call stack: ($((FRAMES - 1)) frames)" # Don't print DEBUG_STACK itself, start from 1 - for i in $(seq 1 "$((FRAMES-1))"); do - DEBUG "- $((i-1)) - ${BASH_SOURCE[$i]}(${BASH_LINENO[$((i-1))]}): ${FUNCNAME[$i]}" + for i in $(seq 1 "$((FRAMES - 1))"); do + DEBUG "- $((i - 1)) - ${BASH_SOURCE[$i]}(${BASH_LINENO[$((i - 1))]}): ${FUNCNAME[$i]}" done } @@ -248,7 +251,7 @@ device_has_partitions() { # In both cases the output is 5 lines: 3 about device info, 1 empty line # and the 5th will be the table header or the invalid message. local DISK_DATA=$(fdisk -l "$DEVICE") - if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || \ + if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || [ "$(echo "$DISK_DATA" | wc -l)" -eq 5 ]; then # No partition table return 1 @@ -305,9 +308,9 @@ list_usb_storage() { done } -# Prompt for a TPM Owner Password if it is not already cached in /tmp/secret/tpm_owner_password. -# Sets tpm_owner_password variable reused in flow, and cache file used until recovery shell is accessed. -# Tools should optionally accept a TPM password on the command line, since some flows need +# Prompt for a TPM Owner Password if it is not already cached in /tmp/secret/tpm_owner_password. +# Sets tpm_owner_password variable reused in flow, and cache file used until recovery shell is accessed. +# Tools should optionally accept a TPM password on the command line, since some flows need # it multiple times and only one prompt is ideal. prompt_tpm_owner_password() { TRACE_FUNC @@ -327,7 +330,7 @@ prompt_tpm_owner_password() { echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM owner_password under /tmp/secret/tpm_owner_password" } -# Prompt for a new TPM Owner Password when resetting the TPM. +# Prompt for a new TPM Owner Password when resetting the TPM. # Returned in tpm_owner_passpword and cached under /tpm/secret/tpm_owner_password # The password must be 1-32 characters and must be entered twice, # the script will loop until this is met. @@ -357,7 +360,7 @@ prompt_new_owner_password() { check_tpm_counter() { TRACE_FUNC - + LABEL=${2:-3135106223} tpm_password="$3" # if the /boot.hashes file already exists, read the TPM counter ID @@ -370,7 +373,7 @@ check_tpm_counter() { -pwdc '' \ -la $LABEL | tee /tmp/counter || - die "Unable to create TPM counter" + die "Unable to create TPM counter" TPM_COUNTER=$(cut -d: -f1 [--number_words|-n ] [--max_length|-m ] [--lowercase|-l]" + echo "Generates a passphrase using a Diceware dictionary." + echo " --dictionary|-d Path to the Diceware dictionary file (defaults to /etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt )." + echo " [--number_words|-n ] Number of words in the passphrase (default: 3)." + echo " [--max_length|-m ] Maximum size of the passphrase (default: 256)." + echo " [--lowercase|-l] Use lowercase words (default: false)." + } + + # Helper subfunction to get a word from the dictionary based on dice rolls + get_word_from_dictionary() { + local rolls="$1" + local dictionary_file="$2" + local word="" + + word=$(grep "^$rolls" "$dictionary_file" | awk '{print $2}') + echo "$word" + } + + # Helper subfunction to generate dice rolls + generate_dice_rolls() { + TRACE_FUNC + local num_rolls="$1" + local rolls="" + local random_bytes + + # Read num_rolls bytes from /dev/urandom in one go + random_bytes=$(dd if=/dev/urandom bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') + + # Process each byte to generate a dice roll + while read -r byte; do + roll=$((byte % 6 + 1)) + DEBUG "Randomized dice roll: $roll" + rolls+=$roll + done <<<"$random_bytes" + + DEBUG "Generated dice rolls: $rolls" + echo "$rolls" + } + + TRACE_FUNC + local dictionary_file="/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt" + local num_words=3 + local max_size=256 + local lowercase=false + + # Parse parameters + while [[ "$#" -gt 0 ]]; do + case "$1" in + --dictionary | -d) + dictionary_file="$2" + shift + ;; + --lowercase | -l) + lowercase=true + ;; + --number_words | -n) + if ! [[ "$2" =~ ^[0-9]+$ ]] || [[ "$2" -le 0 ]]; then + warn "Invalid number of words: $2" + usage_generate_passphrase + return 1 + fi + num_words="$2" + shift + ;; + --max_length | -m) + if ! [[ "$2" =~ ^[0-9]+$ ]] || [[ "$2" -le 0 ]]; then + warn "Invalid maximum size: $2" + usage_generate_passphrase + return 1 + fi + max_size="$2" + shift + ;; + *) + warn "Unknown parameter: $1" + usage_generate_passphrase + return 1 + ;; + esac + shift + done + + # Validate dictionary file + if [[ -z "$dictionary_file" || ! -f "$dictionary_file" ]]; then + warn "Dictionary file not found or not provided: $dictionary_file" + usage_generate_passphrase + return 1 + fi + + local passphrase="" + local word="" + local key="" + local digits=0 + + # Read the number of digits from the first line of the dictionary file + read -r key _ <"$dictionary_file" + + # Validate that the key is composed entirely of digits + if ! [[ $key =~ ^[0-9]+$ ]]; then + echo "Error: Dictionary is not compliant with EFF diceware dictionaries." + echo "The first line of the dictionary should be in the format: " + echo "Example: 11111 word" + exit 1 + fi + + digits=${#key} + DEBUG "Number of digits in dice rolls: $digits" + + for ((i = 0; i < num_words; ++i)); do + key=$(generate_dice_rolls "$digits") + word=$(get_word_from_dictionary "$key" "$dictionary_file") + DEBUG "Retrieved word: $word" + if [[ "$lowercase" == "false" ]]; then + DEBUG "Capitalizing the first letter of the word" + word=${word^} # Capitalize the first letter + fi + passphrase+="$word " + if [[ ${#passphrase} -gt $max_size ]]; then + DEBUG "Passphrase exceeds max size: $max_size, removing last word" + passphrase=${passphrase% *} # Remove the last word if it exceeds max_size + break + fi + done + + echo "$passphrase" + return 0 +} From f8fdfc7b8dbb05b5478223b1cd3a8705a564f5ad Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Nov 2024 14:02:35 -0500 Subject: [PATCH 10/81] WiP initrd/bin/oem-factory-reset: format unification Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 2080 +++++++++++++++++----------------- 1 file changed, 1040 insertions(+), 1040 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 8fa69ca99..533e7252b 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -46,8 +46,8 @@ RSA_KEY_LENGTH=3072 #Override RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards until canokey fixes if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then - DEBUG "Overriding RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards" - RSA_KEY_LENGTH=2048 + DEBUG "Overriding RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards" + RSA_KEY_LENGTH=2048 fi GPG_USER_NAME="OEM Key" @@ -60,195 +60,195 @@ SKIP_BOOT="n" die() { - local msg=$1 - if [ -n "$msg" ]; then - echo -e "\n$msg" - fi - kill -s TERM $TOP_PID - exit 1 + local msg=$1 + if [ -n "$msg" ]; then + echo -e "\n$msg" + fi + kill -s TERM $TOP_PID + exit 1 } local_whiptail_error() { - local msg=$1 - if [ "$msg" = "" ]; then - die "whiptail error: An error msg is required" - fi - whiptail_error --msgbox "${msg}\n\n" $HEIGHT $WIDTH --title "Error" + local msg=$1 + if [ "$msg" = "" ]; then + die "whiptail error: An error msg is required" + fi + whiptail_error --msgbox "${msg}\n\n" $HEIGHT $WIDTH --title "Error" } whiptail_error_die() { - local_whiptail_error "$@" - die + local_whiptail_error "$@" + die } mount_boot() { - TRACE_FUNC - # Mount local disk if it is not already mounted. - # Added so that 'o' can be typed early at boot to enter directly into OEM Factory Reset - if ! grep -q /boot /proc/mounts; then - # try to mount if CONFIG_BOOT_DEV exists - if [ -e "$CONFIG_BOOT_DEV" ]; then - mount -o ro $CONFIG_BOOT_DEV /boot || die "Failed to mount $CONFIG_BOOT_DEV. Please change boot device under Configuration > Boot Device" - fi - fi + TRACE_FUNC + # Mount local disk if it is not already mounted. + # Added so that 'o' can be typed early at boot to enter directly into OEM Factory Reset + if ! grep -q /boot /proc/mounts; then + # try to mount if CONFIG_BOOT_DEV exists + if [ -e "$CONFIG_BOOT_DEV" ]; then + mount -o ro $CONFIG_BOOT_DEV /boot || die "Failed to mount $CONFIG_BOOT_DEV. Please change boot device under Configuration > Boot Device" + fi + fi } #Generate a gpg master key: no expiration date, ${RSA_KEY_LENGTH} bits #This key will be used to sign 3 subkeys: encryption, authentication and signing #The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard generate_inmemory_RSA_master_and_subkeys() { - TRACE_FUNC - - echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits master key..." - # Generate GPG master key - { - echo "Key-Type: RSA" # RSA key - echo "Key-Length: ${RSA_KEY_LENGTH}" # RSA key length - echo "Key-Usage: sign" # RSA key usage - echo "Name-Real: ${GPG_USER_NAME}" # User name - echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment - echo "Name-Email: ${GPG_USER_MAIL}" # User email - echo "Expire-Date: 0" # No expiration date - echo "Passphrase: ${ADMIN_PIN}" # Admin PIN - echo "%commit" # Commit changes - } | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key generation failed!\n\n$ERROR" - fi - - echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits signing subkey..." - # Add signing subkey - { - echo addkey # add key in --edit-key mode - echo 4 # RSA (sign only) - echo ${RSA_KEY_LENGTH} # Signing key size set to RSA_KEY_LENGTH - echo 0 # No expiration date - echo ${ADMIN_PIN} # Local keyring admin pin - echo y # confirm - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key signing subkey generation failed!\n\n$ERROR" - fi - - echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits encryption subkey..." - #Add encryption subkey - { - echo addkey # add key in --edit-key mode - echo 6 # RSA (encrypt only) - echo ${RSA_KEY_LENGTH} # Encryption key size set to RSA_KEY_LENGTH - echo 0 # No expiration date - echo ${ADMIN_PIN} # Local keyring admin pin - echo y # confirm - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key encryption subkey generation failed!\n\n$ERROR" - fi - - echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits authentication subkey..." - #Add authentication subkey - { - #Authentication subkey needs gpg in expert mode to select RSA custom mode (8) - # in order to disable encryption and signing capabilities of subkey - # and then enable authentication capability - echo addkey # add key in --edit-key mode - echo 8 # RSA (set your own capabilities) - echo S # disable sign capability - echo E # disable encryption capability - echo A # enable authentication capability - echo Q # Quit - echo ${RSA_KEY_LENGTH} # Authentication key size set to RSA_KEY_LENGTH - echo 0 # No expiration date - echo ${ADMIN_PIN} # Local keyring admin pin - echo y # confirm - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key authentication subkey generation failed!\n\n$ERROR" - fi + TRACE_FUNC + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits master key..." + # Generate GPG master key + { + echo "Key-Type: RSA" # RSA key + echo "Key-Length: ${RSA_KEY_LENGTH}" # RSA key length + echo "Key-Usage: sign" # RSA key usage + echo "Name-Real: ${GPG_USER_NAME}" # User name + echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment + echo "Name-Email: ${GPG_USER_MAIL}" # User email + echo "Expire-Date: 0" # No expiration date + echo "Passphrase: ${ADMIN_PIN}" # Admin PIN + echo "%commit" # Commit changes + } | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits signing subkey..." + # Add signing subkey + { + echo addkey # add key in --edit-key mode + echo 4 # RSA (sign only) + echo ${RSA_KEY_LENGTH} # Signing key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key signing subkey generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits encryption subkey..." + #Add encryption subkey + { + echo addkey # add key in --edit-key mode + echo 6 # RSA (encrypt only) + echo ${RSA_KEY_LENGTH} # Encryption key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key encryption subkey generation failed!\n\n$ERROR" + fi + + echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits authentication subkey..." + #Add authentication subkey + { + #Authentication subkey needs gpg in expert mode to select RSA custom mode (8) + # in order to disable encryption and signing capabilities of subkey + # and then enable authentication capability + echo addkey # add key in --edit-key mode + echo 8 # RSA (set your own capabilities) + echo S # disable sign capability + echo E # disable encryption capability + echo A # enable authentication capability + echo Q # Quit + echo ${RSA_KEY_LENGTH} # Authentication key size set to RSA_KEY_LENGTH + echo 0 # No expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo y # confirm + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key authentication subkey generation failed!\n\n$ERROR" + fi } #Generate a gpg master key: no expiration date, p256 key (ECC) #This key will be used to sign 3 subkeys: encryption, authentication and signing #The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard generate_inmemory_p256_master_and_subkeys() { - TRACE_FUNC - - echo "Generating GPG p256 bits master key..." - { - echo "Key-Type: ECDSA" # ECDSA key - echo "Key-Curve: nistp256" # ECDSA key curve - echo "Key-Usage: cert" # ECDSA key usage - echo "Name-Real: ${GPG_USER_NAME}" # User name - echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment - echo "Name-Email: ${GPG_USER_MAIL}" # User email - echo "Passphrase: ${ADMIN_PIN}" # Local keyring admin pin - echo "Expire-Date: 0" # No expiration date - echo "%commit" # Commit changes - } | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG p256 Key generation failed!\n\n$ERROR" - fi - - #Keep Master key fingerprint for add key calls - MASTER_KEY_FP=$(gpg --list-secret-keys --with-colons | grep fpr | cut -d: -f10) - - echo "Generating GPG nistp256 signing subkey..." - { - echo addkey # add key in --edit-key mode - echo 11 # ECC own set capability - echo Q # sign already present, do not modify - echo 3 # P-256 - echo 0 # No validity/expiration date - echo ${ADMIN_PIN} # Local keyring admin pin - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR_MSG=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" - fi - - echo "Generating GPG nistp256 encryption subkey..." - { - echo addkey - echo 12 # ECC own set capability - echo Q # Quit - echo 3 # P-256 - echo 0 # No validity/expiration date - echo ${ADMIN_PIN} # Local keyring admin pin - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR_MSG=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" - fi - - echo "Generating GPG nistp256 authentication subkey..." - { - echo addkey # add key in --edit-key mode - echo 11 # ECC own set capability - echo S # deactivate sign - echo A # activate auth - echo Q # Quit - echo 3 # P-256 - echo 0 # no expiration - echo ${ADMIN_PIN} # Local keyring admin pin - echo save # save changes and commit to keyring - } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR_MSG=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" - fi + TRACE_FUNC + + echo "Generating GPG p256 bits master key..." + { + echo "Key-Type: ECDSA" # ECDSA key + echo "Key-Curve: nistp256" # ECDSA key curve + echo "Key-Usage: cert" # ECDSA key usage + echo "Name-Real: ${GPG_USER_NAME}" # User name + echo "Name-Comment: ${GPG_USER_COMMENT}" # User comment + echo "Name-Email: ${GPG_USER_MAIL}" # User email + echo "Passphrase: ${ADMIN_PIN}" # Local keyring admin pin + echo "Expire-Date: 0" # No expiration date + echo "%commit" # Commit changes + } | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG p256 Key generation failed!\n\n$ERROR" + fi + + #Keep Master key fingerprint for add key calls + MASTER_KEY_FP=$(gpg --list-secret-keys --with-colons | grep fpr | cut -d: -f10) + + echo "Generating GPG nistp256 signing subkey..." + { + echo addkey # add key in --edit-key mode + echo 11 # ECC own set capability + echo Q # sign already present, do not modify + echo 3 # P-256 + echo 0 # No validity/expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}" + fi + + echo "Generating GPG nistp256 encryption subkey..." + { + echo addkey + echo 12 # ECC own set capability + echo Q # Quit + echo 3 # P-256 + echo 0 # No validity/expiration date + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}" + fi + + echo "Generating GPG nistp256 authentication subkey..." + { + echo addkey # add key in --edit-key mode + echo 11 # ECC own set capability + echo S # deactivate sign + echo A # activate auth + echo Q # Quit + echo 3 # P-256 + echo 0 # no expiration + echo ${ADMIN_PIN} # Local keyring admin pin + echo save # save changes and commit to keyring + } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR_MSG=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}" + fi } @@ -259,141 +259,141 @@ generate_inmemory_p256_master_and_subkeys() { # The master key was already used to sign the subkeys, so it is not needed anymore # Delete the master key from the keyring once key to card is done (already backed up on LUKS private partition) keytocard_subkeys_to_smartcard() { - TRACE_FUNC - - #make sure usb ready and USB Security Dongle ready to communicate with - enable_usb - enable_usb_storage - gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" - - gpg_key_factory_reset - - echo "Moving subkeys to smartcard..." - { - echo "key 1" #Toggle on Signature key in --edit-key mode on local keyring - echo "keytocard" #Move Signature key to smartcard - echo "1" #Select Signature key key slot on smartcard - echo "${ADMIN_PIN}" #Local keyring Subkey PIN - echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN - echo "0" #No expiration date - echo "key 1" #Toggle off Signature key - echo "key 2" #Toggle on Encryption key - echo "keytocard" #Move Encryption key to smartcard - echo "2" #Select Encryption key key slot on smartcard - echo "${ADMIN_PIN}" #Local keyring Subkey PIN - echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN - echo "key 2" #Toggle off Encryption key - echo "key 3" #Toggle on Authentication key - echo "keytocard" #Move Authentication key to smartcard - echo "3" #Select Authentication key slot on smartcard - echo "${ADMIN_PIN}" #Local keyring Subkey PIN - echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN - echo "key 3" #Toggle off Authentication key - echo "save" #Save changes and commit to keyring - } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" - fi - - TRACE_FUNC + TRACE_FUNC + + #make sure usb ready and USB Security Dongle ready to communicate with + enable_usb + enable_usb_storage + gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" + + gpg_key_factory_reset + + echo "Moving subkeys to smartcard..." + { + echo "key 1" #Toggle on Signature key in --edit-key mode on local keyring + echo "keytocard" #Move Signature key to smartcard + echo "1" #Select Signature key key slot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "0" #No expiration date + echo "key 1" #Toggle off Signature key + echo "key 2" #Toggle on Encryption key + echo "keytocard" #Move Encryption key to smartcard + echo "2" #Select Encryption key key slot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "key 2" #Toggle off Encryption key + echo "key 3" #Toggle on Authentication key + echo "keytocard" #Move Authentication key to smartcard + echo "3" #Select Authentication key slot on smartcard + echo "${ADMIN_PIN}" #Local keyring Subkey PIN + echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN + echo "key 3" #Toggle off Authentication key + echo "save" #Save changes and commit to keyring + } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key moving subkeys to smartcard failed!\n\n$ERROR" + fi + + TRACE_FUNC } #Whiptail prompt to insert to be wiped thumb drive prompt_insert_to_be_wiped_thumb_drive() { - TRACE_FUNC - #Whiptail warning about having only desired to be wiped thumb drive inserted - whiptail_warning --title 'WARNING: Please insert the thumb drive to be wiped' \ - --msgbox "The thumb drive will be WIPED next.\n\nPlease connect only the thumb drive to be wiped and disconnect others." 0 80 || - die "Error displaying warning about having only desired to be wiped thumb drive inserted" + TRACE_FUNC + #Whiptail warning about having only desired to be wiped thumb drive inserted + whiptail_warning --title 'WARNING: Please insert the thumb drive to be wiped' \ + --msgbox "The thumb drive will be WIPED next.\n\nPlease connect only the thumb drive to be wiped and disconnect others." 0 80 || + die "Error displaying warning about having only desired to be wiped thumb drive inserted" } #export master key and subkeys to thumbdrive's private LUKS contained partition export_master_key_subkeys_and_revocation_key_to_private_LUKS_container() { - TRACE_FUNC - - #Sanity check on passed arguments - while [ $# -gt 0 ]; do - case "$1" in - --mode) - mode="$2" - shift - shift - ;; - --device) - device="$2" - shift - shift - ;; - --mountpoint) - mountpoint="$2" - shift - shift - ;; - --pass) - pass="${2}" - shift - shift - ;; - *) - die "Error: unknown argument: $1" - ;; - esac - done - - mount-usb --mode "$mode" --device "$device" --mountpoint "$mountpoint" --pass "$pass" || die "Error mounting thumb drive's private partition" - - #Export master key and subkeys to thumb drive - DEBUG "Exporting master key and subkeys to private LUKS container's partition..." - - gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || - die "Error exporting master key to private LUKS container's partition" - gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || - die "Error exporting subkeys to private LUKS container's partition" - #copy whole keyring to thumb drive, including revocation key and trust database - cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" - #Unmount private LUKS container's mount point - umount "$mountpoint" || die "Error unmounting private LUKS container's mount point" - - TRACE_FUNC + TRACE_FUNC + + #Sanity check on passed arguments + while [ $# -gt 0 ]; do + case "$1" in + --mode) + mode="$2" + shift + shift + ;; + --device) + device="$2" + shift + shift + ;; + --mountpoint) + mountpoint="$2" + shift + shift + ;; + --pass) + pass="${2}" + shift + shift + ;; + *) + die "Error: unknown argument: $1" + ;; + esac + done + + mount-usb --mode "$mode" --device "$device" --mountpoint "$mountpoint" --pass "$pass" || die "Error mounting thumb drive's private partition" + + #Export master key and subkeys to thumb drive + DEBUG "Exporting master key and subkeys to private LUKS container's partition..." + + gpg --export-secret-key --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/privkey.sec || + die "Error exporting master key to private LUKS container's partition" + gpg --export-secret-subkeys --armor --pinentry-mode loopback --passphrase="${pass}" "${GPG_USER_MAIL}" >"$mountpoint"/subkeys.sec || + die "Error exporting subkeys to private LUKS container's partition" + #copy whole keyring to thumb drive, including revocation key and trust database + cp -af ~/.gnupg "$mountpoint"/.gnupg || die "Error copying whole keyring to private LUKS container's partition" + #Unmount private LUKS container's mount point + umount "$mountpoint" || die "Error unmounting private LUKS container's mount point" + + TRACE_FUNC } #Export public key to thumb drive's public partition export_public_key_to_thumbdrive_public_partition() { - TRACE_FUNC - - #Sanity check on passed arguments - while [ $# -gt 0 ]; do - case "$1" in - --mode) - mode="$2" - shift - shift - ;; - --device) - device="$2" - shift - shift - ;; - --mountpoint) - mountpoint="$2" - shift - shift - ;; - *) - die "Error: unknown argument: $1" - ;; - esac - done - - #pass non-empty arguments to --pass, --mountpoint, --device, --mode - mount-usb --device "$device" --mode "$mode" --mountpoint "$mountpoint" || die "Error mounting thumb drive's public partition" - #TODO: reuse "Obtain GPG key ID" so that pubkey on public thumb drive partition is named after key ID - gpg --export --armor "${GPG_USER_MAIL}" >"$mountpoint"/pubkey.asc || die "Error exporting public key to thumb drive's public partition" - umount "$mountpoint" || die "Error unmounting thumb drive's public partition" - - TRACE_FUNC + TRACE_FUNC + + #Sanity check on passed arguments + while [ $# -gt 0 ]; do + case "$1" in + --mode) + mode="$2" + shift + shift + ;; + --device) + device="$2" + shift + shift + ;; + --mountpoint) + mountpoint="$2" + shift + shift + ;; + *) + die "Error: unknown argument: $1" + ;; + esac + done + + #pass non-empty arguments to --pass, --mountpoint, --device, --mode + mount-usb --device "$device" --mode "$mode" --mountpoint "$mountpoint" || die "Error mounting thumb drive's public partition" + #TODO: reuse "Obtain GPG key ID" so that pubkey on public thumb drive partition is named after key ID + gpg --export --armor "${GPG_USER_MAIL}" >"$mountpoint"/pubkey.asc || die "Error exporting public key to thumb drive's public partition" + umount "$mountpoint" || die "Error unmounting thumb drive's public partition" + + TRACE_FUNC } # Select thumb drive and LUKS container size for GPG key export @@ -401,467 +401,467 @@ export_public_key_to_thumbdrive_public_partition() { # - thumb_drive # - thumb_drive_luks_percent select_thumb_drive_for_key_material() { - TRACE_FUNC - - #enable usb storage - enable_usb - enable_usb_storage - - prompt_insert_to_be_wiped_thumb_drive - - #loop until user chooses a disk - thumb_drive="" - while [ -z "$thumb_drive" ]; do - #list usb storage devices - list_usb_storage disks >/tmp/usb_disk_list - # Abort if: - # - no disks found (prevent file_selector's nonsense prompt) - # - file_selector fails for any reason - # - user aborts (file_selector succeeds but FILE is empty) - if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ] && - file_selector --show-size "/tmp/usb_disk_list" "Select USB device to partition" && - [ -n "$FILE" ]; then - # Obtain size of thumb drive to be wiped with fdisk - disk_size_bytes="$(blockdev --getsize64 "$FILE")" - if [ "$disk_size_bytes" -lt "$((128*1024*1024))" ]; then - warn "Thumb drive size is less than 128MB!" - warn "LUKS container needs to be at least 8MB!" - warn "If the next operation fails, try with a bigger thumb drive" - fi - - select_luks_container_size_percent - thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" - - if ! confirm_thumb_drive_format "$FILE" "$thumb_drive_luks_percent"; then - warn "Thumb drive wipe aborted by user!" - continue - fi - - #User chose and confirmed a thumb drive and its size to be wiped - thumb_drive=$FILE - else - #No USB storage device detected - warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership" - sleep 3 - die "No USB storage device detected! User decided to not wipe any thumb drive" - fi - done - thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" + TRACE_FUNC + + #enable usb storage + enable_usb + enable_usb_storage + + prompt_insert_to_be_wiped_thumb_drive + + #loop until user chooses a disk + thumb_drive="" + while [ -z "$thumb_drive" ]; do + #list usb storage devices + list_usb_storage disks >/tmp/usb_disk_list + # Abort if: + # - no disks found (prevent file_selector's nonsense prompt) + # - file_selector fails for any reason + # - user aborts (file_selector succeeds but FILE is empty) + if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ] && + file_selector --show-size "/tmp/usb_disk_list" "Select USB device to partition" && + [ -n "$FILE" ]; then + # Obtain size of thumb drive to be wiped with fdisk + disk_size_bytes="$(blockdev --getsize64 "$FILE")" + if [ "$disk_size_bytes" -lt "$((128 * 1024 * 1024))" ]; then + warn "Thumb drive size is less than 128MB!" + warn "LUKS container needs to be at least 8MB!" + warn "If the next operation fails, try with a bigger thumb drive" + fi + + select_luks_container_size_percent + thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" + + if ! confirm_thumb_drive_format "$FILE" "$thumb_drive_luks_percent"; then + warn "Thumb drive wipe aborted by user!" + continue + fi + + #User chose and confirmed a thumb drive and its size to be wiped + thumb_drive=$FILE + else + #No USB storage device detected + warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership" + sleep 3 + die "No USB storage device detected! User decided to not wipe any thumb drive" + fi + done + thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)" } #Wipe a thumb drive and export master key and subkeys to it # $1 - thumb drive block device # $2 - LUKS container percentage [1-99] wipe_thumb_drive_and_copy_gpg_key_material() { - TRACE_FUNC + TRACE_FUNC - local thumb_drive thumb_drive_luks_percent - thumb_drive="$1" - thumb_drive_luks_percent="$2" + local thumb_drive thumb_drive_luks_percent + thumb_drive="$1" + thumb_drive_luks_percent="$2" - #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) - prepare_thumb_drive "$thumb_drive" "$thumb_drive_luks_percent" "${ADMIN_PIN}" - #Export master key and subkeys to thumb drive first partition - export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" - #Export public key to thumb drive's public partition - export_public_key_to_thumbdrive_public_partition --mode rw --device "$thumb_drive"2 --mountpoint /media + #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) + prepare_thumb_drive "$thumb_drive" "$thumb_drive_luks_percent" "${ADMIN_PIN}" + #Export master key and subkeys to thumb drive first partition + export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" + #Export public key to thumb drive's public partition + export_public_key_to_thumbdrive_public_partition --mode rw --device "$thumb_drive"2 --mountpoint /media - TRACE_FUNC + TRACE_FUNC } gpg_key_factory_reset() { - TRACE_FUNC - - #enable usb storage - enable_usb - - # Factory reset GPG card - echo "GPG factory reset of USB Security Dongle's smartcard..." - { - echo admin # admin menu - echo factory-reset # factory reset smartcard - echo y # confirm - echo yes # confirm - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" - fi - # If Nitrokey Storage is inserted, reset AES keys as well - if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then - DEBUG "Nitrokey Storage detected, resetting AES keys..." - /bin/hotp_verification regenerate ${ADMIN_PIN_DEF} - DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" - killall -9 scdaemon - fi - # Toggle forced sig (good security practice, forcing PIN request for each signature request) - if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then - DEBUG "GPG toggling forcesig on since off..." - { - echo admin # admin menu - echo forcesig # toggle forcesig - echo ${ADMIN_PIN_DEF} # local keyring PIN - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key forcesig toggle on failed!\n\n$ERROR" - fi - fi - # use p256 for key generation if requested - if [ "$GPG_ALGO" = "p256" ]; then - { - echo admin # admin menu - echo key-attr # key attributes - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} # local keyring PIN - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} # local keyring PIN - echo 2 # ECC - echo 3 # P-256 - echo ${ADMIN_PIN_DEF} # local keyring PIN - } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed." - fi - # fallback to RSA key generation by default - elif [ "$GPG_ALGO" = "RSA" ]; then - DEBUG "GPG setting RSA key length to ${RSA_KEY_LENGTH} bits..." - # Set RSA key length - { - echo admin - echo key-attr - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Signing key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} #Local keyring PIN - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Encryption key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} #Local keyring PIN - echo 1 # RSA - echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH - echo ${ADMIN_PIN_DEF} #Local keyring PIN - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security Dongle failed." - fi - else - #Unknown GPG_ALGO - whiptail_error_die "Unknown GPG_ALGO: $GPG_ALGO" - fi - - TRACE_FUNC + TRACE_FUNC + + #enable usb storage + enable_usb + + # Factory reset GPG card + echo "GPG factory reset of USB Security Dongle's smartcard..." + { + echo admin # admin menu + echo factory-reset # factory reset smartcard + echo y # confirm + echo yes # confirm + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" + fi + # If Nitrokey Storage is inserted, reset AES keys as well + if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then + DEBUG "Nitrokey Storage detected, resetting AES keys..." + /bin/hotp_verification regenerate ${ADMIN_PIN_DEF} + DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" + killall -9 scdaemon + fi + # Toggle forced sig (good security practice, forcing PIN request for each signature request) + if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then + DEBUG "GPG toggling forcesig on since off..." + { + echo admin # admin menu + echo forcesig # toggle forcesig + echo ${ADMIN_PIN_DEF} # local keyring PIN + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key forcesig toggle on failed!\n\n$ERROR" + fi + fi + # use p256 for key generation if requested + if [ "$GPG_ALGO" = "p256" ]; then + { + echo admin # admin menu + echo key-attr # key attributes + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + echo 2 # ECC + echo 3 # P-256 + echo ${ADMIN_PIN_DEF} # local keyring PIN + } | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed." + fi + # fallback to RSA key generation by default + elif [ "$GPG_ALGO" = "RSA" ]; then + DEBUG "GPG setting RSA key length to ${RSA_KEY_LENGTH} bits..." + # Set RSA key length + { + echo admin + echo key-attr + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Signing key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} #Local keyring PIN + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Encryption key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} #Local keyring PIN + echo 1 # RSA + echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH + echo ${ADMIN_PIN_DEF} #Local keyring PIN + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security Dongle failed." + fi + else + #Unknown GPG_ALGO + whiptail_error_die "Unknown GPG_ALGO: $GPG_ALGO" + fi + + TRACE_FUNC } generate_OEM_gpg_keys() { - TRACE_FUNC - - #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in USB Security Dongle's smartcard..." - { - echo admin # admin menu - echo generate # generate keys - echo n # Do not export keys - echo ${ADMIN_PIN_DEF} # Default admin PIN since we just factory reset - echo ${USER_PIN_DEF} # Default user PIN since we just factory reset - echo 0 # No key expiration - echo ${GPG_USER_NAME} # User name - echo ${GPG_USER_MAIL} # User email - echo ${GPG_USER_COMMENT} # User comment - echo ${USER_PIN_DEF} # Default user PIN since we just factory reset - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" - fi - - TRACE_FUNC + TRACE_FUNC + + #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset + echo "Generating GPG keys in USB Security Dongle's smartcard..." + { + echo admin # admin menu + echo generate # generate keys + echo n # Do not export keys + echo ${ADMIN_PIN_DEF} # Default admin PIN since we just factory reset + echo ${USER_PIN_DEF} # Default user PIN since we just factory reset + echo 0 # No key expiration + echo ${GPG_USER_NAME} # User name + echo ${GPG_USER_MAIL} # User email + echo ${GPG_USER_COMMENT} # User comment + echo ${USER_PIN_DEF} # Default user PIN since we just factory reset + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output) + whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" + fi + + TRACE_FUNC } gpg_key_change_pin() { - TRACE_FUNC - DEBUG "Changing GPG key PIN" - # 1 = user PIN, 3 = admin PIN - PIN_TYPE=$1 - PIN_ORIG=${2} - PIN_NEW=${3} - # Change PIN - { - echo admin # admin menu - echo passwd # change PIN - echo ${PIN_TYPE} # 1 = user PIN, 3 = admin PIN - echo ${PIN_ORIG} # old PIN - echo ${PIN_NEW} # new PIN - echo ${PIN_NEW} # confirm new PIN - echo q # quit - echo q - } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ - >/tmp/gpg_card_edit_output 2>&1 - if [ $? -ne 0 ]; then - ERROR=$(cat /tmp/gpg_card_edit_output | fold -s) - whiptail_error_die "GPG Key PIN change failed!\n\n$ERROR" - fi - - TRACE_FUNC + TRACE_FUNC + DEBUG "Changing GPG key PIN" + # 1 = user PIN, 3 = admin PIN + PIN_TYPE=$1 + PIN_ORIG=${2} + PIN_NEW=${3} + # Change PIN + { + echo admin # admin menu + echo passwd # change PIN + echo ${PIN_TYPE} # 1 = user PIN, 3 = admin PIN + echo ${PIN_ORIG} # old PIN + echo ${PIN_NEW} # new PIN + echo ${PIN_NEW} # confirm new PIN + echo q # quit + echo q + } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ + >/tmp/gpg_card_edit_output 2>&1 + if [ $? -ne 0 ]; then + ERROR=$(cat /tmp/gpg_card_edit_output | fold -s) + whiptail_error_die "GPG Key PIN change failed!\n\n$ERROR" + fi + + TRACE_FUNC } generate_checksums() { - TRACE_FUNC - - # ensure /boot mounted - if ! grep -q /boot /proc/mounts; then - mount -o rw /boot || whiptail_error_die "Unable to mount /boot" - else - mount -o remount,rw /boot || whiptail_error_die "Unable to mount /boot" - fi - - #Check if previous LUKS TPM Disk Unlock Key was set - if [ -e /boot/kexec_key_devices.txt ]; then - TPM_DISK_ENCRYPTION_KEY_SET=1 - fi - - # clear any existing checksums/signatures - rm /boot/kexec* 2>/dev/null - - # create Heads TPM counter - if [ "$CONFIG_TPM" = "y" ]; then - if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then - tpmr counter_create \ - -pwdc '' \ - -la -3135106223 | - tee /tmp/counter || - whiptail_error_die "Unable to create TPM counter" - TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1 || - whiptail_error_die "Unable to increment tpm counter" - - # create rollback file - sha256sum /tmp/counter-$TPM_COUNTER >/boot/kexec_rollback.txt 2>/dev/null || - whiptail_error_die "Unable to create rollback file" - else - ## needs to exist for initial call to unseal-hotp - echo "0" >/boot/kexec_hotp_counter - fi - fi - - # set default boot option only if no LUKS TPM Disk Unlock Key previously set - if [ -z "$TPM_DISK_ENCRYPTION_KEY_SET" ]; then - set_default_boot_option - fi - - DEBUG "Generating hashes" - ( - set -e -o pipefail - cd /boot - find ./ -type f ! -path './kexec*' -print0 | - xargs -0 sha256sum >/boot/kexec_hashes.txt 2>/dev/null - print_tree >/boot/kexec_tree.txt - ) - [ $? -eq 0 ] || whiptail_error_die "Error generating kexec hashes" - - param_files=$(find /boot/kexec*.txt) - [ -z "$param_files" ] && - whiptail_error_die "No kexec parameter files to sign" - - if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" -a "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "n" ]; then - #The local keyring used to generate in memory subkeys is still valid since no key has been moved to smartcard - #Local keyring passwd is ADMIN_PIN. We need to set USER_PIN to ADMIN_PIN to be able to sign next in this boot session - DEBUG "Setting GPG User PIN to GPG Admin PIN so local keyring can be used to detach-sign kexec files next" - USER_PIN=$ADMIN_PIN - fi - - DEBUG "Detach-signing boot files under kexec.sig: ${param_files}" - if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG --mask-position 4 gpg \ - --pinentry-mode loopback \ - --passphrase "${USER_PIN}" \ - --digest-algo SHA256 \ - --detach-sign \ - -a \ - >/boot/kexec.sig 2>/tmp/error; then - # successful - update the validated params - if ! check_config /boot >/dev/null 2>/tmp/error; then - cat /tmp/error - ret=1 - else - ret=0 - fi - else - cat /tmp/error - ret=1 - fi - - # done writing to /boot, switch back to RO - mount -o ro,remount /boot - - if [ $ret = 1 ]; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error signing kexec boot files:\n\n$ERROR" - fi - - TRACE_FUNC + TRACE_FUNC + + # ensure /boot mounted + if ! grep -q /boot /proc/mounts; then + mount -o rw /boot || whiptail_error_die "Unable to mount /boot" + else + mount -o remount,rw /boot || whiptail_error_die "Unable to mount /boot" + fi + + #Check if previous LUKS TPM Disk Unlock Key was set + if [ -e /boot/kexec_key_devices.txt ]; then + TPM_DISK_ENCRYPTION_KEY_SET=1 + fi + + # clear any existing checksums/signatures + rm /boot/kexec* 2>/dev/null + + # create Heads TPM counter + if [ "$CONFIG_TPM" = "y" ]; then + if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then + tpmr counter_create \ + -pwdc '' \ + -la -3135106223 | + tee /tmp/counter || + whiptail_error_die "Unable to create TPM counter" + TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1 || + whiptail_error_die "Unable to increment tpm counter" + + # create rollback file + sha256sum /tmp/counter-$TPM_COUNTER >/boot/kexec_rollback.txt 2>/dev/null || + whiptail_error_die "Unable to create rollback file" + else + ## needs to exist for initial call to unseal-hotp + echo "0" >/boot/kexec_hotp_counter + fi + fi + + # set default boot option only if no LUKS TPM Disk Unlock Key previously set + if [ -z "$TPM_DISK_ENCRYPTION_KEY_SET" ]; then + set_default_boot_option + fi + + DEBUG "Generating hashes" + ( + set -e -o pipefail + cd /boot + find ./ -type f ! -path './kexec*' -print0 | + xargs -0 sha256sum >/boot/kexec_hashes.txt 2>/dev/null + print_tree >/boot/kexec_tree.txt + ) + [ $? -eq 0 ] || whiptail_error_die "Error generating kexec hashes" + + param_files=$(find /boot/kexec*.txt) + [ -z "$param_files" ] && + whiptail_error_die "No kexec parameter files to sign" + + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" -a "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "n" ]; then + #The local keyring used to generate in memory subkeys is still valid since no key has been moved to smartcard + #Local keyring passwd is ADMIN_PIN. We need to set USER_PIN to ADMIN_PIN to be able to sign next in this boot session + DEBUG "Setting GPG User PIN to GPG Admin PIN so local keyring can be used to detach-sign kexec files next" + USER_PIN=$ADMIN_PIN + fi + + DEBUG "Detach-signing boot files under kexec.sig: ${param_files}" + if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG gpg \ + --pinentry-mode loopback \ + --passphrase "${USER_PIN}" \ + --digest-algo SHA256 \ + --detach-sign \ + -a \ + >/boot/kexec.sig 2>/tmp/error; then + # successful - update the validated params + if ! check_config /boot >/dev/null 2>/tmp/error; then + cat /tmp/error + ret=1 + else + ret=0 + fi + else + cat /tmp/error + ret=1 + fi + + # done writing to /boot, switch back to RO + mount -o ro,remount /boot + + if [ $ret = 1 ]; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error signing kexec boot files:\n\n$ERROR" + fi + + TRACE_FUNC } set_default_boot_option() { - TRACE_FUNC - - option_file="/tmp/kexec_options.txt" - tmp_menu_file="/tmp/kexec/kexec_menu.txt" - hash_file="/boot/kexec_default_hashes.txt" - - mkdir -p /tmp/kexec/ - rm $option_file 2>/dev/null - # parse boot options from grub.cfg - for i in $(find /boot -name "grub.cfg"); do - kexec-parse-boot "/boot" "$i" >>$option_file - done - # FC29/30+ may use BLS format grub config files - # https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault - # only parse these if $option_file is still empty - if [ ! -s $option_file ] && [ -d "/boot/loader/entries" ]; then - for i in $(find /boot -name "grub.cfg"); do - kexec-parse-bls "/boot" "$i" "/boot/loader/entries" >>$option_file - done - fi - [ ! -s $option_file ] && - whiptail_error_die "Failed to parse any boot options" - - # sort boot options - sort -r $option_file | uniq >$tmp_menu_file - - ## save first option as default - entry=$(head -n 1 $tmp_menu_file | tail -1) - - # clear existing default configs - rm "/boot/kexec_default.*.txt" 2>/dev/null - - # get correct index for entry - index=$(grep -n "$entry" $option_file | cut -f1 -d ':') - - # write new config - echo "$entry" >/boot/kexec_default.$index.txt - - # validate boot option - (cd /boot && /bin/kexec-boot -b "/boot" -e "$entry" -f | - xargs sha256sum >$hash_file 2>/dev/null) || - whiptail_error_die "Failed to create hashes of boot files" - - TRACE_FUNC + TRACE_FUNC + + option_file="/tmp/kexec_options.txt" + tmp_menu_file="/tmp/kexec/kexec_menu.txt" + hash_file="/boot/kexec_default_hashes.txt" + + mkdir -p /tmp/kexec/ + rm $option_file 2>/dev/null + # parse boot options from grub.cfg + for i in $(find /boot -name "grub.cfg"); do + kexec-parse-boot "/boot" "$i" >>$option_file + done + # FC29/30+ may use BLS format grub config files + # https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault + # only parse these if $option_file is still empty + if [ ! -s $option_file ] && [ -d "/boot/loader/entries" ]; then + for i in $(find /boot -name "grub.cfg"); do + kexec-parse-bls "/boot" "$i" "/boot/loader/entries" >>$option_file + done + fi + [ ! -s $option_file ] && + whiptail_error_die "Failed to parse any boot options" + + # sort boot options + sort -r $option_file | uniq >$tmp_menu_file + + ## save first option as default + entry=$(head -n 1 $tmp_menu_file | tail -1) + + # clear existing default configs + rm "/boot/kexec_default.*.txt" 2>/dev/null + + # get correct index for entry + index=$(grep -n "$entry" $option_file | cut -f1 -d ':') + + # write new config + echo "$entry" >/boot/kexec_default.$index.txt + + # validate boot option + (cd /boot && /bin/kexec-boot -b "/boot" -e "$entry" -f | + xargs sha256sum >$hash_file 2>/dev/null) || + whiptail_error_die "Failed to create hashes of boot files" + + TRACE_FUNC } report_integrity_measurements() { - TRACE_FUNC - - #check for GPG key in keyring - GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) - if [ "$GPG_KEY_COUNT" -ne 0 ]; then - # Check and report TOTP - # update the TOTP code every thirty seconds - date=$(date "+%Y-%m-%d %H:%M:%S %Z") - seconds=$(date "+%s") - half=$(expr \( "$seconds" % 60 \) / 30) - if [ "$CONFIG_TPM" != "y" ]; then - TOTP="NO TPM" - elif [ "$half" != "$last_half" ]; then - last_half=$half - TOTP=$(unseal-totp) >/dev/null 2>&1 - fi - - # Check and report on HOTP status - if [ -x /bin/hotp_verification ]; then - HOTP="Unverified" - enable_usb - for attempt in 1 2 3; do - if ! hotp_verification info >/dev/null 2>&1; then - whiptail_warning --title "WARNING: Please insert your HOTP enabled USB Security Dongle (Attempt $attempt/3)" --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 - else - break - fi - done - - if [ $attempt -eq 3 ]; then - die "No HOTP enabled USB Security Dongle detected. Please disable 'CONFIG_HOTPKEY' in the board config and rebuild." - fi - - # Don't output HOTP codes to screen, so as to make replay attacks harder - HOTP=$(unseal-hotp) >/dev/null 2>&1 - hotp_verification check $HOTP - case "$?" in - 0) - HOTP="Success" - ;; - 4) - HOTP="Invalid code" - BG_COLOR_MAIN_MENU="error" - ;; - *) - HOTP="Error checking code, Insert USB Security Dongle and retry" - BG_COLOR_MAIN_MENU="warning" - ;; - esac - else - HOTP='N/A' - fi - # Check for detached signed digest and report on /boot integrity status - check_config /boot force - TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" - - if (cd /boot && sha256sum -c "$TMP_HASH_FILE" >/tmp/hash_output); then - HASH="OK" - else - HASH="ALTERED" - fi - - #Show results - whiptail_type $BG_COLOR_MAIN_MENU --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 - fi - - TRACE_FUNC + TRACE_FUNC + + #check for GPG key in keyring + GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) + if [ "$GPG_KEY_COUNT" -ne 0 ]; then + # Check and report TOTP + # update the TOTP code every thirty seconds + date=$(date "+%Y-%m-%d %H:%M:%S %Z") + seconds=$(date "+%s") + half=$(expr \( "$seconds" % 60 \) / 30) + if [ "$CONFIG_TPM" != "y" ]; then + TOTP="NO TPM" + elif [ "$half" != "$last_half" ]; then + last_half=$half + TOTP=$(unseal-totp) >/dev/null 2>&1 + fi + + # Check and report on HOTP status + if [ -x /bin/hotp_verification ]; then + HOTP="Unverified" + enable_usb + for attempt in 1 2 3; do + if ! hotp_verification info >/dev/null 2>&1; then + whiptail_warning --title "WARNING: Please insert your HOTP enabled USB Security Dongle (Attempt $attempt/3)" --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + else + break + fi + done + + if [ $attempt -eq 3 ]; then + die "No HOTP enabled USB Security Dongle detected. Please disable 'CONFIG_HOTPKEY' in the board config and rebuild." + fi + + # Don't output HOTP codes to screen, so as to make replay attacks harder + HOTP=$(unseal-hotp) >/dev/null 2>&1 + hotp_verification check $HOTP + case "$?" in + 0) + HOTP="Success" + ;; + 4) + HOTP="Invalid code" + BG_COLOR_MAIN_MENU="error" + ;; + *) + HOTP="Error checking code, Insert USB Security Dongle and retry" + BG_COLOR_MAIN_MENU="warning" + ;; + esac + else + HOTP='N/A' + fi + # Check for detached signed digest and report on /boot integrity status + check_config /boot force + TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + + if (cd /boot && sha256sum -c "$TMP_HASH_FILE" >/tmp/hash_output); then + HASH="OK" + else + HASH="ALTERED" + fi + + #Show results + whiptail_type $BG_COLOR_MAIN_MENU --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 + fi + + TRACE_FUNC } usb_security_token_capabilities_check() { - TRACE_FUNC - - enable_usb - # ... first set board config preference - if [ -n "$CONFIG_GPG_ALGO" ]; then - GPG_ALGO=$CONFIG_GPG_ALGO - DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" - fi - # ... overwrite with usb-token capability - if lsusb | grep -q "20a0:42b2"; then - GPG_ALGO="p256" - DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" - fi + TRACE_FUNC + + enable_usb + # ... first set board config preference + if [ -n "$CONFIG_GPG_ALGO" ]; then + GPG_ALGO=$CONFIG_GPG_ALGO + DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO" + fi + # ... overwrite with usb-token capability + if lsusb | grep -q "20a0:42b2"; then + GPG_ALGO="p256" + DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" + fi } ## main script start # check for args if [ "$1" != "" ]; then - title_text=$1 + title_text=$1 else - title_text="OEM Factory Reset / Re-Ownership" + title_text="OEM Factory Reset / Re-Ownership" fi if [ "$2" != "" ]; then - bg_color=$2 + bg_color=$2 else - bg_color="" + bg_color="" fi # show warning prompt if [ "$CONFIG_TPM" = "y" ]; then - TPM_STR=" * ERASE the TPM and own it with a password\n" + TPM_STR=" * ERASE the TPM and own it with a password\n" else - TPM_STR="" + TPM_STR="" fi if ! whiptail_warning --yesno " This operation will automatically:\n @@ -873,8 +873,8 @@ $TPM_STR * Sign all of the files in /boot with the new GPG key\n\n It requires that you already have an OS installed on a\n dedicated /boot partition. Do you wish to continue?" \ - $HEIGHT $WIDTH $CONTINUE $CANCEL $CLEAR --title "$title_text"; then - exit 1 + $HEIGHT $WIDTH $CONTINUE $CANCEL $CLEAR --title "$title_text"; then + exit 1 fi #Make sure /boot is mounted if board config defines default @@ -891,191 +891,191 @@ echo -e -n "Would you like to use default configuration options?\nIf N, you will read -n 1 use_defaults if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then - #Give general guidance to user on how to answer prompts - echo - echo "****************************************************" - echo "**** Factory Reset / Re-Ownership Questionnaire ****" - echo "****************************************************" - echo "The following questionnaire will help you configure the security components of your system." - echo "Each prompt requires a single letter answer: eg. (Y/n)." - echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" - - # Re-ownership of LUKS encrypted Disk: key, content and passphrase - echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past configured passphrase would not permit to access content.\n Note that without re-encrypting disk, a backed up header could be restored to access encrypted content with old passphrase) [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - luks_new_Disk_Recovery_Key_passphrase_desired=1 - echo -e "\n" - fi - - echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new LUKS Disk Recovery Key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backed up header to be restored to access encrypted data) [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - TRACE_FUNC - test_luks_current_disk_recovery_key_passphrase - luks_new_Disk_Recovery_Key_desired=1 - echo -e "\n" - fi - - #Prompt to ask if user wants to generate GPG key material in memory or on smartcard - echo -e -n "Would you like to format an encrypted USB Thumb drive to store GPG key material?\n (Required to enable GPG authentication) [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ] \ - ; then - GPG_GEN_KEY_IN_MEMORY="y" - echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" - echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "n" \ - -o "$prompt_output" == "N" ]; then - warn "Subkeys will NOT be copied to USB Security Dongle's smartcard" - warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" - GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" - else - echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++" - warn "Please keep your GPG key material backup thumb drive safe" - GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="y" - fi - else - echo "GPG key material will be generated on USB Security Dongle's smartcard without backup" - GPG_GEN_KEY_IN_MEMORY="n" - GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" - fi - - # Dynamic messages to be given to user in terms of security components that will be applied - # based on previous answers - CUSTOM_PASS_AFFECTED_COMPONENTS="\n" - # Adapt message to be given to user in terms of security components that will be applied. - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="LUKS Disk Recovery Key passphrase\n" - fi - if [ "$CONFIG_TPM" = "y" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" - fi - if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same as GPG Admin PIN)\n" - fi - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" - # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY not requested or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is - if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" - fi - - # Inform user of security components affected for the following prompts - echo - echo -e "The following Security Components will be configured with defaults or further chosen PINs/passwords: + #Give general guidance to user on how to answer prompts + echo + echo "****************************************************" + echo "**** Factory Reset / Re-Ownership Questionnaire ****" + echo "****************************************************" + echo "The following questionnaire will help you configure the security components of your system." + echo "Each prompt requires a single letter answer: eg. (Y/n)." + echo -e "If you don't know what to answer, pressing Enter will select the default answer for that prompt: eg. Y, above.\n" + + # Re-ownership of LUKS encrypted Disk: key, content and passphrase + echo -e -n "\n\nWould you like to change the current LUKS Disk Recovery Key passphrase?\n (Highly recommended if you didn't install the Operating System yourself, so that past configured passphrase would not permit to access content.\n Note that without re-encrypting disk, a backed up header could be restored to access encrypted content with old passphrase) [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + luks_new_Disk_Recovery_Key_passphrase_desired=1 + echo -e "\n" + fi + + echo -e -n "Would you like to re-encrypt LUKS encrypted container and generate new LUKS Disk Recovery Key?\n (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backed up header to be restored to access encrypted data) [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + TRACE_FUNC + test_luks_current_disk_recovery_key_passphrase + luks_new_Disk_Recovery_Key_desired=1 + echo -e "\n" + fi + + #Prompt to ask if user wants to generate GPG key material in memory or on smartcard + echo -e -n "Would you like to format an encrypted USB Thumb drive to store GPG key material?\n (Required to enable GPG authentication) [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ] \ + ; then + GPG_GEN_KEY_IN_MEMORY="y" + echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" + echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "n" \ + -o "$prompt_output" == "N" ]; then + warn "Subkeys will NOT be copied to USB Security Dongle's smartcard" + warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" + else + echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++" + warn "Please keep your GPG key material backup thumb drive safe" + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="y" + fi + else + echo "GPG key material will be generated on USB Security Dongle's smartcard without backup" + GPG_GEN_KEY_IN_MEMORY="n" + GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" + fi + + # Dynamic messages to be given to user in terms of security components that will be applied + # based on previous answers + CUSTOM_PASS_AFFECTED_COMPONENTS="\n" + # Adapt message to be given to user in terms of security components that will be applied. + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -o -n "$luks_new_Disk_Recovery_Key_passphrase" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="LUKS Disk Recovery Key passphrase\n" + fi + if [ "$CONFIG_TPM" = "y" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="TPM Owner Password\n" + fi + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Key material backup passphrase (Same as GPG Admin PIN)\n" + fi + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG Admin PIN\n" + # Only show GPG User PIN as affected component if GPG_GEN_KEY_IN_MEMORY not requested or GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is + if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then + CUSTOM_PASS_AFFECTED_COMPONENTS+="GPG User PIN\n" + fi + + # Inform user of security components affected for the following prompts + echo + echo -e "The following Security Components will be configured with defaults or further chosen PINs/passwords: $CUSTOM_PASS_AFFECTED_COMPONENTS\n" - # Prompt to change default passwords - echo -e -n "Would you like to set a single custom password to all previously stated security components? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\nThe chosen custom password must be between 8 and $MAX_HOTP_GPG_PIN_LENGTH characters in length." - while [[ ${#CUSTOM_SINGLE_PASS} -lt 8 ]] || [[ ${#CUSTOM_SINGLE_PASS} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do - echo -e -n "Enter the custom password: " - read CUSTOM_SINGLE_PASS - done - echo - TPM_PASS=${CUSTOM_SINGLE_PASS} - USER_PIN=${CUSTOM_SINGLE_PASS} - ADMIN_PIN=${CUSTOM_SINGLE_PASS} - - # Only set if user said desired - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} - fi - else - echo -e -n "Would you like to set distinct PINs/passwords to configure previously stated security components? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\nThe TPM Owner Password and Admin PIN must be at least 8, the User PIN at least 6 characters in length.\n" - echo - if [ "$CONFIG_TPM" = "y" ]; then - while [[ ${#TPM_PASS} -lt 8 ]]; do - echo -e -n "Enter desired TPM Owner Password: " - read TPM_PASS - done - fi - while [[ ${#ADMIN_PIN} -lt 6 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do - echo -e -n "\nThis PIN should be between 6 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" - echo -e -n "Enter desired GPG Admin PIN: " - read ADMIN_PIN - done - #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY not requested of if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is - # That is, if keys were NOT generated in memory (on smartcard only) or - # if keys were generated in memory but are to be moved from local keyring to smartcard - if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - while [[ ${#USER_PIN} -lt 6 ]] || [[ ${#USER_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do - echo -e -n "\nThis PIN should be between 6 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" - echo -e -n "Enter desired GPG User PIN: " - read USER_PIN - done - fi - echo - fi - fi - - if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then - # We catch here if changing LUKS Disk Recovery Key passphrase was desired - # but yet undone. This is if not being covered by the single password - echo -e "\nEnter desired replacement for current LUKS Disk Recovery Key passphrase (At least 8 characters long):" - while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do - { - read -r luks_new_Disk_Recovery_Key_passphrase - } - done - #We test that current LUKS Disk Recovery Key passphrase is known prior of going further - TRACE_FUNC - test_luks_current_disk_recovery_key_passphrase - echo -e "\n" - fi - - # Prompt to change default GnuPG key information - echo -e -n "Would you like to set custom user information for the GnuPG key? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ]; then - echo -e "\n\n" - echo -e "We will generate a GnuPG (PGP) keypair identifiable with the following text form:" - echo -e "Real Name (Comment) email@address.org" - - echo -e "\nEnter your Real Name (Optional):" - read -r GPG_USER_NAME - - echo -e "\nEnter your email@adress.org:" - read -r GPG_USER_MAIL - while ! $(expr "$GPG_USER_MAIL" : '.*@' >/dev/null); do - { - echo -e "\nEnter your email@address.org:" - read -r GPG_USER_MAIL - } - done - - echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" - read -r GPG_USER_COMMENT - while [[ ${#GPG_USER_COMMENT} -gt 60 ]]; do - { - echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" - read -r GPG_USER_COMMENT - } - done - fi - - if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then - select_thumb_drive_for_key_material - fi + # Prompt to change default passwords + echo -e -n "Would you like to set a single custom password to all previously stated security components? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\nThe chosen custom password must be between 8 and $MAX_HOTP_GPG_PIN_LENGTH characters in length." + while [[ ${#CUSTOM_SINGLE_PASS} -lt 8 ]] || [[ ${#CUSTOM_SINGLE_PASS} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "Enter the custom password: " + read CUSTOM_SINGLE_PASS + done + echo + TPM_PASS=${CUSTOM_SINGLE_PASS} + USER_PIN=${CUSTOM_SINGLE_PASS} + ADMIN_PIN=${CUSTOM_SINGLE_PASS} + + # Only set if user said desired + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then + luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} + fi + else + echo -e -n "Would you like to set distinct PINs/passwords to configure previously stated security components? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\nThe TPM Owner Password and Admin PIN must be at least 8, the User PIN at least 6 characters in length.\n" + echo + if [ "$CONFIG_TPM" = "y" ]; then + while [[ ${#TPM_PASS} -lt 8 ]]; do + echo -e -n "Enter desired TPM Owner Password: " + read TPM_PASS + done + fi + while [[ ${#ADMIN_PIN} -lt 6 ]] || [[ ${#ADMIN_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "\nThis PIN should be between 6 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" + echo -e -n "Enter desired GPG Admin PIN: " + read ADMIN_PIN + done + #USER PIN not required in case of GPG_GEN_KEY_IN_MEMORY not requested of if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is + # That is, if keys were NOT generated in memory (on smartcard only) or + # if keys were generated in memory but are to be moved from local keyring to smartcard + if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then + while [[ ${#USER_PIN} -lt 6 ]] || [[ ${#USER_PIN} -gt $MAX_HOTP_GPG_PIN_LENGTH ]]; do + echo -e -n "\nThis PIN should be between 6 to $MAX_HOTP_GPG_PIN_LENGTH characters in length.\n" + echo -e -n "Enter desired GPG User PIN: " + read USER_PIN + done + fi + echo + fi + fi + + if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase" ]; then + # We catch here if changing LUKS Disk Recovery Key passphrase was desired + # but yet undone. This is if not being covered by the single password + echo -e "\nEnter desired replacement for current LUKS Disk Recovery Key passphrase (At least 8 characters long):" + while [[ ${#luks_new_Disk_Recovery_Key_passphrase} -lt 8 ]]; do + { + read -r luks_new_Disk_Recovery_Key_passphrase + } + done + #We test that current LUKS Disk Recovery Key passphrase is known prior of going further + TRACE_FUNC + test_luks_current_disk_recovery_key_passphrase + echo -e "\n" + fi + + # Prompt to change default GnuPG key information + echo -e -n "Would you like to set custom user information for the GnuPG key? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ]; then + echo -e "\n\n" + echo -e "We will generate a GnuPG (PGP) keypair identifiable with the following text form:" + echo -e "Real Name (Comment) email@address.org" + + echo -e "\nEnter your Real Name (Optional):" + read -r GPG_USER_NAME + + echo -e "\nEnter your email@adress.org:" + read -r GPG_USER_MAIL + while ! $(expr "$GPG_USER_MAIL" : '.*@' >/dev/null); do + { + echo -e "\nEnter your email@address.org:" + read -r GPG_USER_MAIL + } + done + + echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" + read -r GPG_USER_COMMENT + while [[ ${#GPG_USER_COMMENT} -gt 60 ]]; do + { + echo -e "\nEnter Comment (Optional, to distinguish this key from others with same previous attributes. Must be smaller then 60 characters):" + read -r GPG_USER_COMMENT + } + done + fi + + if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then + select_thumb_drive_for_key_material + fi fi # If nothing is stored in custom variables, we set them to their defaults @@ -1086,49 +1086,49 @@ if [ "$ADMIN_PIN" == "" ]; then ADMIN_PIN=${ADMIN_PIN_DEF}; fi ## sanity check the USB, GPG key, and boot device before proceeding further if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" ]; then - # Prompt to insert USB drive if desired - echo -e -n "\nWould you like to export your public key to an USB drive? [y/N]: " - read -n 1 prompt_output - echo - if [ "$prompt_output" == "y" \ - -o "$prompt_output" == "Y" ] \ - ; then - GPG_EXPORT=1 - # mount USB over /media only if not already mounted - if ! grep -q /media /proc/mounts; then - # mount USB in rw - if ! mount-usb --mode rw 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Unable to mount USB on /media:\n\n${ERROR}" - fi - else - #/media already mounted, make sure it is in r+w mode - if ! mount -o remount,rw /media 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Unable to remount in read+write USB on /media:\n\n${ERROR}" - fi - fi - else - GPG_EXPORT=0 - # needed for USB Security Dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 - enable_usb - fi + # Prompt to insert USB drive if desired + echo -e -n "\nWould you like to export your public key to an USB drive? [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" \ + -o "$prompt_output" == "Y" ] \ + ; then + GPG_EXPORT=1 + # mount USB over /media only if not already mounted + if ! grep -q /media /proc/mounts; then + # mount USB in rw + if ! mount-usb --mode rw 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Unable to mount USB on /media:\n\n${ERROR}" + fi + else + #/media already mounted, make sure it is in r+w mode + if ! mount -o remount,rw /media 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Unable to remount in read+write USB on /media:\n\n${ERROR}" + fi + fi + else + GPG_EXPORT=0 + # needed for USB Security Dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 + enable_usb + fi fi # ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - echo -e "\nChecking for USB Security Dongle...\n" - 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." - 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}" - fi - fi - - #Now that USB Security Dongle is detected, we can check its capabilities and limitations - usb_security_token_capabilities_check + echo -e "\nChecking for USB Security Dongle...\n" + 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." + 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}" + fi + fi + + #Now that USB Security Dongle is detected, we can check its capabilities and limitations + usb_security_token_capabilities_check fi assert_signable @@ -1143,37 +1143,37 @@ rm -rf /.gnupg/*.kbx /.gnupg/*.gpg >/dev/null 2>&1 || true # detect and set /boot device echo -e "\nDetecting and setting boot device...\n" if ! detect_boot_device; then - SKIP_BOOT="y" + SKIP_BOOT="y" else - echo -e "Boot device set to $CONFIG_BOOT_DEV\n" + echo -e "Boot device set to $CONFIG_BOOT_DEV\n" fi # update configs if [[ "$SKIP_BOOT" == "n" ]]; then - replace_config /etc/config.user "CONFIG_BOOT_DEV" "$CONFIG_BOOT_DEV" - combine_configs + replace_config /etc/config.user "CONFIG_BOOT_DEV" "$CONFIG_BOOT_DEV" + combine_configs fi if [ -n "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Reencryption of disk, LUKS Disk Recovery Key and LUKS Disk Recovery Key passphrase change is requested - luks_reencrypt - luks_change_passphrase + #Reencryption of disk, LUKS Disk Recovery Key and LUKS Disk Recovery Key passphrase change is requested + luks_reencrypt + luks_change_passphrase elif [ -n "$luks_new_Disk_Recovery_Key_desired" -a -z "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Reencryption of disk was requested but not passphrase change - luks_reencrypt + #Reencryption of disk was requested but not passphrase change + luks_reencrypt elif [ -z "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - #Passphrase change is requested without disk reencryption - luks_change_passphrase + #Passphrase change is requested without disk reencryption + luks_change_passphrase fi ## reset TPM and set password if [ "$CONFIG_TPM" = "y" ]; then - echo -e "\nResetting TPM...\n" - tpmr reset "$TPM_PASS" >/dev/null 2>/tmp/error + echo -e "\nResetting TPM...\n" + tpmr reset "$TPM_PASS" >/dev/null 2>/tmp/error fi if [ $? -ne 0 ]; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error resetting TPM:\n\n${ERROR}" + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error resetting TPM:\n\n${ERROR}" fi # clear local keyring @@ -1184,24 +1184,24 @@ gpg --list-keys >/dev/null 2>&1 #Generate keys in memory and copy to smartcard if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then - if [ "$GPG_ALGO" == "RSA" ]; then - # Generate GPG master key - generate_inmemory_RSA_master_and_subkeys - elif [ "$GPG_ALGO" == "p256" ]; then - generate_inmemory_p256_master_and_subkeys - else - die "Unsupported GPG_ALGO: $GPG_ALGO" - fi - wipe_thumb_drive_and_copy_gpg_key_material "$thumb_drive" "$thumb_drive_luks_percent" - set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" - if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - keytocard_subkeys_to_smartcard - fi + if [ "$GPG_ALGO" == "RSA" ]; then + # Generate GPG master key + generate_inmemory_RSA_master_and_subkeys + elif [ "$GPG_ALGO" == "p256" ]; then + generate_inmemory_p256_master_and_subkeys + else + die "Unsupported GPG_ALGO: $GPG_ALGO" + fi + wipe_thumb_drive_and_copy_gpg_key_material "$thumb_drive" "$thumb_drive_luks_percent" + set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" + if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then + keytocard_subkeys_to_smartcard + fi else - #Generate GPG key and subkeys on smartcard only - echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" - gpg_key_factory_reset - generate_OEM_gpg_keys + #Generate GPG key and subkeys on smartcard only + echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" + gpg_key_factory_reset + generate_OEM_gpg_keys fi # Obtain GPG key ID @@ -1211,101 +1211,101 @@ PUBKEY="/tmp/${GPG_GEN_KEY}.asc" # export pubkey to file if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR" fi #Applying custom GPG PINs to the smartcard if they were provided if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - #Only apply smartcard PIN change if smartcard only or if keytocard op is expected next - if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then - echo -e "\nChanging default GPG Admin PIN\n" - gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" - echo -e "\nChanging default GPG User PIN\n" - gpg_key_change_pin "1" "${USER_PIN_DEF}" "${USER_PIN}" - fi + #Only apply smartcard PIN change if smartcard only or if keytocard op is expected next + if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then + echo -e "\nChanging default GPG Admin PIN\n" + gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" + echo -e "\nChanging default GPG User PIN\n" + gpg_key_change_pin "1" "${USER_PIN_DEF}" "${USER_PIN}" + fi fi ## export pubkey to USB if [ "$GPG_EXPORT" != "0" ]; then - echo -e "\nExporting generated key to USB...\n" - # copy to USB - if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" - fi - mount -o remount,ro /media 2>/dev/null + echo -e "\nExporting generated key to USB...\n" + # copy to USB + if ! cp "${PUBKEY}" "/media/${GPG_GEN_KEY}.asc" 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Key export error: unable to copy ${GPG_GEN_KEY}.asc to /media:\n\n$ERROR" + fi + mount -o remount,ro /media 2>/dev/null fi # ensure key imported locally if ! cat "$PUBKEY" | DO_WITH_DEBUG gpg --import >/dev/null 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error importing GPG key:\n\n$ERROR" + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error importing GPG key:\n\n$ERROR" fi # update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys if ! gpg --list-keys --fingerprint --with-colons 2>/dev/null | - sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' | - gpg --import-ownertrust >/dev/null 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error importing GPG ownertrust:\n\n$ERROR" + sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' | + gpg --import-ownertrust >/dev/null 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error importing GPG ownertrust:\n\n$ERROR" fi if ! gpg --update-trust >/dev/null 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error updating GPG ownertrust:\n\n$ERROR" fi # Do not attempt to flash the key to ROM if we are running in QEMU based on CONFIG_BOARD_NAME matching glob pattern containing qemu-* # We check for qemu-* instead of ^qemu- because CONFIG_BOARD_NAME could be renamed to UNTESTED-qemu-* in a probable future if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then - warn "Skipping flash of GPG key to ROM because we are running in QEMU without internal flashing support." - warn "Please review boards/qemu*/qemu*.md documentation to extract public key from raw disk and inject at build time" - warn "Also review boards/qemu*/qemu*.config to tweak CONFIG_* options you might need to turn on/off manually at build time" + warn "Skipping flash of GPG key to ROM because we are running in QEMU without internal flashing support." + warn "Please review boards/qemu*/qemu*.md documentation to extract public key from raw disk and inject at build time" + warn "Also review boards/qemu*/qemu*.config to tweak CONFIG_* options you might need to turn on/off manually at build time" else - #We are not running in QEMU, so flash the key to ROM - - ## flash generated key to ROM - echo -e "\nReading current firmware...\n(this will take a minute or two)\n" - /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error - if [ ! -s /tmp/oem-setup.rom ]; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error reading current firmware:\n\n$ERROR" - fi - - # clear any existing heads/gpg files from current firmware - for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do - cbfs.sh -o /tmp/oem-setup.rom -d "$i" - done - # add heads/gpg files to current firmware - - if [ -e /.gnupg/pubring.kbx ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ]; then - rm /.gnupg/pubring.gpg - fi - elif [ -e /.gnupg/pubring.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - if [ -e /.gnupg/trustdb.gpg ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - fi - - # persist user config changes (boot device) - if [ -e /etc/config.user ]; then - cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user - fi - - # flash updated firmware image - echo -e "\nAdding generated key to current firmware and re-flashing...\n" - if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" - fi + #We are not running in QEMU, so flash the key to ROM + + ## flash generated key to ROM + echo -e "\nReading current firmware...\n(this will take a minute or two)\n" + /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error + if [ ! -s /tmp/oem-setup.rom ]; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error reading current firmware:\n\n$ERROR" + fi + + # clear any existing heads/gpg files from current firmware + for i in $(cbfs.sh -o /tmp/oem-setup.rom -l | grep -e "heads/"); do + cbfs.sh -o /tmp/oem-setup.rom -d "$i" + done + # add heads/gpg files to current firmware + + if [ -e /.gnupg/pubring.kbx ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ]; then + rm /.gnupg/pubring.gpg + fi + elif [ -e /.gnupg/pubring.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + if [ -e /.gnupg/trustdb.gpg ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + fi + + # persist user config changes (boot device) + if [ -e /etc/config.user ]; then + cbfs.sh -o /tmp/oem-setup.rom -a "heads/initrd/etc/config.user" -f /etc/config.user + fi + + # flash updated firmware image + echo -e "\nAdding generated key to current firmware and re-flashing...\n" + if ! /bin/flash.sh /tmp/oem-setup.rom 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error_die "Error flashing updated firmware image:\n\n$ERROR" + fi fi ## sign files in /boot and generate checksums if [[ "$SKIP_BOOT" == "n" ]]; then - echo -e "\nSigning boot files and generating checksums...\n" - generate_checksums + echo -e "\nSigning boot files and generating checksums...\n" + generate_checksums fi # passphrases set to be empty first @@ -1313,29 +1313,29 @@ passphrases="\n" # Prepare whiptail output of configured secrets if [ -n "$luks_new_Disk_Recovery_Key_passphrase" -o -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then - passphrases+="LUKS Disk Recovery Key passphrase: ${luks_new_Disk_Recovery_Key_passphrase}\n" + passphrases+="LUKS Disk Recovery Key passphrase: ${luks_new_Disk_Recovery_Key_passphrase}\n" fi if [ "$CONFIG_TPM" = "y" ]; then - passphrases+="TPM Owner Password: ${TPM_PASS}\n" + passphrases+="TPM Owner Password: ${TPM_PASS}\n" fi #GPG PINs output passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" #USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not active or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is active if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - passphrases+="GPG User PIN: ${USER_PIN}\n" + passphrases+="GPG User PIN: ${USER_PIN}\n" fi #If user decided to generate keys in memory, we add the thumb drive passphrase if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then - passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" + passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi ## Show to user current configured secrets prior of rebooting whiptail --msgbox " - $(echo -e "$passphrases" | fold -w $((WIDTH-5)))" \ - $HEIGHT $WIDTH --title "Configured secrets" + $(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ + $HEIGHT $WIDTH --title "Configured secrets" ## all done -- reboot whiptail --msgbox " @@ -1343,7 +1343,7 @@ whiptail --msgbox " After rebooting, you will need to generate new TOTP/HOTP secrets\n when prompted in order to complete the setup process.\n\n Press Enter to reboot.\n" \ - $HEIGHT $WIDTH --title "OEM Factory Reset / Re-Ownership Complete" + $HEIGHT $WIDTH --title "OEM Factory Reset / Re-Ownership Complete" # Clean LUKS secrets luks_secrets_cleanup From 108e6ed0b1c7977abacebde5fdd38b6fc64e1f94 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Nov 2024 14:07:10 -0500 Subject: [PATCH 11/81] WiP initrd/bin/oem-factory-reset: add --mode (oem/user) skeleton Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 55 ++++++++++++++++++++++++++++++++++-- initrd/init | 4 +-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 533e7252b..135ecbedb 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -44,6 +44,45 @@ GPG_ALGO="RSA" # Default RSA key length is 3072 bits for OEM key gen. 4096 are way longer to generate in smartcard RSA_KEY_LENGTH=3072 +# Function to handle --mode parameter +handle_mode() { + local mode=$1 + case $mode in + oem) + DEBUG "OEM mode selected" + # Add OEM mode specific logic here + ;; + user) + DEBUG "User mode selected" + # Add User mode specific logic here + ;; + *) + warn "Unknown mode: $mode" + exit 1 + ;; + esac +} + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + --mode) + MODE="$2" + shift # past argument + shift # past value + ;; + *) + shift # past unrecognized argument + ;; + esac +done + +# Handle the --mode parameter if provided +if [[ -n "$MODE" ]]; then + handle_mode "$MODE" +fi + #Override RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards until canokey fixes if [[ "$CONFIG_BOARD_NAME" == qemu-* ]]; then DEBUG "Overriding RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards" @@ -1332,10 +1371,20 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi -## Show to user current configured secrets prior of rebooting -whiptail --msgbox " +# Show qrcode of configured secrets and ask user to confirm scanning of and loop until confirmed with qrenc $passphrases +while true; do + whiptail --msgbox " $(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ - $HEIGHT $WIDTH --title "Configured secrets" + $HEIGHT $WIDTH --title "Configured secrets" + qrencode "$passphrases" + # Prompt user to confirm scanning of qrcode on console prompt not whiptail: y/n + echo -e -n "Please confirm you have scanned the QR code above [y/N]: " + read -n 1 prompt_output + echo + if [ "$prompt_output" == "y" -o "$prompt_output" == "Y" ]; then + break + fi +done ## all done -- reboot whiptail --msgbox " diff --git a/initrd/init b/initrd/init index 83ea659cf..30b08663a 100755 --- a/initrd/init +++ b/initrd/init @@ -206,8 +206,8 @@ if [ "$boot_option" = "r" ]; then # just in case... exit elif [ "$boot_option" = "o" ]; then - # Launch OEM Factory Reset/Re-Ownership - oem-factory-reset + # Launch OEM Factory Reset mode + oem-factory-reset --mode oem # just in case... exit fi From 40df08ecbc72f1e46bc22a00830677f813c0c2c8 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Nov 2024 17:36:21 -0500 Subject: [PATCH 12/81] /etc/functions:: reuse detect_boot_device instead of trying only to mount /etc/fstab existing /boot partition (otherwise early 'o' to enter oem mode of oem-factory-reset Signed-off-by: Thierry Laurion --- initrd/etc/functions | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 6a89dc60a..8bca8937d 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -570,9 +570,7 @@ escape_zero() { assert_signable() { TRACE_FUNC # ensure /boot mounted - if ! grep -q /boot /proc/mounts; then - mount -o ro /boot || die "Unable to mount /boot" - fi + detect_boot_device find /boot -print0 >/tmp/signable.ref local del='\001-\037\134\177-\377' From a6df16ec3c4d8ca84b1979aa657c31c2ed4a3443 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Nov 2024 17:37:30 -0500 Subject: [PATCH 13/81] WiP initrd/bin/oem-factory-reset: add qrcode+secet output loop until user press y (end of reownership wizard secret output) Signed-off-by: Thierry Laurion works: - oem and user mode passphrase generation - qrcode missing: - unattended - luks reencryption + passphrase change for OEM mode (only input to be provided) with SINGLE passphrase when in unattended mode - same for user reownership when previously OEM reset unattended Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 31 +++++++++++++++++++++---------- initrd/etc/functions | 16 ++++++---------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 135ecbedb..9b5f81422 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -23,12 +23,10 @@ CANCEL="--no-button Cancel" HEIGHT="0" WIDTH="80" +# Default values USER_PIN_DEF=123456 ADMIN_PIN_DEF=12345678 TPM_PASS_DEF=12345678 -USER_PIN="" -ADMIN_PIN="" -TPM_PASS="" GPG_GEN_KEY_IN_MEMORY="n" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" @@ -50,11 +48,16 @@ handle_mode() { case $mode in oem) DEBUG "OEM mode selected" - # Add OEM mode specific logic here + CUSTOM_SINGLE_PASS=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + USER_PIN=$CUSTOM_SINGLE_PASS + ADMIN_PIN=$CUSTOM_SINGLE_PASS + TPM_PASS=$CUSTOM_SINGLE_PASS ;; user) DEBUG "User mode selected" - # Add User mode specific logic here + USER_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + ADMIN_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + TPM_PASS=$ADMIN_PIN ;; *) warn "Unknown mode: $mode" @@ -81,6 +84,9 @@ done # Handle the --mode parameter if provided if [[ -n "$MODE" ]]; then handle_mode "$MODE" +else + # Default to User Re-Ownership mode + handle_mode "user" fi #Override RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards until canokey fixes @@ -719,9 +725,10 @@ generate_checksums() { fi DEBUG "Detach-signing boot files under kexec.sig: ${param_files}" - if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG gpg \ + + if sha256sum $param_files 2>/dev/null | gpg \ --pinentry-mode loopback \ - --passphrase "${USER_PIN}" \ + --passphrase-file <(echo -n "$USER_PIN") \ --digest-algo SHA256 \ --detach-sign \ -a \ @@ -1371,14 +1378,18 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi -# Show qrcode of configured secrets and ask user to confirm scanning of and loop until confirmed with qrenc $passphrases +# Show configured secrets in whiptail and loop until user confirms qr code was scanned while true; do whiptail --msgbox " $(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ $HEIGHT $WIDTH --title "Configured secrets" - qrencode "$passphrases" + # strip the initial newline of passphrases + qr_code=$(echo -e "$passphrases" | sed '1s/^\n//') + #Tell user to scan the QR code containing all configured secrets + echo -e "\nScan the QR code below to save the secrets to a secure location" + qrenc "$qr_code" # Prompt user to confirm scanning of qrcode on console prompt not whiptail: y/n - echo -e -n "Please confirm you have scanned the QR code above [y/N]: " + echo -e -n "Please confirm you have scanned the QR code above and/or written down the secrets? [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" -o "$prompt_output" == "Y" ]; then diff --git a/initrd/etc/functions b/initrd/etc/functions index 8bca8937d..aa57676d9 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -887,7 +887,7 @@ generate_passphrase() { local dictionary_file="$2" local word="" - word=$(grep "^$rolls" "$dictionary_file" | awk '{print $2}') + word=$(grep "^$rolls" "$dictionary_file" | awk -F ' ' '{print $2}') echo "$word" } @@ -898,17 +898,14 @@ generate_passphrase() { local rolls="" local random_bytes - # Read num_rolls bytes from /dev/urandom in one go - random_bytes=$(dd if=/dev/urandom bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') + # Read num_rolls bytes from /dev/random, fed by CPU RRAND in one go + random_bytes=$(dd if=/dev/random bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') # Process each byte to generate a dice roll while read -r byte; do roll=$((byte % 6 + 1)) - DEBUG "Randomized dice roll: $roll" rolls+=$roll done <<<"$random_bytes" - - DEBUG "Generated dice rolls: $rolls" echo "$rolls" } @@ -978,15 +975,12 @@ generate_passphrase() { exit 1 fi - digits=${#key} - DEBUG "Number of digits in dice rolls: $digits" + digits=${#key} #Number of digits in dice rolls for ((i = 0; i < num_words; ++i)); do key=$(generate_dice_rolls "$digits") word=$(get_word_from_dictionary "$key" "$dictionary_file") - DEBUG "Retrieved word: $word" if [[ "$lowercase" == "false" ]]; then - DEBUG "Capitalizing the first letter of the word" word=${word^} # Capitalize the first letter fi passphrase+="$word " @@ -997,6 +991,8 @@ generate_passphrase() { fi done + #Remove passphrase trailing space from passphrase+="$word" + passphrase=${passphrase% } echo "$passphrase" return 0 } From 223e5041bca4fcc81fe296f1399fff7ba9098f86 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 28 Nov 2024 16:39:02 -0500 Subject: [PATCH 14/81] WiP: bump to hotp-verification version supporting reset of secret app Signed-off-by: Thierry Laurion --- modules/hotp-verification | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/hotp-verification b/modules/hotp-verification index 14957e74b..861579a69 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -2,12 +2,12 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification hotp-verification_depends := libusb $(musl_dep) -# v1.6 -hotp-verification_version := e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 +# v1.6 + patch from https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46/commits/de355ed93ba50280bf377772082b76b7a2285185 +hotp-verification_version := de355ed93ba50280bf377772082b76b7a2285185 hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz -hotp-verification_hash := 480c978d3585eee73b9aa5186b471d4caeeeeba411217e1544eef7cfd90312ac +hotp-verification_hash := adbc2eb75257f4adda201419ed1282950a8cf86d167b2c76f708047d0b7aeaa5 hotp-verification_target := \ $(MAKE_JOBS) \ From 814f4fabd9152e7027640589318b8ce145e61dba Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 28 Nov 2024 16:57:26 -0500 Subject: [PATCH 15/81] WiP: add nk3 secret app reset function and call it following security dongle reset logic Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 9b5f81422..30717fe33 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -138,6 +138,17 @@ mount_boot() { fi } +reset_nk3_secret_app() { + TRACE_FUNC + # Reset Nitrokey 3 secret app + if lsusb | grep -q "20a0:42b2"; then + echo + echo "Resetting Nitrokey 3 secret app" + # Reset Nitrokey 3 secret app + /bin/hotp_verification reset + fi +} + #Generate a gpg master key: no expiration date, ${RSA_KEY_LENGTH} bits #This key will be used to sign 3 subkeys: encryption, authentication and signing #The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard @@ -533,6 +544,11 @@ gpg_key_factory_reset() { ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" fi + + #Reset Nitrokey 3 secret app + reset_nk3_secret_app + # Nk3 now ready to set secret app PIN on first use... + # If Nitrokey Storage is inserted, reset AES keys as well if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then DEBUG "Nitrokey Storage detected, resetting AES keys..." @@ -540,6 +556,7 @@ gpg_key_factory_reset() { DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" killall -9 scdaemon fi + # Toggle forced sig (good security practice, forcing PIN request for each signature request) if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then DEBUG "GPG toggling forcesig on since off..." @@ -554,6 +571,7 @@ gpg_key_factory_reset() { whiptail_error_die "GPG Key forcesig toggle on failed!\n\n$ERROR" fi fi + # use p256 for key generation if requested if [ "$GPG_ALGO" = "p256" ]; then { From 351a2e213072f122274fa60a18620cf8d540aefd Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:21:34 -0500 Subject: [PATCH 16/81] modules/hotp-verification: revert to 1.6, add patches tested instead Signed-off-by: Thierry Laurion --- modules/hotp-verification | 6 +- .../43.patch | 450 ++++++++++++++++++ .../46.patch | 219 +++++++++ 3 files changed, 672 insertions(+), 3 deletions(-) create mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch create mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch diff --git a/modules/hotp-verification b/modules/hotp-verification index 861579a69..14957e74b 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -2,12 +2,12 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification hotp-verification_depends := libusb $(musl_dep) -# v1.6 + patch from https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46/commits/de355ed93ba50280bf377772082b76b7a2285185 -hotp-verification_version := de355ed93ba50280bf377772082b76b7a2285185 +# v1.6 +hotp-verification_version := e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz -hotp-verification_hash := adbc2eb75257f4adda201419ed1282950a8cf86d167b2c76f708047d0b7aeaa5 +hotp-verification_hash := 480c978d3585eee73b9aa5186b471d4caeeeeba411217e1544eef7cfd90312ac hotp-verification_target := \ $(MAKE_JOBS) \ diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch new file mode 100644 index 000000000..26ad2bc45 --- /dev/null +++ b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch @@ -0,0 +1,450 @@ +From 707c6545a509eeb24a06537e5f835d786c2e657e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Thu, 5 Dec 2024 16:44:30 +0100 +Subject: [PATCH] Add support for nitrokey 3 distinction between the secrets + app and other + +This now adds the secrets app version and the nitrokey 3 firmware version, +and also the gpg pins +--- + src/ccid.c | 71 +++++++++++++++++++++++++- + src/ccid.h | 2 + + src/device.c | 29 +++++------ + src/device.h | 2 +- + src/main.c | 41 +++++++++++---- + src/operations_ccid.c | 113 +++++++++++++++++++++++++++++++++++++----- + src/operations_ccid.h | 2 +- + src/structs.h | 19 +++++++ + 8 files changed, 238 insertions(+), 41 deletions(-) + +diff --git a/src/ccid.c b/src/ccid.c +index 9cf24a0..a2cc919 100644 +--- a/src/ccid.c ++++ b/src/ccid.c +@@ -104,7 +104,7 @@ IccResult parse_icc_result(uint8_t *buf, size_t buf_len) { + // .buffer_len = buf_len + }; + // Make sure the response do not contain overread attempts +- rassert(i.data_len < buf_len - 10); ++ rassert(i.data_len <= buf_len - 10); + return i; + } + +@@ -307,6 +307,75 @@ int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_siz + return RET_NO_ERROR; + } + ++int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { ++ unsigned char cmd_select[] = { ++ 0x6f, ++ 0x0E, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0xa4, ++ 0x04, ++ 0x00, ++ 0x09, ++ 0xa0, ++ 0x00, ++ 0x00, ++ 0x08, ++ 0x47, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x01, ++ }; ++ ++ check_ret( ++ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), ++ RET_COMM_ERROR); ++ ++ ++ return RET_NO_ERROR; ++} ++ ++int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { ++ unsigned char cmd_select[] = { ++ 0x6f, ++ 0x0C, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0xA4, ++ 0x04, ++ 0x00, ++ 0x06, ++ 0xD2, ++ 0x76, ++ 0x00, ++ 0x01, ++ 0x24, ++ 0x01, ++ 0x00, ++ }; ++ ++ check_ret( ++ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), ++ RET_COMM_ERROR); ++ ++ ++ return RET_NO_ERROR; ++} + + int ccid_init(libusb_device_handle *handle) { + +diff --git a/src/ccid.h b/src/ccid.h +index ed17dc7..3dcf106 100644 +--- a/src/ccid.h ++++ b/src/ccid.h +@@ -70,6 +70,8 @@ uint32_t icc_pack_tlvs_for_sending(uint8_t *buf, size_t buflen, TLV tlvs[], int + libusb_device_handle *get_device(libusb_context *ctx, const struct VidPid pPid[], int devices_count); + int ccid_init(libusb_device_handle *handle); + int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); ++int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); ++int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); + + + enum { +diff --git a/src/device.c b/src/device.c +index 4b9361e..52acece 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -29,6 +29,7 @@ + #include "structs.h" + #include "utils.h" + #include ++#include + #include + #include + #include +@@ -259,23 +260,19 @@ int device_receive_buf(struct Device *dev) { + + #include "operations_ccid.h" + +-int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { +- assert(out_status != NULL); ++int device_get_status(struct Device *dev, struct FullResponseStatus *out_response) { ++ assert(out_response != NULL); + assert(dev != NULL); +- memset(out_status, 0, sizeof(struct ResponseStatus)); ++ memset(out_response, 0, sizeof(struct FullResponseStatus)); ++ ++ struct ResponseStatus *out_status = &out_response->response_status; + + if (dev->connection_type == CONNECTION_CCID) { +- int counter = 0; +- uint32_t serial = 0; +- uint16_t version = 0; +- int res = status_ccid(dev->mp_devhandle_ccid, +- &counter, +- &version, +- &serial); +- out_status->retry_admin = counter; +- out_status->retry_user = counter; +- out_status->card_serial_u32 = serial; +- out_status->firmware_version = version; ++ int res = status_ccid(dev->mp_devhandle_ccid, out_response); ++ // out_status->retry_admin = counter; ++ // out_status->retry_user = counter; ++ // out_status->card_serial_u32 = serial; ++ // out_status->firmware_version = version; + return res; + } + +@@ -290,7 +287,7 @@ int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { + + device_send_buf(dev, GET_STATUS); + device_receive_buf(dev); +- *out_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; ++ out_response->response_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; + + if (out_status->firmware_version_st.minor == 1) { + for (int i = 0; i < 100; ++i) { +@@ -343,4 +340,4 @@ const char *command_status_to_string(uint8_t status_code) { + void clean_buffers(struct Device *dev) { + memset(dev->ccid_buffer_in, 0, sizeof dev->ccid_buffer_in); + memset(dev->ccid_buffer_out, 0, sizeof dev->ccid_buffer_out); +-} +\ No newline at end of file ++} +diff --git a/src/device.h b/src/device.h +index c895546..97feeeb 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -72,7 +72,7 @@ struct Device { + + int device_connect(struct Device *dev); + int device_disconnect(struct Device *dev); +-int device_get_status(struct Device *dev, struct ResponseStatus *out_status); ++int device_get_status(struct Device *dev, struct FullResponseStatus *out_status); + int device_send(struct Device *dev, uint8_t *in_data, size_t data_size, uint8_t command_ID); + int device_receive(struct Device *dev, uint8_t *out_data, size_t out_buffer_size); + int device_send_buf(struct Device *dev, uint8_t command_ID); +diff --git a/src/main.c b/src/main.c +index 059069e..9b38552 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -93,25 +93,46 @@ int parse_cmd_and_run(int argc, char *const *argv) { + res = RET_NO_ERROR; + break; + case 'i': {// id | info +- struct ResponseStatus status; ++ struct FullResponseStatus status; ++ memset(&status, 0, sizeof (struct FullResponseStatus)); ++ + res = device_get_status(&dev, &status); + check_ret((res != RET_NO_ERROR) && (res != RET_NO_PIN_ATTEMPTS), res); + if (strnlen(argv[1], 10) == 2 && argv[1][1] == 'd') { + // id command - print ID only +- print_card_serial(&status); ++ print_card_serial(&status.response_status); + } else { + // info command - print status + printf("Connected device status:\n"); + printf("\tCard serial: "); +- print_card_serial(&status); +- printf("\tFirmware: v%d.%d\n", +- status.firmware_version_st.major, +- status.firmware_version_st.minor); +- if (res != RET_NO_PIN_ATTEMPTS) { +- printf("\tCard counters: Admin %d, User %d\n", +- status.retry_admin, status.retry_user); ++ print_card_serial(&status.response_status); ++ if (status.device_type == Nk3) { ++ printf("\tFirmware Nitrokey 3: v%d.%d.%d\n", ++ (status.nk3_extra_info.firmware_version >> 22) & 0b1111111111, ++ (status.nk3_extra_info.firmware_version >> 6) & 0xFFFF, ++ status.nk3_extra_info.firmware_version & 0b111111); ++ printf("\tFirmware Secrets App: v%d.%d\n", ++ status.response_status.firmware_version_st.major, ++ status.response_status.firmware_version_st.minor); ++ if (res != RET_NO_PIN_ATTEMPTS) { ++ printf("\tSecrets app PIN counter: %d\n", ++ status.response_status.retry_user); ++ } else { ++ printf("\tSecrets app PIN counter: PIN is not set - set PIN before the first use\n"); ++ } ++ printf("\tGPG Card counters: Admin %d, User %d\n", ++ status.nk3_extra_info.pgp_admin_pin_retries, ++ status.nk3_extra_info.pgp_user_pin_retries); + } else { +- printf("\tCard counters: PIN is not set - set PIN before the first use\n"); ++ printf("\tFirmware: v%d.%d\n", ++ status.response_status.firmware_version_st.major, ++ status.response_status.firmware_version_st.minor); ++ if (res != RET_NO_PIN_ATTEMPTS) { ++ printf("\tCard counters: Admin %d, User %d\n", ++ status.response_status.retry_admin, status.response_status.retry_user); ++ } else { ++ printf("\tCard counters: PIN is not set - set PIN before the first use\n"); ++ } + } + } + if (res == RET_NO_PIN_ATTEMPTS) { +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index eb46124..25772e5 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -273,14 +273,102 @@ int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify) { + return RET_VALIDATION_PASSED; + } + +-int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number) { ++int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response) { ++ rassert(full_response != NULL); ++ struct ResponseStatus *response = &full_response->response_status; + rassert(handle != NULL); +- rassert(attempt_counter != NULL); +- rassert(firmware_version != NULL); +- rassert(serial_number != NULL); + uint8_t buf[1024] = {}; + IccResult iccResult = {}; +- int r = send_select_ccid(handle, buf, sizeof buf, &iccResult); ++ bool pin_counter_is_error = false; ++ int r; ++ libusb_device *usb_dev; ++ struct libusb_device_descriptor usb_desc; ++ ++ usb_dev = libusb_get_device(handle); ++ ++ r = libusb_get_device_descriptor(usb_dev, &usb_desc); ++ ++ if (r < 0) { ++ return r; ++ } ++ ++ ++ if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_3_USB_PID) { ++ full_response->device_type = Nk3; ++ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_PRO_USB_PID) { ++ full_response->device_type = NkPro2; ++ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_STORAGE_USB_PID) { ++ full_response->device_type = NkStorage; ++ } else if (usb_desc.idVendor == LIBREM_KEY_USB_VID || usb_desc.idProduct == LIBREM_KEY_USB_PID) { ++ full_response->device_type = LibremKey; ++ } ++ ++ if (full_response->device_type == Nk3) { ++ r = send_select_nk3_admin_ccid(handle, buf, sizeof buf, &iccResult); ++ if (r != RET_NO_ERROR) { ++ return r; ++ } ++ ++ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; ++ uint32_t iso_actual_length = iso7816_compose( ++ data_iso, sizeof data_iso, ++ 0x61, 0, 0, 0, 4, NULL, 0); ++ ++ // encode ccid wrapper ++ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, ++ 0x6F, iso_actual_length, ++ 0, 0, 0, data_iso); ++ int transferred; ++ r = ccid_send(handle, &transferred, buf, icc_actual_length); ++ if (r != 0) { ++ return r; ++ } ++ ++ r = ccid_receive(handle, &transferred, buf, sizeof buf); ++ if (r != 0) { ++ return r; ++ } ++ ++ IccResult iccResult = parse_icc_result(buf, transferred); ++ rassert(iccResult.data_status_code == 0x9000); ++ rassert(iccResult.data_len == 6); ++ full_response->nk3_extra_info.firmware_version = be32toh(*(uint32_t *) iccResult.data); ++ } ++ ++ if (full_response->device_type == Nk3) { ++ r = send_select_nk3_pgp_ccid(handle, buf, sizeof buf, &iccResult); ++ if (r != RET_NO_ERROR) { ++ return r; ++ } ++ ++ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; ++ uint32_t iso_actual_length = iso7816_compose( ++ data_iso, sizeof data_iso, ++ 0xCA, 0, 0xC4, 0, 0xFF, NULL, 0); ++ ++ // encode ccid wrapper ++ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, ++ 0x6F, iso_actual_length, ++ 0, 0, 0, data_iso); ++ int transferred; ++ r = ccid_send(handle, &transferred, buf, icc_actual_length); ++ if (r != 0) { ++ return r; ++ } ++ ++ r = ccid_receive(handle, &transferred, buf, sizeof buf); ++ if (r != 0) { ++ return r; ++ } ++ ++ IccResult iccResult = parse_icc_result(buf, transferred); ++ rassert(iccResult.data_status_code == 0x9000); ++ rassert(iccResult.data_len == 9); ++ full_response->nk3_extra_info.pgp_user_pin_retries = iccResult.data[4]; ++ full_response->nk3_extra_info.pgp_admin_pin_retries = iccResult.data[6]; ++ } ++ ++ r = send_select_ccid(handle, buf, sizeof buf, &iccResult); + if (r != RET_NO_ERROR) { + return r; + } +@@ -292,29 +380,30 @@ int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *fi + r = get_tlv(iccResult.data, iccResult.data_len, Tag_PINCounter, &counter_tlv); + if (!(r == RET_NO_ERROR && counter_tlv.tag == Tag_PINCounter)) { + // PIN counter not found - comm error (ignore) or PIN not set +- *attempt_counter = -1; ++ pin_counter_is_error = true; + } else { +- *attempt_counter = counter_tlv.v_data[0]; ++ response->retry_admin = counter_tlv.v_data[0]; ++ response->retry_user = counter_tlv.v_data[0]; + } + + TLV serial_tlv = {}; + r = get_tlv(iccResult.data, iccResult.data_len, Tag_SerialNumber, &serial_tlv); + if (r == RET_NO_ERROR && serial_tlv.tag == Tag_SerialNumber) { +- *serial_number = be32toh(*(uint32_t *) serial_tlv.v_data); ++ response->card_serial_u32 = be32toh(*(uint32_t *) serial_tlv.v_data); + } else { + // ignore errors - unsupported or hidden serial_tlv number +- *serial_number = 0; ++ response->card_serial_u32 = 0; + } + + TLV version_tlv = {}; + r = get_tlv(iccResult.data, iccResult.data_len, Tag_Version, &version_tlv); + if (!(r == RET_NO_ERROR && version_tlv.tag == Tag_Version)) { +- *firmware_version = 0; ++ response->firmware_version = 0; + return RET_COMM_ERROR; + } +- *firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); ++ response->firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); + +- if (*attempt_counter == -1) { ++ if (pin_counter_is_error == true) { + return RET_NO_PIN_ATTEMPTS; + } + return RET_NO_ERROR; +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index b26b3c7..ea463b4 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -10,7 +10,7 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN); + int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); +-int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); ++int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H +diff --git a/src/structs.h b/src/structs.h +index 6309cd0..9e87134 100644 +--- a/src/structs.h ++++ b/src/structs.h +@@ -116,6 +116,25 @@ struct ResponseStatus { + uint8_t retry_user; /*not present in the firmware response for the Status command in v0.8 firmware*/ + }; + ++enum DeviceType { ++ Unknown = 0, ++ Nk3, ++ NkPro2, ++ NkStorage, ++ LibremKey, ++}; ++ ++struct FullResponseStatus { ++ enum DeviceType device_type; ++ struct ResponseStatus response_status; ++ struct { ++ // Only valid if device_type is NK3 ++ uint8_t pgp_admin_pin_retries; ++ uint8_t pgp_user_pin_retries; ++ uint32_t firmware_version; ++ } nk3_extra_info; ++}; ++ + + struct WriteToOTPSlot { + //admin auth diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch new file mode 100644 index 000000000..781c10ffa --- /dev/null +++ b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch @@ -0,0 +1,219 @@ +From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Mon, 25 Nov 2024 17:04:47 +0100 +Subject: [PATCH 1/3] Add reset command for nitrokey 3 + +--- + src/main.c | 10 ++++++++-- + src/operations_ccid.c | 41 +++++++++++++++++++++++++++++++++++++++++ + src/operations_ccid.h | 1 + + 3 files changed, 50 insertions(+), 2 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 059069e..b80b71d 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -21,6 +21,7 @@ + + #include "ccid.h" + #include "operations.h" ++#include "operations_ccid.h" + #include "return_codes.h" + #include "utils.h" + #include "version.h" +@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { + } + break; + case 'r': +- if (argc != 3) break; +- res = regenerate_AES_key(&dev, argv[2]); ++ if (strncmp(argv[1], "reset", 15) == 0) { ++ if (argc != 2) break; ++ res = nk3_reset(&dev); ++ } else if (strncmp(argv[1], "regenerate", 15) == 0) { ++ if (argc != 3) break; ++ res = regenerate_AES_key(&dev, argv[2]); ++ } + break; + default: + break; +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index eb46124..574155d 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -32,6 +32,47 @@ + #include + + ++ ++int nk3_reset(struct Device *dev) { ++ libusb_device *usb_dev; ++ struct libusb_device_descriptor usb_desc; ++ usb_dev = libusb_get_device(dev->mp_devhandle_ccid); ++ ++ int r = libusb_get_device_descriptor(usb_dev, &usb_desc); ++ ++ if (r < 0) { ++ return r; ++ } ++ ++ ++ if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { ++ return 0; ++ } ++ ++ ++ uint8_t buf[10]; ++ // encode ++ uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); ++ ++ // encode ccid wrapper ++ icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, ++ 0x6F, icc_actual_length, ++ 0, 0, 0, buf); ++ // send ++ IccResult iccResult; ++ r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, ++ dev->ccid_buffer_out, icc_actual_length, &iccResult); ++ if (r != 0) { ++ return r; ++ } ++ // check status code ++ if (iccResult.data_status_code != 0x9000) { ++ return 1; ++ } ++ ++ return RET_NO_ERROR; ++} ++ + int set_pin_ccid(struct Device *dev, const char *admin_PIN) { + TLV tlvs[] = { + { +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index b26b3c7..ec0070c 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); ++int nk3_reset(struct Device *dev); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H + +From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Mon, 2 Dec 2024 10:29:59 +0100 +Subject: [PATCH 2/3] Add optional new pin when resetting + +--- + src/main.c | 9 +++++---- + src/operations_ccid.c | 6 +++++- + src/operations_ccid.h | 5 ++++- + 3 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/src/main.c b/src/main.c +index b80b71d..3f4a1cc 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -38,9 +38,10 @@ void print_help(char *app_name) { + "\t%s info\n" + "\t%s version\n" + "\t%s check \n" +- "\t%s regenerate \n" ++ "\t%s reset [ADMIN PIN]\n" ++ "\t%s regenerate\n" + "\t%s set [COUNTER]\n", +- app_name, app_name, app_name, app_name, app_name, app_name); ++ app_name, app_name, app_name, app_name, app_name, app_name, app_name); + } + + +@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { + break; + case 'r': + if (strncmp(argv[1], "reset", 15) == 0) { +- if (argc != 2) break; +- res = nk3_reset(&dev); ++ if (argc != 2 && argc != 3) break; ++ res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); + } else if (strncmp(argv[1], "regenerate", 15) == 0) { + if (argc != 3) break; + res = regenerate_AES_key(&dev, argv[2]); +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index 574155d..07834ce 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -33,7 +33,7 @@ + + + +-int nk3_reset(struct Device *dev) { ++int nk3_reset(struct Device *dev, const char * new_pin) { + libusb_device *usb_dev; + struct libusb_device_descriptor usb_desc; + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); +@@ -70,6 +70,10 @@ int nk3_reset(struct Device *dev) { + return 1; + } + ++ if (new_pin != NULL) { ++ set_pin_ccid(dev, new_pin); ++ } ++ + return RET_NO_ERROR; + } + +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index ec0070c..61cad72 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); +-int nk3_reset(struct Device *dev); ++// new_pin can be `null` ++// ++// If it is, no new pin will be set ++int nk3_reset(struct Device *dev, const char * new_pin); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H + +From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Tue, 3 Dec 2024 10:48:27 +0100 +Subject: [PATCH 3/3] Fix null pointer bug on non nk3 + +--- + src/operations_ccid.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index 07834ce..538d434 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -36,6 +36,12 @@ + int nk3_reset(struct Device *dev, const char * new_pin) { + libusb_device *usb_dev; + struct libusb_device_descriptor usb_desc; ++ ++ if (!dev->mp_devhandle_ccid) { ++ // Not an NK3 ++ return RET_NO_ERROR; ++ } ++ + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); + + int r = libusb_get_device_descriptor(usb_dev, &usb_desc); +@@ -46,7 +52,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { + + + if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { +- return 0; ++ return RET_NO_ERROR; + } + + From fd136cd95712cc4102ae0aefa5f32fffedbbdd63 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:23:37 -0500 Subject: [PATCH 17/81] oem-factory-reset: add reset secure app PIN = ADMIN_PIN at reownership, make sure defaults are set for all modes, including default which uses current defaults being DEF pins (12345678 and 123456 as master) Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 30717fe33..7c0340aa7 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -60,8 +60,10 @@ handle_mode() { TPM_PASS=$ADMIN_PIN ;; *) - warn "Unknown mode: $mode" - exit 1 + warn "Unknown oem-factory-reset lauched mode, setting PINs to weak defaults" + USER_PIN=$USER_PIN_DEF + ADMIN_PIN=$ADMIN_PIN_DEF + TPM_PASS=$ADMIN_PIN_DEF ;; esac } @@ -144,8 +146,10 @@ reset_nk3_secret_app() { if lsusb | grep -q "20a0:42b2"; then echo echo "Resetting Nitrokey 3 secret app" + DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" + killall -9 scdaemon 2>&1 >/dev/null || true # Reset Nitrokey 3 secret app - /bin/hotp_verification reset + /bin/hotp_verification reset $ADMIN_PIN fi } From 7f9f84b83014d8dbb9c4b8b308d219d42ac54b14 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:32:23 -0500 Subject: [PATCH 18/81] modules/hotp-verification: 1.6, removing patch pr43, only keeping 46 for this PR (43 conflicts when applied atop 46. 46 is needed here) Signed-off-by: Thierry Laurion --- .../43.patch | 450 ------------------ 1 file changed, 450 deletions(-) delete mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch deleted file mode 100644 index 26ad2bc45..000000000 --- a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 707c6545a509eeb24a06537e5f835d786c2e657e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Thu, 5 Dec 2024 16:44:30 +0100 -Subject: [PATCH] Add support for nitrokey 3 distinction between the secrets - app and other - -This now adds the secrets app version and the nitrokey 3 firmware version, -and also the gpg pins ---- - src/ccid.c | 71 +++++++++++++++++++++++++- - src/ccid.h | 2 + - src/device.c | 29 +++++------ - src/device.h | 2 +- - src/main.c | 41 +++++++++++---- - src/operations_ccid.c | 113 +++++++++++++++++++++++++++++++++++++----- - src/operations_ccid.h | 2 +- - src/structs.h | 19 +++++++ - 8 files changed, 238 insertions(+), 41 deletions(-) - -diff --git a/src/ccid.c b/src/ccid.c -index 9cf24a0..a2cc919 100644 ---- a/src/ccid.c -+++ b/src/ccid.c -@@ -104,7 +104,7 @@ IccResult parse_icc_result(uint8_t *buf, size_t buf_len) { - // .buffer_len = buf_len - }; - // Make sure the response do not contain overread attempts -- rassert(i.data_len < buf_len - 10); -+ rassert(i.data_len <= buf_len - 10); - return i; - } - -@@ -307,6 +307,75 @@ int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_siz - return RET_NO_ERROR; - } - -+int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { -+ unsigned char cmd_select[] = { -+ 0x6f, -+ 0x0E, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0xa4, -+ 0x04, -+ 0x00, -+ 0x09, -+ 0xa0, -+ 0x00, -+ 0x00, -+ 0x08, -+ 0x47, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x01, -+ }; -+ -+ check_ret( -+ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), -+ RET_COMM_ERROR); -+ -+ -+ return RET_NO_ERROR; -+} -+ -+int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { -+ unsigned char cmd_select[] = { -+ 0x6f, -+ 0x0C, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0xA4, -+ 0x04, -+ 0x00, -+ 0x06, -+ 0xD2, -+ 0x76, -+ 0x00, -+ 0x01, -+ 0x24, -+ 0x01, -+ 0x00, -+ }; -+ -+ check_ret( -+ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), -+ RET_COMM_ERROR); -+ -+ -+ return RET_NO_ERROR; -+} - - int ccid_init(libusb_device_handle *handle) { - -diff --git a/src/ccid.h b/src/ccid.h -index ed17dc7..3dcf106 100644 ---- a/src/ccid.h -+++ b/src/ccid.h -@@ -70,6 +70,8 @@ uint32_t icc_pack_tlvs_for_sending(uint8_t *buf, size_t buflen, TLV tlvs[], int - libusb_device_handle *get_device(libusb_context *ctx, const struct VidPid pPid[], int devices_count); - int ccid_init(libusb_device_handle *handle); - int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); -+int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); -+int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); - - - enum { -diff --git a/src/device.c b/src/device.c -index 4b9361e..52acece 100644 ---- a/src/device.c -+++ b/src/device.c -@@ -29,6 +29,7 @@ - #include "structs.h" - #include "utils.h" - #include -+#include - #include - #include - #include -@@ -259,23 +260,19 @@ int device_receive_buf(struct Device *dev) { - - #include "operations_ccid.h" - --int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { -- assert(out_status != NULL); -+int device_get_status(struct Device *dev, struct FullResponseStatus *out_response) { -+ assert(out_response != NULL); - assert(dev != NULL); -- memset(out_status, 0, sizeof(struct ResponseStatus)); -+ memset(out_response, 0, sizeof(struct FullResponseStatus)); -+ -+ struct ResponseStatus *out_status = &out_response->response_status; - - if (dev->connection_type == CONNECTION_CCID) { -- int counter = 0; -- uint32_t serial = 0; -- uint16_t version = 0; -- int res = status_ccid(dev->mp_devhandle_ccid, -- &counter, -- &version, -- &serial); -- out_status->retry_admin = counter; -- out_status->retry_user = counter; -- out_status->card_serial_u32 = serial; -- out_status->firmware_version = version; -+ int res = status_ccid(dev->mp_devhandle_ccid, out_response); -+ // out_status->retry_admin = counter; -+ // out_status->retry_user = counter; -+ // out_status->card_serial_u32 = serial; -+ // out_status->firmware_version = version; - return res; - } - -@@ -290,7 +287,7 @@ int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { - - device_send_buf(dev, GET_STATUS); - device_receive_buf(dev); -- *out_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; -+ out_response->response_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; - - if (out_status->firmware_version_st.minor == 1) { - for (int i = 0; i < 100; ++i) { -@@ -343,4 +340,4 @@ const char *command_status_to_string(uint8_t status_code) { - void clean_buffers(struct Device *dev) { - memset(dev->ccid_buffer_in, 0, sizeof dev->ccid_buffer_in); - memset(dev->ccid_buffer_out, 0, sizeof dev->ccid_buffer_out); --} -\ No newline at end of file -+} -diff --git a/src/device.h b/src/device.h -index c895546..97feeeb 100644 ---- a/src/device.h -+++ b/src/device.h -@@ -72,7 +72,7 @@ struct Device { - - int device_connect(struct Device *dev); - int device_disconnect(struct Device *dev); --int device_get_status(struct Device *dev, struct ResponseStatus *out_status); -+int device_get_status(struct Device *dev, struct FullResponseStatus *out_status); - int device_send(struct Device *dev, uint8_t *in_data, size_t data_size, uint8_t command_ID); - int device_receive(struct Device *dev, uint8_t *out_data, size_t out_buffer_size); - int device_send_buf(struct Device *dev, uint8_t command_ID); -diff --git a/src/main.c b/src/main.c -index 059069e..9b38552 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -93,25 +93,46 @@ int parse_cmd_and_run(int argc, char *const *argv) { - res = RET_NO_ERROR; - break; - case 'i': {// id | info -- struct ResponseStatus status; -+ struct FullResponseStatus status; -+ memset(&status, 0, sizeof (struct FullResponseStatus)); -+ - res = device_get_status(&dev, &status); - check_ret((res != RET_NO_ERROR) && (res != RET_NO_PIN_ATTEMPTS), res); - if (strnlen(argv[1], 10) == 2 && argv[1][1] == 'd') { - // id command - print ID only -- print_card_serial(&status); -+ print_card_serial(&status.response_status); - } else { - // info command - print status - printf("Connected device status:\n"); - printf("\tCard serial: "); -- print_card_serial(&status); -- printf("\tFirmware: v%d.%d\n", -- status.firmware_version_st.major, -- status.firmware_version_st.minor); -- if (res != RET_NO_PIN_ATTEMPTS) { -- printf("\tCard counters: Admin %d, User %d\n", -- status.retry_admin, status.retry_user); -+ print_card_serial(&status.response_status); -+ if (status.device_type == Nk3) { -+ printf("\tFirmware Nitrokey 3: v%d.%d.%d\n", -+ (status.nk3_extra_info.firmware_version >> 22) & 0b1111111111, -+ (status.nk3_extra_info.firmware_version >> 6) & 0xFFFF, -+ status.nk3_extra_info.firmware_version & 0b111111); -+ printf("\tFirmware Secrets App: v%d.%d\n", -+ status.response_status.firmware_version_st.major, -+ status.response_status.firmware_version_st.minor); -+ if (res != RET_NO_PIN_ATTEMPTS) { -+ printf("\tSecrets app PIN counter: %d\n", -+ status.response_status.retry_user); -+ } else { -+ printf("\tSecrets app PIN counter: PIN is not set - set PIN before the first use\n"); -+ } -+ printf("\tGPG Card counters: Admin %d, User %d\n", -+ status.nk3_extra_info.pgp_admin_pin_retries, -+ status.nk3_extra_info.pgp_user_pin_retries); - } else { -- printf("\tCard counters: PIN is not set - set PIN before the first use\n"); -+ printf("\tFirmware: v%d.%d\n", -+ status.response_status.firmware_version_st.major, -+ status.response_status.firmware_version_st.minor); -+ if (res != RET_NO_PIN_ATTEMPTS) { -+ printf("\tCard counters: Admin %d, User %d\n", -+ status.response_status.retry_admin, status.response_status.retry_user); -+ } else { -+ printf("\tCard counters: PIN is not set - set PIN before the first use\n"); -+ } - } - } - if (res == RET_NO_PIN_ATTEMPTS) { -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index eb46124..25772e5 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -273,14 +273,102 @@ int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify) { - return RET_VALIDATION_PASSED; - } - --int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number) { -+int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response) { -+ rassert(full_response != NULL); -+ struct ResponseStatus *response = &full_response->response_status; - rassert(handle != NULL); -- rassert(attempt_counter != NULL); -- rassert(firmware_version != NULL); -- rassert(serial_number != NULL); - uint8_t buf[1024] = {}; - IccResult iccResult = {}; -- int r = send_select_ccid(handle, buf, sizeof buf, &iccResult); -+ bool pin_counter_is_error = false; -+ int r; -+ libusb_device *usb_dev; -+ struct libusb_device_descriptor usb_desc; -+ -+ usb_dev = libusb_get_device(handle); -+ -+ r = libusb_get_device_descriptor(usb_dev, &usb_desc); -+ -+ if (r < 0) { -+ return r; -+ } -+ -+ -+ if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_3_USB_PID) { -+ full_response->device_type = Nk3; -+ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_PRO_USB_PID) { -+ full_response->device_type = NkPro2; -+ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_STORAGE_USB_PID) { -+ full_response->device_type = NkStorage; -+ } else if (usb_desc.idVendor == LIBREM_KEY_USB_VID || usb_desc.idProduct == LIBREM_KEY_USB_PID) { -+ full_response->device_type = LibremKey; -+ } -+ -+ if (full_response->device_type == Nk3) { -+ r = send_select_nk3_admin_ccid(handle, buf, sizeof buf, &iccResult); -+ if (r != RET_NO_ERROR) { -+ return r; -+ } -+ -+ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; -+ uint32_t iso_actual_length = iso7816_compose( -+ data_iso, sizeof data_iso, -+ 0x61, 0, 0, 0, 4, NULL, 0); -+ -+ // encode ccid wrapper -+ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, -+ 0x6F, iso_actual_length, -+ 0, 0, 0, data_iso); -+ int transferred; -+ r = ccid_send(handle, &transferred, buf, icc_actual_length); -+ if (r != 0) { -+ return r; -+ } -+ -+ r = ccid_receive(handle, &transferred, buf, sizeof buf); -+ if (r != 0) { -+ return r; -+ } -+ -+ IccResult iccResult = parse_icc_result(buf, transferred); -+ rassert(iccResult.data_status_code == 0x9000); -+ rassert(iccResult.data_len == 6); -+ full_response->nk3_extra_info.firmware_version = be32toh(*(uint32_t *) iccResult.data); -+ } -+ -+ if (full_response->device_type == Nk3) { -+ r = send_select_nk3_pgp_ccid(handle, buf, sizeof buf, &iccResult); -+ if (r != RET_NO_ERROR) { -+ return r; -+ } -+ -+ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; -+ uint32_t iso_actual_length = iso7816_compose( -+ data_iso, sizeof data_iso, -+ 0xCA, 0, 0xC4, 0, 0xFF, NULL, 0); -+ -+ // encode ccid wrapper -+ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, -+ 0x6F, iso_actual_length, -+ 0, 0, 0, data_iso); -+ int transferred; -+ r = ccid_send(handle, &transferred, buf, icc_actual_length); -+ if (r != 0) { -+ return r; -+ } -+ -+ r = ccid_receive(handle, &transferred, buf, sizeof buf); -+ if (r != 0) { -+ return r; -+ } -+ -+ IccResult iccResult = parse_icc_result(buf, transferred); -+ rassert(iccResult.data_status_code == 0x9000); -+ rassert(iccResult.data_len == 9); -+ full_response->nk3_extra_info.pgp_user_pin_retries = iccResult.data[4]; -+ full_response->nk3_extra_info.pgp_admin_pin_retries = iccResult.data[6]; -+ } -+ -+ r = send_select_ccid(handle, buf, sizeof buf, &iccResult); - if (r != RET_NO_ERROR) { - return r; - } -@@ -292,29 +380,30 @@ int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *fi - r = get_tlv(iccResult.data, iccResult.data_len, Tag_PINCounter, &counter_tlv); - if (!(r == RET_NO_ERROR && counter_tlv.tag == Tag_PINCounter)) { - // PIN counter not found - comm error (ignore) or PIN not set -- *attempt_counter = -1; -+ pin_counter_is_error = true; - } else { -- *attempt_counter = counter_tlv.v_data[0]; -+ response->retry_admin = counter_tlv.v_data[0]; -+ response->retry_user = counter_tlv.v_data[0]; - } - - TLV serial_tlv = {}; - r = get_tlv(iccResult.data, iccResult.data_len, Tag_SerialNumber, &serial_tlv); - if (r == RET_NO_ERROR && serial_tlv.tag == Tag_SerialNumber) { -- *serial_number = be32toh(*(uint32_t *) serial_tlv.v_data); -+ response->card_serial_u32 = be32toh(*(uint32_t *) serial_tlv.v_data); - } else { - // ignore errors - unsupported or hidden serial_tlv number -- *serial_number = 0; -+ response->card_serial_u32 = 0; - } - - TLV version_tlv = {}; - r = get_tlv(iccResult.data, iccResult.data_len, Tag_Version, &version_tlv); - if (!(r == RET_NO_ERROR && version_tlv.tag == Tag_Version)) { -- *firmware_version = 0; -+ response->firmware_version = 0; - return RET_COMM_ERROR; - } -- *firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); -+ response->firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); - -- if (*attempt_counter == -1) { -+ if (pin_counter_is_error == true) { - return RET_NO_PIN_ATTEMPTS; - } - return RET_NO_ERROR; -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index b26b3c7..ea463b4 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -10,7 +10,7 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN); - int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); --int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); -+int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H -diff --git a/src/structs.h b/src/structs.h -index 6309cd0..9e87134 100644 ---- a/src/structs.h -+++ b/src/structs.h -@@ -116,6 +116,25 @@ struct ResponseStatus { - uint8_t retry_user; /*not present in the firmware response for the Status command in v0.8 firmware*/ - }; - -+enum DeviceType { -+ Unknown = 0, -+ Nk3, -+ NkPro2, -+ NkStorage, -+ LibremKey, -+}; -+ -+struct FullResponseStatus { -+ enum DeviceType device_type; -+ struct ResponseStatus response_status; -+ struct { -+ // Only valid if device_type is NK3 -+ uint8_t pgp_admin_pin_retries; -+ uint8_t pgp_user_pin_retries; -+ uint32_t firmware_version; -+ } nk3_extra_info; -+}; -+ - - struct WriteToOTPSlot { - //admin auth From e01d346fe8f09c028c6607ae542f0fca8b83628a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:42:11 -0500 Subject: [PATCH 19/81] oem-factory-reset: don't set user re-ownership by default for now: use current defaults being DEF pins (12345678 and 123456 as master) Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 3 --- 1 file changed, 3 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 7c0340aa7..e69a7ddd1 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -86,9 +86,6 @@ done # Handle the --mode parameter if provided if [[ -n "$MODE" ]]; then handle_mode "$MODE" -else - # Default to User Re-Ownership mode - handle_mode "user" fi #Override RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards until canokey fixes From 03e5ec0ddf8e89abbd551cd92cfe1a9637c49f1d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:46:25 -0500 Subject: [PATCH 20/81] oem-factory-reset: if nk3, also display Secure App PIN = GPG Admin PIN as text and in Qr code Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index e69a7ddd1..74894e875 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -1387,6 +1387,12 @@ fi #GPG PINs output passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" + +#if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID +if lsusb | grep -q "20a0:42b2"; then + passphrases+="Nitrokey 3 Security App PIN: ${ADMIN_PIN}\n" +fi + #USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not active or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is active if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then passphrases+="GPG User PIN: ${USER_PIN}\n" @@ -1397,6 +1403,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi + # Show configured secrets in whiptail and loop until user confirms qr code was scanned while true; do whiptail --msgbox " From 789231fac3322e3eed123bd48faeddd8854c911a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 13:55:39 -0500 Subject: [PATCH 21/81] oem-factory-reset: fix Secure App wording, prevent word globbing, warn that physical presence is needed Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 74894e875..3c99eb627 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -139,14 +139,15 @@ mount_boot() { reset_nk3_secret_app() { TRACE_FUNC - # Reset Nitrokey 3 secret app + # Reset Nitrokey 3 Secret App if lsusb | grep -q "20a0:42b2"; then echo - echo "Resetting Nitrokey 3 secret app" + echo "Resetting Nitrokey 3 Secret App PIN. Physical presence (touch) will be required" + #TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" killall -9 scdaemon 2>&1 >/dev/null || true - # Reset Nitrokey 3 secret app - /bin/hotp_verification reset $ADMIN_PIN + # Reset Nitrokey 3 secret app with PIN + /bin/hotp_verification reset "${ADMIN_PIN}" fi } @@ -548,7 +549,6 @@ gpg_key_factory_reset() { #Reset Nitrokey 3 secret app reset_nk3_secret_app - # Nk3 now ready to set secret app PIN on first use... # If Nitrokey Storage is inserted, reset AES keys as well if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then @@ -1390,7 +1390,7 @@ passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" #if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID if lsusb | grep -q "20a0:42b2"; then - passphrases+="Nitrokey 3 Security App PIN: ${ADMIN_PIN}\n" + passphrases+="Nitrokey 3 Secret App PIN: ${ADMIN_PIN}\n" fi #USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not active or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is active From c3723702105dc0da54713d6380e0ceaf61027568 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 14:25:22 -0500 Subject: [PATCH 22/81] oem-factory-reset: set title_text accordingly to mode, either 'OEM Factory Reset Mode', 'Re-Ownership Mode' or 'OEM Factory Reset / Re-Ownership' TODO: further specialize warning prompt to tell what is going to happen (randomized PIN, signle custom randomized PIN etc) Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 3c99eb627..939377102 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -52,12 +52,16 @@ handle_mode() { USER_PIN=$CUSTOM_SINGLE_PASS ADMIN_PIN=$CUSTOM_SINGLE_PASS TPM_PASS=$CUSTOM_SINGLE_PASS + + title_text="OEM Factory Reset Mode" ;; user) DEBUG "User mode selected" USER_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) ADMIN_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) TPM_PASS=$ADMIN_PIN + + title_text="User Re-Ownership Mode" ;; *) warn "Unknown oem-factory-reset lauched mode, setting PINs to weak defaults" @@ -911,9 +915,7 @@ usb_security_token_capabilities_check() { ## main script start # check for args -if [ "$1" != "" ]; then - title_text=$1 -else +if [ -z "$title_text" ]; then title_text="OEM Factory Reset / Re-Ownership" fi if [ "$2" != "" ]; then From e25fb595b67d32e928115d0dd1c39d246f8526b2 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 14:37:48 -0500 Subject: [PATCH 23/81] oem-factory-reset: reset nk3 secure app PIN early since we need physical presence, put nk3 secure APP PIN after TPM but before GPG PINS in output for consistency Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 939377102..a3f6933f3 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -148,8 +148,6 @@ reset_nk3_secret_app() { echo echo "Resetting Nitrokey 3 Secret App PIN. Physical presence (touch) will be required" #TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed - DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" - killall -9 scdaemon 2>&1 >/dev/null || true # Reset Nitrokey 3 secret app with PIN /bin/hotp_verification reset "${ADMIN_PIN}" fi @@ -537,6 +535,9 @@ gpg_key_factory_reset() { #enable usb storage enable_usb + #Reset Nitrokey 3 secret app + reset_nk3_secret_app + # Factory reset GPG card echo "GPG factory reset of USB Security Dongle's smartcard..." { @@ -551,8 +552,6 @@ gpg_key_factory_reset() { whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" fi - #Reset Nitrokey 3 secret app - reset_nk3_secret_app # If Nitrokey Storage is inserted, reset AES keys as well if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then @@ -1387,14 +1386,13 @@ if [ "$CONFIG_TPM" = "y" ]; then passphrases+="TPM Owner Password: ${TPM_PASS}\n" fi -#GPG PINs output -passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" - #if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID if lsusb | grep -q "20a0:42b2"; then passphrases+="Nitrokey 3 Secret App PIN: ${ADMIN_PIN}\n" fi +#GPG PINs output +passphrases+="GPG Admin PIN: ${ADMIN_PIN}\n" #USER PIN was configured if GPG_GEN_KEY_IN_MEMORY is not active or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD is active if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then passphrases+="GPG User PIN: ${USER_PIN}\n" From 95473d6c89d13371133f52dd59d3ad9b3269b385 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 16:08:34 -0500 Subject: [PATCH 24/81] kexec-sign-config: mount rw, write things to /boot, mount ro after Signed-off-by: Thierry Laurion --- initrd/bin/kexec-sign-config | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/initrd/bin/kexec-sign-config b/initrd/bin/kexec-sign-config index c34060d0b..d0d66c69e 100755 --- a/initrd/bin/kexec-sign-config +++ b/initrd/bin/kexec-sign-config @@ -27,6 +27,9 @@ assert_signable confirm_gpg_card +# remount /boot as rw +mount -o remount,rw /boot + # update hashes in /boot before signing if [ "$update" = "y" ]; then ( @@ -81,8 +84,15 @@ for tries in 1 2 3; do ; then # successful - update the validated params check_config $paramsdir + + # remount /boot as ro + mount -o remount,ro /boot + exit 0 fi done +# remount /boot as ro +mount -o remount,ro /boot + die "$paramsdir: Unable to sign kexec hashes" From 847b4ddbdff5b82a0b40a2735cad4945c02033b6 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 5 Dec 2024 16:48:32 -0500 Subject: [PATCH 25/81] WiP seal-hotp: customize message to be GPG Admin PIN or Secure App PIN TODO: check logic in this file because assumptions on PINs retry count are wrong and will depend on https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 not tested here Signed-off-by: Thierry Laurion --- initrd/bin/seal-hotpkey | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 957b94240..930d78059 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -127,23 +127,33 @@ else fi if [ "$admin_pin_status" -ne 0 ]; then + + # create custom message for PIN prompt based on nk3 lsusb product id + prompt_message="" + if lsusb | grep -q "20a0:42b2"; then + prompt_message="Secure App" + else + prompt_message="GPG Admin" + fi + + # prompt user for PIN and retry echo "" - read -s -p "Enter your $HOTPKEY_BRANDING Admin PIN: " admin_pin + read -s -p "Enter your $HOTPKEY_BRANDING $prompt_message PIN: " admin_pin echo -e "\n" hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" if [ $? -ne 0 ]; then echo -e "\n" - read -s -p "Error setting HOTP secret, re-enter Admin PIN and try again: " admin_pin + read -s -p "Error setting HOTP secret, re-enter $prompt_message PIN and try again: " admin_pin echo -e "\n" if ! hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" ; then # don't leak key on failure shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null if [ "$HOTPKEY_BRANDING" == "Nitrokey" ]; then - fatal_error "Setting HOTP secret failed, to reset nitrokey pin use: nitropy nk3 secrets reset or the Nitrokey App 2" + fatal_error "Setting HOTP secret failed, to reset $prompt_message PIN, redo Re-Ownership procedure, the Nitrokey App 2 or contact Nitrokey support" else - fatal_error "Setting HOTP secret failed" + fatal_error "Setting HOTP secret failed" fi fi fi From 4fd710696e83e82c539e3be20a315dfe71f76ad2 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 6 Dec 2024 10:50:59 -0500 Subject: [PATCH 26/81] hotp-verification patches: Use https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 instead of https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46 for hotp-verification info parsing and validation of oem-factory-reset and seal-hotp Signed-off-by: Thierry Laurion --- .../43.patch | 450 ++++++++++++++++++ .../46.patch | 219 --------- 2 files changed, 450 insertions(+), 219 deletions(-) create mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch delete mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch new file mode 100644 index 000000000..26ad2bc45 --- /dev/null +++ b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch @@ -0,0 +1,450 @@ +From 707c6545a509eeb24a06537e5f835d786c2e657e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Thu, 5 Dec 2024 16:44:30 +0100 +Subject: [PATCH] Add support for nitrokey 3 distinction between the secrets + app and other + +This now adds the secrets app version and the nitrokey 3 firmware version, +and also the gpg pins +--- + src/ccid.c | 71 +++++++++++++++++++++++++- + src/ccid.h | 2 + + src/device.c | 29 +++++------ + src/device.h | 2 +- + src/main.c | 41 +++++++++++---- + src/operations_ccid.c | 113 +++++++++++++++++++++++++++++++++++++----- + src/operations_ccid.h | 2 +- + src/structs.h | 19 +++++++ + 8 files changed, 238 insertions(+), 41 deletions(-) + +diff --git a/src/ccid.c b/src/ccid.c +index 9cf24a0..a2cc919 100644 +--- a/src/ccid.c ++++ b/src/ccid.c +@@ -104,7 +104,7 @@ IccResult parse_icc_result(uint8_t *buf, size_t buf_len) { + // .buffer_len = buf_len + }; + // Make sure the response do not contain overread attempts +- rassert(i.data_len < buf_len - 10); ++ rassert(i.data_len <= buf_len - 10); + return i; + } + +@@ -307,6 +307,75 @@ int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_siz + return RET_NO_ERROR; + } + ++int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { ++ unsigned char cmd_select[] = { ++ 0x6f, ++ 0x0E, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0xa4, ++ 0x04, ++ 0x00, ++ 0x09, ++ 0xa0, ++ 0x00, ++ 0x00, ++ 0x08, ++ 0x47, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x01, ++ }; ++ ++ check_ret( ++ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), ++ RET_COMM_ERROR); ++ ++ ++ return RET_NO_ERROR; ++} ++ ++int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { ++ unsigned char cmd_select[] = { ++ 0x6f, ++ 0x0C, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0x00, ++ 0xA4, ++ 0x04, ++ 0x00, ++ 0x06, ++ 0xD2, ++ 0x76, ++ 0x00, ++ 0x01, ++ 0x24, ++ 0x01, ++ 0x00, ++ }; ++ ++ check_ret( ++ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), ++ RET_COMM_ERROR); ++ ++ ++ return RET_NO_ERROR; ++} + + int ccid_init(libusb_device_handle *handle) { + +diff --git a/src/ccid.h b/src/ccid.h +index ed17dc7..3dcf106 100644 +--- a/src/ccid.h ++++ b/src/ccid.h +@@ -70,6 +70,8 @@ uint32_t icc_pack_tlvs_for_sending(uint8_t *buf, size_t buflen, TLV tlvs[], int + libusb_device_handle *get_device(libusb_context *ctx, const struct VidPid pPid[], int devices_count); + int ccid_init(libusb_device_handle *handle); + int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); ++int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); ++int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); + + + enum { +diff --git a/src/device.c b/src/device.c +index 4b9361e..52acece 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -29,6 +29,7 @@ + #include "structs.h" + #include "utils.h" + #include ++#include + #include + #include + #include +@@ -259,23 +260,19 @@ int device_receive_buf(struct Device *dev) { + + #include "operations_ccid.h" + +-int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { +- assert(out_status != NULL); ++int device_get_status(struct Device *dev, struct FullResponseStatus *out_response) { ++ assert(out_response != NULL); + assert(dev != NULL); +- memset(out_status, 0, sizeof(struct ResponseStatus)); ++ memset(out_response, 0, sizeof(struct FullResponseStatus)); ++ ++ struct ResponseStatus *out_status = &out_response->response_status; + + if (dev->connection_type == CONNECTION_CCID) { +- int counter = 0; +- uint32_t serial = 0; +- uint16_t version = 0; +- int res = status_ccid(dev->mp_devhandle_ccid, +- &counter, +- &version, +- &serial); +- out_status->retry_admin = counter; +- out_status->retry_user = counter; +- out_status->card_serial_u32 = serial; +- out_status->firmware_version = version; ++ int res = status_ccid(dev->mp_devhandle_ccid, out_response); ++ // out_status->retry_admin = counter; ++ // out_status->retry_user = counter; ++ // out_status->card_serial_u32 = serial; ++ // out_status->firmware_version = version; + return res; + } + +@@ -290,7 +287,7 @@ int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { + + device_send_buf(dev, GET_STATUS); + device_receive_buf(dev); +- *out_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; ++ out_response->response_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; + + if (out_status->firmware_version_st.minor == 1) { + for (int i = 0; i < 100; ++i) { +@@ -343,4 +340,4 @@ const char *command_status_to_string(uint8_t status_code) { + void clean_buffers(struct Device *dev) { + memset(dev->ccid_buffer_in, 0, sizeof dev->ccid_buffer_in); + memset(dev->ccid_buffer_out, 0, sizeof dev->ccid_buffer_out); +-} +\ No newline at end of file ++} +diff --git a/src/device.h b/src/device.h +index c895546..97feeeb 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -72,7 +72,7 @@ struct Device { + + int device_connect(struct Device *dev); + int device_disconnect(struct Device *dev); +-int device_get_status(struct Device *dev, struct ResponseStatus *out_status); ++int device_get_status(struct Device *dev, struct FullResponseStatus *out_status); + int device_send(struct Device *dev, uint8_t *in_data, size_t data_size, uint8_t command_ID); + int device_receive(struct Device *dev, uint8_t *out_data, size_t out_buffer_size); + int device_send_buf(struct Device *dev, uint8_t command_ID); +diff --git a/src/main.c b/src/main.c +index 059069e..9b38552 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -93,25 +93,46 @@ int parse_cmd_and_run(int argc, char *const *argv) { + res = RET_NO_ERROR; + break; + case 'i': {// id | info +- struct ResponseStatus status; ++ struct FullResponseStatus status; ++ memset(&status, 0, sizeof (struct FullResponseStatus)); ++ + res = device_get_status(&dev, &status); + check_ret((res != RET_NO_ERROR) && (res != RET_NO_PIN_ATTEMPTS), res); + if (strnlen(argv[1], 10) == 2 && argv[1][1] == 'd') { + // id command - print ID only +- print_card_serial(&status); ++ print_card_serial(&status.response_status); + } else { + // info command - print status + printf("Connected device status:\n"); + printf("\tCard serial: "); +- print_card_serial(&status); +- printf("\tFirmware: v%d.%d\n", +- status.firmware_version_st.major, +- status.firmware_version_st.minor); +- if (res != RET_NO_PIN_ATTEMPTS) { +- printf("\tCard counters: Admin %d, User %d\n", +- status.retry_admin, status.retry_user); ++ print_card_serial(&status.response_status); ++ if (status.device_type == Nk3) { ++ printf("\tFirmware Nitrokey 3: v%d.%d.%d\n", ++ (status.nk3_extra_info.firmware_version >> 22) & 0b1111111111, ++ (status.nk3_extra_info.firmware_version >> 6) & 0xFFFF, ++ status.nk3_extra_info.firmware_version & 0b111111); ++ printf("\tFirmware Secrets App: v%d.%d\n", ++ status.response_status.firmware_version_st.major, ++ status.response_status.firmware_version_st.minor); ++ if (res != RET_NO_PIN_ATTEMPTS) { ++ printf("\tSecrets app PIN counter: %d\n", ++ status.response_status.retry_user); ++ } else { ++ printf("\tSecrets app PIN counter: PIN is not set - set PIN before the first use\n"); ++ } ++ printf("\tGPG Card counters: Admin %d, User %d\n", ++ status.nk3_extra_info.pgp_admin_pin_retries, ++ status.nk3_extra_info.pgp_user_pin_retries); + } else { +- printf("\tCard counters: PIN is not set - set PIN before the first use\n"); ++ printf("\tFirmware: v%d.%d\n", ++ status.response_status.firmware_version_st.major, ++ status.response_status.firmware_version_st.minor); ++ if (res != RET_NO_PIN_ATTEMPTS) { ++ printf("\tCard counters: Admin %d, User %d\n", ++ status.response_status.retry_admin, status.response_status.retry_user); ++ } else { ++ printf("\tCard counters: PIN is not set - set PIN before the first use\n"); ++ } + } + } + if (res == RET_NO_PIN_ATTEMPTS) { +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index eb46124..25772e5 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -273,14 +273,102 @@ int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify) { + return RET_VALIDATION_PASSED; + } + +-int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number) { ++int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response) { ++ rassert(full_response != NULL); ++ struct ResponseStatus *response = &full_response->response_status; + rassert(handle != NULL); +- rassert(attempt_counter != NULL); +- rassert(firmware_version != NULL); +- rassert(serial_number != NULL); + uint8_t buf[1024] = {}; + IccResult iccResult = {}; +- int r = send_select_ccid(handle, buf, sizeof buf, &iccResult); ++ bool pin_counter_is_error = false; ++ int r; ++ libusb_device *usb_dev; ++ struct libusb_device_descriptor usb_desc; ++ ++ usb_dev = libusb_get_device(handle); ++ ++ r = libusb_get_device_descriptor(usb_dev, &usb_desc); ++ ++ if (r < 0) { ++ return r; ++ } ++ ++ ++ if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_3_USB_PID) { ++ full_response->device_type = Nk3; ++ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_PRO_USB_PID) { ++ full_response->device_type = NkPro2; ++ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_STORAGE_USB_PID) { ++ full_response->device_type = NkStorage; ++ } else if (usb_desc.idVendor == LIBREM_KEY_USB_VID || usb_desc.idProduct == LIBREM_KEY_USB_PID) { ++ full_response->device_type = LibremKey; ++ } ++ ++ if (full_response->device_type == Nk3) { ++ r = send_select_nk3_admin_ccid(handle, buf, sizeof buf, &iccResult); ++ if (r != RET_NO_ERROR) { ++ return r; ++ } ++ ++ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; ++ uint32_t iso_actual_length = iso7816_compose( ++ data_iso, sizeof data_iso, ++ 0x61, 0, 0, 0, 4, NULL, 0); ++ ++ // encode ccid wrapper ++ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, ++ 0x6F, iso_actual_length, ++ 0, 0, 0, data_iso); ++ int transferred; ++ r = ccid_send(handle, &transferred, buf, icc_actual_length); ++ if (r != 0) { ++ return r; ++ } ++ ++ r = ccid_receive(handle, &transferred, buf, sizeof buf); ++ if (r != 0) { ++ return r; ++ } ++ ++ IccResult iccResult = parse_icc_result(buf, transferred); ++ rassert(iccResult.data_status_code == 0x9000); ++ rassert(iccResult.data_len == 6); ++ full_response->nk3_extra_info.firmware_version = be32toh(*(uint32_t *) iccResult.data); ++ } ++ ++ if (full_response->device_type == Nk3) { ++ r = send_select_nk3_pgp_ccid(handle, buf, sizeof buf, &iccResult); ++ if (r != RET_NO_ERROR) { ++ return r; ++ } ++ ++ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; ++ uint32_t iso_actual_length = iso7816_compose( ++ data_iso, sizeof data_iso, ++ 0xCA, 0, 0xC4, 0, 0xFF, NULL, 0); ++ ++ // encode ccid wrapper ++ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, ++ 0x6F, iso_actual_length, ++ 0, 0, 0, data_iso); ++ int transferred; ++ r = ccid_send(handle, &transferred, buf, icc_actual_length); ++ if (r != 0) { ++ return r; ++ } ++ ++ r = ccid_receive(handle, &transferred, buf, sizeof buf); ++ if (r != 0) { ++ return r; ++ } ++ ++ IccResult iccResult = parse_icc_result(buf, transferred); ++ rassert(iccResult.data_status_code == 0x9000); ++ rassert(iccResult.data_len == 9); ++ full_response->nk3_extra_info.pgp_user_pin_retries = iccResult.data[4]; ++ full_response->nk3_extra_info.pgp_admin_pin_retries = iccResult.data[6]; ++ } ++ ++ r = send_select_ccid(handle, buf, sizeof buf, &iccResult); + if (r != RET_NO_ERROR) { + return r; + } +@@ -292,29 +380,30 @@ int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *fi + r = get_tlv(iccResult.data, iccResult.data_len, Tag_PINCounter, &counter_tlv); + if (!(r == RET_NO_ERROR && counter_tlv.tag == Tag_PINCounter)) { + // PIN counter not found - comm error (ignore) or PIN not set +- *attempt_counter = -1; ++ pin_counter_is_error = true; + } else { +- *attempt_counter = counter_tlv.v_data[0]; ++ response->retry_admin = counter_tlv.v_data[0]; ++ response->retry_user = counter_tlv.v_data[0]; + } + + TLV serial_tlv = {}; + r = get_tlv(iccResult.data, iccResult.data_len, Tag_SerialNumber, &serial_tlv); + if (r == RET_NO_ERROR && serial_tlv.tag == Tag_SerialNumber) { +- *serial_number = be32toh(*(uint32_t *) serial_tlv.v_data); ++ response->card_serial_u32 = be32toh(*(uint32_t *) serial_tlv.v_data); + } else { + // ignore errors - unsupported or hidden serial_tlv number +- *serial_number = 0; ++ response->card_serial_u32 = 0; + } + + TLV version_tlv = {}; + r = get_tlv(iccResult.data, iccResult.data_len, Tag_Version, &version_tlv); + if (!(r == RET_NO_ERROR && version_tlv.tag == Tag_Version)) { +- *firmware_version = 0; ++ response->firmware_version = 0; + return RET_COMM_ERROR; + } +- *firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); ++ response->firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); + +- if (*attempt_counter == -1) { ++ if (pin_counter_is_error == true) { + return RET_NO_PIN_ATTEMPTS; + } + return RET_NO_ERROR; +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index b26b3c7..ea463b4 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -10,7 +10,7 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN); + int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); +-int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); ++int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H +diff --git a/src/structs.h b/src/structs.h +index 6309cd0..9e87134 100644 +--- a/src/structs.h ++++ b/src/structs.h +@@ -116,6 +116,25 @@ struct ResponseStatus { + uint8_t retry_user; /*not present in the firmware response for the Status command in v0.8 firmware*/ + }; + ++enum DeviceType { ++ Unknown = 0, ++ Nk3, ++ NkPro2, ++ NkStorage, ++ LibremKey, ++}; ++ ++struct FullResponseStatus { ++ enum DeviceType device_type; ++ struct ResponseStatus response_status; ++ struct { ++ // Only valid if device_type is NK3 ++ uint8_t pgp_admin_pin_retries; ++ uint8_t pgp_user_pin_retries; ++ uint32_t firmware_version; ++ } nk3_extra_info; ++}; ++ + + struct WriteToOTPSlot { + //admin auth diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch deleted file mode 100644 index 781c10ffa..000000000 --- a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch +++ /dev/null @@ -1,219 +0,0 @@ -From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Mon, 25 Nov 2024 17:04:47 +0100 -Subject: [PATCH 1/3] Add reset command for nitrokey 3 - ---- - src/main.c | 10 ++++++++-- - src/operations_ccid.c | 41 +++++++++++++++++++++++++++++++++++++++++ - src/operations_ccid.h | 1 + - 3 files changed, 50 insertions(+), 2 deletions(-) - -diff --git a/src/main.c b/src/main.c -index 059069e..b80b71d 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -21,6 +21,7 @@ - - #include "ccid.h" - #include "operations.h" -+#include "operations_ccid.h" - #include "return_codes.h" - #include "utils.h" - #include "version.h" -@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { - } - break; - case 'r': -- if (argc != 3) break; -- res = regenerate_AES_key(&dev, argv[2]); -+ if (strncmp(argv[1], "reset", 15) == 0) { -+ if (argc != 2) break; -+ res = nk3_reset(&dev); -+ } else if (strncmp(argv[1], "regenerate", 15) == 0) { -+ if (argc != 3) break; -+ res = regenerate_AES_key(&dev, argv[2]); -+ } - break; - default: - break; -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index eb46124..574155d 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -32,6 +32,47 @@ - #include - - -+ -+int nk3_reset(struct Device *dev) { -+ libusb_device *usb_dev; -+ struct libusb_device_descriptor usb_desc; -+ usb_dev = libusb_get_device(dev->mp_devhandle_ccid); -+ -+ int r = libusb_get_device_descriptor(usb_dev, &usb_desc); -+ -+ if (r < 0) { -+ return r; -+ } -+ -+ -+ if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { -+ return 0; -+ } -+ -+ -+ uint8_t buf[10]; -+ // encode -+ uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); -+ -+ // encode ccid wrapper -+ icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, -+ 0x6F, icc_actual_length, -+ 0, 0, 0, buf); -+ // send -+ IccResult iccResult; -+ r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, -+ dev->ccid_buffer_out, icc_actual_length, &iccResult); -+ if (r != 0) { -+ return r; -+ } -+ // check status code -+ if (iccResult.data_status_code != 0x9000) { -+ return 1; -+ } -+ -+ return RET_NO_ERROR; -+} -+ - int set_pin_ccid(struct Device *dev, const char *admin_PIN) { - TLV tlvs[] = { - { -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index b26b3c7..ec0070c 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); -+int nk3_reset(struct Device *dev); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H - -From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Mon, 2 Dec 2024 10:29:59 +0100 -Subject: [PATCH 2/3] Add optional new pin when resetting - ---- - src/main.c | 9 +++++---- - src/operations_ccid.c | 6 +++++- - src/operations_ccid.h | 5 ++++- - 3 files changed, 14 insertions(+), 6 deletions(-) - -diff --git a/src/main.c b/src/main.c -index b80b71d..3f4a1cc 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -38,9 +38,10 @@ void print_help(char *app_name) { - "\t%s info\n" - "\t%s version\n" - "\t%s check \n" -- "\t%s regenerate \n" -+ "\t%s reset [ADMIN PIN]\n" -+ "\t%s regenerate\n" - "\t%s set [COUNTER]\n", -- app_name, app_name, app_name, app_name, app_name, app_name); -+ app_name, app_name, app_name, app_name, app_name, app_name, app_name); - } - - -@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { - break; - case 'r': - if (strncmp(argv[1], "reset", 15) == 0) { -- if (argc != 2) break; -- res = nk3_reset(&dev); -+ if (argc != 2 && argc != 3) break; -+ res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); - } else if (strncmp(argv[1], "regenerate", 15) == 0) { - if (argc != 3) break; - res = regenerate_AES_key(&dev, argv[2]); -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 574155d..07834ce 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -33,7 +33,7 @@ - - - --int nk3_reset(struct Device *dev) { -+int nk3_reset(struct Device *dev, const char * new_pin) { - libusb_device *usb_dev; - struct libusb_device_descriptor usb_desc; - usb_dev = libusb_get_device(dev->mp_devhandle_ccid); -@@ -70,6 +70,10 @@ int nk3_reset(struct Device *dev) { - return 1; - } - -+ if (new_pin != NULL) { -+ set_pin_ccid(dev, new_pin); -+ } -+ - return RET_NO_ERROR; - } - -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index ec0070c..61cad72 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); --int nk3_reset(struct Device *dev); -+// new_pin can be `null` -+// -+// If it is, no new pin will be set -+int nk3_reset(struct Device *dev, const char * new_pin); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H - -From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Tue, 3 Dec 2024 10:48:27 +0100 -Subject: [PATCH 3/3] Fix null pointer bug on non nk3 - ---- - src/operations_ccid.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 07834ce..538d434 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -36,6 +36,12 @@ - int nk3_reset(struct Device *dev, const char * new_pin) { - libusb_device *usb_dev; - struct libusb_device_descriptor usb_desc; -+ -+ if (!dev->mp_devhandle_ccid) { -+ // Not an NK3 -+ return RET_NO_ERROR; -+ } -+ - usb_dev = libusb_get_device(dev->mp_devhandle_ccid); - - int r = libusb_get_device_descriptor(usb_dev, &usb_desc); -@@ -46,7 +52,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { - - - if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { -- return 0; -+ return RET_NO_ERROR; - } - - From ebf4d1d22180f1649ad4b2a352629759857701ff Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 6 Dec 2024 09:48:28 -0500 Subject: [PATCH 27/81] oem-factory-reset+seal-hotp nk3 hotp-verification info adaptations - oem-factory-reset: fix strings for nk3 is from https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 is Secrets app, not Secret App singular, not App capitalized - initrd/bin/seal-hotpkey: adapt to check nk3 Secrets App PIN counter if nk3, keep Card counters for --- initrd/bin/oem-factory-reset | 16 ++-- initrd/bin/seal-hotpkey | 152 +++++++++++++++++------------------ 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index a3f6933f3..613569530 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -143,13 +143,15 @@ mount_boot() { reset_nk3_secret_app() { TRACE_FUNC - # Reset Nitrokey 3 Secret App + # Reset Nitrokey 3 Secrets App if lsusb | grep -q "20a0:42b2"; then echo - echo "Resetting Nitrokey 3 Secret App PIN. Physical presence (touch) will be required" + warn "Resetting Nitrokey 3 Secrets App PIN. Physical presence (touch) will be required" #TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed # Reset Nitrokey 3 secret app with PIN - /bin/hotp_verification reset "${ADMIN_PIN}" + if ! /bin/hotp_verification reset "${ADMIN_PIN}"; then + whiptail_error_die "Failed to reset Nitrokey 3 Secrets App with error code $?, contact Nitrokey support" + fi fi } @@ -552,7 +554,6 @@ gpg_key_factory_reset() { whiptail_error_die "GPG Key factory reset failed!\n\n$ERROR" fi - # If Nitrokey Storage is inserted, reset AES keys as well if lsusb | grep -q "20a0:4109" && [ -x /bin/hotp_verification ]; then DEBUG "Nitrokey Storage detected, resetting AES keys..." @@ -560,7 +561,7 @@ gpg_key_factory_reset() { DEBUG "Restarting scdaemon to remove possible exclusive lock of dongle" killall -9 scdaemon fi - + # Toggle forced sig (good security practice, forcing PIN request for each signature request) if gpg --card-status | grep "Signature PIN" | grep -q "not forced"; then DEBUG "GPG toggling forcesig on since off..." @@ -575,7 +576,7 @@ gpg_key_factory_reset() { whiptail_error_die "GPG Key forcesig toggle on failed!\n\n$ERROR" fi fi - + # use p256 for key generation if requested if [ "$GPG_ALGO" = "p256" ]; then { @@ -1388,7 +1389,7 @@ fi #if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID if lsusb | grep -q "20a0:42b2"; then - passphrases+="Nitrokey 3 Secret App PIN: ${ADMIN_PIN}\n" + passphrases+="Nitrokey 3 Secrets App PIN: ${ADMIN_PIN}\n" fi #GPG PINs output @@ -1403,7 +1404,6 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi - # Show configured secrets in whiptail and loop until user confirms qr code was scanned while true; do whiptail --msgbox " diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 930d78059..266bc48f6 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -8,28 +8,26 @@ HOTP_SECRET="/tmp/secret/hotp.key" HOTP_COUNTER="/boot/kexec_hotp_counter" HOTP_KEY="/boot/kexec_hotp_key" -mount_boot() -{ - TRACE_FUNC - # Mount local disk if it is not already mounted - if ! grep -q /boot /proc/mounts; then - if ! mount -o ro /boot; then - whiptail_error --title 'ERROR' \ - --msgbox "Couldn't mount /boot.\n\nCheck the /boot device in configuration settings, or perform an OEM reset." 0 80 - return 1 - fi - fi +mount_boot() { + TRACE_FUNC + # Mount local disk if it is not already mounted + if ! grep -q /boot /proc/mounts; then + if ! mount -o ro /boot; then + whiptail_error --title 'ERROR' \ + --msgbox "Couldn't mount /boot.\n\nCheck the /boot device in configuration settings, or perform an OEM reset." 0 80 + return 1 + fi + fi } TRACE_FUNC -fatal_error() -{ - echo -e "\nERROR: ${1}; press Enter to continue." - read - # get lsusb output for debugging - DEBUG "lsusb output: $(lsusb)" - die "$1" +fatal_error() { + echo -e "\nERROR: ${1}; press Enter to continue." + read + # get lsusb output for debugging + DEBUG "lsusb output: $(lsusb)" + die "$1" } # Use stored HOTP key branding (this might be useful after OEM reset) @@ -41,11 +39,11 @@ fi if [ "$CONFIG_TPM" = "y" ]; then DEBUG "Sealing HOTP secret reuses TOTP sealed secret..." - tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" \ - || fatal_error "Unable to unseal HOTP secret" + tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" || + fatal_error "Unable to unseal HOTP secret" else # without a TPM, generate a secret based on the SHA-256 of the ROM - secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed" + secret_from_rom_hash >"$HOTP_SECRET" || die "Reading ROM failed" fi # Store counter in file instead of TPM for now, as it conflicts with Heads @@ -69,20 +67,20 @@ counter_value=1 enable_usb # While making sure the key is inserted, capture the status so we can check how # many PIN attempts remain -if ! hotp_token_info="$(hotp_verification info)" ; then - echo -e "\nInsert your $HOTPKEY_BRANDING and press Enter to configure it" - read - if ! hotp_token_info="$(hotp_verification info)" ; then - # don't leak key on failure - shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null - fatal_error "Unable to find $HOTPKEY_BRANDING" - fi +if ! hotp_token_info="$(hotp_verification info)"; then + echo -e "\nInsert your $HOTPKEY_BRANDING and press Enter to configure it" + read + if ! hotp_token_info="$(hotp_verification info)"; then + # don't leak key on failure + shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null + fatal_error "Unable to find $HOTPKEY_BRANDING" + fi fi # Set HOTP USB Security Dongle branding based on VID -if lsusb | grep -q "20a0:" ; then +if lsusb | grep -q "20a0:"; then HOTPKEY_BRANDING="Nitrokey" -elif lsusb | grep -q "316d:" ; then +elif lsusb | grep -q "316d:"; then HOTPKEY_BRANDING="Librem Key" else HOTPKEY_BRANDING="HOTP USB Security Dongle" @@ -99,19 +97,25 @@ gpg_key_create_time="${gpg_key_create_time:-0}" DEBUG "Signature key was created at $(date -d "@$gpg_key_create_time")" now_date="$(date '+%s')" -# Get the number of admin PIN retry attempts remaining -awk_admin_counter_regex='/^\s*Card counters: Admin (\d),.*$/' -awk_get_admin_counter="$awk_admin_counter_regex"' { print gensub('"$awk_admin_counter_regex"', "\\1", "") }' -admin_pin_retries="$(echo "$hotp_token_info" | awk "$awk_get_admin_counter")" +# Get the number of HOTP related PIN retry attempts remaining +# if nk3 detected by lsusb, use different regex to get admin counter +if lsusb | grep -q "20a0:42b2"; then + # Nitrokey 3: Secrets app PIN counter: 8 + admin_pin_retries=$(echo "$hotp_token_info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ') + prompt_message="Secrets app" +else + admin_pin_retries=$(echo "$hotp_token_info" | grep "Card counters: Admin" | cut -d ':' -f 2 | tr -d ' ') + prompt_message="GPG Admin" +fi + admin_pin_retries="${admin_pin_retries:-0}" -DEBUG "Admin PIN retry counter is $admin_pin_retries" -#TODO: as per hotp_verification 1.6: this is 8 for nk3 and wrong. FIX +DEBUG "HOTP related PIN retry counter is $admin_pin_retries" # Try using factory default admin PIN for 1 month following OEM reset to ease # initial setup. But don't do it forever to encourage changing the PIN and # so PIN attempts are not consumed by the default attempt. admin_pin="12345678" -month_secs="$((30*24*60*60))" +month_secs="$((30 * 24 * 60 * 60))" admin_pin_status=1 if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then # Remind what the default PIN was in case it still hasn't been changed @@ -122,48 +126,42 @@ if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then elif [ "$admin_pin_retries" -lt 3 ]; then echo "Not trying default PIN ($admin_pin), only $admin_pin_retries attempt(s) left" else - hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1 + echo "Trying $prompt_message PIN ($admin_pin) to seal HOTP secret on $HOTPKEY_BRANDING... You may be requested to touch the dongle..." + #TODO: silence the output of hotp_initialize once https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed + #hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1 + hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" admin_pin_status="$?" fi if [ "$admin_pin_status" -ne 0 ]; then - # create custom message for PIN prompt based on nk3 lsusb product id - prompt_message="" - if lsusb | grep -q "20a0:42b2"; then - prompt_message="Secure App" - else - prompt_message="GPG Admin" - fi - - - # prompt user for PIN and retry - echo "" - read -s -p "Enter your $HOTPKEY_BRANDING $prompt_message PIN: " admin_pin - echo -e "\n" - - hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" - if [ $? -ne 0 ]; then - echo -e "\n" - read -s -p "Error setting HOTP secret, re-enter $prompt_message PIN and try again: " admin_pin - echo -e "\n" - if ! hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" ; then - # don't leak key on failure - shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null - if [ "$HOTPKEY_BRANDING" == "Nitrokey" ]; then - fatal_error "Setting HOTP secret failed, to reset $prompt_message PIN, redo Re-Ownership procedure, the Nitrokey App 2 or contact Nitrokey support" - else - fatal_error "Setting HOTP secret failed" - fi - fi - fi -else - # remind user to change admin password - echo -e "\nWARNING: default admin PIN detected: please change this as soon as possible." + # prompt user for PIN and retry + echo "" + read -s -p "Enter your $HOTPKEY_BRANDING $prompt_message PIN: " admin_pin + echo -e "\n" + + hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" + if [ $? -ne 0 ]; then + echo -e "\n" + read -s -p "Error setting HOTP secret, re-enter $prompt_message PIN and try again: " admin_pin + echo -e "\n" + if ! hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING"; then + # don't leak key on failure + shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null + if [ "$HOTPKEY_BRANDING" == "Nitrokey" ]; then + fatal_error "Setting HOTP secret failed, to reset $prompt_message PIN, redo Re-Ownership procedure, use the Nitrokey App 2 or contact Nitrokey support" + else + fatal_error "Setting HOTP secret failed" + fi + fi + fi +else + # remind user to change admin password + warn "Factory $prompt_message default PIN detected: please change this PIN as soon as possible through OEM Factory Reset/User Re-Ownership" fi # HOTP key no longer needed -shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null +shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null # Make sure our counter is incremented ahead of the next check #increment_tpm_counter $counter > /dev/null \ @@ -173,13 +171,13 @@ shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null mount -o remount,rw /boot -counter_value=`expr $counter_value + 1` -echo $counter_value > $HOTP_COUNTER \ -|| fatal_error "Unable to create hotp counter file" +counter_value=$(expr $counter_value + 1) +echo $counter_value >$HOTP_COUNTER || + fatal_error "Unable to create hotp counter file" # Store/overwrite HOTP USB Security Dongle branding found out beforehand -echo $HOTPKEY_BRANDING > $HOTP_KEY \ -|| die "Unable to store hotp key file" +echo $HOTPKEY_BRANDING >$HOTP_KEY || + die "Unable to store hotp key file" #sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ #|| die "Unable to create hotp counter file" From 27ab17377d54c6f232bf93d252b6c3b80c7f9031 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 6 Dec 2024 11:36:50 -0500 Subject: [PATCH 28/81] hotp-verification: removed patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 directory: waiting for https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 and https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46 to be merged to change modules/hotp-verification commit Signed-off-by: Thierry Laurion --- .../43.patch | 450 ------------------ 1 file changed, 450 deletions(-) delete mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch deleted file mode 100644 index 26ad2bc45..000000000 --- a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/43.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 707c6545a509eeb24a06537e5f835d786c2e657e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Thu, 5 Dec 2024 16:44:30 +0100 -Subject: [PATCH] Add support for nitrokey 3 distinction between the secrets - app and other - -This now adds the secrets app version and the nitrokey 3 firmware version, -and also the gpg pins ---- - src/ccid.c | 71 +++++++++++++++++++++++++- - src/ccid.h | 2 + - src/device.c | 29 +++++------ - src/device.h | 2 +- - src/main.c | 41 +++++++++++---- - src/operations_ccid.c | 113 +++++++++++++++++++++++++++++++++++++----- - src/operations_ccid.h | 2 +- - src/structs.h | 19 +++++++ - 8 files changed, 238 insertions(+), 41 deletions(-) - -diff --git a/src/ccid.c b/src/ccid.c -index 9cf24a0..a2cc919 100644 ---- a/src/ccid.c -+++ b/src/ccid.c -@@ -104,7 +104,7 @@ IccResult parse_icc_result(uint8_t *buf, size_t buf_len) { - // .buffer_len = buf_len - }; - // Make sure the response do not contain overread attempts -- rassert(i.data_len < buf_len - 10); -+ rassert(i.data_len <= buf_len - 10); - return i; - } - -@@ -307,6 +307,75 @@ int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_siz - return RET_NO_ERROR; - } - -+int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { -+ unsigned char cmd_select[] = { -+ 0x6f, -+ 0x0E, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0xa4, -+ 0x04, -+ 0x00, -+ 0x09, -+ 0xa0, -+ 0x00, -+ 0x00, -+ 0x08, -+ 0x47, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x01, -+ }; -+ -+ check_ret( -+ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), -+ RET_COMM_ERROR); -+ -+ -+ return RET_NO_ERROR; -+} -+ -+int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult) { -+ unsigned char cmd_select[] = { -+ 0x6f, -+ 0x0C, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0x00, -+ 0xA4, -+ 0x04, -+ 0x00, -+ 0x06, -+ 0xD2, -+ 0x76, -+ 0x00, -+ 0x01, -+ 0x24, -+ 0x01, -+ 0x00, -+ }; -+ -+ check_ret( -+ ccid_process_single(handle, buf, buf_size, cmd_select, sizeof cmd_select, iccResult), -+ RET_COMM_ERROR); -+ -+ -+ return RET_NO_ERROR; -+} - - int ccid_init(libusb_device_handle *handle) { - -diff --git a/src/ccid.h b/src/ccid.h -index ed17dc7..3dcf106 100644 ---- a/src/ccid.h -+++ b/src/ccid.h -@@ -70,6 +70,8 @@ uint32_t icc_pack_tlvs_for_sending(uint8_t *buf, size_t buflen, TLV tlvs[], int - libusb_device_handle *get_device(libusb_context *ctx, const struct VidPid pPid[], int devices_count); - int ccid_init(libusb_device_handle *handle); - int send_select_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); -+int send_select_nk3_admin_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); -+int send_select_nk3_pgp_ccid(libusb_device_handle *handle, uint8_t buf[], size_t buf_size, IccResult *iccResult); - - - enum { -diff --git a/src/device.c b/src/device.c -index 4b9361e..52acece 100644 ---- a/src/device.c -+++ b/src/device.c -@@ -29,6 +29,7 @@ - #include "structs.h" - #include "utils.h" - #include -+#include - #include - #include - #include -@@ -259,23 +260,19 @@ int device_receive_buf(struct Device *dev) { - - #include "operations_ccid.h" - --int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { -- assert(out_status != NULL); -+int device_get_status(struct Device *dev, struct FullResponseStatus *out_response) { -+ assert(out_response != NULL); - assert(dev != NULL); -- memset(out_status, 0, sizeof(struct ResponseStatus)); -+ memset(out_response, 0, sizeof(struct FullResponseStatus)); -+ -+ struct ResponseStatus *out_status = &out_response->response_status; - - if (dev->connection_type == CONNECTION_CCID) { -- int counter = 0; -- uint32_t serial = 0; -- uint16_t version = 0; -- int res = status_ccid(dev->mp_devhandle_ccid, -- &counter, -- &version, -- &serial); -- out_status->retry_admin = counter; -- out_status->retry_user = counter; -- out_status->card_serial_u32 = serial; -- out_status->firmware_version = version; -+ int res = status_ccid(dev->mp_devhandle_ccid, out_response); -+ // out_status->retry_admin = counter; -+ // out_status->retry_user = counter; -+ // out_status->card_serial_u32 = serial; -+ // out_status->firmware_version = version; - return res; - } - -@@ -290,7 +287,7 @@ int device_get_status(struct Device *dev, struct ResponseStatus *out_status) { - - device_send_buf(dev, GET_STATUS); - device_receive_buf(dev); -- *out_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; -+ out_response->response_status = *(struct ResponseStatus *) dev->packet_response.response_st.payload; - - if (out_status->firmware_version_st.minor == 1) { - for (int i = 0; i < 100; ++i) { -@@ -343,4 +340,4 @@ const char *command_status_to_string(uint8_t status_code) { - void clean_buffers(struct Device *dev) { - memset(dev->ccid_buffer_in, 0, sizeof dev->ccid_buffer_in); - memset(dev->ccid_buffer_out, 0, sizeof dev->ccid_buffer_out); --} -\ No newline at end of file -+} -diff --git a/src/device.h b/src/device.h -index c895546..97feeeb 100644 ---- a/src/device.h -+++ b/src/device.h -@@ -72,7 +72,7 @@ struct Device { - - int device_connect(struct Device *dev); - int device_disconnect(struct Device *dev); --int device_get_status(struct Device *dev, struct ResponseStatus *out_status); -+int device_get_status(struct Device *dev, struct FullResponseStatus *out_status); - int device_send(struct Device *dev, uint8_t *in_data, size_t data_size, uint8_t command_ID); - int device_receive(struct Device *dev, uint8_t *out_data, size_t out_buffer_size); - int device_send_buf(struct Device *dev, uint8_t command_ID); -diff --git a/src/main.c b/src/main.c -index 059069e..9b38552 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -93,25 +93,46 @@ int parse_cmd_and_run(int argc, char *const *argv) { - res = RET_NO_ERROR; - break; - case 'i': {// id | info -- struct ResponseStatus status; -+ struct FullResponseStatus status; -+ memset(&status, 0, sizeof (struct FullResponseStatus)); -+ - res = device_get_status(&dev, &status); - check_ret((res != RET_NO_ERROR) && (res != RET_NO_PIN_ATTEMPTS), res); - if (strnlen(argv[1], 10) == 2 && argv[1][1] == 'd') { - // id command - print ID only -- print_card_serial(&status); -+ print_card_serial(&status.response_status); - } else { - // info command - print status - printf("Connected device status:\n"); - printf("\tCard serial: "); -- print_card_serial(&status); -- printf("\tFirmware: v%d.%d\n", -- status.firmware_version_st.major, -- status.firmware_version_st.minor); -- if (res != RET_NO_PIN_ATTEMPTS) { -- printf("\tCard counters: Admin %d, User %d\n", -- status.retry_admin, status.retry_user); -+ print_card_serial(&status.response_status); -+ if (status.device_type == Nk3) { -+ printf("\tFirmware Nitrokey 3: v%d.%d.%d\n", -+ (status.nk3_extra_info.firmware_version >> 22) & 0b1111111111, -+ (status.nk3_extra_info.firmware_version >> 6) & 0xFFFF, -+ status.nk3_extra_info.firmware_version & 0b111111); -+ printf("\tFirmware Secrets App: v%d.%d\n", -+ status.response_status.firmware_version_st.major, -+ status.response_status.firmware_version_st.minor); -+ if (res != RET_NO_PIN_ATTEMPTS) { -+ printf("\tSecrets app PIN counter: %d\n", -+ status.response_status.retry_user); -+ } else { -+ printf("\tSecrets app PIN counter: PIN is not set - set PIN before the first use\n"); -+ } -+ printf("\tGPG Card counters: Admin %d, User %d\n", -+ status.nk3_extra_info.pgp_admin_pin_retries, -+ status.nk3_extra_info.pgp_user_pin_retries); - } else { -- printf("\tCard counters: PIN is not set - set PIN before the first use\n"); -+ printf("\tFirmware: v%d.%d\n", -+ status.response_status.firmware_version_st.major, -+ status.response_status.firmware_version_st.minor); -+ if (res != RET_NO_PIN_ATTEMPTS) { -+ printf("\tCard counters: Admin %d, User %d\n", -+ status.response_status.retry_admin, status.response_status.retry_user); -+ } else { -+ printf("\tCard counters: PIN is not set - set PIN before the first use\n"); -+ } - } - } - if (res == RET_NO_PIN_ATTEMPTS) { -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index eb46124..25772e5 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -273,14 +273,102 @@ int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify) { - return RET_VALIDATION_PASSED; - } - --int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number) { -+int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response) { -+ rassert(full_response != NULL); -+ struct ResponseStatus *response = &full_response->response_status; - rassert(handle != NULL); -- rassert(attempt_counter != NULL); -- rassert(firmware_version != NULL); -- rassert(serial_number != NULL); - uint8_t buf[1024] = {}; - IccResult iccResult = {}; -- int r = send_select_ccid(handle, buf, sizeof buf, &iccResult); -+ bool pin_counter_is_error = false; -+ int r; -+ libusb_device *usb_dev; -+ struct libusb_device_descriptor usb_desc; -+ -+ usb_dev = libusb_get_device(handle); -+ -+ r = libusb_get_device_descriptor(usb_dev, &usb_desc); -+ -+ if (r < 0) { -+ return r; -+ } -+ -+ -+ if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_3_USB_PID) { -+ full_response->device_type = Nk3; -+ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_PRO_USB_PID) { -+ full_response->device_type = NkPro2; -+ } else if (usb_desc.idVendor == NITROKEY_USB_VID || usb_desc.idProduct == NITROKEY_STORAGE_USB_PID) { -+ full_response->device_type = NkStorage; -+ } else if (usb_desc.idVendor == LIBREM_KEY_USB_VID || usb_desc.idProduct == LIBREM_KEY_USB_PID) { -+ full_response->device_type = LibremKey; -+ } -+ -+ if (full_response->device_type == Nk3) { -+ r = send_select_nk3_admin_ccid(handle, buf, sizeof buf, &iccResult); -+ if (r != RET_NO_ERROR) { -+ return r; -+ } -+ -+ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; -+ uint32_t iso_actual_length = iso7816_compose( -+ data_iso, sizeof data_iso, -+ 0x61, 0, 0, 0, 4, NULL, 0); -+ -+ // encode ccid wrapper -+ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, -+ 0x6F, iso_actual_length, -+ 0, 0, 0, data_iso); -+ int transferred; -+ r = ccid_send(handle, &transferred, buf, icc_actual_length); -+ if (r != 0) { -+ return r; -+ } -+ -+ r = ccid_receive(handle, &transferred, buf, sizeof buf); -+ if (r != 0) { -+ return r; -+ } -+ -+ IccResult iccResult = parse_icc_result(buf, transferred); -+ rassert(iccResult.data_status_code == 0x9000); -+ rassert(iccResult.data_len == 6); -+ full_response->nk3_extra_info.firmware_version = be32toh(*(uint32_t *) iccResult.data); -+ } -+ -+ if (full_response->device_type == Nk3) { -+ r = send_select_nk3_pgp_ccid(handle, buf, sizeof buf, &iccResult); -+ if (r != RET_NO_ERROR) { -+ return r; -+ } -+ -+ uint8_t data_iso[MAX_CCID_BUFFER_SIZE] = {}; -+ uint32_t iso_actual_length = iso7816_compose( -+ data_iso, sizeof data_iso, -+ 0xCA, 0, 0xC4, 0, 0xFF, NULL, 0); -+ -+ // encode ccid wrapper -+ uint32_t icc_actual_length = icc_compose(buf, sizeof buf, -+ 0x6F, iso_actual_length, -+ 0, 0, 0, data_iso); -+ int transferred; -+ r = ccid_send(handle, &transferred, buf, icc_actual_length); -+ if (r != 0) { -+ return r; -+ } -+ -+ r = ccid_receive(handle, &transferred, buf, sizeof buf); -+ if (r != 0) { -+ return r; -+ } -+ -+ IccResult iccResult = parse_icc_result(buf, transferred); -+ rassert(iccResult.data_status_code == 0x9000); -+ rassert(iccResult.data_len == 9); -+ full_response->nk3_extra_info.pgp_user_pin_retries = iccResult.data[4]; -+ full_response->nk3_extra_info.pgp_admin_pin_retries = iccResult.data[6]; -+ } -+ -+ r = send_select_ccid(handle, buf, sizeof buf, &iccResult); - if (r != RET_NO_ERROR) { - return r; - } -@@ -292,29 +380,30 @@ int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *fi - r = get_tlv(iccResult.data, iccResult.data_len, Tag_PINCounter, &counter_tlv); - if (!(r == RET_NO_ERROR && counter_tlv.tag == Tag_PINCounter)) { - // PIN counter not found - comm error (ignore) or PIN not set -- *attempt_counter = -1; -+ pin_counter_is_error = true; - } else { -- *attempt_counter = counter_tlv.v_data[0]; -+ response->retry_admin = counter_tlv.v_data[0]; -+ response->retry_user = counter_tlv.v_data[0]; - } - - TLV serial_tlv = {}; - r = get_tlv(iccResult.data, iccResult.data_len, Tag_SerialNumber, &serial_tlv); - if (r == RET_NO_ERROR && serial_tlv.tag == Tag_SerialNumber) { -- *serial_number = be32toh(*(uint32_t *) serial_tlv.v_data); -+ response->card_serial_u32 = be32toh(*(uint32_t *) serial_tlv.v_data); - } else { - // ignore errors - unsupported or hidden serial_tlv number -- *serial_number = 0; -+ response->card_serial_u32 = 0; - } - - TLV version_tlv = {}; - r = get_tlv(iccResult.data, iccResult.data_len, Tag_Version, &version_tlv); - if (!(r == RET_NO_ERROR && version_tlv.tag == Tag_Version)) { -- *firmware_version = 0; -+ response->firmware_version = 0; - return RET_COMM_ERROR; - } -- *firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); -+ response->firmware_version = be16toh(*(uint16_t *) version_tlv.v_data); - -- if (*attempt_counter == -1) { -+ if (pin_counter_is_error == true) { - return RET_NO_PIN_ATTEMPTS; - } - return RET_NO_ERROR; -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index b26b3c7..ea463b4 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -10,7 +10,7 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN); - int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); --int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); -+int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H -diff --git a/src/structs.h b/src/structs.h -index 6309cd0..9e87134 100644 ---- a/src/structs.h -+++ b/src/structs.h -@@ -116,6 +116,25 @@ struct ResponseStatus { - uint8_t retry_user; /*not present in the firmware response for the Status command in v0.8 firmware*/ - }; - -+enum DeviceType { -+ Unknown = 0, -+ Nk3, -+ NkPro2, -+ NkStorage, -+ LibremKey, -+}; -+ -+struct FullResponseStatus { -+ enum DeviceType device_type; -+ struct ResponseStatus response_status; -+ struct { -+ // Only valid if device_type is NK3 -+ uint8_t pgp_admin_pin_retries; -+ uint8_t pgp_user_pin_retries; -+ uint32_t firmware_version; -+ } nk3_extra_info; -+}; -+ - - struct WriteToOTPSlot { - //admin auth From 98e20544efdd4f03697d0d6c0a13be8566d2e129 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 6 Dec 2024 16:22:52 -0500 Subject: [PATCH 29/81] functions: Fix spelling of 'dictionaries' Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- .../eff_short_wordlist_2_0.txt | 0 initrd/etc/functions | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename initrd/etc/{diceware_dictionnaries => diceware_dictionaries}/eff_short_wordlist_2_0.txt (100%) diff --git a/initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt b/initrd/etc/diceware_dictionaries/eff_short_wordlist_2_0.txt similarity index 100% rename from initrd/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt rename to initrd/etc/diceware_dictionaries/eff_short_wordlist_2_0.txt diff --git a/initrd/etc/functions b/initrd/etc/functions index aa57676d9..ae25bc2b2 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -875,7 +875,7 @@ generate_passphrase() { usage_generate_passphrase() { echo "Usage: generate_passphrase --dictionary|-d [--number_words|-n ] [--max_length|-m ] [--lowercase|-l]" echo "Generates a passphrase using a Diceware dictionary." - echo " --dictionary|-d Path to the Diceware dictionary file (defaults to /etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt )." + echo " --dictionary|-d Path to the Diceware dictionary file (defaults to /etc/diceware_dictionaries/eff_short_wordlist_2_0.txt )." echo " [--number_words|-n ] Number of words in the passphrase (default: 3)." echo " [--max_length|-m ] Maximum size of the passphrase (default: 256)." echo " [--lowercase|-l] Use lowercase words (default: false)." @@ -910,7 +910,7 @@ generate_passphrase() { } TRACE_FUNC - local dictionary_file="/etc/diceware_dictionnaries/eff_short_wordlist_2_0.txt" + local dictionary_file="/etc/diceware_dictionaries/eff_short_wordlist_2_0.txt" local num_words=3 local max_size=256 local lowercase=false From be49517a0d00b4131617f7a845e5c69563bdf6ba Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 6 Dec 2024 16:24:20 -0500 Subject: [PATCH 30/81] functions: Simplify dictionary word selection The dice-rolls method was relatively complex and somewhat biased (~2.4% biased toward 1-4 on each roll due to modulo bias). Just pick a line from the dictionary at random. Using all 32 bits of entropy to pick a line once distributes the modulo bias so it is only 0.000003% biased toward the first 1263 words. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/etc/functions | 56 ++++++++++---------------------------------- 1 file changed, 13 insertions(+), 43 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index ae25bc2b2..2dabda7b3 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -881,32 +881,18 @@ generate_passphrase() { echo " [--lowercase|-l] Use lowercase words (default: false)." } - # Helper subfunction to get a word from the dictionary based on dice rolls - get_word_from_dictionary() { - local rolls="$1" - local dictionary_file="$2" - local word="" - - word=$(grep "^$rolls" "$dictionary_file" | awk -F ' ' '{print $2}') - echo "$word" - } - - # Helper subfunction to generate dice rolls - generate_dice_rolls() { - TRACE_FUNC - local num_rolls="$1" - local rolls="" - local random_bytes - - # Read num_rolls bytes from /dev/random, fed by CPU RRAND in one go - random_bytes=$(dd if=/dev/random bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') - - # Process each byte to generate a dice roll - while read -r byte; do - roll=$((byte % 6 + 1)) - rolls+=$roll - done <<<"$random_bytes" - echo "$rolls" + # Helper subfunction to get a random word from the dictionary + get_random_word_from_dictionary() { + local dictionary_file="$1" lines random + + lines="$(wc -l <"$dictionary_file")" + # 4 random bytes are used to reduce modulo bias to an acceptable + # level. 4 bytes with modulus 1296 results in 0.000003% bias + # toward the first 1263 words. + random="$(dd if=/dev/random bs=4 count=1 status=none | hexdump -e '1/4 "%u\n"')" + ((random%=lines)) + ((++random)) # tail's line count is 1-based + tail -n +"$random" "$dictionary_file" | head -1 | cut -d$'\t' -f2 } TRACE_FUNC @@ -961,25 +947,9 @@ generate_passphrase() { local passphrase="" local word="" - local key="" - local digits=0 - - # Read the number of digits from the first line of the dictionary file - read -r key _ <"$dictionary_file" - - # Validate that the key is composed entirely of digits - if ! [[ $key =~ ^[0-9]+$ ]]; then - echo "Error: Dictionary is not compliant with EFF diceware dictionaries." - echo "The first line of the dictionary should be in the format: " - echo "Example: 11111 word" - exit 1 - fi - - digits=${#key} #Number of digits in dice rolls for ((i = 0; i < num_words; ++i)); do - key=$(generate_dice_rolls "$digits") - word=$(get_word_from_dictionary "$key" "$dictionary_file") + word=$(get_random_word_from_dictionary "$dictionary_file") if [[ "$lowercase" == "false" ]]; then word=${word^} # Capitalize the first letter fi From 54baa37d4a808adc156393e9df5a9389ff6d94e0 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 6 Dec 2024 16:26:41 -0500 Subject: [PATCH 31/81] oem-factory-reset: Stop adding leading blank lines in 'passphrases' msg We're adding leading blank lines, which makes the prompt look odd and now have to be removed later. Just stop adding the leading blank lines. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 613569530..66340e65c 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -1376,7 +1376,7 @@ if [[ "$SKIP_BOOT" == "n" ]]; then fi # passphrases set to be empty first -passphrases="\n" +passphrases="" # Prepare whiptail output of configured secrets if [ -n "$luks_new_Disk_Recovery_Key_passphrase" -o -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then @@ -1406,14 +1406,11 @@ fi # Show configured secrets in whiptail and loop until user confirms qr code was scanned while true; do - whiptail --msgbox " - $(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ + whiptail --msgbox "$(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ $HEIGHT $WIDTH --title "Configured secrets" - # strip the initial newline of passphrases - qr_code=$(echo -e "$passphrases" | sed '1s/^\n//') #Tell user to scan the QR code containing all configured secrets echo -e "\nScan the QR code below to save the secrets to a secure location" - qrenc "$qr_code" + qrenc "$(echo -e "$passphrases")" # Prompt user to confirm scanning of qrcode on console prompt not whiptail: y/n echo -e -n "Please confirm you have scanned the QR code above and/or written down the secrets? [y/N]: " read -n 1 prompt_output From 4ba7cc54957054c2b677eee73dfa4ad1eb46524d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 7 Dec 2024 11:12:38 -0500 Subject: [PATCH 32/81] patches/hotp-verification-*/46.patch : readd https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46 so that this PR can be tested and reviewed from OEM Factory Reset/User Re-Ownership perspective (PR 43 not in which fixes hotp_verification info, needed to reuse default PINs under seal-hotp if pubkey age <1 month and if Secret app PIN/GPG Admin PIN count >=3 ) Repro: mkdir patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 wget https://patch-diff.githubusercontent.com/raw/Nitrokey/nitrokey-hotp-verification/pull/46.patch -O patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch sudo rm -rf build/x86/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/ ./docker_repro.sh make BOARD=qemu-coreboot-whiptail-tpm2-hotp USB_TOKEN=Nitrokey3NFC PUBKEY_ASC=pubkey.asc inject_gpg run Signed-off-by: Thierry Laurion --- .../46.patch | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch new file mode 100644 index 000000000..781c10ffa --- /dev/null +++ b/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch @@ -0,0 +1,219 @@ +From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Mon, 25 Nov 2024 17:04:47 +0100 +Subject: [PATCH 1/3] Add reset command for nitrokey 3 + +--- + src/main.c | 10 ++++++++-- + src/operations_ccid.c | 41 +++++++++++++++++++++++++++++++++++++++++ + src/operations_ccid.h | 1 + + 3 files changed, 50 insertions(+), 2 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 059069e..b80b71d 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -21,6 +21,7 @@ + + #include "ccid.h" + #include "operations.h" ++#include "operations_ccid.h" + #include "return_codes.h" + #include "utils.h" + #include "version.h" +@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { + } + break; + case 'r': +- if (argc != 3) break; +- res = regenerate_AES_key(&dev, argv[2]); ++ if (strncmp(argv[1], "reset", 15) == 0) { ++ if (argc != 2) break; ++ res = nk3_reset(&dev); ++ } else if (strncmp(argv[1], "regenerate", 15) == 0) { ++ if (argc != 3) break; ++ res = regenerate_AES_key(&dev, argv[2]); ++ } + break; + default: + break; +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index eb46124..574155d 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -32,6 +32,47 @@ + #include + + ++ ++int nk3_reset(struct Device *dev) { ++ libusb_device *usb_dev; ++ struct libusb_device_descriptor usb_desc; ++ usb_dev = libusb_get_device(dev->mp_devhandle_ccid); ++ ++ int r = libusb_get_device_descriptor(usb_dev, &usb_desc); ++ ++ if (r < 0) { ++ return r; ++ } ++ ++ ++ if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { ++ return 0; ++ } ++ ++ ++ uint8_t buf[10]; ++ // encode ++ uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); ++ ++ // encode ccid wrapper ++ icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, ++ 0x6F, icc_actual_length, ++ 0, 0, 0, buf); ++ // send ++ IccResult iccResult; ++ r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, ++ dev->ccid_buffer_out, icc_actual_length, &iccResult); ++ if (r != 0) { ++ return r; ++ } ++ // check status code ++ if (iccResult.data_status_code != 0x9000) { ++ return 1; ++ } ++ ++ return RET_NO_ERROR; ++} ++ + int set_pin_ccid(struct Device *dev, const char *admin_PIN) { + TLV tlvs[] = { + { +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index b26b3c7..ec0070c 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); ++int nk3_reset(struct Device *dev); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H + +From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Mon, 2 Dec 2024 10:29:59 +0100 +Subject: [PATCH 2/3] Add optional new pin when resetting + +--- + src/main.c | 9 +++++---- + src/operations_ccid.c | 6 +++++- + src/operations_ccid.h | 5 ++++- + 3 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/src/main.c b/src/main.c +index b80b71d..3f4a1cc 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -38,9 +38,10 @@ void print_help(char *app_name) { + "\t%s info\n" + "\t%s version\n" + "\t%s check \n" +- "\t%s regenerate \n" ++ "\t%s reset [ADMIN PIN]\n" ++ "\t%s regenerate\n" + "\t%s set [COUNTER]\n", +- app_name, app_name, app_name, app_name, app_name, app_name); ++ app_name, app_name, app_name, app_name, app_name, app_name, app_name); + } + + +@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { + break; + case 'r': + if (strncmp(argv[1], "reset", 15) == 0) { +- if (argc != 2) break; +- res = nk3_reset(&dev); ++ if (argc != 2 && argc != 3) break; ++ res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); + } else if (strncmp(argv[1], "regenerate", 15) == 0) { + if (argc != 3) break; + res = regenerate_AES_key(&dev, argv[2]); +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index 574155d..07834ce 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -33,7 +33,7 @@ + + + +-int nk3_reset(struct Device *dev) { ++int nk3_reset(struct Device *dev, const char * new_pin) { + libusb_device *usb_dev; + struct libusb_device_descriptor usb_desc; + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); +@@ -70,6 +70,10 @@ int nk3_reset(struct Device *dev) { + return 1; + } + ++ if (new_pin != NULL) { ++ set_pin_ccid(dev, new_pin); ++ } ++ + return RET_NO_ERROR; + } + +diff --git a/src/operations_ccid.h b/src/operations_ccid.h +index ec0070c..61cad72 100644 +--- a/src/operations_ccid.h ++++ b/src/operations_ccid.h +@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); +-int nk3_reset(struct Device *dev); ++// new_pin can be `null` ++// ++// If it is, no new pin will be set ++int nk3_reset(struct Device *dev, const char * new_pin); + + + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H + +From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Tue, 3 Dec 2024 10:48:27 +0100 +Subject: [PATCH 3/3] Fix null pointer bug on non nk3 + +--- + src/operations_ccid.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index 07834ce..538d434 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -36,6 +36,12 @@ + int nk3_reset(struct Device *dev, const char * new_pin) { + libusb_device *usb_dev; + struct libusb_device_descriptor usb_desc; ++ ++ if (!dev->mp_devhandle_ccid) { ++ // Not an NK3 ++ return RET_NO_ERROR; ++ } ++ + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); + + int r = libusb_get_device_descriptor(usb_dev, &usb_desc); +@@ -46,7 +52,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { + + + if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { +- return 0; ++ return RET_NO_ERROR; + } + + From abc97fe1be517246e4a119ac0c06691feac4fb5e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 9 Dec 2024 12:48:16 -0500 Subject: [PATCH 33/81] WiP: staging changes including https://github.com/linuxboot/heads/pull/1850 https://github.com/Nitrokey/nitrokey-hotp-verification/pull/43 and https://github.com/Nitrokey/nitrokey-hotp-verification/pull/46 Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 4 +- initrd/bin/kexec-insert-key | 2 +- initrd/bin/oem-factory-reset | 70 +++++++------ initrd/bin/seal-hotpkey | 10 +- initrd/bin/tpmr | 78 ++++++++------- initrd/etc/ash_functions | 2 +- initrd/init | 3 +- modules/hotp-verification | 6 +- .../46.patch | 97 ++++++++++++------- 9 files changed, 166 insertions(+), 106 deletions(-) rename patches/{hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 => hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d}/46.patch (67%) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 4bb8f4d97..9e94c30e1 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -162,7 +162,7 @@ generate_totp_hotp() echo if [ -x /bin/hotp_verification ]; then if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then - echo "Once you have scanned the QR code, hit Enter to configure your HOTP USB Security Dongle (e.g. Librem Key or Nitrokey)" + echo "Once you have scanned the QR code, hit Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)" read fi /bin/seal-hotpkey @@ -644,7 +644,7 @@ TRACE_FUNC if [ -r /boot/kexec_hotp_key ]; then HOTPKEY_BRANDING="$(cat /boot/kexec_hotp_key)" else - HOTPKEY_BRANDING="HOTP USB Security Dongle" + HOTPKEY_BRANDING="HOTP USB Security dongle" fi if [ -x /bin/hotp_verification ]; then diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index ca5db6a57..68b9bed2c 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -92,7 +92,7 @@ echo '+++ Building initrd' # pad the initramfs (dracut doesn't pad the last gz blob) # without this the kernel init/initramfs.c fails to read # the subsequent uncompressed/compressed cpio -dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync || +dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync > /dev/null 2>&1 || die "Failed to copy initrd to /tmp" if [ "$unseal_failed" = "n" ]; then diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 66340e65c..17b714781 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -143,15 +143,26 @@ mount_boot() { reset_nk3_secret_app() { TRACE_FUNC - # Reset Nitrokey 3 Secrets App + # Reset Nitrokey 3 Secrets app with $ADMIN_PIN (default 12345678, or customised) if lsusb | grep -q "20a0:42b2"; then echo - warn "Resetting Nitrokey 3 Secrets App PIN. Physical presence (touch) will be required" - #TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed + warn "Resetting Nitrokey 3 Secrets App with PIN. Physical presence (touch) will be required" + # TODO: change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed # Reset Nitrokey 3 secret app with PIN - if ! /bin/hotp_verification reset "${ADMIN_PIN}"; then - whiptail_error_die "Failed to reset Nitrokey 3 Secrets App with error code $?, contact Nitrokey support" - fi + # Do 3 attempts to reset Nitrokey 3 Secrets App if return code is 3 (no touch) + for attempt in 1 2 3; do + if /bin/hotp_verification reset "${ADMIN_PIN}"; then + echo + return 0 + else + error_code=$? + if [ $error_code -eq 3 ] && [ $attempt -lt 3 ]; then + whiptail --msgbox "Nitrokey 3 requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "Nk3 cecrets app reset attempt: $attempt/3" + else + whiptail_error_die "Nitrokey 3 secrets app reset failed with error:$error_code. Contact Nitrokey support" + fi + fi + done fi } @@ -323,7 +334,7 @@ generate_inmemory_p256_master_and_subkeys() { keytocard_subkeys_to_smartcard() { TRACE_FUNC - #make sure usb ready and USB Security Dongle ready to communicate with + #make sure usb ready and USB Security dongle ready to communicate with enable_usb enable_usb_storage gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status" @@ -541,7 +552,7 @@ gpg_key_factory_reset() { reset_nk3_secret_app # Factory reset GPG card - echo "GPG factory reset of USB Security Dongle's smartcard..." + echo "GPG factory reset of USB Security dongle's OpenPGP smartcard..." { echo admin # admin menu echo factory-reset # factory reset smartcard @@ -595,7 +606,7 @@ gpg_key_factory_reset() { >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed." + whiptail_error_die "Setting key to NIST-P256 in USB Security dongle failed." fi # fallback to RSA key generation by default elif [ "$GPG_ALGO" = "RSA" ]; then @@ -617,7 +628,7 @@ gpg_key_factory_reset() { >/tmp/gpg_card_edit_output 2>&1 if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) - whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security Dongle failed." + whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security dongle failed." fi else #Unknown GPG_ALGO @@ -631,7 +642,7 @@ generate_OEM_gpg_keys() { TRACE_FUNC #This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset - echo "Generating GPG keys in USB Security Dongle's smartcard..." + echo "Generating GPG keys in USB Security dongle's OpenPGP smartcard..." { echo admin # admin menu echo generate # generate keys @@ -645,6 +656,11 @@ generate_OEM_gpg_keys() { echo ${USER_PIN_DEF} # Default user PIN since we just factory reset } | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \ >/tmp/gpg_card_edit_output 2>&1 + #This outputs to console \ + # "gpg: checking the trustdb" + # "gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model" + # "gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u" + #TODO: Suppress this output to console (stdout shown in DEBUG mode)? if [ $? -ne 0 ]; then ERROR=$(cat /tmp/gpg_card_edit_output) whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR" @@ -704,7 +720,7 @@ generate_checksums() { tpmr counter_create \ -pwdc '' \ -la -3135106223 | - tee /tmp/counter || + tee /tmp/counter >/dev/null 2>&1 || whiptail_error_die "Unable to create TPM counter" TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1; then - whiptail_warning --title "WARNING: Please insert your HOTP enabled USB Security Dongle (Attempt $attempt/3)" --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + whiptail_warning --title "WARNING: Please insert your HOTP enabled USB Security dongle (Attempt $attempt/3)" --msgbox "Your HOTP enabled USB Security dongle was not detected.\n\nPlease remove it and insert it again." 0 80 else break fi done if [ $attempt -eq 3 ]; then - die "No HOTP enabled USB Security Dongle detected. Please disable 'CONFIG_HOTPKEY' in the board config and rebuild." + die "No HOTP enabled USB Security dongle detected. Please disable 'CONFIG_HOTPKEY' in the board config and rebuild." fi # Don't output HOTP codes to screen, so as to make replay attacks harder @@ -872,7 +888,7 @@ report_integrity_measurements() { BG_COLOR_MAIN_MENU="error" ;; *) - HOTP="Error checking code, Insert USB Security Dongle and retry" + HOTP="Error checking code, Insert USB Security dongle and retry" BG_COLOR_MAIN_MENU="warning" ;; esac @@ -997,21 +1013,21 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then ; then GPG_GEN_KEY_IN_MEMORY="y" echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++" - echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " + echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security dongle's OpenPGP smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: " read -n 1 prompt_output echo if [ "$prompt_output" == "n" \ -o "$prompt_output" == "N" ]; then - warn "Subkeys will NOT be copied to USB Security Dongle's smartcard" + warn "Subkeys will NOT be copied to USB Security dongle's OpenPGP smartcard" warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" else - echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++" + echo "++++ Subkeys will be copied to USB Security dongle's OpenPGP smartcard ++++" warn "Please keep your GPG key material backup thumb drive safe" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="y" fi else - echo "GPG key material will be generated on USB Security Dongle's smartcard without backup" + echo "GPG key material will be generated on USB Security dongle's OpenPGP smartcard without backup" GPG_GEN_KEY_IN_MEMORY="n" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" fi @@ -1177,24 +1193,24 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" ]; then fi else GPG_EXPORT=0 - # needed for USB Security Dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 + # needed for USB Security dongle below and is ensured via mount-usb in case of GPG_EXPORT=1 enable_usb fi fi -# ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y +# ensure USB Security dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - echo -e "\nChecking for USB Security Dongle...\n" + echo -e "\nChecking for USB Security dongle...\n" 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 USB Security dongle; \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 USB Security dongle:\n\n${ERROR}" fi fi - #Now that USB Security Dongle is detected, we can check its capabilities and limitations + #Now that USB Security dongle is detected, we can check its capabilities and limitations usb_security_token_capabilities_check fi @@ -1266,7 +1282,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then fi else #Generate GPG key and subkeys on smartcard only - echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" + echo -e "\nResetting USB Security dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" gpg_key_factory_reset generate_OEM_gpg_keys fi @@ -1389,7 +1405,7 @@ fi #if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID if lsusb | grep -q "20a0:42b2"; then - passphrases+="Nitrokey 3 Secrets App PIN: ${ADMIN_PIN}\n" + passphrases+="Nitrokey 3 Secrets app PIN: ${ADMIN_PIN}\n" fi #GPG PINs output diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 266bc48f6..2e78d7fb7 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -1,5 +1,5 @@ #!/bin/bash -# Retrieve the sealed TOTP secret and initialize a USB Security Dongle with it +# Retrieve the sealed TOTP secret and initialize a USB Security dongle with it . /etc/functions . /etc/gui_functions @@ -34,7 +34,7 @@ fatal_error() { if [ -r /boot/kexec_hotp_key ]; then HOTPKEY_BRANDING="$(cat /boot/kexec_hotp_key)" else - HOTPKEY_BRANDING="HOTP USB Security Dongle" + HOTPKEY_BRANDING="HOTP USB Security dongle" fi if [ "$CONFIG_TPM" = "y" ]; then @@ -77,13 +77,13 @@ if ! hotp_token_info="$(hotp_verification info)"; then fi fi -# Set HOTP USB Security Dongle branding based on VID +# Set HOTP USB Security dongle branding based on VID if lsusb | grep -q "20a0:"; then HOTPKEY_BRANDING="Nitrokey" elif lsusb | grep -q "316d:"; then HOTPKEY_BRANDING="Librem Key" else - HOTPKEY_BRANDING="HOTP USB Security Dongle" + HOTPKEY_BRANDING="HOTP USB Security dongle" fi # Truncate the secret if it is longer than the maximum HOTP secret @@ -175,7 +175,7 @@ counter_value=$(expr $counter_value + 1) echo $counter_value >$HOTP_COUNTER || fatal_error "Unable to create hotp counter file" -# Store/overwrite HOTP USB Security Dongle branding found out beforehand +# Store/overwrite HOTP USB Security dongle branding found out beforehand echo $HOTPKEY_BRANDING >$HOTP_KEY || die "Unable to store hotp key file" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 65ecbe534..e94cf6058 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -29,7 +29,6 @@ else . /etc/config fi - # Busybox xxd lacks -r, and we get hex dumps from TPM1 commands. This converts # a hex dump to binary data using sed and printf hex2bin() { @@ -258,7 +257,7 @@ tpm2_extend() { esac done tpm2 pcrextend "$index:sha256=$hash" - LOG $(tpm2 pcrread "sha256:$index" 2>&1) + LOG $(tpm2 pcrread "sha256:$index" 2>&1) TRACE_FUNC DEBUG "TPM: Extended PCR[$index] with hash $hash" @@ -307,7 +306,7 @@ tpm1_counter_create() { # other parameters for TPM1 are passed directly, and TPM2 mimics the # TPM1 interface. prompt_tpm_owner_password - if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@"; then + if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@" >/dev/null 2>&1; then DEBUG "Failed to create counter from tpm1_counter_create. Wiping /tmp/secret/tpm_owner_password" shred -n 10 -z -u /tmp/secret/tpm_owner_password die "Unable to create counter from tpm1_counter_create" @@ -334,7 +333,7 @@ tpm2_counter_create() { prompt_tpm_owner_password rand_index="1$(dd if=/dev/urandom bs=1 count=3 2>/dev/null | xxd -pc3)" tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \ - -P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/console || + -P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/null 2>&1 || { DEBUG "Failed to create counter from tpm2_counter_create. Wiping /tmp/secret/tpm_owner_password" shred -n 10 -z -u /tmp/secret/tpm_owner_password @@ -357,12 +356,13 @@ tpm2_startsession() { tpm2 flushcontext -Q \ --saved-session || die "tpm2_flushcontext: unable to flush saved session" - tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE" + #TODO: readpublic cannot be silenced even if redirected to /dev/null with both stderr and stdout redirected? + tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE" >/dev/null 2>&1 #TODO: do the right thing to not have to suppress "WARN: check public portion the tpmkey manually" see https://github.com/linuxboot/heads/pull/1630#issuecomment-2075120429 - tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE" > /dev/null 2>&1 + tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE" >/dev/null 2>&1 #TODO: do the right thing to not have to suppress "WARN: check public portion the tpmkey manually" see https://github.com/linuxboot/heads/pull/1630#issuecomment-2075120429 - tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$DEC_SESSION_FILE" > /dev/null 2>&1 - tpm2 sessionconfig -Q --disable-encrypt "$DEC_SESSION_FILE" + tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$DEC_SESSION_FILE" >/dev/null 2>&1 + tpm2 sessionconfig -Q --disable-encrypt "$DEC_SESSION_FILE" >/dev/null 2>&1 } # Use cleanup_session() with at_exit to release a TPM2 session and delete the @@ -412,7 +412,7 @@ tpm1_destroy() { index="$1" # Index of the sealed file size="$2" # Size of zeroes to overwrite for TPM1 - dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero > /dev/null 2>&1 + dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero >/dev/null 2>&1 tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero || die "Unable to wipe sealed secret from TPM NVRAM" } @@ -502,7 +502,7 @@ tpm1_seal() { pcrl="$3" #0,1,2,3,4,5,6,7 (does not include algorithm prefix) pcrf="$4" sealed_size="$5" - pass="$6" # May be empty to seal with no password + pass="$6" # May be empty to seal with no password tpm_owner_password="$7" # Owner password - will prompt if needed and not empty sealed_file="$SECRET_DIR/tpm1_seal_sealed.bin" @@ -512,7 +512,6 @@ tpm1_seal() { DEBUG "tpm1_seal arguments: file=$file index=$index pcrl=$pcrl pcrf=$pcrf sealed_size=$sealed_size pass=$(mask_param "$pass") tpm_password=$(mask_param "$tpm_password")" - # If a password was given, add it to the policy arguments if [ "$pass" ]; then POLICY_ARGS+=(-pwdd "$pass") @@ -534,7 +533,7 @@ tpm1_seal() { -of "$sealed_file" \ -hk 40000000 \ "${POLICY_ARGS[@]}" - + # try it without the TPM Owner Password first if ! tpm nv_writevalue -in "$index" -if "$sealed_file"; then # to create an nvram space we need the TPM Owner Password @@ -605,9 +604,22 @@ tpm2_unseal() { UNSEAL_PASS_SUFFIX="+$(tpm2_password_hex "$pass")" fi - tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ - -S "$ENC_SESSION_FILE" >"$file" + # tpm2 unseal will write the unsealed data to stdout and any errors to + # stderr. We capture the unsealed data to $file, but still log the errors for quiet mode. + # In case of unseal error, caller will also report on TOTP not being able to be unsealed. + TMP_ERR_FILE=$(mktemp) +if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ + -S "$ENC_SESSION_FILE" >"$file" 2>"$TMP_ERR_FILE"; then + # Log the contents of the temporary error file + while IFS= read -r line; do + LOG "tpm2 stderr: $line" + done <"$TMP_ERR_FILE" + rm -f "$TMP_ERR_FILE" + die "Unable to unseal secret from TPM NVRAM with tpm2 unseal" +fi +rm -f "$TMP_ERR_FILE" } + tpm1_unseal() { TRACE_FUNC index="$1" @@ -650,15 +662,15 @@ tpm2_reset() { # output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" - tpm2 clear -c platform > /dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy" - tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change owner password" - tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change endorsement password" + tpm2 clear -c platform >/dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy" + tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change owner password" + tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change endorsement password" tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \ - -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to create primary key" + -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to create primary key" tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \ - -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to evict primary key" - shred -u "$SECRET_DIR/primary.ctx" > /dev/null 2>&1 - tpm2_startsession > /dev/null 2>&1 || LOG "Unable to start session" + -P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to evict primary key" + shred -u "$SECRET_DIR/primary.ctx" >/dev/null 2>&1 + tpm2_startsession >/dev/null 2>&1 || LOG "Unable to start session" # Set the dictionary attack parameters. TPM2 defaults vary widely, we # want consistent behavior on any TPM. @@ -681,7 +693,7 @@ tpm2_reset() { --max-tries=10 \ --recovery-time=3600 \ --lockout-recovery-time=0 \ - --auth="session:$ENC_SESSION_FILE" > /dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters" + --auth="session:$ENC_SESSION_FILE" >/dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters" # Set a random DA lockout password, so the DA lockout can't be cleared # with a password. Heads doesn't offer dictionary attach reset, instead @@ -690,7 +702,7 @@ tpm2_reset() { # The default lockout password is empty, so we must set this, and we # don't need to provide any auth (use the default empty password). tpm2 changeauth -Q -c lockout \ - "hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" > /dev/null 2>&1 || LOG "Unable to set lockout password" + "hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" >/dev/null 2>&1 || LOG "Unable to set lockout password" } tpm1_reset() { TRACE_FUNC @@ -700,17 +712,17 @@ tpm1_reset() { DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" # Make sure the TPM is ready to be reset - tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence" - tpm physicalenable > /dev/null 2>&1 || >LOG "Unable to enable TPM" - tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM" - tpm forceclear -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to clear TPM" - tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM" - tpm takeown -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to take ownership of TPM" + tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence" + tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" + tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM" + tpm forceclear -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to clear TPM" + tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" + tpm takeown -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to take ownership of TPM" # And now turn it all back on - tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence" - tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM" - tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM" + tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence" + tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" + tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM physical presence requirement" } # Perform final cleanup before boot and lock the platform heirarchy. @@ -784,7 +796,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then DEBUG "TPM: Will extend PCR[$3] with hash of filename $string" hash="$(echo -n "$5" | sha1sum | cut -d' ' -f1)" fi - + TRACE_FUNC LOG "TPM: Extending PCR[$3] with hash $hash" DO_WITH_DEBUG exec tpm "$@" diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index c0182002a..c55ae7516 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -147,7 +147,7 @@ confirm_gpg_card() { fi fi - # setup the USB so we can reach the USB Security Dongle's smartcard + # setup the USB so we can reach the USB Security dongle's OpenPGP smartcard enable_usb echo -e "\nVerifying presence of GPG card...\n" diff --git a/initrd/init b/initrd/init index 30b08663a..3b308f139 100755 --- a/initrd/init +++ b/initrd/init @@ -181,7 +181,7 @@ fi # Setup recovery serial shell if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then stty -F "$CONFIG_BOOT_RECOVERY_SERIAL" 115200 - pause_recovery 'Console recovery shell' \ + pause_recovery 'Serial console recovery shell' \ < "$CONFIG_BOOT_RECOVERY_SERIAL" \ > "$CONFIG_BOOT_RECOVERY_SERIAL" 2>&1 & fi @@ -207,6 +207,7 @@ if [ "$boot_option" = "r" ]; then exit elif [ "$boot_option" = "o" ]; then # Launch OEM Factory Reset mode + echo -e "***** Entering OEM Factory Reset mode\n" > /dev/tty0 oem-factory-reset --mode oem # just in case... exit diff --git a/modules/hotp-verification b/modules/hotp-verification index 14957e74b..def337f50 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -2,12 +2,12 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification hotp-verification_depends := libusb $(musl_dep) -# v1.6 -hotp-verification_version := e9050e0c914e7a8ffef5d1c82a014e0e2bf79346 +# v1.6 + patches for nk3 reset + info fixes (no version bump yet) +hotp-verification_version := 05ac293dfef8abe463ccea8f248066e8686ce62d hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz -hotp-verification_hash := 480c978d3585eee73b9aa5186b471d4caeeeeba411217e1544eef7cfd90312ac +hotp-verification_hash := 1095640fdae77938ce2d2ce294c7ecb8c27b77060975af8d838b6fd056ed5068 hotp-verification_target := \ $(MAKE_JOBS) \ diff --git a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch b/patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch similarity index 67% rename from patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch rename to patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch index 781c10ffa..7007da379 100644 --- a/patches/hotp-verification-e9050e0c914e7a8ffef5d1c82a014e0e2bf79346/46.patch +++ b/patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch @@ -1,7 +1,7 @@ -From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001 +From 45fb0932c3a45978d894fcaae2c242ffa93516f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 25 Nov 2024 17:04:47 +0100 -Subject: [PATCH 1/3] Add reset command for nitrokey 3 +Subject: [PATCH 1/4] Add reset command for nitrokey 3 --- src/main.c | 10 ++++++++-- @@ -10,7 +10,7 @@ Subject: [PATCH 1/3] Add reset command for nitrokey 3 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c -index 059069e..b80b71d 100644 +index ed26932..41b1692 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ @@ -20,8 +20,8 @@ index 059069e..b80b71d 100644 +#include "operations_ccid.h" #include "return_codes.h" #include "utils.h" - #include "version.h" -@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { + #include "operations_ccid.h" +@@ -161,8 +162,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { } break; case 'r': @@ -38,7 +38,7 @@ index 059069e..b80b71d 100644 default: break; diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index eb46124..574155d 100644 +index 1ca6f54..cdaf940 100644 --- a/src/operations_ccid.c +++ b/src/operations_ccid.c @@ -32,6 +32,47 @@ @@ -90,47 +90,48 @@ index eb46124..574155d 100644 TLV tlvs[] = { { diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index b26b3c7..ec0070c 100644 +index 77a6fdc..20415c0 100644 --- a/src/operations_ccid.h +++ b/src/operations_ccid.h -@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); +@@ -12,6 +12,7 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); + int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); + int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin); +int nk3_reset(struct Device *dev); #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H -From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001 +From 12ba32eb823a3d895ce77052022f8da3e40172ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 2 Dec 2024 10:29:59 +0100 -Subject: [PATCH 2/3] Add optional new pin when resetting +Subject: [PATCH 2/4] Add optional new pin when resetting --- - src/main.c | 9 +++++---- - src/operations_ccid.c | 6 +++++- - src/operations_ccid.h | 5 ++++- - 3 files changed, 14 insertions(+), 6 deletions(-) + src/main.c | 11 +++++++---- + src/operations_ccid.c | 6 +++++- + src/operations_ccid.h | 5 ++++- + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c -index b80b71d..3f4a1cc 100644 +index 41b1692..84c0afe 100644 --- a/src/main.c +++ b/src/main.c -@@ -38,9 +38,10 @@ void print_help(char *app_name) { - "\t%s info\n" - "\t%s version\n" +@@ -41,8 +41,11 @@ void print_help(char *app_name) { "\t%s check \n" -- "\t%s regenerate \n" + "\t%s regenerate \n" + "\t%s set [COUNTER]\n" +- "\t%s nk3-change-pin \n", +- app_name, app_name, app_name, app_name, app_name, app_name, app_name); ++ "\t%s nk3-change-pin \n" + "\t%s reset [ADMIN PIN]\n" + "\t%s regenerate\n" - "\t%s set [COUNTER]\n", -- app_name, app_name, app_name, app_name, app_name, app_name); -+ app_name, app_name, app_name, app_name, app_name, app_name, app_name); ++ "\t%s set [COUNTER]\n", ++ app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name); } -@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { +@@ -163,8 +166,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { break; case 'r': if (strncmp(argv[1], "reset", 15) == 0) { @@ -142,7 +143,7 @@ index b80b71d..3f4a1cc 100644 if (argc != 3) break; res = regenerate_AES_key(&dev, argv[2]); diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 574155d..07834ce 100644 +index cdaf940..8b6ba77 100644 --- a/src/operations_ccid.c +++ b/src/operations_ccid.c @@ -33,7 +33,7 @@ @@ -166,13 +167,13 @@ index 574155d..07834ce 100644 } diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index ec0070c..61cad72 100644 +index 20415c0..4d55ad8 100644 --- a/src/operations_ccid.h +++ b/src/operations_ccid.h -@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); - int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); +@@ -12,7 +12,10 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); + int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); + int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin); -int nk3_reset(struct Device *dev); +// new_pin can be `null` +// @@ -182,17 +183,17 @@ index ec0070c..61cad72 100644 #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H -From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001 +From 0bbc6ea354b1f807a4d7ad4c0cd57f9cbab25a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Tue, 3 Dec 2024 10:48:27 +0100 -Subject: [PATCH 3/3] Fix null pointer bug on non nk3 +Subject: [PATCH 3/4] Fix null pointer bug on non nk3 --- src/operations_ccid.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 07834ce..538d434 100644 +index 8b6ba77..1221764 100644 --- a/src/operations_ccid.c +++ b/src/operations_ccid.c @@ -36,6 +36,12 @@ @@ -217,3 +218,33 @@ index 07834ce..538d434 100644 } + +From 0c5bd3da36ea8de5b8adf7878e9260b079bc110b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= +Date: Mon, 9 Dec 2024 17:42:54 +0100 +Subject: [PATCH 4/4] Print warning when device is not an NK3 + +--- + src/operations_ccid.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/operations_ccid.c b/src/operations_ccid.c +index 1221764..356a1b4 100644 +--- a/src/operations_ccid.c ++++ b/src/operations_ccid.c +@@ -39,6 +39,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { + + if (!dev->mp_devhandle_ccid) { + // Not an NK3 ++ printf("No Nitrokey 3 found. No operation performed\n"); + return RET_NO_ERROR; + } + +@@ -52,6 +53,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { + + + if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { ++ printf("No Nitrokey 3 found. No operation performed\n"); + return RET_NO_ERROR; + } + From 19fd98df2dde010ea54ad93a3017e28adfb443d0 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 10 Dec 2024 14:50:52 -0500 Subject: [PATCH 34/81] WiP: staging changes (TPM1 regression fixes for LOG/DEBUG on quiet mode) Signed-off-by: Thierry Laurion --- ...oot-fbwhiptail-tpm1-hotp-prod_quiet.config | 100 ++++++++++++++++++ initrd/bin/kexec-select-boot | 1 + initrd/bin/tpmr | 42 +++++--- initrd/etc/functions | 4 +- 4 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config new file mode 100644 index 000000000..bbda97069 --- /dev/null +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config @@ -0,0 +1,100 @@ +# Configuration for building a coreboot ROM that works in +# the qemu emulator in console mode thanks to Whiptail +# +# TPM can be used with a qemu software TPM (TIS, 1.2). A Librem Key or +# Nitrokey Pro can also be used by forwarding the USB device from the host to +# the VM. +export CONFIG_COREBOOT=y +export CONFIG_COREBOOT_VERSION=24.02.01 +export CONFIG_LINUX_VERSION=6.1.8 + +CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1-prod.config +CONFIG_LINUX_CONFIG=config/linux-qemu.config + +#Enable only one RESTRICTED/BASIC boot modes below to test them manually (we cannot inject config under QEMU (no internal flashing) +#export CONFIG_RESTRICTED_BOOT=y +#export CONFIG_BASIC=y + +#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) +#export CONFIG_HAVE_GPG_KEY_BACKUP=y + +#Enable DEBUG output +#export CONFIG_DEBUG_OUTPUT=y +#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=y + +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y + +#On-demand hardware support (modules.cpio) +CONFIG_LINUX_USB=y +CONFIG_LINUX_E1000=y +#CONFIG_MOBILE_TETHERING=y +#Runtime on-demand additional hardware support (modules.cpio) +export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y + + + +#Modules packed into tools.cpio +ifeq "$(CONFIG_UROOT)" "y" +CONFIG_BUSYBOX=n +else +#Modules packed into tools.cpio +CONFIG_CRYPTSETUP2=y +CONFIG_FLASHPROG=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +#Runtime tools to write to MSR +#CONFIG_MSRTOOLS=y +#Remote attestation support +# TPM2 requirements +#CONFIG_TPM2_TSS=y +#CONFIG_OPENSSL=y +#Remote Attestation common tools +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y +#HOTP based remote attestation for supported USB Security dongle +#With/Without TPM support +CONFIG_HOTPKEY=y +#Nitrokey Storage admin tool (deprecated) +#CONFIG_NKSTORECLI=n +#GUI Support +#Console based Whiptail support(Console based, no FB): +#CONFIG_SLANG=y +#CONFIG_NEWT=y +#FBWhiptail based (Graphical): +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y +#Additional tools (tools.cpio): +#SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) +CONFIG_DROPBEAR=y +endif + +#Runtime configuration +#Automatically boot if HOTP is valid +export CONFIG_AUTO_BOOT_TIMEOUT=5 +#TPM2 requirements +#export CONFIG_TPM2_TOOLS=y +#export CONFIG_PRIMARY_KEY_TYPE=ecc +#TPM1 requirements +export CONFIG_TPM=y +export CONFIG_BOOTSCRIPT=/bin/gui-init +#text-based original init: +#export CONFIG_BOOTSCRIPT=/bin/generic-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_RECOVERY_SERIAL="/dev/ttyS0" +export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" +export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" +export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1-hotp" +#export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" +export CONFIG_AUTO_BOOT_TIMEOUT=5 + +BOARD_TARGETS := qemu diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index bdda8aaf8..81d0e5ff8 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -113,6 +113,7 @@ verify_global_hashes() { } verify_rollback_counter() { + TRACE_FUNC TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2) if [ -z "$TPM_COUNTER" ]; then die "$TMP_ROLLBACK_FILE: TPM counter not found?" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index e94cf6058..ccf1f6c23 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -306,11 +306,18 @@ tpm1_counter_create() { # other parameters for TPM1 are passed directly, and TPM2 mimics the # TPM1 interface. prompt_tpm_owner_password - if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@" >/dev/null 2>&1; then + TMP_ERR_FILE=$(mktemp) + if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@" 2>"$TMP_ERR_FILE"; then DEBUG "Failed to create counter from tpm1_counter_create. Wiping /tmp/secret/tpm_owner_password" shred -n 10 -z -u /tmp/secret/tpm_owner_password + # Log the contents of the temporary error file + while IFS= read -r line; do + DEBUG "tpm1 stderr: $line" + done <"$TMP_ERR_FILE" + rm -f "$TMP_ERR_FILE" die "Unable to create counter from tpm1_counter_create" fi + rm -f "$TMP_ERR_FILE" } tpm2_counter_create() { @@ -608,16 +615,16 @@ tpm2_unseal() { # stderr. We capture the unsealed data to $file, but still log the errors for quiet mode. # In case of unseal error, caller will also report on TOTP not being able to be unsealed. TMP_ERR_FILE=$(mktemp) -if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ - -S "$ENC_SESSION_FILE" >"$file" 2>"$TMP_ERR_FILE"; then - # Log the contents of the temporary error file - while IFS= read -r line; do - LOG "tpm2 stderr: $line" - done <"$TMP_ERR_FILE" - rm -f "$TMP_ERR_FILE" - die "Unable to unseal secret from TPM NVRAM with tpm2 unseal" -fi -rm -f "$TMP_ERR_FILE" + if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ + -S "$ENC_SESSION_FILE" >"$file" 2>"$TMP_ERR_FILE"; then + # Log the contents of the temporary error file + while IFS= read -r line; do + LOG "tpm2 stderr: $line" + done <"$TMP_ERR_FILE" + rm -f "$TMP_ERR_FILE" + die "Unable to unseal secret from TPM NVRAM with tpm2 unseal" + fi + rm -f "$TMP_ERR_FILE" } tpm1_unseal() { @@ -715,7 +722,7 @@ tpm1_reset() { tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence" tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM" - tpm forceclear -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to clear TPM" + tpm forceclear >/dev/null 2>&1 || LOG "Unable to clear TPM" tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" tpm takeown -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to take ownership of TPM" @@ -787,7 +794,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then tpm1_destroy "$@" ;; extend) - #check if we extend with a hash or a file + # Check if we extend with a hash or a file if [ "$4" = "-if" ]; then DEBUG "TPM: Will extend PCR[$3] hash content of file $5" hash="$(sha1sum "$5" | cut -d' ' -f1)" @@ -799,7 +806,14 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then TRACE_FUNC LOG "TPM: Extending PCR[$3] with hash $hash" - DO_WITH_DEBUG exec tpm "$@" + + # Redirect the output of DO_WITH_DEBUG to a temporary file so we can LOG it in quiet mode + TMP_DEBUG_FILE=$(mktemp) + DO_WITH_DEBUG exec tpm "$@" >"$TMP_DEBUG_FILE" 2>&1 + while IFS= read -r line; do + LOG "$line" + done <"$TMP_DEBUG_FILE" + rm -f "$TMP_DEBUG_FILE" ;; seal) shift diff --git a/initrd/etc/functions b/initrd/etc/functions index 2dabda7b3..f6438ae73 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -372,7 +372,7 @@ check_tpm_counter() { tpmr counter_create \ -pwdc '' \ -la $LABEL | - tee /tmp/counter || + tee /tmp/counter > /dev/null 2>&1 || die "Unable to create TPM counter" TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1 || die "TPM counter increment failed for rollback prevention. Please reset the TPM" } From 94b77e870405dfe099ed0221863e134f21c83e23 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 10 Dec 2024 17:12:47 -0500 Subject: [PATCH 35/81] WiP: staging changes Insights: - We should use oem generated pubkey naming to distinguish between oem/user generated keys and try to use default PINs also for GPG User to sign with default PIN and warn even if it works/doesn't, urging users to do reownership - Point is that oem factory reset does in the direction of using randomized PINs, while continuing to use those for a user should be strongly discouraged Signed-off-by: Thierry Laurion --- initrd/.ash_history | 2 +- initrd/bin/gpg-gui.sh | 2 +- initrd/bin/kexec-seal-key | 8 ++++---- initrd/bin/oem-factory-reset | 24 +++++++++++++++--------- initrd/bin/seal-hotpkey | 8 ++++++-- initrd/bin/tpmr | 2 +- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/initrd/.ash_history b/initrd/.ash_history index 12d10333b..7f03d3ee1 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -4,7 +4,7 @@ mount /boot find /boot/kexec*.txt | gpg --verify /boot/kexec.sig - #remove invalid kexec_* signed files mount /dev/sda1 /boot && mount -o remount,rw /boot && rm /boot/kexec* && mount -o remount,ro /boot -#Generate keys from GPG smartcard: +#Generate keys on OpenPGP smartcard: mount-usb && gpg --home=/.gnupg/ --card-edit #Copy generated public key, private_subkey, trustdb and artifacts to external media for backup: mount -o remount,rw /media && mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor email@address.com > /media/gpg_keys/private.key && gpg --export --armor email@address.com > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh index 9a3eb8e5e..738de34ab 100755 --- a/initrd/bin/gpg-gui.sh +++ b/initrd/bin/gpg-gui.sh @@ -148,7 +148,7 @@ while true; do 'e' ' Replace GPG key(s) in the current ROM and reflash' \ 'l' ' List GPG keys in your keyring' \ 'p' ' Export public GPG key to USB drive' \ - 'g' ' Generate GPG keys manually on a USB security token' \ + 'g' ' Generate GPG keys manually on a USB security dongle' \ 'x' ' Exit' \ 2>/tmp/whiptail || recovery "GUI menu failed" diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index bd35fe354..558c579b5 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -97,16 +97,16 @@ done attempts=0 while [ $attempts -lt 3 ]; do - read -s -p "New LUKS TPM Disk Unlock Key passphrase (DUK) for booting: " key_password + read -s -p "New LUKS TPM Disk Unlock Key (DUK) passphrase for booting: " key_password echo read -s -p "Repeat LUKS TPM Disk Unlock Key (DUK) passphrase for booting: " key_password2 echo if [ "$key_password" != "$key_password2" ]; then attempts=$((attempts + 1)) if [ "$attempts" == "3" ]; then - die "Disk Unlock Key passphrases do not match. Exiting..." + die "Disk Unlock Key (DUK) passphrases do not match. Exiting..." else - warn "Disk Unlock Key passphrases do not match. Please try again." + warn "Disk Unlock Key (DUK) passphrases do not match. Please try again." fi else break @@ -168,7 +168,7 @@ for dev in $key_devices; do die "$dev: Unable to find a key slot that can be unlocked with provided passphrase. Exiting..." fi - # If the key slot is not the expected DUK o FRK key slot, we will ask the user to confirm the wipe + # If the key slot is not the expected DUK or DRK key slot, we will ask the user to confirm the wipe for keyslot in "${luks_used_keyslots[@]}"; do if [ "$keyslot" != "$drk_key_slot" ]; then #set wipe_desired to no by default diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 17b714781..a4096153f 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -146,7 +146,7 @@ reset_nk3_secret_app() { # Reset Nitrokey 3 Secrets app with $ADMIN_PIN (default 12345678, or customised) if lsusb | grep -q "20a0:42b2"; then echo - warn "Resetting Nitrokey 3 Secrets App with PIN. Physical presence (touch) will be required" + warn "Resetting Nitrokey 3's Secrets App with PIN. Physical presence (touch) will be required" # TODO: change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed # Reset Nitrokey 3 secret app with PIN # Do 3 attempts to reset Nitrokey 3 Secrets App if return code is 3 (no touch) @@ -159,7 +159,7 @@ reset_nk3_secret_app() { if [ $error_code -eq 3 ] && [ $attempt -lt 3 ]; then whiptail --msgbox "Nitrokey 3 requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "Nk3 cecrets app reset attempt: $attempt/3" else - whiptail_error_die "Nitrokey 3 secrets app reset failed with error:$error_code. Contact Nitrokey support" + whiptail_error_die "Nitrokey 3's secrets app reset failed with error:$error_code. Contact Nitrokey support" fi fi done @@ -547,10 +547,7 @@ gpg_key_factory_reset() { #enable usb storage enable_usb - - #Reset Nitrokey 3 secret app - reset_nk3_secret_app - + # Factory reset GPG card echo "GPG factory reset of USB Security dongle's OpenPGP smartcard..." { @@ -671,6 +668,7 @@ generate_OEM_gpg_keys() { gpg_key_change_pin() { TRACE_FUNC + DEBUG "Changing GPG key PIN" # 1 = user PIN, 3 = admin PIN PIN_TYPE=$1 @@ -915,6 +913,8 @@ report_integrity_measurements() { usb_security_token_capabilities_check() { TRACE_FUNC + echo -e "\nChecking for USB Security dongle...\n" + enable_usb # ... first set board config preference if [ -n "$CONFIG_GPG_ALGO" ]; then @@ -926,6 +926,8 @@ usb_security_token_capabilities_check() { GPG_ALGO="p256" DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO" fi + + #TODO: put everything related to USB Security dongle here } ## main script start @@ -1281,8 +1283,12 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then keytocard_subkeys_to_smartcard fi else + #enable usb storage + enable_usb + #Reset Nitrokey 3 secret app + reset_nk3_secret_app #Generate GPG key and subkeys on smartcard only - echo -e "\nResetting USB Security dongle's GPG smartcard...\n(this will take around 3 minutes...)\n" + echo -e "\nResetting USB Security dongle's OpenPGP smartcard with GPG...\n(this will take around 3 minutes...)\n" gpg_key_factory_reset generate_OEM_gpg_keys fi @@ -1301,7 +1307,7 @@ fi #Applying custom GPG PINs to the smartcard if they were provided if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then #Only apply smartcard PIN change if smartcard only or if keytocard op is expected next - if [ "${USER_PIN}" != "" -o "${ADMIN_PIN}" != "" ]; then + if [ "${USER_PIN}" != "${USER_PIN_DEF}" -o "${ADMIN_PIN}" != "${ADMIN_PIN_DEF}" ]; then echo -e "\nChanging default GPG Admin PIN\n" gpg_key_change_pin "3" "${ADMIN_PIN_DEF}" "${ADMIN_PIN}" echo -e "\nChanging default GPG User PIN\n" @@ -1387,7 +1393,7 @@ fi ## sign files in /boot and generate checksums if [[ "$SKIP_BOOT" == "n" ]]; then - echo -e "\nSigning boot files and generating checksums...\n" + echo -e "\nUpdating checksums and signing all files in /boot...\n" generate_checksums fi diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 2e78d7fb7..70d86e952 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -126,7 +126,11 @@ if [ "$((now_date - gpg_key_create_time))" -gt "$month_secs" ]; then elif [ "$admin_pin_retries" -lt 3 ]; then echo "Not trying default PIN ($admin_pin), only $admin_pin_retries attempt(s) left" else - echo "Trying $prompt_message PIN ($admin_pin) to seal HOTP secret on $HOTPKEY_BRANDING... You may be requested to touch the dongle..." + echo "Trying $prompt_message PIN ($admin_pin) to seal HOTP secret on $HOTPKEY_BRANDING..." + #if we deal with the nk3, say to the user that touch will be required + if lsusb | grep -q "20a0:42b2"; then + warn "Touching the Nitrokey 3 to confirm presence operation is required" + fi #TODO: silence the output of hotp_initialize once https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed #hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1 hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" @@ -157,7 +161,7 @@ if [ "$admin_pin_status" -ne 0 ]; then fi else # remind user to change admin password - warn "Factory $prompt_message default PIN detected: please change this PIN as soon as possible through OEM Factory Reset/User Re-Ownership" + warn "Factory $prompt_message default PIN 12345678 detected: please change this PIN as soon as possible through OEM Factory Reset/User Re-Ownership" fi # HOTP key no longer needed diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index ccf1f6c23..61d966787 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -622,7 +622,7 @@ tpm2_unseal() { LOG "tpm2 stderr: $line" done <"$TMP_ERR_FILE" rm -f "$TMP_ERR_FILE" - die "Unable to unseal secret from TPM NVRAM with tpm2 unseal" + die "Unable to unseal secret from TPM NVRAM" fi rm -f "$TMP_ERR_FILE" } From f68df1ccf0de0a1e42401326119028c69835d06a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 12 Dec 2024 16:34:21 -0500 Subject: [PATCH 36/81] Bump hotp-verification to version 1.7, remove patches: contains info fixes and reset fixes so that oem-factory-reset can reset secrets app PIN Signed-off-by: Thierry Laurion --- modules/hotp-verification | 4 +- .../46.patch | 250 ------------------ 2 files changed, 2 insertions(+), 252 deletions(-) delete mode 100644 patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch diff --git a/modules/hotp-verification b/modules/hotp-verification index def337f50..5bd1650a8 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -2,8 +2,8 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification hotp-verification_depends := libusb $(musl_dep) -# v1.6 + patches for nk3 reset + info fixes (no version bump yet) -hotp-verification_version := 05ac293dfef8abe463ccea8f248066e8686ce62d +# v1.7 +hotp-verification_version := e6cf719d67a811356eecff69769fa1dbce47f953 hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz diff --git a/patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch b/patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch deleted file mode 100644 index 7007da379..000000000 --- a/patches/hotp-verification-05ac293dfef8abe463ccea8f248066e8686ce62d/46.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 45fb0932c3a45978d894fcaae2c242ffa93516f2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Mon, 25 Nov 2024 17:04:47 +0100 -Subject: [PATCH 1/4] Add reset command for nitrokey 3 - ---- - src/main.c | 10 ++++++++-- - src/operations_ccid.c | 41 +++++++++++++++++++++++++++++++++++++++++ - src/operations_ccid.h | 1 + - 3 files changed, 50 insertions(+), 2 deletions(-) - -diff --git a/src/main.c b/src/main.c -index ed26932..41b1692 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -21,6 +21,7 @@ - - #include "ccid.h" - #include "operations.h" -+#include "operations_ccid.h" - #include "return_codes.h" - #include "utils.h" - #include "operations_ccid.h" -@@ -161,8 +162,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { - } - break; - case 'r': -- if (argc != 3) break; -- res = regenerate_AES_key(&dev, argv[2]); -+ if (strncmp(argv[1], "reset", 15) == 0) { -+ if (argc != 2) break; -+ res = nk3_reset(&dev); -+ } else if (strncmp(argv[1], "regenerate", 15) == 0) { -+ if (argc != 3) break; -+ res = regenerate_AES_key(&dev, argv[2]); -+ } - break; - default: - break; -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 1ca6f54..cdaf940 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -32,6 +32,47 @@ - #include - - -+ -+int nk3_reset(struct Device *dev) { -+ libusb_device *usb_dev; -+ struct libusb_device_descriptor usb_desc; -+ usb_dev = libusb_get_device(dev->mp_devhandle_ccid); -+ -+ int r = libusb_get_device_descriptor(usb_dev, &usb_desc); -+ -+ if (r < 0) { -+ return r; -+ } -+ -+ -+ if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { -+ return 0; -+ } -+ -+ -+ uint8_t buf[10]; -+ // encode -+ uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); -+ -+ // encode ccid wrapper -+ icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, -+ 0x6F, icc_actual_length, -+ 0, 0, 0, buf); -+ // send -+ IccResult iccResult; -+ r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, -+ dev->ccid_buffer_out, icc_actual_length, &iccResult); -+ if (r != 0) { -+ return r; -+ } -+ // check status code -+ if (iccResult.data_status_code != 0x9000) { -+ return 1; -+ } -+ -+ return RET_NO_ERROR; -+} -+ - int set_pin_ccid(struct Device *dev, const char *admin_PIN) { - TLV tlvs[] = { - { -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index 77a6fdc..20415c0 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -12,6 +12,7 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); - int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin); -+int nk3_reset(struct Device *dev); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H - -From 12ba32eb823a3d895ce77052022f8da3e40172ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Mon, 2 Dec 2024 10:29:59 +0100 -Subject: [PATCH 2/4] Add optional new pin when resetting - ---- - src/main.c | 11 +++++++---- - src/operations_ccid.c | 6 +++++- - src/operations_ccid.h | 5 ++++- - 3 files changed, 16 insertions(+), 6 deletions(-) - -diff --git a/src/main.c b/src/main.c -index 41b1692..84c0afe 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -41,8 +41,11 @@ void print_help(char *app_name) { - "\t%s check \n" - "\t%s regenerate \n" - "\t%s set [COUNTER]\n" -- "\t%s nk3-change-pin \n", -- app_name, app_name, app_name, app_name, app_name, app_name, app_name); -+ "\t%s nk3-change-pin \n" -+ "\t%s reset [ADMIN PIN]\n" -+ "\t%s regenerate\n" -+ "\t%s set [COUNTER]\n", -+ app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name); - } - - -@@ -163,8 +166,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { - break; - case 'r': - if (strncmp(argv[1], "reset", 15) == 0) { -- if (argc != 2) break; -- res = nk3_reset(&dev); -+ if (argc != 2 && argc != 3) break; -+ res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); - } else if (strncmp(argv[1], "regenerate", 15) == 0) { - if (argc != 3) break; - res = regenerate_AES_key(&dev, argv[2]); -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index cdaf940..8b6ba77 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -33,7 +33,7 @@ - - - --int nk3_reset(struct Device *dev) { -+int nk3_reset(struct Device *dev, const char * new_pin) { - libusb_device *usb_dev; - struct libusb_device_descriptor usb_desc; - usb_dev = libusb_get_device(dev->mp_devhandle_ccid); -@@ -70,6 +70,10 @@ int nk3_reset(struct Device *dev) { - return 1; - } - -+ if (new_pin != NULL) { -+ set_pin_ccid(dev, new_pin); -+ } -+ - return RET_NO_ERROR; - } - -diff --git a/src/operations_ccid.h b/src/operations_ccid.h -index 20415c0..4d55ad8 100644 ---- a/src/operations_ccid.h -+++ b/src/operations_ccid.h -@@ -12,7 +12,10 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c - int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); - int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); - int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin); --int nk3_reset(struct Device *dev); -+// new_pin can be `null` -+// -+// If it is, no new pin will be set -+int nk3_reset(struct Device *dev, const char * new_pin); - - - #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H - -From 0bbc6ea354b1f807a4d7ad4c0cd57f9cbab25a8b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Tue, 3 Dec 2024 10:48:27 +0100 -Subject: [PATCH 3/4] Fix null pointer bug on non nk3 - ---- - src/operations_ccid.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 8b6ba77..1221764 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -36,6 +36,12 @@ - int nk3_reset(struct Device *dev, const char * new_pin) { - libusb_device *usb_dev; - struct libusb_device_descriptor usb_desc; -+ -+ if (!dev->mp_devhandle_ccid) { -+ // Not an NK3 -+ return RET_NO_ERROR; -+ } -+ - usb_dev = libusb_get_device(dev->mp_devhandle_ccid); - - int r = libusb_get_device_descriptor(usb_dev, &usb_desc); -@@ -46,7 +52,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { - - - if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { -- return 0; -+ return RET_NO_ERROR; - } - - - -From 0c5bd3da36ea8de5b8adf7878e9260b079bc110b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= -Date: Mon, 9 Dec 2024 17:42:54 +0100 -Subject: [PATCH 4/4] Print warning when device is not an NK3 - ---- - src/operations_ccid.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/operations_ccid.c b/src/operations_ccid.c -index 1221764..356a1b4 100644 ---- a/src/operations_ccid.c -+++ b/src/operations_ccid.c -@@ -39,6 +39,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { - - if (!dev->mp_devhandle_ccid) { - // Not an NK3 -+ printf("No Nitrokey 3 found. No operation performed\n"); - return RET_NO_ERROR; - } - -@@ -52,6 +53,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { - - - if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { -+ printf("No Nitrokey 3 found. No operation performed\n"); - return RET_NO_ERROR; - } - From eca4e341769d0bd97b73dab15376242214abbfda Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 12 Dec 2024 17:03:47 -0500 Subject: [PATCH 37/81] WiP: staging changes Attacking nv index next for TPM nvram read in prod_quiet testing Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 4 +++- initrd/bin/oem-factory-reset | 4 ++-- initrd/etc/functions | 4 ++-- modules/hotp-verification | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 9e94c30e1..c9ee5d45e 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -571,7 +571,7 @@ reset_tpm() # now that the TPM is reset, remove invalid TPM counter files mount_boot mount -o rw,remount /boot - warn "Removing rollback and primary handle hash under /boot" + LOG "Removing rollback and primary handle hash under /boot" rm -f /boot/kexec_rollback.txt rm -f /boot/kexec_primhdl_hash.txt @@ -585,6 +585,8 @@ reset_tpm() sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ || die "Unable to create rollback file" + + warn "boot content has been modified, please update the checksums and sign the files from Options -> Update checksums and sign all files in /boot" mount -o ro,remount /boot generate_totp_hotp "$tpm_owner_password" diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index a4096153f..58ab1e599 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -1288,7 +1288,7 @@ else #Reset Nitrokey 3 secret app reset_nk3_secret_app #Generate GPG key and subkeys on smartcard only - echo -e "\nResetting USB Security dongle's OpenPGP smartcard with GPG...\n(this will take around 3 minutes...)\n" + echo -e "\nResetting USB Security dongle's OpenPGP smartcard with GPG...\n(this may take up to 3 minutes...)\n" gpg_key_factory_reset generate_OEM_gpg_keys fi @@ -1353,7 +1353,7 @@ else #We are not running in QEMU, so flash the key to ROM ## flash generated key to ROM - echo -e "\nReading current firmware...\n(this will take a minute or two)\n" + echo -e "\nReading current firmware...\n(this may take up to two minutes...)\n" /bin/flash.sh -r /tmp/oem-setup.rom >/dev/null 2>/tmp/error if [ ! -s /tmp/oem-setup.rom ]; then ERROR=$(tail -n 1 /tmp/error | fold -s) diff --git a/initrd/etc/functions b/initrd/etc/functions index f6438ae73..e6cd706f8 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -368,7 +368,7 @@ check_tpm_counter() { if [ -r "$1" ]; then TPM_COUNTER=$(grep counter- "$1" | cut -d- -f2) else - warn "$1 does not exist; creating new TPM counter" + LOG "$1 does not exist; creating new TPM counter" tpmr counter_create \ -pwdc '' \ -la $LABEL | @@ -384,7 +384,7 @@ check_tpm_counter() { read_tpm_counter() { TRACE_FUNC - tpmr counter_read -ix "$1" | tee "/tmp/counter-$1" || + tpmr counter_read -ix "$1" | tee "/tmp/counter-$1" > /dev/null 2>&1 || die "Counter read failed" } diff --git a/modules/hotp-verification b/modules/hotp-verification index 5bd1650a8..d9511d2a8 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -7,7 +7,7 @@ hotp-verification_version := e6cf719d67a811356eecff69769fa1dbce47f953 hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz -hotp-verification_hash := 1095640fdae77938ce2d2ce294c7ecb8c27b77060975af8d838b6fd056ed5068 +hotp-verification_hash := 3c8b44e4d9a1f7454269f76102f32de6ed9de19ab0cf7119747eb97377c66a84 hotp-verification_target := \ $(MAKE_JOBS) \ From c7ab861325246a2fd3c019de1313a8b864a0cfe4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 12 Dec 2024 18:44:51 -0500 Subject: [PATCH 38/81] Turn some info on default boot into LOGged info, LOG might go out forever if not pertinent to most? Signed-off-by: Thierry Laurion --- initrd/bin/kexec-select-boot | 6 +++--- initrd/etc/functions | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 81d0e5ff8..daed067a4 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -79,10 +79,10 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then fi verify_global_hashes() { - echo "+++ Checking verified boot hash file " + LOG "+++ Checking verified boot hash file " # Check the hashes of all the files if verify_checksums "$bootdir" "$gui_menu"; then - echo "+++ Verified boot hashes " + LOG "+++ Verified boot hashes " valid_hash='y' valid_global_hash='y' else @@ -204,7 +204,7 @@ parse_option() { } scan_options() { - echo "+++ Scanning for unsigned boot options" + LOG "+++ Scanning for unsigned boot options" option_file="/tmp/kexec_options.txt" scan_boot_options "$bootdir" "$config" "$option_file" if [ ! -s $option_file ]; then diff --git a/initrd/etc/functions b/initrd/etc/functions index e6cd706f8..b228b18ed 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -419,7 +419,7 @@ check_config() { fi fi - echo "+++ Found verified kexec boot params" + LOG "+++ Found verified kexec boot params" cp $1/kexec*.txt /tmp/kexec || die "Failed to copy kexec boot params to tmp" } From d768e80de677e1bff59ec5439c2d266074d858d7 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 13 Dec 2024 14:50:24 -0500 Subject: [PATCH 39/81] WiP: staging changes, no more tpm output. Next warn /boot changed because htop counter and primary handle until removed outside of this PR Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 2 +- initrd/bin/kexec-select-boot | 2 +- initrd/etc/functions | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index c9ee5d45e..c38119870 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -580,7 +580,7 @@ reset_tpm() || die "Unable to find/create tpm counter" counter="$TPM_COUNTER" - increment_tpm_counter $counter \ + increment_tpm_counter $counter > /dev/null 2>&1 \ || die "Unable to increment tpm counter" sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index daed067a4..60215506b 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -119,7 +119,7 @@ verify_rollback_counter() { die "$TMP_ROLLBACK_FILE: TPM counter not found?" fi - read_tpm_counter $TPM_COUNTER || + read_tpm_counter $TPM_COUNTER > /dev/null 2>&1 || die "Failed to read TPM counter" sha256sum -c $TMP_ROLLBACK_FILE || diff --git a/initrd/etc/functions b/initrd/etc/functions index b228b18ed..311644a8c 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -382,12 +382,14 @@ check_tpm_counter() { fi } +# Read the TPM counter value from the TPM. read_tpm_counter() { TRACE_FUNC tpmr counter_read -ix "$1" | tee "/tmp/counter-$1" > /dev/null 2>&1 || die "Counter read failed" } +# Increment the TPM counter value in the TPM. increment_tpm_counter() { TRACE_FUNC tpmr counter_increment -ix "$1" -pwdc '' | @@ -395,6 +397,7 @@ increment_tpm_counter() { die "TPM counter increment failed for rollback prevention. Please reset the TPM" } +# Check detached signature on kexec boot params check_config() { TRACE_FUNC if [ ! -d /tmp/kexec ]; then @@ -414,6 +417,7 @@ check_config() { fi if [ "$2" != "force" ]; then + # Note that kexec.sig detached signature is solely verifying kexec*.txt files here! if ! sha256sum $(find $1/kexec*.txt) | gpgv $1/kexec.sig -; then die 'Invalid signature on kexec boot params' fi @@ -436,6 +440,7 @@ replace_rom_file() { cbfs.sh -o "$ROM" -a "$ROM_FILE" -f "$NEW_FILE" } +# Replace the config file by the changed one replace_config() { TRACE_FUNC CONFIG_FILE=$1 @@ -469,6 +474,7 @@ secret_from_rom_hash() { sha256sum "${ROM_IMAGE}" | cut -f1 -d ' ' | fromhex_plain } +# Update the checksums of the files in /boot and sign them update_checksums() { TRACE_FUNC # ensure /boot mounted @@ -499,6 +505,7 @@ update_checksums() { return $rv } +# Print the file and directory structure of /boot to caller's stdout print_tree() { TRACE_FUNC find ./ ! -path './kexec*' -print0 | sort -z @@ -584,6 +591,7 @@ assert_signable() { rm -f /tmp/signable.* } +# Verify the checksums of the files in /boot verify_checksums() { TRACE_FUNC local boot_dir="$1" From 0d3964274ee2ba256eb571ce1291e0cdb8071eb8 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 13 Dec 2024 15:50:05 -0500 Subject: [PATCH 40/81] WiP: staging changes, warn loud and clear of weak security posture by using weak OEM defaults provisioned secrets Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 2 +- initrd/bin/seal-hotpkey | 8 ++++++-- initrd/bin/tpmr | 7 +++++-- initrd/bin/unseal-totp | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index c38119870..f89f1e151 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -557,7 +557,7 @@ reset_tpm() TRACE_FUNC if [ "$CONFIG_TPM" = "y" ]; then if (whiptail_warning --title 'Reset the TPM' \ - --yesno "This will clear the TPM and TPM password, replace them with new ones!\n\nDo you want to proceed?" 0 80) then + --yesno "This will clear the TPM and replace its Owner password with a new one!\n\nDo you want to proceed?" 0 80) then if ! prompt_new_owner_password; then echo "Press Enter to return to the menu..." diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 70d86e952..9c01d5d60 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -129,7 +129,8 @@ else echo "Trying $prompt_message PIN ($admin_pin) to seal HOTP secret on $HOTPKEY_BRANDING..." #if we deal with the nk3, say to the user that touch will be required if lsusb | grep -q "20a0:42b2"; then - warn "Touching the Nitrokey 3 to confirm presence operation is required" + warn "Nitrokey 3 requires physical presence : touch the dongle when prompted" + echo fi #TODO: silence the output of hotp_initialize once https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed #hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1 @@ -161,7 +162,10 @@ if [ "$admin_pin_status" -ne 0 ]; then fi else # remind user to change admin password - warn "Factory $prompt_message default PIN 12345678 detected: please change this PIN as soon as possible through OEM Factory Reset/User Re-Ownership" + warn "Weak OEM default PINs are under use to enforce remote attestation/encryption/signature operations" + warn "$CONFIG_BRAND_NAME security is compromised until the ownership of this device is re-established by changing secrets by non-default values" + warn "You must change current default secrets through 'Options -> OEM Factory Reset/Re-Ownership' menu and not accept the default options" + warn "You will be asked to answer a questionnaire to re-own your device and USB security dongles with new secrets" fi # HOTP key no longer needed diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 61d966787..7dbe50432 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -363,7 +363,6 @@ tpm2_startsession() { tpm2 flushcontext -Q \ --saved-session || die "tpm2_flushcontext: unable to flush saved session" - #TODO: readpublic cannot be silenced even if redirected to /dev/null with both stderr and stdout redirected? tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE" >/dev/null 2>&1 #TODO: do the right thing to not have to suppress "WARN: check public portion the tpmkey manually" see https://github.com/linuxboot/heads/pull/1630#issuecomment-2075120429 tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE" >/dev/null 2>&1 @@ -622,7 +621,10 @@ tpm2_unseal() { LOG "tpm2 stderr: $line" done <"$TMP_ERR_FILE" rm -f "$TMP_ERR_FILE" - die "Unable to unseal secret from TPM NVRAM" + LOG "Unable to unseal secret from TPM NVRAM" + + # should succeed, exit if it doesn't + exit 1 fi rm -f "$TMP_ERR_FILE" } @@ -649,6 +651,7 @@ tpm1_unseal() { -sz "$sealed_size" \ -of "$sealed_file" || die "Unable to read sealed file from TPM NVRAM" + # TODO: Cannot log + exit instead of dying!?! PASS_ARGS=() if [ "$pass" ]; then diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index b5ec14145..3ca7cf281 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -9,7 +9,7 @@ TRACE_FUNC if [ "$CONFIG_TPM" = "y" ]; then tpmr unseal 4d47 0,1,2,3,4,7 312 "$TOTP_SECRET" || - die "Unable to unseal TOTP secret" + die "Unable to unseal TOTP secret from TPM" fi if ! totp -q <"$TOTP_SECRET"; then From 53156c3917144a4159391418ed2176d8faa00e21 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 13 Dec 2024 16:56:05 -0500 Subject: [PATCH 41/81] WiP: staging changes, refusing to fight against tools helping me, formatting changed. sign after tpm-reset now to work around primary handle issue. Signed-off-by: Thierry Laurion --- initrd/bin/gui-init | 1172 +++++++++++++++++----------------- initrd/bin/kexec-select-boot | 9 +- initrd/bin/kexec-sign-config | 39 +- initrd/bin/oem-factory-reset | 2 +- initrd/bin/seal-hotpkey | 8 +- initrd/bin/tpmr | 2 +- initrd/etc/ash_functions | 7 + 7 files changed, 622 insertions(+), 617 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index f89f1e151..1311963cb 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -1,7 +1,7 @@ #!/bin/bash # Boot from a local disk installation -BOARD_NAME=${CONFIG_BOARD_NAME:-${CONFIG_BOARD}} +BOARD_NAME=${CONFIG_BOARD_NAME:-${CONFIG_BOARD}} MAIN_MENU_TITLE="${BOARD_NAME} | $CONFIG_BRAND_NAME Boot Menu" export BG_COLOR_MAIN_MENU="normal" @@ -16,627 +16,615 @@ export BG_COLOR_MAIN_MENU="normal" # # see errors again. skip_to_menu="false" - - -mount_boot() -{ - TRACE_FUNC - # Mount local disk if it is not already mounted - while ! grep -q /boot /proc/mounts ; do - # try to mount if CONFIG_BOOT_DEV exists - if [ -e "$CONFIG_BOOT_DEV" ]; then - mount -o ro $CONFIG_BOOT_DEV /boot - [[ $? -eq 0 ]] && continue - fi - - # CONFIG_BOOT_DEV doesn't exist or couldn't be mounted, so give user options - BG_COLOR_MAIN_MENU="error" - whiptail_error --title "ERROR: No Bootable OS Found!" \ - --menu " No bootable OS was found on the default boot device $CONFIG_BOOT_DEV. +mount_boot() { + TRACE_FUNC + # Mount local disk if it is not already mounted + while ! grep -q /boot /proc/mounts; do + # try to mount if CONFIG_BOOT_DEV exists + if [ -e "$CONFIG_BOOT_DEV" ]; then + mount -o ro $CONFIG_BOOT_DEV /boot + [[ $? -eq 0 ]] && continue + fi + + # CONFIG_BOOT_DEV doesn't exist or couldn't be mounted, so give user options + BG_COLOR_MAIN_MENU="error" + whiptail_error --title "ERROR: No Bootable OS Found!" \ + --menu " No bootable OS was found on the default boot device $CONFIG_BOOT_DEV. How would you like to proceed?" 0 80 4 \ - 'b' ' Select a new boot device' \ - 'u' ' Boot from USB' \ - 'm' ' Continue to the main menu' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - b ) - config-gui.sh boot_device_select - if [ $? -eq 0 ]; then - # update CONFIG_BOOT_DEV - . /tmp/config - BG_COLOR_MAIN_MENU="normal" - fi - ;; - u ) - exec /bin/usb-init - ;; - m ) - skip_to_menu="true" - break - ;; - * ) - recovery "User requested recovery shell" - ;; - esac - done + 'b' ' Select a new boot device' \ + 'u' ' Boot from USB' \ + 'm' ' Continue to the main menu' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + b) + config-gui.sh boot_device_select + if [ $? -eq 0 ]; then + # update CONFIG_BOOT_DEV + . /tmp/config + BG_COLOR_MAIN_MENU="normal" + fi + ;; + u) + exec /bin/usb-init + ;; + m) + skip_to_menu="true" + break + ;; + *) + recovery "User requested recovery shell" + ;; + esac + done } -verify_global_hashes() -{ - TRACE_FUNC - # Check the hashes of all the files, ignoring signatures for now - check_config /boot force - TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" - TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" - TMP_PACKAGE_TRIGGER_PRE="/tmp/kexec/kexec_package_trigger_pre.txt" - TMP_PACKAGE_TRIGGER_POST="/tmp/kexec/kexec_package_trigger_post.txt" - - if verify_checksums /boot ; then - return 0 - elif [[ ! -f "$TMP_HASH_FILE" || ! -f "$TMP_TREE_FILE" ]] ; then - if (whiptail_error --title 'ERROR: Missing File!' \ - --yesno "One of the files containing integrity information for /boot is missing!\n\nIf you are setting up heads for the first time or upgrading from an\nolder version, select Yes to create the missing files.\n\nOtherwise this could indicate a compromise and you should select No to\nreturn to the main menu.\n\nWould you like to create the missing files now?" 0 80) then - if update_checksums ; then - BG_COLOR_MAIN_MENU="normal" - return 0; - else - whiptail_error --title 'ERROR' \ - --msgbox "Failed to update checksums / sign default config" 0 80 - fi - fi - BG_COLOR_MAIN_MENU="error" - return 1 - else - CHANGED_FILES=$(grep -v 'OK$' /tmp/hash_output | cut -f1 -d ':' | tee -a /tmp/hash_output_mismatches) - CHANGED_FILES_COUNT=$(wc -l /tmp/hash_output_mismatches | cut -f1 -d ' ') - - # if files changed before package manager started, show stern warning - if [ -f "$TMP_PACKAGE_TRIGGER_PRE" ]; then - PRE_CHANGED_FILES=$(grep '^CHANGED_FILES' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') - TEXT="The following files failed the verification process BEFORE package updates ran:\n${PRE_CHANGED_FILES}\n\nCompare against the files $CONFIG_BRAND_NAME has detected have changed:\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums anyway?" - - # if files changed after package manager started, probably caused by package manager - elif [ -f "$TMP_PACKAGE_TRIGGER_POST" ]; then - LAST_PACKAGE_LIST=$(grep -E "^(Install|Remove|Upgrade|Reinstall):" $TMP_PACKAGE_TRIGGER_POST) - UPDATE_INITRAMFS_PACKAGE=$(grep '^UPDATE_INITRAMFS_PACKAGE' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') - - if [ "$UPDATE_INITRAMFS_PACKAGE" != "" ]; then - TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis is likely due to package triggers in$UPDATE_INITRAMFS_PACKAGE.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" - else - TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis might be due to the following package updates:\n$LAST_PACKAGE_LIST.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" - fi - - else - if [ $CHANGED_FILES_COUNT -gt 10 ]; then - # drop to console to show full file list - whiptail_error --title 'ERROR: Boot Hash Mismatch' \ - --msgbox "${CHANGED_FILES_COUNT} files failed the verification process!\\n\nThis could indicate a compromise!\n\nHit OK to review the list of files.\n\nType \"q\" to exit the list and return." 0 80 - - echo "Type \"q\" to exit the list and return." >> /tmp/hash_output_mismatches - less /tmp/hash_output_mismatches - #move outdated hash mismatch list - mv /tmp/hash_output_mismatches /tmp/hash_output_mismatch_old - TEXT="Would you like to update your checksums now?" - else - TEXT="The following files failed the verification process:\n\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums now?" - fi - fi - - if (whiptail_error --title 'ERROR: Boot Hash Mismatch' --yesno "$TEXT" 0 80) then - if update_checksums ; then - BG_COLOR_MAIN_MENU="normal" - return 0; - else - whiptail_error --title 'ERROR' \ - --msgbox "Failed to update checksums / sign default config" 0 80 - fi - fi - BG_COLOR_MAIN_MENU="error" - return 1 - fi +verify_global_hashes() { + TRACE_FUNC + # Check the hashes of all the files, ignoring signatures for now + check_config /boot force + TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" + TMP_PACKAGE_TRIGGER_PRE="/tmp/kexec/kexec_package_trigger_pre.txt" + TMP_PACKAGE_TRIGGER_POST="/tmp/kexec/kexec_package_trigger_post.txt" + + if verify_checksums /boot; then + return 0 + elif [[ ! -f "$TMP_HASH_FILE" || ! -f "$TMP_TREE_FILE" ]]; then + if (whiptail_error --title 'ERROR: Missing File!' \ + --yesno "One of the files containing integrity information for /boot is missing!\n\nIf you are setting up heads for the first time or upgrading from an\nolder version, select Yes to create the missing files.\n\nOtherwise this could indicate a compromise and you should select No to\nreturn to the main menu.\n\nWould you like to create the missing files now?" 0 80); then + if update_checksums; then + BG_COLOR_MAIN_MENU="normal" + return 0 + else + whiptail_error --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + fi + fi + BG_COLOR_MAIN_MENU="error" + return 1 + else + CHANGED_FILES=$(grep -v 'OK$' /tmp/hash_output | cut -f1 -d ':' | tee -a /tmp/hash_output_mismatches) + CHANGED_FILES_COUNT=$(wc -l /tmp/hash_output_mismatches | cut -f1 -d ' ') + + # if files changed before package manager started, show stern warning + if [ -f "$TMP_PACKAGE_TRIGGER_PRE" ]; then + PRE_CHANGED_FILES=$(grep '^CHANGED_FILES' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') + TEXT="The following files failed the verification process BEFORE package updates ran:\n${PRE_CHANGED_FILES}\n\nCompare against the files $CONFIG_BRAND_NAME has detected have changed:\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums anyway?" + + # if files changed after package manager started, probably caused by package manager + elif [ -f "$TMP_PACKAGE_TRIGGER_POST" ]; then + LAST_PACKAGE_LIST=$(grep -E "^(Install|Remove|Upgrade|Reinstall):" $TMP_PACKAGE_TRIGGER_POST) + UPDATE_INITRAMFS_PACKAGE=$(grep '^UPDATE_INITRAMFS_PACKAGE' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') + + if [ "$UPDATE_INITRAMFS_PACKAGE" != "" ]; then + TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis is likely due to package triggers in$UPDATE_INITRAMFS_PACKAGE.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" + else + TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis might be due to the following package updates:\n$LAST_PACKAGE_LIST.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" + fi + + else + if [ $CHANGED_FILES_COUNT -gt 10 ]; then + # drop to console to show full file list + whiptail_error --title 'ERROR: Boot Hash Mismatch' \ + --msgbox "${CHANGED_FILES_COUNT} files failed the verification process!\\n\nThis could indicate a compromise!\n\nHit OK to review the list of files.\n\nType \"q\" to exit the list and return." 0 80 + + echo "Type \"q\" to exit the list and return." >>/tmp/hash_output_mismatches + less /tmp/hash_output_mismatches + #move outdated hash mismatch list + mv /tmp/hash_output_mismatches /tmp/hash_output_mismatch_old + TEXT="Would you like to update your checksums now?" + else + TEXT="The following files failed the verification process:\n\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums now?" + fi + fi + + if (whiptail_error --title 'ERROR: Boot Hash Mismatch' --yesno "$TEXT" 0 80); then + if update_checksums; then + BG_COLOR_MAIN_MENU="normal" + return 0 + else + whiptail_error --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + fi + fi + BG_COLOR_MAIN_MENU="error" + return 1 + fi } -prompt_update_checksums() -{ - TRACE_FUNC - if (whiptail_warning --title 'Update Checksums and sign all files in /boot' \ - --yesno "You have chosen to update the checksums and sign all of the files in /boot.\n\nThis means that you trust that these files have not been tampered with.\n\nYou will need your GPG key available, and this change will modify your disk.\n\nDo you want to continue?" 0 80) then - if ! update_checksums ; then - whiptail_error --title 'ERROR' \ - --msgbox "Failed to update checksums / sign default config" 0 80 - fi - fi +prompt_update_checksums() { + TRACE_FUNC + if (whiptail_warning --title 'Update Checksums and sign all files in /boot' \ + --yesno "You have chosen to update the checksums and sign all of the files in /boot.\n\nThis means that you trust that these files have not been tampered with.\n\nYou will need your GPG key available, and this change will modify your disk.\n\nDo you want to continue?" 0 80); then + if ! update_checksums; then + whiptail_error --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + fi + fi } -generate_totp_hotp() -{ - TRACE_FUNC - tpm_owner_password="$1" # May be empty, will prompt if needed and empty - if [ "$CONFIG_TPM" != "y" ] && [ -x /bin/hotp_verification ]; then - echo "Generating new HOTP secret" - /bin/seal-hotpkey - elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_owner_password"; then - echo - if [ -x /bin/hotp_verification ]; then - if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then - echo "Once you have scanned the QR code, hit Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)" - read - fi - /bin/seal-hotpkey - else - if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then - echo "Once you have scanned the QR code, hit Enter to continue" - read - fi - fi - # clear screen - printf "\033c" - else - warn "Unsealing TOTP/HOTP secret from previous sealed measurements failed" - warn 'Try "Generate new HOTP/TOTP secret" option if you updated firmware content' - fi +generate_totp_hotp() { + TRACE_FUNC + tpm_owner_password="$1" # May be empty, will prompt if needed and empty + if [ "$CONFIG_TPM" != "y" ] && [ -x /bin/hotp_verification ]; then + echo "Generating new HOTP secret" + /bin/seal-hotpkey + elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_owner_password"; then + echo + if [ -x /bin/hotp_verification ]; then + if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then + echo "Once you have scanned the QR code, hit Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)" + read + fi + /bin/seal-hotpkey + else + if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then + echo "Once you have scanned the QR code, hit Enter to continue" + read + fi + fi + # clear screen + printf "\033c" + else + warn "Unsealing TOTP/HOTP secret from previous sealed measurements failed" + warn 'Try "Generate new HOTP/TOTP secret" option if you updated firmware content' + fi } -update_totp() -{ - TRACE_FUNC - # update the TOTP code - date=`date "+%Y-%m-%d %H:%M:%S %Z"` - tries=0 - if [ "$CONFIG_TPM" != "y" ]; then - TOTP="NO TPM" - else - TOTP=`unseal-totp` - # On platforms using CONFIG_BOOT_EXTRA_TTYS multiple processes may try to - # access TPM at the same time, failing with EBUSY. The order of execution - # is unpredictable, so the error may appear on main console, secondary one, - # or neither of them if the calls are sufficiently staggered. Try up to - # three times (including previous one) with small delays in case of error, - # instead of immediately scaring users with "you've been pwned" message. - while [ $? -ne 0 ] && [ $tries -lt 2 ]; do - sleep 0.5 - ((tries++)) - TOTP=`unseal-totp` - done - if [ $? -ne 0 ]; then - BG_COLOR_MAIN_MENU="error" - if [ "$skip_to_menu" = "true" ]; then - return 1 # Already asked to skip to menu from a prior error - fi - - DEBUG "CONFIG_TPM: $CONFIG_TPM" - DEBUG "CONFIG_TPM2_TOOLS: $CONFIG_TPM2_TOOLS" - DEBUG "Show PCRs" - DEBUG "$(pcrs)" - - whiptail_error --title "ERROR: TOTP Generation Failed!" \ - --menu " ERROR: $CONFIG_BRAND_NAME couldn't generate the TOTP code.\n +update_totp() { + TRACE_FUNC + # update the TOTP code + date=$(date "+%Y-%m-%d %H:%M:%S %Z") + tries=0 + if [ "$CONFIG_TPM" != "y" ]; then + TOTP="NO TPM" + else + TOTP=$(unseal-totp) + # On platforms using CONFIG_BOOT_EXTRA_TTYS multiple processes may try to + # access TPM at the same time, failing with EBUSY. The order of execution + # is unpredictable, so the error may appear on main console, secondary one, + # or neither of them if the calls are sufficiently staggered. Try up to + # three times (including previous one) with small delays in case of error, + # instead of immediately scaring users with "you've been pwned" message. + while [ $? -ne 0 ] && [ $tries -lt 2 ]; do + sleep 0.5 + ((tries++)) + TOTP=$(unseal-totp) + done + if [ $? -ne 0 ]; then + BG_COLOR_MAIN_MENU="error" + if [ "$skip_to_menu" = "true" ]; then + return 1 # Already asked to skip to menu from a prior error + fi + + DEBUG "CONFIG_TPM: $CONFIG_TPM" + DEBUG "CONFIG_TPM2_TOOLS: $CONFIG_TPM2_TOOLS" + DEBUG "Show PCRs" + DEBUG "$(pcrs)" + + whiptail_error --title "ERROR: TOTP Generation Failed!" \ + --menu " ERROR: $CONFIG_BRAND_NAME couldn't generate the TOTP code.\n If you have just completed a Factory Reset, or just reflashed your BIOS, you should generate a new HOTP/TOTP secret.\n If this is the first time the system has booted, you should reset the TPM and set your own password.\n If you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n How would you like to proceed?" 0 80 4 \ - 'g' ' Generate new HOTP/TOTP secret' \ - 'i' ' Ignore error and continue to main menu' \ - 'p' ' Reset the TPM' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - g ) - if (whiptail_warning --title 'Generate new TOTP/HOTP secret' \ - --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then - generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key - fi - ;; - i ) - skip_to_menu="true" - return 1 - ;; - p ) - reset_tpm && update_totp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key - ;; - x ) - recovery "User requested recovery shell" - ;; - esac - fi - fi + 'g' ' Generate new HOTP/TOTP secret' \ + 'i' ' Ignore error and continue to main menu' \ + 'p' ' Reset the TPM' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + g) + if (whiptail_warning --title 'Generate new TOTP/HOTP secret' \ + --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80); then + generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key + fi + ;; + i) + skip_to_menu="true" + return 1 + ;; + p) + reset_tpm && update_totp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key + ;; + x) + recovery "User requested recovery shell" + ;; + esac + fi + fi } -update_hotp() -{ - TRACE_FUNC - HOTP="Unverified" - if [ -x /bin/hotp_verification ]; then - if ! hotp_verification info ; then - if [ "$skip_to_menu" = "true" ]; then - return 1 # Already asked to skip to menu from a prior error - fi - if ! whiptail_warning \ - --title "WARNING: Please Insert Your $HOTPKEY_BRANDING" \ - --yes-button "Retry" --no-button "Skip" \ - --yesno "Your $HOTPKEY_BRANDING was not detected.\n\nPlease insert your $HOTPKEY_BRANDING" 0 80 ; then - HOTP="Error checking code, Insert $HOTPKEY_BRANDING and retry" - BG_COLOR_MAIN_MENU="warning" - return - fi - fi - HOTP=`unseal-hotp` - # Don't output HOTP codes to screen, so as to make replay attacks harder - hotp_verification check "$HOTP" - case "$?" in - 0 ) - HOTP="Success" - BG_COLOR_MAIN_MENU="normal" - ;; - 4|7 ) # 4: code was incorrect, 7: code was not a valid HOTP code at all - HOTP="Invalid code" - BG_COLOR_MAIN_MENU="error" - ;; - * ) - HOTP="Error checking code, Insert $HOTPKEY_BRANDING and retry" - BG_COLOR_MAIN_MENU="warning" - ;; - esac - else - HOTP='N/A' - fi - - if [[ "$CONFIG_TPM" = n && "$HOTP" = "Invalid code" ]]; then - whiptail_error --title "ERROR: HOTP Validation Failed!" \ - --menu "ERROR: $CONFIG_BRAND_NAME couldn't validate the HOTP code.\n\nIf you just reflashed your BIOS, you should generate a new TOTP/HOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \ - 'g' ' Generate new TOTP/HOTP secret' \ - 'i' ' Ignore error and continue to main menu' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - g ) - if (whiptail_warning --title 'Generate new TOTP/HOTP secret' \ - --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then - generate_totp_hotp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key - fi - ;; - i ) - return 1 - ;; - x ) - recovery "User requested recovery shell" - ;; - esac - fi +update_hotp() { + TRACE_FUNC + HOTP="Unverified" + if [ -x /bin/hotp_verification ]; then + if ! hotp_verification info; then + if [ "$skip_to_menu" = "true" ]; then + return 1 # Already asked to skip to menu from a prior error + fi + if ! whiptail_warning \ + --title "WARNING: Please Insert Your $HOTPKEY_BRANDING" \ + --yes-button "Retry" --no-button "Skip" \ + --yesno "Your $HOTPKEY_BRANDING was not detected.\n\nPlease insert your $HOTPKEY_BRANDING" 0 80; then + HOTP="Error checking code, Insert $HOTPKEY_BRANDING and retry" + BG_COLOR_MAIN_MENU="warning" + return + fi + fi + HOTP=$(unseal-hotp) + # Don't output HOTP codes to screen, so as to make replay attacks harder + hotp_verification check "$HOTP" + case "$?" in + 0) + HOTP="Success" + BG_COLOR_MAIN_MENU="normal" + ;; + 4 | 7) # 4: code was incorrect, 7: code was not a valid HOTP code at all + HOTP="Invalid code" + BG_COLOR_MAIN_MENU="error" + ;; + *) + HOTP="Error checking code, Insert $HOTPKEY_BRANDING and retry" + BG_COLOR_MAIN_MENU="warning" + ;; + esac + else + HOTP='N/A' + fi + + if [[ "$CONFIG_TPM" = n && "$HOTP" = "Invalid code" ]]; then + whiptail_error --title "ERROR: HOTP Validation Failed!" \ + --menu "ERROR: $CONFIG_BRAND_NAME couldn't validate the HOTP code.\n\nIf you just reflashed your BIOS, you should generate a new TOTP/HOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \ + 'g' ' Generate new TOTP/HOTP secret' \ + 'i' ' Ignore error and continue to main menu' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + g) + if (whiptail_warning --title 'Generate new TOTP/HOTP secret' \ + --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80); then + generate_totp_hotp && BG_COLOR_MAIN_MENU="normal" && reseal_tpm_disk_decryption_key + fi + ;; + i) + return 1 + ;; + x) + recovery "User requested recovery shell" + ;; + esac + fi } -clean_boot_check() -{ - TRACE_FUNC - # assume /boot mounted - if ! grep -q /boot /proc/mounts ; then - return - fi - - # check for any kexec files in /boot - kexec_files=`find /boot -name kexec*.txt` - [ ! -z "$kexec_files" ] && return - - #check for GPG key in keyring - GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` - [ $GPG_KEY_COUNT -ne 0 ] && return - - # check for USB security token - if [ -x /bin/hotp_verification ]; then - if ! gpg --card-status > /dev/null ; then - return - fi - fi - - # OS is installed, no kexec files present, no GPG keys in keyring, security token present - # prompt user to run OEM factory reset - oem-factory-reset \ - "Clean Boot Detected - Perform OEM Factory Reset / Re-Ownership?" +clean_boot_check() { + TRACE_FUNC + # assume /boot mounted + if ! grep -q /boot /proc/mounts; then + return + fi + + # check for any kexec files in /boot + kexec_files=$(find /boot -name kexec*.txt) + [ ! -z "$kexec_files" ] && return + + #check for GPG key in keyring + GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) + [ $GPG_KEY_COUNT -ne 0 ] && return + + # check for USB security token + if [ -x /bin/hotp_verification ]; then + if ! gpg --card-status >/dev/null; then + return + fi + fi + + # OS is installed, no kexec files present, no GPG keys in keyring, security token present + # prompt user to run OEM factory reset + oem-factory-reset \ + "Clean Boot Detected - Perform OEM Factory Reset / Re-Ownership?" } -check_gpg_key() -{ - TRACE_FUNC - GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` - if [ $GPG_KEY_COUNT -eq 0 ]; then - BG_COLOR_MAIN_MENU="error" - if [ "$skip_to_menu" = "true" ]; then - return 1 # Already asked to skip to menu from a prior error - fi - whiptail_error --title "ERROR: GPG keyring empty!" \ - --menu "ERROR: $CONFIG_BRAND_NAME couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted,\nyou should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one\npublic key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \ - 'g' ' Add a GPG key to the running BIOS' \ - 'F' ' OEM Factory Reset / Re-Ownership' \ - 'i' ' Ignore error and continue to main menu' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - g ) - gpg-gui.sh && BG_COLOR_MAIN_MENU="normal" - ;; - i ) - skip_to_menu="true" - return 1 - ;; - F ) - oem-factory-reset - ;; - - x ) - recovery "User requested recovery shell" - ;; - esac - fi +check_gpg_key() { + TRACE_FUNC + GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) + if [ $GPG_KEY_COUNT -eq 0 ]; then + BG_COLOR_MAIN_MENU="error" + if [ "$skip_to_menu" = "true" ]; then + return 1 # Already asked to skip to menu from a prior error + fi + whiptail_error --title "ERROR: GPG keyring empty!" \ + --menu "ERROR: $CONFIG_BRAND_NAME couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted,\nyou should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one\npublic key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \ + 'g' ' Add a GPG key to the running BIOS' \ + 'F' ' OEM Factory Reset / Re-Ownership' \ + 'i' ' Ignore error and continue to main menu' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + g) + gpg-gui.sh && BG_COLOR_MAIN_MENU="normal" + ;; + i) + skip_to_menu="true" + return 1 + ;; + F) + oem-factory-reset + ;; + + x) + recovery "User requested recovery shell" + ;; + esac + fi } -prompt_auto_default_boot() -{ - TRACE_FUNC - echo -e "\nHOTP verification success\n\n" - if pause_automatic_boot; then - echo -e "\n\nAttempting default boot...\n\n" - attempt_default_boot - fi +prompt_auto_default_boot() { + TRACE_FUNC + echo -e "\nHOTP verification success\n\n" + if pause_automatic_boot; then + echo -e "\n\nAttempting default boot...\n\n" + attempt_default_boot + fi } -show_main_menu() -{ - TRACE_FUNC - date=`date "+%Y-%m-%d %H:%M:%S %Z"` - whiptail_type $BG_COLOR_MAIN_MENU --title "$MAIN_MENU_TITLE" \ - --menu "$date\nTOTP: $TOTP | HOTP: $HOTP" 0 80 10 \ - 'd' ' Default boot' \ - 'r' ' Refresh TOTP/HOTP' \ - 'o' ' Options -->' \ - 's' ' System Info' \ - 'p' ' Power Off' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - d ) - attempt_default_boot - ;; - r ) - update_totp && update_hotp - ;; - o ) - show_options_menu - ;; - s ) - show_system_info - ;; - p ) - poweroff - ;; - esac +show_main_menu() { + TRACE_FUNC + date=$(date "+%Y-%m-%d %H:%M:%S %Z") + whiptail_type $BG_COLOR_MAIN_MENU --title "$MAIN_MENU_TITLE" \ + --menu "$date\nTOTP: $TOTP | HOTP: $HOTP" 0 80 10 \ + 'd' ' Default boot' \ + 'r' ' Refresh TOTP/HOTP' \ + 'o' ' Options -->' \ + 's' ' System Info' \ + 'p' ' Power Off' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + d) + attempt_default_boot + ;; + r) + update_totp && update_hotp + ;; + o) + show_options_menu + ;; + s) + show_system_info + ;; + p) + poweroff + ;; + esac } -show_options_menu() -{ - TRACE_FUNC - whiptail_type $BG_COLOR_MAIN_MENU --title "$CONFIG_BRAND_NAME Options" \ - --menu "" 0 80 10 \ - 'b' ' Boot Options -->' \ - 't' ' TPM/TOTP/HOTP Options -->' \ - 'h' ' Change system time' \ - 'u' ' Update checksums and sign all files in /boot' \ - 'c' ' Change configuration settings -->' \ - 'f' ' Flash/Update the BIOS -->' \ - 'g' ' GPG Options -->' \ - 'F' ' OEM Factory Reset / Re-Ownership -->' \ - 'C' ' Reencrypt LUKS container -->' \ - 'P' ' Change LUKS Disk Recovery Key passphrase ->' \ - 'R' ' Check/Update file hashes on root disk -->' \ - 'x' ' Exit to recovery shell' \ - 'r' ' <-- Return to main menu' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - b ) - show_boot_options_menu - ;; - t ) - show_tpm_totp_hotp_options_menu - ;; - h ) - change-time.sh - ;; - u ) - prompt_update_checksums - ;; - c ) - config-gui.sh - ;; - f ) - flash-gui.sh - ;; - g ) - gpg-gui.sh - ;; - F ) - oem-factory-reset - ;; - C ) - luks_reencrypt - luks_secrets_cleanup - ;; - P ) - luks_change_passphrase - luks_secrets_cleanup - ;; - R ) - root-hashes-gui.sh - ;; - x ) - recovery "User requested recovery shell" - ;; - r ) - ;; - esac +show_options_menu() { + TRACE_FUNC + whiptail_type $BG_COLOR_MAIN_MENU --title "$CONFIG_BRAND_NAME Options" \ + --menu "" 0 80 10 \ + 'b' ' Boot Options -->' \ + 't' ' TPM/TOTP/HOTP Options -->' \ + 'h' ' Change system time' \ + 'u' ' Update checksums and sign all files in /boot' \ + 'c' ' Change configuration settings -->' \ + 'f' ' Flash/Update the BIOS -->' \ + 'g' ' GPG Options -->' \ + 'F' ' OEM Factory Reset / Re-Ownership -->' \ + 'C' ' Reencrypt LUKS container -->' \ + 'P' ' Change LUKS Disk Recovery Key passphrase ->' \ + 'R' ' Check/Update file hashes on root disk -->' \ + 'x' ' Exit to recovery shell' \ + 'r' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + b) + show_boot_options_menu + ;; + t) + show_tpm_totp_hotp_options_menu + ;; + h) + change-time.sh + ;; + u) + prompt_update_checksums + ;; + c) + config-gui.sh + ;; + f) + flash-gui.sh + ;; + g) + gpg-gui.sh + ;; + F) + oem-factory-reset + ;; + C) + luks_reencrypt + luks_secrets_cleanup + ;; + P) + luks_change_passphrase + luks_secrets_cleanup + ;; + R) + root-hashes-gui.sh + ;; + x) + recovery "User requested recovery shell" + ;; + r) ;; + esac } -show_boot_options_menu() -{ - TRACE_FUNC - whiptail_type $BG_COLOR_MAIN_MENU --title "Boot Options" \ - --menu "Select A Boot Option" 0 80 10 \ - 'm' ' Show OS boot menu' \ - 'u' ' USB boot' \ - 'i' ' Ignore tampering and force a boot (Unsafe!)' \ - 'r' ' <-- Return to main menu' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - m ) - # select a kernel from the menu - select_os_boot_option - ;; - u ) - exec /bin/usb-init - ;; - i ) - force_unsafe_boot - ;; - r ) - ;; - esac +show_boot_options_menu() { + TRACE_FUNC + whiptail_type $BG_COLOR_MAIN_MENU --title "Boot Options" \ + --menu "Select A Boot Option" 0 80 10 \ + 'm' ' Show OS boot menu' \ + 'u' ' USB boot' \ + 'i' ' Ignore tampering and force a boot (Unsafe!)' \ + 'r' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + m) + # select a kernel from the menu + select_os_boot_option + ;; + u) + exec /bin/usb-init + ;; + i) + force_unsafe_boot + ;; + r) ;; + esac } -show_tpm_totp_hotp_options_menu() -{ - TRACE_FUNC - whiptail_type $BG_COLOR_MAIN_MENU --title "TPM/TOTP/HOTP Options" \ - --menu "Select An Option" 0 80 10 \ - 'g' ' Generate new TOTP/HOTP secret' \ - 'r' ' Reset the TPM' \ - 't' ' TOTP/HOTP does not match after refresh, troubleshoot' \ - 'm' ' <-- Return to main menu' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - option=$(cat /tmp/whiptail) - case "$option" in - g ) - generate_totp_hotp && reseal_tpm_disk_decryption_key - ;; - r ) - reset_tpm && reseal_tpm_disk_decryption_key - ;; - t ) - prompt_totp_mismatch - ;; - m ) - ;; - esac +show_tpm_totp_hotp_options_menu() { + TRACE_FUNC + whiptail_type $BG_COLOR_MAIN_MENU --title "TPM/TOTP/HOTP Options" \ + --menu "Select An Option" 0 80 10 \ + 'g' ' Generate new TOTP/HOTP secret' \ + 'r' ' Reset the TPM' \ + 't' ' TOTP/HOTP does not match after refresh, troubleshoot' \ + 'm' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + option=$(cat /tmp/whiptail) + case "$option" in + g) + generate_totp_hotp && reseal_tpm_disk_decryption_key + ;; + r) + reset_tpm && reseal_tpm_disk_decryption_key + ;; + t) + prompt_totp_mismatch + ;; + m) ;; + esac } -prompt_totp_mismatch() -{ - TRACE_FUNC - if (whiptail_warning --title "TOTP/HOTP code mismatched" \ - --yesno "TOTP/HOTP code mismatches could indicate TPM tampering or clock drift.\n\nThe current UTC time is: $(date "+%Y-%m-%d %H:%M:%S")\nIf this is incorrect, set the correct time and check TOTP/HOTP again.\n\nDo you want to change the time?" 0 80) then - change-time.sh - fi +prompt_totp_mismatch() { + TRACE_FUNC + if (whiptail_warning --title "TOTP/HOTP code mismatched" \ + --yesno "TOTP/HOTP code mismatches could indicate TPM tampering or clock drift.\n\nThe current UTC time is: $(date "+%Y-%m-%d %H:%M:%S")\nIf this is incorrect, set the correct time and check TOTP/HOTP again.\n\nDo you want to change the time?" 0 80); then + change-time.sh + fi } -reset_tpm() -{ - TRACE_FUNC - if [ "$CONFIG_TPM" = "y" ]; then - if (whiptail_warning --title 'Reset the TPM' \ - --yesno "This will clear the TPM and replace its Owner password with a new one!\n\nDo you want to proceed?" 0 80) then - - if ! prompt_new_owner_password; then - echo "Press Enter to return to the menu..." - read - echo - return 1 - fi - - tpmr reset "$tpm_owner_password" - - # now that the TPM is reset, remove invalid TPM counter files - mount_boot - mount -o rw,remount /boot - LOG "Removing rollback and primary handle hash under /boot" - rm -f /boot/kexec_rollback.txt - rm -f /boot/kexec_primhdl_hash.txt - - # create Heads TPM counter before any others - check_tpm_counter /boot/kexec_rollback.txt "" "$tpm_owner_password" \ - || die "Unable to find/create tpm counter" - counter="$TPM_COUNTER" - - increment_tpm_counter $counter > /dev/null 2>&1 \ - || die "Unable to increment tpm counter" - - sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ - || die "Unable to create rollback file" - - warn "boot content has been modified, please update the checksums and sign the files from Options -> Update checksums and sign all files in /boot" - mount -o ro,remount /boot - - generate_totp_hotp "$tpm_owner_password" - else - echo "Returning to the main menu" - fi - else - whiptail_error --title 'ERROR: No TPM Detected' --msgbox "This device does not have a TPM.\n\nPress OK to return to the Main Menu" 0 80 - fi +reset_tpm() { + TRACE_FUNC + if [ "$CONFIG_TPM" = "y" ]; then + if (whiptail_warning --title 'Reset the TPM' \ + --yesno "This will clear the TPM and replace its Owner password with a new one!\n\nDo you want to proceed?" 0 80); then + + if ! prompt_new_owner_password; then + echo "Press Enter to return to the menu..." + read + echo + return 1 + fi + + tpmr reset "$tpm_owner_password" + + # now that the TPM is reset, remove invalid TPM counter files + mount_boot + mount -o rw,remount /boot + #TODO: this is really problematic, we should really remove the primary handle hash + + LOG "Removing rollback and primary handle hash under /boot" + rm -f /boot/kexec_rollback.txt + rm -f /boot/kexec_primhdl_hash.txt + + # create Heads TPM counter before any others + check_tpm_counter /boot/kexec_rollback.txt "" "$tpm_owner_password" || + die "Unable to find/create tpm counter" + counter="$TPM_COUNTER" + + increment_tpm_counter $counter >/dev/null 2>&1 || + die "Unable to increment tpm counter" + + sha256sum /tmp/counter-$counter >/boot/kexec_rollback.txt || + die "Unable to create rollback file" + + # As a countermeasure for existing primary handle hash, we will now force sign /boot without it + if (whiptail --title 'TPM Reset Successfully' \ + --yesno "Would you like to update the checksums and sign all of the files in /boot?\n\nYou will need your GPG key to continue and this will modify your disk.\n\nOtherwise the system will reboot immediately." 0 80); then + if ! update_checksums; then + whiptail_error --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + fi + else + die "TPM reset successful, but user chose not to update checksums" + fi + mount -o ro,remount /boot + + generate_totp_hotp "$tpm_owner_password" + else + echo "Returning to the main menu" + fi + else + whiptail_error --title 'ERROR: No TPM Detected' --msgbox "This device does not have a TPM.\n\nPress OK to return to the Main Menu" 0 80 + fi } -select_os_boot_option() -{ - TRACE_FUNC - mount_boot - if verify_global_hashes ; then - kexec-select-boot -m -b /boot -c "grub.cfg" -g - fi +select_os_boot_option() { + TRACE_FUNC + mount_boot + if verify_global_hashes; then + kexec-select-boot -m -b /boot -c "grub.cfg" -g + fi } -attempt_default_boot() -{ - TRACE_FUNC - mount_boot - - if ! verify_global_hashes; then - return - fi - DEFAULT_FILE=`find /boot/kexec_default.*.txt 2>/dev/null | head -1` - if [ -r "$DEFAULT_FILE" ]; then - kexec-select-boot -b /boot -c "grub.cfg" -g \ - || recovery "Failed default boot" - elif (whiptail_warning --title 'No Default Boot Option Configured' \ - --yesno "There is no default boot option configured yet.\nWould you like to load a menu of boot options?\nOtherwise you will return to the main menu." 0 80) then - kexec-select-boot -m -b /boot -c "grub.cfg" -g - fi +attempt_default_boot() { + TRACE_FUNC + mount_boot + + if ! verify_global_hashes; then + return + fi + DEFAULT_FILE=$(find /boot/kexec_default.*.txt 2>/dev/null | head -1) + if [ -r "$DEFAULT_FILE" ]; then + kexec-select-boot -b /boot -c "grub.cfg" -g || + recovery "Failed default boot" + elif (whiptail_warning --title 'No Default Boot Option Configured' \ + --yesno "There is no default boot option configured yet.\nWould you like to load a menu of boot options?\nOtherwise you will return to the main menu." 0 80); then + kexec-select-boot -m -b /boot -c "grub.cfg" -g + fi } -force_unsafe_boot() -{ - TRACE_FUNC - if [ "$CONFIG_RESTRICTED_BOOT" = y ]; then - whiptail_error --title 'ERROR: Restricted Boot Enabled' --msgbox "Restricted Boot is Enabled, forced boot not allowed.\n\nPress OK to return to the Main Menu" 0 80 - return - fi - # Run the menu selection in "force" mode, bypassing hash checks - if (whiptail_warning --title 'Unsafe Forced Boot Selected!' \ - --yesno "WARNING: You have chosen to skip all tamper checks and boot anyway.\n\nThis is an unsafe option!\n\nDo you want to proceed?" 0 80) then - mount_boot && kexec-select-boot -m -b /boot -c "grub.cfg" -g -f - fi +force_unsafe_boot() { + TRACE_FUNC + if [ "$CONFIG_RESTRICTED_BOOT" = y ]; then + whiptail_error --title 'ERROR: Restricted Boot Enabled' --msgbox "Restricted Boot is Enabled, forced boot not allowed.\n\nPress OK to return to the Main Menu" 0 80 + return + fi + # Run the menu selection in "force" mode, bypassing hash checks + if (whiptail_warning --title 'Unsafe Forced Boot Selected!' \ + --yesno "WARNING: You have chosen to skip all tamper checks and boot anyway.\n\nThis is an unsafe option!\n\nDo you want to proceed?" 0 80); then + mount_boot && kexec-select-boot -m -b /boot -c "grub.cfg" -g -f + fi } # gui-init start @@ -650,16 +638,16 @@ else fi if [ -x /bin/hotp_verification ]; then - enable_usb + enable_usb fi -if detect_boot_device ; then - # /boot device with installed OS found - clean_boot_check +if detect_boot_device; then + # /boot device with installed OS found + clean_boot_check else - # can't determine /boot device or no OS installed, - # so fall back to interactive selection - mount_boot + # can't determine /boot device or no OS installed, + # so fall back to interactive selection + mount_boot fi # detect whether any GPG keys exist in the keyring, if not, initialize that first @@ -670,13 +658,13 @@ update_totp update_hotp if [ "$HOTP" = "Success" -a -n "$CONFIG_AUTO_BOOT_TIMEOUT" ]; then - prompt_auto_default_boot + prompt_auto_default_boot fi while true; do - TRACE_FUNC - skip_to_menu="false" - show_main_menu + TRACE_FUNC + skip_to_menu="false" + show_main_menu done recovery "Something failed during boot" diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 60215506b..7a45c9f8c 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -115,15 +115,18 @@ verify_global_hashes() { verify_rollback_counter() { TRACE_FUNC TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2) + + DEBUG "TPM_COUNTER: $TPM_COUNTER found in $TMP_ROLLBACK_FILE" + if [ -z "$TPM_COUNTER" ]; then die "$TMP_ROLLBACK_FILE: TPM counter not found?" fi - read_tpm_counter $TPM_COUNTER > /dev/null 2>&1 || + read_tpm_counter $TPM_COUNTER >/dev/null 2>&1 || die "Failed to read TPM counter" sha256sum -c $TMP_ROLLBACK_FILE || - die "Invalid TPM counter state" + die "Invalid TPM counter state. TPM Reset required" valid_rollback="y" } @@ -268,7 +271,7 @@ default_select() { if [ "$CONFIG_BASIC" != "y" ]; then # Enforce that default option hashes are valid - echo "+++ Checking verified default boot hash file " + LOG "+++ Checking verified default boot hash file " # Check the hashes of all the files if (cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" >/tmp/hash_output); then echo "+++ Verified default boot hashes " diff --git a/initrd/bin/kexec-sign-config b/initrd/bin/kexec-sign-config index d0d66c69e..52e6add6d 100755 --- a/initrd/bin/kexec-sign-config +++ b/initrd/bin/kexec-sign-config @@ -10,10 +10,13 @@ rollback="n" update="n" while getopts "p:c:ur" arg; do case $arg in - p) paramsdir="$OPTARG" ;; - c) counter="$OPTARG"; rollback="y" ;; - u) update="y" ;; - r) rollback="y" ;; + p) paramsdir="$OPTARG" ;; + c) + counter="$OPTARG" + rollback="y" + ;; + u) update="y" ;; + r) rollback="y" ;; esac done @@ -34,14 +37,14 @@ mount -o remount,rw /boot if [ "$update" = "y" ]; then ( cd /boot - find ./ -type f ! -path './kexec*' -print0 | xargs -0 sha256sum > /boot/kexec_hashes.txt + find ./ -type f ! -path './kexec*' -print0 | xargs -0 sha256sum >/boot/kexec_hashes.txt if [ -e /boot/kexec_default_hashes.txt ]; then DEFAULT_FILES=$(cat /boot/kexec_default_hashes.txt | cut -f3 -d ' ') - echo $DEFAULT_FILES | xargs sha256sum > /boot/kexec_default_hashes.txt + echo $DEFAULT_FILES | xargs sha256sum >/boot/kexec_default_hashes.txt fi #also save the file & directory structure to detect added files - print_tree > /boot/kexec_tree.txt + print_tree >/boot/kexec_tree.txt ) [ $? -eq 0 ] || die "$paramsdir: Failed to update hashes." @@ -55,23 +58,23 @@ if [ "$rollback" = "y" ]; then if [ -n "$counter" ]; then # use existing counter - read_tpm_counter $counter \ - || die "$paramsdir: Unable to read tpm counter '$counter'" + read_tpm_counter $counter >/dev/null 2>&1 || + die "$paramsdir: Unable to read tpm counter '$counter'" else # increment counter - check_tpm_counter $rollback_file \ - || die "$paramsdir: Unable to find/create tpm counter" + check_tpm_counter $rollback_file >/dev/null 2>&1 || + die "$paramsdir: Unable to find/create tpm counter" counter="$TPM_COUNTER" - increment_tpm_counter $counter \ - || die "$paramsdir: Unable to increment tpm counter" + increment_tpm_counter $counter >/dev/null 2>&1 || + die "$paramsdir: Unable to increment tpm counter" fi - sha256sum /tmp/counter-$counter > $rollback_file \ - || die "$paramsdir: Unable to create rollback file" + sha256sum /tmp/counter-$counter >$rollback_file || + die "$paramsdir: Unable to create rollback file" fi -param_files=`find $paramsdir/kexec*.txt` +param_files=$(find $paramsdir/kexec*.txt) if [ -z "$param_files" ]; then die "$paramsdir: No kexec parameter files to sign" fi @@ -80,8 +83,8 @@ for tries in 1 2 3; do if sha256sum $param_files | gpg \ --detach-sign \ -a \ - > $paramsdir/kexec.sig \ - ; then + >$paramsdir/kexec.sig \ + ; then # successful - update the validated params check_config $paramsdir diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 58ab1e599..b4e33e6c0 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -547,7 +547,7 @@ gpg_key_factory_reset() { #enable usb storage enable_usb - + # Factory reset GPG card echo "GPG factory reset of USB Security dongle's OpenPGP smartcard..." { diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 9c01d5d60..7600d03fd 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -65,6 +65,10 @@ mount_boot || exit 1 counter_value=1 enable_usb + +# Make sure no conflicting GPG related services are running, gpg-agent will respawn +killall gpg-agent scdaemon >/dev/null 2>&1 + # While making sure the key is inserted, capture the status so we can check how # many PIN attempts remain if ! hotp_token_info="$(hotp_verification info)"; then @@ -162,8 +166,8 @@ if [ "$admin_pin_status" -ne 0 ]; then fi else # remind user to change admin password - warn "Weak OEM default PINs are under use to enforce remote attestation/encryption/signature operations" - warn "$CONFIG_BRAND_NAME security is compromised until the ownership of this device is re-established by changing secrets by non-default values" + warn "Weak OEM default PINs are under use to enforce remote attestation/encryption/signature operations" + warn "$CONFIG_BRAND_NAME security is compromised until the ownership of this device is re-established by changing secrets by non-default values" warn "You must change current default secrets through 'Options -> OEM Factory Reset/Re-Ownership' menu and not accept the default options" warn "You will be asked to answer a questionnaire to re-own your device and USB security dongles with new secrets" fi diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 7dbe50432..14e595fc1 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -651,7 +651,7 @@ tpm1_unseal() { -sz "$sealed_size" \ -of "$sealed_file" || die "Unable to read sealed file from TPM NVRAM" - # TODO: Cannot log + exit instead of dying!?! + # TODO: Cannot log + exit instead of dying!?! PASS_ARGS=() if [ "$pass" ]; then diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index c55ae7516..e60c58465 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -75,6 +75,13 @@ preserve_rom() { } confirm_gpg_card() { + + #TODO: ideally, we ask for confirmation only once per boot session + #TODO: even change logic here to try first and then ask user to confirm if not found + #TODO: or ask GPG user PIN once and cache it for the rest of the boot session for reusal + # This is getting in the way of unattended stuff and GPG prompts are confusing anyway, hide them from user. + + TRACE "Under /etc/ash_functions:confirm_gpg_card" #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry #TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config? From a54a4b8afabe21cd56eb985e39c2e272681b8a0e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 13 Dec 2024 17:20:52 -0500 Subject: [PATCH 42/81] hot-verification: bump to 1.7+ unrelease patchset https://github.com/Nitrokey/nitrokey-hotp-verification/pull/51 I give up trying to make Nitrokey do the right thing. They will propose PR to Heads next to fix their own fixes for their own caused regressions and security vulns. I just stopped caring for sanity reasons, i'm making quiet+eom/user-reownership fixes for feature freeze. If nitrokey pays, there is gonna be future collaboration, if they don't, they will do Heads related stuff themselves. Signed-off-by: Thierry Laurion --- modules/hotp-verification | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/hotp-verification b/modules/hotp-verification index d9511d2a8..032c80903 100644 --- a/modules/hotp-verification +++ b/modules/hotp-verification @@ -2,12 +2,12 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification hotp-verification_depends := libusb $(musl_dep) -# v1.7 -hotp-verification_version := e6cf719d67a811356eecff69769fa1dbce47f953 +# v1.7 + non-released stuff under 1.7 version bump (Nitrokey will do PR to change this in the future and also fixes to Heads related to regression fixes under Heads) +hotp-verification_version := f4583b701a354dfa50c690075a568bc5cdf160e1 hotp-verification_dir := hotp-verification-$(hotp-verification_version) hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz -hotp-verification_hash := 3c8b44e4d9a1f7454269f76102f32de6ed9de19ab0cf7119747eb97377c66a84 +hotp-verification_hash := 42efeba9a61e4a00df55bf5337c157948bc76c895410fc76d02b87d6cd3b38eb hotp-verification_target := \ $(MAKE_JOBS) \ From 4354cd4c229aa7b15d1c56f91aacee5679e13692 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 15 Dec 2024 20:41:08 -0500 Subject: [PATCH 43/81] config-gui.sh: Add quiet mode toggle, which turns off debug+tracing if enabled, and where enabling debug+tracing disables Quiet mode Signed-off-by: Thierry Laurion --- initrd/bin/config-gui.sh | 1088 +++++++++++++++++++------------------- 1 file changed, 558 insertions(+), 530 deletions(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index b09860ea6..f3299d1aa 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -13,329 +13,334 @@ param=$1 # Read the current ROM; if it fails display an error and exit. read_rom() { - /bin/flash.sh -r "$1" - if [ ! -s "$1" ]; then - whiptail_error --title 'ERROR: BIOS Read Failed!' \ - --msgbox "Unable to read BIOS" 0 80 - exit 1 - fi + /bin/flash.sh -r "$1" + if [ ! -s "$1" ]; then + whiptail_error --title 'ERROR: BIOS Read Failed!' \ + --msgbox "Unable to read BIOS" 0 80 + exit 1 + fi } while true; do - if [ ! -z "$param" ]; then - # use first char from parameter - menu_choice=${param::1} - unset param - else - # Re-source config because we change it when an option is toggled - . /tmp/config - - dynamic_config_options=( - 'b' ' Change the /boot device' - ) - - # Options that don't apply to basic mode - [ "$CONFIG_BASIC" != "y" ] && dynamic_config_options+=( - 'r' ' Clear GPG key(s) and reset all user settings' - 'R' ' Change the root device for hashing' - 'D' ' Change the root directories to hash' - 'B' " $(get_config_display_action "$CONFIG_ROOT_CHECK_AT_BOOT") root check at boot" - 'L' " $(get_config_display_action "$CONFIG_RESTRICTED_BOOT") Restricted Boot" - ) - - # Basic itself is always available (though RB will refuse to enable it) - dynamic_config_options+=( - 'P' " $(get_config_display_action "$CONFIG_BASIC") $CONFIG_BRAND_NAME Basic Mode" - ) - - # Blob jail is only offered if this is a configuration with the blobs in - # firmware - [ "$CONFIG_SUPPORT_BLOB_JAIL" = "y" ] && dynamic_config_options+=( - 'J' " $(get_config_display_action "$CONFIG_USE_BLOB_JAIL") Firmware Blob Jail" - ) - - # Automatic boot - dynamic_config_options+=( - 'M' " Configure automatic boot" - ) - - # Basic-only options for automatic boot - [ "$CONFIG_BASIC" = "y" ] && dynamic_config_options+=( - 'A' " $(get_inverted_config_display_action "$CONFIG_BASIC_NO_AUTOMATIC_DEFAULT") automatic default boot option" - 'U' " $(get_config_display_action "$CONFIG_BASIC_USB_AUTOBOOT") USB automatic boot" - ) - - # Automatic power on - requires board support - [ "$CONFIG_SUPPORT_AUTOMATIC_POWERON" = "y" ] && dynamic_config_options+=( - 'N' " $(get_config_display_action "$CONFIG_AUTOMATIC_POWERON") automatic power-on" - ) - - # Boards with built-in keyboards can support optional USB keyboards as well. - # Boards that do not have a built-in keyboard/internal keyboard is USB connected export - # CONFIG_USB_KEYBOARD_REQUIRED=y; this hides the config option and ensures - # USB keyboard support always loads. - [ "$CONFIG_USB_KEYBOARD_REQUIRED" != y ] && dynamic_config_options+=( - 'K' " $(get_config_display_action "$CONFIG_USER_USB_KEYBOARD") USB keyboard" - ) - - # Debugging option always available - dynamic_config_options+=( - 'Z' " $(get_config_display_action "$CONFIG_DEBUG_OUTPUT") $CONFIG_BRAND_NAME debug and function tracing output" - ) - - [ "$CONFIG_FINALIZE_PLATFORM_LOCKING" = "y" ] && dynamic_config_options+=( - 't' ' Deactivate Platform Locking to permit OS write access to firmware' - ) - - dynamic_config_options+=( - 's' ' Save the current configuration to the running BIOS' \ - 'x' ' Return to Main Menu' - ) - - unset menu_choice - whiptail_type $BG_COLOR_MAIN_MENU --title "Config Management Menu" \ - --menu "This menu lets you change settings for the current BIOS session.\n\nAll changes will revert after a reboot,\n\nunless you also save them to the running BIOS." 0 80 10 \ - "${dynamic_config_options[@]}" \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - menu_choice=$(cat /tmp/whiptail) - fi - - case "$menu_choice" in - "t" ) - unset CONFIG_FINALIZE_PLATFORM_LOCKING - replace_config /etc/config.user "CONFIG_FINALIZE_PLATFORM_LOCKING" "n" - combine_configs - . /tmp/config - ;; - "x" ) - exit 0 - ;; - "b" ) - CURRENT_OPTION="$(load_config_value CONFIG_BOOT_DEV)" - if ! fdisk -l | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" > /tmp/disklist.txt ; then - whiptail_error --title 'ERROR: No bootable devices found' \ - --msgbox " $ERROR\n\n" 0 80 - exit 1 - fi - # filter out extraneous options - > /tmp/boot_device_list.txt - for i in `cat /tmp/disklist.txt`; do - # remove block device from list if numeric partitions exist, since not bootable - DEV_NUM_PARTITIONS=$((`ls -1 $i* | wc -l`-1)) - if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then - echo $i >> /tmp/boot_device_list.txt - else - ls $i* | tail -${DEV_NUM_PARTITIONS} >> /tmp/boot_device_list.txt - fi - done - file_selector "/tmp/boot_device_list.txt" \ - "Choose the default /boot device.\n\n${CURRENT_OPTION:+\n\nCurrently set to }$CURRENT_OPTION." \ - "Boot Device Selection" - if [ "$FILE" == "" ]; then - return - else - SELECTED_FILE=$FILE - fi - - # unmount /boot if needed - if grep -q /boot /proc/mounts ; then - umount /boot 2>/dev/null - fi - # mount newly selected /boot device - if ! mount -o ro $SELECTED_FILE /boot 2>/tmp/error ; then - ERROR=`cat /tmp/error` - whiptail_error --title 'ERROR: unable to mount /boot' \ - --msgbox " $ERROR\n\n" 0 80 - exit 1 - fi - - set_config /etc/config.user "CONFIG_BOOT_DEV" "$SELECTED_FILE" - combine_configs - - whiptail --title 'Config change successful' \ - --msgbox "The /boot device was successfully changed to $SELECTED_FILE" 0 80 - ;; - "s" ) - read_rom /tmp/config-gui.rom - - replace_rom_file /tmp/config-gui.rom "heads/initrd/etc/config.user" /etc/config.user - - if (whiptail --title 'Update ROM?' \ - --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 0 80) then - /bin/flash.sh /tmp/config-gui.rom - whiptail --title 'BIOS Updated Successfully' \ - --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 0 80 - /bin/reboot - else - exit 0 - fi - ;; - "r" ) - # prompt for confirmation - if (whiptail_warning --title 'Reset Configuration?' \ - --yesno "This will clear all GPG keys, clear boot signatures and checksums, + if [ ! -z "$param" ]; then + # use first char from parameter + menu_choice=${param::1} + unset param + else + # Re-source config because we change it when an option is toggled + . /tmp/config + + dynamic_config_options=( + 'b' ' Change the /boot device' + ) + + # Options that don't apply to basic mode + [ "$CONFIG_BASIC" != "y" ] && dynamic_config_options+=( + 'r' ' Clear GPG key(s) and reset all user settings' + 'R' ' Change the root device for hashing' + 'D' ' Change the root directories to hash' + 'B' " $(get_config_display_action "$CONFIG_ROOT_CHECK_AT_BOOT") root check at boot" + 'L' " $(get_config_display_action "$CONFIG_RESTRICTED_BOOT") Restricted Boot" + ) + + # Basic itself is always available (though RB will refuse to enable it) + dynamic_config_options+=( + 'P' " $(get_config_display_action "$CONFIG_BASIC") $CONFIG_BRAND_NAME Basic Mode" + ) + + # Blob jail is only offered if this is a configuration with the blobs in + # firmware + [ "$CONFIG_SUPPORT_BLOB_JAIL" = "y" ] && dynamic_config_options+=( + 'J' " $(get_config_display_action "$CONFIG_USE_BLOB_JAIL") Firmware Blob Jail" + ) + + # Automatic boot + dynamic_config_options+=( + 'M' " Configure automatic boot" + ) + + # Basic-only options for automatic boot + [ "$CONFIG_BASIC" = "y" ] && dynamic_config_options+=( + 'A' " $(get_inverted_config_display_action "$CONFIG_BASIC_NO_AUTOMATIC_DEFAULT") automatic default boot option" + 'U' " $(get_config_display_action "$CONFIG_BASIC_USB_AUTOBOOT") USB automatic boot" + ) + + # Automatic power on - requires board support + [ "$CONFIG_SUPPORT_AUTOMATIC_POWERON" = "y" ] && dynamic_config_options+=( + 'N' " $(get_config_display_action "$CONFIG_AUTOMATIC_POWERON") automatic power-on" + ) + + # Boards with built-in keyboards can support optional USB keyboards as well. + # Boards that do not have a built-in keyboard/internal keyboard is USB connected export + # CONFIG_USB_KEYBOARD_REQUIRED=y; this hides the config option and ensures + # USB keyboard support always loads. + [ "$CONFIG_USB_KEYBOARD_REQUIRED" != y ] && dynamic_config_options+=( + 'K' " $(get_config_display_action "$CONFIG_USER_USB_KEYBOARD") USB keyboard" + ) + + # Debugging option always available + dynamic_config_options+=( + 'Z' " $(get_config_display_action "$CONFIG_DEBUG_OUTPUT") $CONFIG_BRAND_NAME debug and function tracing output" + ) + + # Quiet option always available + dynamic_config_options+=( + 'Q' " $(get_config_display_action "$CONFIG_QUIET_MODE") $CONFIG_BRAND_NAME quiet mode" + ) + + [ "$CONFIG_FINALIZE_PLATFORM_LOCKING" = "y" ] && dynamic_config_options+=( + 't' ' Deactivate Platform Locking to permit OS write access to firmware' + ) + + dynamic_config_options+=( + 's' ' Save the current configuration to the running BIOS' + 'x' ' Return to Main Menu' + ) + + unset menu_choice + whiptail_type $BG_COLOR_MAIN_MENU --title "Config Management Menu" \ + --menu "This menu lets you change settings for the current BIOS session.\n\nAll changes will revert after a reboot,\n\nunless you also save them to the running BIOS." 0 80 10 \ + "${dynamic_config_options[@]}" \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + menu_choice=$(cat /tmp/whiptail) + fi + + case "$menu_choice" in + "t") + unset CONFIG_FINALIZE_PLATFORM_LOCKING + replace_config /etc/config.user "CONFIG_FINALIZE_PLATFORM_LOCKING" "n" + combine_configs + . /tmp/config + ;; + "x") + exit 0 + ;; + "b") + CURRENT_OPTION="$(load_config_value CONFIG_BOOT_DEV)" + if ! fdisk -l | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist.txt; then + whiptail_error --title 'ERROR: No bootable devices found' \ + --msgbox " $ERROR\n\n" 0 80 + exit 1 + fi + # filter out extraneous options + >/tmp/boot_device_list.txt + for i in $(cat /tmp/disklist.txt); do + # remove block device from list if numeric partitions exist, since not bootable + DEV_NUM_PARTITIONS=$(($(ls -1 $i* | wc -l) - 1)) + if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then + echo $i >>/tmp/boot_device_list.txt + else + ls $i* | tail -${DEV_NUM_PARTITIONS} >>/tmp/boot_device_list.txt + fi + done + file_selector "/tmp/boot_device_list.txt" \ + "Choose the default /boot device.\n\n${CURRENT_OPTION:+\n\nCurrently set to }$CURRENT_OPTION." \ + "Boot Device Selection" + if [ "$FILE" == "" ]; then + return + else + SELECTED_FILE=$FILE + fi + + # unmount /boot if needed + if grep -q /boot /proc/mounts; then + umount /boot 2>/dev/null + fi + # mount newly selected /boot device + if ! mount -o ro $SELECTED_FILE /boot 2>/tmp/error; then + ERROR=$(cat /tmp/error) + whiptail_error --title 'ERROR: unable to mount /boot' \ + --msgbox " $ERROR\n\n" 0 80 + exit 1 + fi + + set_config /etc/config.user "CONFIG_BOOT_DEV" "$SELECTED_FILE" + combine_configs + + whiptail --title 'Config change successful' \ + --msgbox "The /boot device was successfully changed to $SELECTED_FILE" 0 80 + ;; + "s") + read_rom /tmp/config-gui.rom + + replace_rom_file /tmp/config-gui.rom "heads/initrd/etc/config.user" /etc/config.user + + if (whiptail --title 'Update ROM?' \ + --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 0 80); then + /bin/flash.sh /tmp/config-gui.rom + whiptail --title 'BIOS Updated Successfully' \ + --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 0 80 + /bin/reboot + else + exit 0 + fi + ;; + "r") + # prompt for confirmation + if (whiptail_warning --title 'Reset Configuration?' \ + --yesno "This will clear all GPG keys, clear boot signatures and checksums, \nreset the /boot device, clear/reset the TPM (if present), \nand reflash your BIOS with the cleaned configuration. - \n\nDo you want to proceed?" 0 80) then - read_rom /tmp/config-gui.rom - # clear local keyring - rm -rf /.gnupg/* || true - - # clear /boot signatures/checksums - detect_boot_device - mount -o remount,rw /boot - rm -f /boot/kexec* || true - mount -o remount,ro /boot - - # clear GPG keys and user settings - for i in `cbfs.sh -o /tmp/config-gui.rom -l | grep -e "heads/"`; do - cbfs.sh -o /tmp/config-gui.rom -d $i - done - # flash cleared ROM - /bin/flash.sh -c /tmp/config-gui.rom - - # reset TPM if present - if [ "$CONFIG_TPM" = "y" ]; then - /bin/tpm-reset - fi - whiptail --title 'Configuration Reset Updated Successfully' \ - --msgbox "Configuration reset and BIOS updated successfully.\n\nPress Enter to reboot" 0 80 - /bin/reboot - else - exit 0 - fi - ;; - "R" ) - CURRENT_OPTION="$(load_config_value CONFIG_ROOT_DEV)" - fdisk -l | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" > /tmp/disklist.txt - # filter out extraneous options - > /tmp/root_device_list.txt - for i in `cat /tmp/disklist.txt`; do - # remove block device from list if numeric partitions exist, since not bootable - DEV_NUM_PARTITIONS=$((`ls -1 $i* | wc -l`-1)) - if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then - echo $i >> /tmp/root_device_list.txt - else - ls $i* | tail -${DEV_NUM_PARTITIONS} >> /tmp/root_device_list.txt - fi - done - file_selector "/tmp/root_device_list.txt" \ - "Choose the default root device.${CURRENT_OPTION:+\n\nCurrently set to }$CURRENT_OPTION." \ - "Root Device Selection" - if [ "$FILE" == "" ]; then - break - else - SELECTED_FILE=$FILE - fi - - set_config /etc/config.user "CONFIG_ROOT_DEV" "$SELECTED_FILE" - combine_configs - - whiptail --title 'Config change successful' \ - --msgbox "The root device was successfully changed to $SELECTED_FILE" 0 80 - ;; - "D" ) - CURRENT_OPTION="$(load_config_value CONFIG_ROOT_DIRLIST)" - - # Separate from prior prompt history on the terminal with two blanks - echo -e "\n" - - if [ -n "$CURRENT_OPTION" ]; then - echo -e "The current list of directories to hash is $CURRENT_OPTION" - fi - echo -e "Enter the new list of directories separated by spaces:" - echo -e "(Press enter with the list empty to cancel)" - read -r NEW_CONFIG_ROOT_DIRLIST - - # strip any leading forward slashes - NEW_CONFIG_ROOT_DIRLIST=$(echo $NEW_CONFIG_ROOT_DIRLIST | sed -e 's/^\///;s/ \// /g') - - #check if list empty - if [ -z "$NEW_CONFIG_ROOT_DIRLIST" ] ; then - whiptail --title 'Config change canceled' \ - --msgbox "Root device directory change canceled by user" 0 80 - break - fi - - set_config /etc/config.user "CONFIG_ROOT_DIRLIST" "$NEW_CONFIG_ROOT_DIRLIST" - combine_configs - - whiptail --title 'Config change successful' \ - --msgbox "The root directories to hash was successfully changed to:\n$NEW_CONFIG_ROOT_DIRLIST" 0 80 - ;; - "B" ) - if [ "$CONFIG_ROOT_CHECK_AT_BOOT" != "y" ]; then - # Root device and directories must be set to enable this - if [ -z "$CONFIG_ROOT_DEV" ] || [ -z "$CONFIG_ROOT_DIRLIST" ]; then - whiptail_error --title 'Root Check Not Configured' \ - --msgbox "Set the root device and directories to hash before enabling this feature." 0 80 - elif (whiptail --title 'Enable Root Hash Check at Boot?' \ - --yesno "This will enable checking root hashes each time you boot. + \n\nDo you want to proceed?" 0 80); then + read_rom /tmp/config-gui.rom + # clear local keyring + rm -rf /.gnupg/* || true + + # clear /boot signatures/checksums + detect_boot_device + mount -o remount,rw /boot + rm -f /boot/kexec* || true + mount -o remount,ro /boot + + # clear GPG keys and user settings + for i in $(cbfs.sh -o /tmp/config-gui.rom -l | grep -e "heads/"); do + cbfs.sh -o /tmp/config-gui.rom -d $i + done + # flash cleared ROM + /bin/flash.sh -c /tmp/config-gui.rom + + # reset TPM if present + if [ "$CONFIG_TPM" = "y" ]; then + /bin/tpm-reset + fi + whiptail --title 'Configuration Reset Updated Successfully' \ + --msgbox "Configuration reset and BIOS updated successfully.\n\nPress Enter to reboot" 0 80 + /bin/reboot + else + exit 0 + fi + ;; + "R") + CURRENT_OPTION="$(load_config_value CONFIG_ROOT_DEV)" + fdisk -l | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist.txt + # filter out extraneous options + >/tmp/root_device_list.txt + for i in $(cat /tmp/disklist.txt); do + # remove block device from list if numeric partitions exist, since not bootable + DEV_NUM_PARTITIONS=$(($(ls -1 $i* | wc -l) - 1)) + if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then + echo $i >>/tmp/root_device_list.txt + else + ls $i* | tail -${DEV_NUM_PARTITIONS} >>/tmp/root_device_list.txt + fi + done + file_selector "/tmp/root_device_list.txt" \ + "Choose the default root device.${CURRENT_OPTION:+\n\nCurrently set to }$CURRENT_OPTION." \ + "Root Device Selection" + if [ "$FILE" == "" ]; then + break + else + SELECTED_FILE=$FILE + fi + + set_config /etc/config.user "CONFIG_ROOT_DEV" "$SELECTED_FILE" + combine_configs + + whiptail --title 'Config change successful' \ + --msgbox "The root device was successfully changed to $SELECTED_FILE" 0 80 + ;; + "D") + CURRENT_OPTION="$(load_config_value CONFIG_ROOT_DIRLIST)" + + # Separate from prior prompt history on the terminal with two blanks + echo -e "\n" + + if [ -n "$CURRENT_OPTION" ]; then + echo -e "The current list of directories to hash is $CURRENT_OPTION" + fi + echo -e "Enter the new list of directories separated by spaces:" + echo -e "(Press enter with the list empty to cancel)" + read -r NEW_CONFIG_ROOT_DIRLIST + + # strip any leading forward slashes + NEW_CONFIG_ROOT_DIRLIST=$(echo $NEW_CONFIG_ROOT_DIRLIST | sed -e 's/^\///;s/ \// /g') + + #check if list empty + if [ -z "$NEW_CONFIG_ROOT_DIRLIST" ]; then + whiptail --title 'Config change canceled' \ + --msgbox "Root device directory change canceled by user" 0 80 + break + fi + + set_config /etc/config.user "CONFIG_ROOT_DIRLIST" "$NEW_CONFIG_ROOT_DIRLIST" + combine_configs + + whiptail --title 'Config change successful' \ + --msgbox "The root directories to hash was successfully changed to:\n$NEW_CONFIG_ROOT_DIRLIST" 0 80 + ;; + "B") + if [ "$CONFIG_ROOT_CHECK_AT_BOOT" != "y" ]; then + # Root device and directories must be set to enable this + if [ -z "$CONFIG_ROOT_DEV" ] || [ -z "$CONFIG_ROOT_DIRLIST" ]; then + whiptail_error --title 'Root Check Not Configured' \ + --msgbox "Set the root device and directories to hash before enabling this feature." 0 80 + elif (whiptail --title 'Enable Root Hash Check at Boot?' \ + --yesno "This will enable checking root hashes each time you boot. \nDepending on the directories you are checking, this might add \na minute or more to the boot time. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_ROOT_CHECK_AT_BOOT" "y" - - # check that root hash file exists - if [ ! -f ${ROOT_HASH_FILE} ]; then - if (whiptail --title 'Generate Root Hash File' \ - --yesno "\nNo root hash file exists. - \nWould you like to create the initial hash file now?" 0 80) then - root-hashes-gui.sh -n - fi - fi - - whiptail --title 'Config change successful' \ - --msgbox "The root device will be checked at each boot." 0 80 - - fi - else - if (whiptail --title 'Disable Root Hash Check at Boot?' \ - --yesno "This will disable checking root hashes each time you boot. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_ROOT_CHECK_AT_BOOT" "n" - - whiptail --title 'Config change successful' \ - --msgbox "The root device will not be checked at each boot." 0 80 - fi - fi - ;; - "P" ) - if [ "$CONFIG_RESTRICTED_BOOT" = "y" ]; then - whiptail_error --title 'Restricted Boot Active' \ - --msgbox "Disable Restricted Boot to enable Basic Mode." 0 80 - elif [ "$CONFIG_BASIC" != "y" ]; then - if (whiptail --title "Enable $CONFIG_BRAND_NAME Basic Mode?" \ - --yesno "This will remove all signature checking on the firmware + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_ROOT_CHECK_AT_BOOT" "y" + + # check that root hash file exists + if [ ! -f ${ROOT_HASH_FILE} ]; then + if (whiptail --title 'Generate Root Hash File' \ + --yesno "\nNo root hash file exists. + \nWould you like to create the initial hash file now?" 0 80); then + root-hashes-gui.sh -n + fi + fi + + whiptail --title 'Config change successful' \ + --msgbox "The root device will be checked at each boot." 0 80 + + fi + else + if (whiptail --title 'Disable Root Hash Check at Boot?' \ + --yesno "This will disable checking root hashes each time you boot. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_ROOT_CHECK_AT_BOOT" "n" + + whiptail --title 'Config change successful' \ + --msgbox "The root device will not be checked at each boot." 0 80 + fi + fi + ;; + "P") + if [ "$CONFIG_RESTRICTED_BOOT" = "y" ]; then + whiptail_error --title 'Restricted Boot Active' \ + --msgbox "Disable Restricted Boot to enable Basic Mode." 0 80 + elif [ "$CONFIG_BASIC" != "y" ]; then + if (whiptail --title "Enable $CONFIG_BRAND_NAME Basic Mode?" \ + --yesno "This will remove all signature checking on the firmware \nand boot files, and disable use of the Librem Key. - \n\nDo you want to proceed?" 0 80) then + \n\nDo you want to proceed?" 0 80); then - set_user_config "CONFIG_BASIC" "y" + set_user_config "CONFIG_BASIC" "y" - whiptail --title 'Config change successful' \ - --msgbox "$CONFIG_BRAND_NAME Basic mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 + whiptail --title 'Config change successful' \ + --msgbox "$CONFIG_BRAND_NAME Basic mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title "Disable $CONFIG_BRAND_NAME Basic Mode?" \ - --yesno "This will enable all signature checking on the firmware + fi + else + if (whiptail --title "Disable $CONFIG_BRAND_NAME Basic Mode?" \ + --yesno "This will enable all signature checking on the firmware \nand boot files, and enable use of the Librem Key. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_BASIC" "n" - - whiptail --title 'Config change successful' \ - --msgbox "$CONFIG_BRAND_NAME Basic mode has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "L" ) - if [ "$CONFIG_RESTRICTED_BOOT" != "y" ]; then - if (whiptail --title 'Enable Restricted Boot Mode?' \ - --yesno "Restricted Boot allows booting: + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_BASIC" "n" + + whiptail --title 'Config change successful' \ + --msgbox "$CONFIG_BRAND_NAME Basic mode has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "L") + if [ "$CONFIG_RESTRICTED_BOOT" != "y" ]; then + if (whiptail --title 'Enable Restricted Boot Mode?' \ + --yesno "Restricted Boot allows booting: \n* Signed installed OS \n* Signed ISOs from USB \nAll other boot methods are blocked. Recovery console and firmware updates @@ -343,235 +348,258 @@ while true; do \nRestricted boot can be disabled at any time. This resets TOTP/HOTP so it \nis evident that Restricted Boot was disabled. \n - \nDo you want to proceed?" 0 80) then + \nDo you want to proceed?" 0 80); then - set_user_config "CONFIG_RESTRICTED_BOOT" "y" + set_user_config "CONFIG_RESTRICTED_BOOT" "y" - whiptail --title 'Config change successful' \ - --msgbox "Restricted Boot mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 + whiptail --title 'Config change successful' \ + --msgbox "Restricted Boot mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable Restricted Boot Mode?' \ - --yesno "This will re-enable all boot methods, the recovery console, and firmware + fi + else + if (whiptail --title 'Disable Restricted Boot Mode?' \ + --yesno "This will re-enable all boot methods, the recovery console, and firmware \nupdates. \nThis will also erase the TOTP/HOTP secret. \nProceeding will automatically update the boot firmware and reboot! - \n\nDo you want to proceed?" 0 80) then - - # Wipe the TPM TOTP/HOTP secret before flashing. Otherwise, enabling - # Restricted Boot again might restore the firmware to an identical - # state, and there would be no evidence that it had been temporarily - # disabled. - if ! wipe-totp >/dev/null 2>/tmp/error; then - ERROR=$(tail -n 1 /tmp/error | fold -s) - whiptail_error --title 'ERROR: erasing TOTP secret' \ - --msgbox "Erasing TOTP Secret Failed\n\n${ERROR}" 0 80 - exit 1 - fi - - # We can't allow Restricted Boot to be disabled without flashing the - # firmware - this would allow the use of unrestricted mode without - # leaving evidence in the firmware. Disable it by flashing the new - # config directly. - FLASH_USER_CONFIG=/tmp/config-gui-config-user - cp /etc/config.user "$FLASH_USER_CONFIG" - set_config "$FLASH_USER_CONFIG" "CONFIG_RESTRICTED_BOOT" "n" - - read_rom /tmp/config-gui.rom - - replace_rom_file /tmp/config-gui.rom "heads/initrd/etc/config.user" "$FLASH_USER_CONFIG" - - /bin/flash.sh /tmp/config-gui.rom - whiptail --title 'BIOS Updated Successfully' \ - --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 0 80 - /bin/reboot - fi - fi - ;; - "J" ) - if [ "$CONFIG_USE_BLOB_JAIL" != "y" ]; then - if (whiptail --title 'Enable Firmware Blob Jail?' \ - --yesno "This will enable loading of firmware from flash on each boot - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_USE_BLOB_JAIL" "y" - - whiptail --title 'Config change successful' \ - --msgbox "Firmware Blob Jail use has been enabled;\nsave the config change and reboot for it to go into effect." 0 80 - - fi - else - if (whiptail --title 'Disable Firmware Blob Jail?' \ - --yesno "This will disable loading of firmware from flash on each boot. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_USE_BLOB_JAIL" "n" - - whiptail --title 'Config change successful' \ - --msgbox "Firmware Blob Jail use has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "M" ) - if [ -z "$CONFIG_AUTO_BOOT_TIMEOUT" ]; then - current_msg="Automatic boot is currently disabled." - elif [ "$CONFIG_AUTO_BOOT_TIMEOUT" = 1 ]; then - current_msg="Currently boots automatically after 1 second." - else - current_msg="Currently boots automatically after $CONFIG_AUTO_BOOT_TIMEOUT seconds." - fi - whiptail --title "Automatic Boot" \ - --menu "$CONFIG_BRAND_NAME can boot automatically. Select the amount of time to wait\nbefore booting.\n\n$current_msg" 0 80 10 \ - "0" "Don't boot automatically" \ - "1" "1 second" \ - "5" "5 seconds" \ - "10" "10 seconds" \ - "C" "Cancel" \ - 2>/tmp/whiptail - new_setting="$(cat /tmp/whiptail)" - if ! [ "$new_setting" = "C" ]; then - if [ "$new_setting" = "0" ]; then - new_setting= # Empty disables automatic boot - current_msg="$CONFIG_BRAND_NAME will not boot automatically." - elif [ "$new_setting" = "1" ]; then - current_msg="$CONFIG_BRAND_NAME will boot automatically after 1 second." - else - current_msg="$CONFIG_BRAND_NAME will boot automatically after $new_setting seconds." - fi - set_user_config "CONFIG_AUTO_BOOT_TIMEOUT" "$new_setting" - whiptail --title 'Config change successful' \ - --msgbox "$current_msg\nSave the config change and reboot for it to go into effect." 0 80 - fi - ;; - "A" ) - if [ "$CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" != "y" ]; then - if (whiptail --title 'Disable automatic default boot?' \ - --yesno "You will need to select a default boot option. + \n\nDo you want to proceed?" 0 80); then + + # Wipe the TPM TOTP/HOTP secret before flashing. Otherwise, enabling + # Restricted Boot again might restore the firmware to an identical + # state, and there would be no evidence that it had been temporarily + # disabled. + if ! wipe-totp >/dev/null 2>/tmp/error; then + ERROR=$(tail -n 1 /tmp/error | fold -s) + whiptail_error --title 'ERROR: erasing TOTP secret' \ + --msgbox "Erasing TOTP Secret Failed\n\n${ERROR}" 0 80 + exit 1 + fi + + # We can't allow Restricted Boot to be disabled without flashing the + # firmware - this would allow the use of unrestricted mode without + # leaving evidence in the firmware. Disable it by flashing the new + # config directly. + FLASH_USER_CONFIG=/tmp/config-gui-config-user + cp /etc/config.user "$FLASH_USER_CONFIG" + set_config "$FLASH_USER_CONFIG" "CONFIG_RESTRICTED_BOOT" "n" + + read_rom /tmp/config-gui.rom + + replace_rom_file /tmp/config-gui.rom "heads/initrd/etc/config.user" "$FLASH_USER_CONFIG" + + /bin/flash.sh /tmp/config-gui.rom + whiptail --title 'BIOS Updated Successfully' \ + --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 0 80 + /bin/reboot + fi + fi + ;; + "J") + if [ "$CONFIG_USE_BLOB_JAIL" != "y" ]; then + if (whiptail --title 'Enable Firmware Blob Jail?' \ + --yesno "This will enable loading of firmware from flash on each boot + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_USE_BLOB_JAIL" "y" + + whiptail --title 'Config change successful' \ + --msgbox "Firmware Blob Jail use has been enabled;\nsave the config change and reboot for it to go into effect." 0 80 + + fi + else + if (whiptail --title 'Disable Firmware Blob Jail?' \ + --yesno "This will disable loading of firmware from flash on each boot. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_USE_BLOB_JAIL" "n" + + whiptail --title 'Config change successful' \ + --msgbox "Firmware Blob Jail use has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "M") + if [ -z "$CONFIG_AUTO_BOOT_TIMEOUT" ]; then + current_msg="Automatic boot is currently disabled." + elif [ "$CONFIG_AUTO_BOOT_TIMEOUT" = 1 ]; then + current_msg="Currently boots automatically after 1 second." + else + current_msg="Currently boots automatically after $CONFIG_AUTO_BOOT_TIMEOUT seconds." + fi + whiptail --title "Automatic Boot" \ + --menu "$CONFIG_BRAND_NAME can boot automatically. Select the amount of time to wait\nbefore booting.\n\n$current_msg" 0 80 10 \ + "0" "Don't boot automatically" \ + "1" "1 second" \ + "5" "5 seconds" \ + "10" "10 seconds" \ + "C" "Cancel" \ + 2>/tmp/whiptail + new_setting="$(cat /tmp/whiptail)" + if ! [ "$new_setting" = "C" ]; then + if [ "$new_setting" = "0" ]; then + new_setting= # Empty disables automatic boot + current_msg="$CONFIG_BRAND_NAME will not boot automatically." + elif [ "$new_setting" = "1" ]; then + current_msg="$CONFIG_BRAND_NAME will boot automatically after 1 second." + else + current_msg="$CONFIG_BRAND_NAME will boot automatically after $new_setting seconds." + fi + set_user_config "CONFIG_AUTO_BOOT_TIMEOUT" "$new_setting" + whiptail --title 'Config change successful' \ + --msgbox "$current_msg\nSave the config change and reboot for it to go into effect." 0 80 + fi + ;; + "A") + if [ "$CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" != "y" ]; then + if (whiptail --title 'Disable automatic default boot?' \ + --yesno "You will need to select a default boot option. \nIf the boot options are changed, such as for an OS update, \nyou will be prompted to select a new default. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" "y" - - whiptail --title 'Config change successful' \ - --msgbox "Automatic default boot disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Enable automatic default boot?' \ - --yesno "The first boot option will be used automatically. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" "n" - - whiptail --title 'Config change successful' \ - --msgbox "Automatic default boot enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "U" ) - if [ "$CONFIG_BASIC_USB_AUTOBOOT" != "y" ]; then - if (whiptail --title 'Enable USB automatic boot?' \ - --yesno "During boot, an attached bootable USB disk will be booted + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" "y" + + whiptail --title 'Config change successful' \ + --msgbox "Automatic default boot disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + else + if (whiptail --title 'Enable automatic default boot?' \ + --yesno "The first boot option will be used automatically. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_BASIC_NO_AUTOMATIC_DEFAULT" "n" + + whiptail --title 'Config change successful' \ + --msgbox "Automatic default boot enabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "U") + if [ "$CONFIG_BASIC_USB_AUTOBOOT" != "y" ]; then + if (whiptail --title 'Enable USB automatic boot?' \ + --yesno "During boot, an attached bootable USB disk will be booted \nby default instead of the installed operating system. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_BASIC_USB_AUTOBOOT" "y" - - whiptail --title 'Config change successful' \ - --msgbox "USB automatic boot enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable USB automatic boot?' \ - --yesno "USB disks will no longer be booted by default. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_BASIC_USB_AUTOBOOT" "n" - - whiptail --title 'Config change successful' \ - --msgbox "USB automatic boot disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "N" ) - if [ "$CONFIG_AUTOMATIC_POWERON" != "y" ]; then - if (whiptail --title 'Enable automatic power-on?' \ - --yesno "The system will boot automatically when power is applied. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_AUTOMATIC_POWERON" "y" - - whiptail --title 'Config change successful' \ - --msgbox "Automatic power-on enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable automatic power-on?' \ - --yesno "The system will stay off when power is applied. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_AUTOMATIC_POWERON" "n" - - # Disable the EC BRAM setting too, otherwise it persists until - # manually disabled. On the off chance the user does not actually - # flash this change, we'll enable it again during boot. - set_ec_poweron.sh n - - whiptail --title 'Config change successful' \ - --msgbox "Automatic power-on disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "K" ) - if [ "$CONFIG_USER_USB_KEYBOARD" != "y" ]; then - if (whiptail --title 'Enable USB Keyboard?' \ - --yesno "USB keyboards will be usable in $CONFIG_BRAND_NAME. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_BASIC_USB_AUTOBOOT" "y" + + whiptail --title 'Config change successful' \ + --msgbox "USB automatic boot enabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + else + if (whiptail --title 'Disable USB automatic boot?' \ + --yesno "USB disks will no longer be booted by default. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_BASIC_USB_AUTOBOOT" "n" + + whiptail --title 'Config change successful' \ + --msgbox "USB automatic boot disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "N") + if [ "$CONFIG_AUTOMATIC_POWERON" != "y" ]; then + if (whiptail --title 'Enable automatic power-on?' \ + --yesno "The system will boot automatically when power is applied. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_AUTOMATIC_POWERON" "y" + + whiptail --title 'Config change successful' \ + --msgbox "Automatic power-on enabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + else + if (whiptail --title 'Disable automatic power-on?' \ + --yesno "The system will stay off when power is applied. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_AUTOMATIC_POWERON" "n" + + # Disable the EC BRAM setting too, otherwise it persists until + # manually disabled. On the off chance the user does not actually + # flash this change, we'll enable it again during boot. + set_ec_poweron.sh n + + whiptail --title 'Config change successful' \ + --msgbox "Automatic power-on disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "K") + if [ "$CONFIG_USER_USB_KEYBOARD" != "y" ]; then + if (whiptail --title 'Enable USB Keyboard?' \ + --yesno "USB keyboards will be usable in $CONFIG_BRAND_NAME. \n\nEnabling USB keyboards could allow a compromised USB device to control \n$CONFIG_BRAND_NAME. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_USER_USB_KEYBOARD" "y" - - whiptail --title 'Config change successful' \ - --msgbox "USB Keyboard support has been enabled;\nsave the config change and reboot for it to go into effect." 0 80 - - fi - else - if (whiptail --title 'Disable USB Keyboard?' \ - --yesno "Only the built-in keyboard will be usable in $CONFIG_BRAND_NAME. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_USER_USB_KEYBOARD" "n" - - whiptail --title 'Config change successful' \ - --msgbox "USB Keyboard support has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "Z" ) - if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then - if (whiptail --title 'Enable Debugging and Tracing output?' \ - --yesno "This will enable DEBUG and TRACE output from scripts. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_DEBUG_OUTPUT" "y" - set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "y" - - whiptail --title 'Config change successful' \ - --msgbox "Debugging and Tracing output enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable Enable Debugging and Tracing output?' \ - --yesno "This will disable DEBUG and TRACE output from scripts. - \n\nDo you want to proceed?" 0 80) then - - set_user_config "CONFIG_DEBUG_OUTPUT" "n" - set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "n" - - whiptail --title 'Config change successful' \ - --msgbox "Debugging and Tracing output disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - esac - + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_USER_USB_KEYBOARD" "y" + + whiptail --title 'Config change successful' \ + --msgbox "USB Keyboard support has been enabled;\nsave the config change and reboot for it to go into effect." 0 80 + + fi + else + if (whiptail --title 'Disable USB Keyboard?' \ + --yesno "Only the built-in keyboard will be usable in $CONFIG_BRAND_NAME. + \n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_USER_USB_KEYBOARD" "n" + + whiptail --title 'Config change successful' \ + --msgbox "USB Keyboard support has been disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "Z") + if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then + if (whiptail --title 'Enable Debugging and Tracing output?' \ + --yesno "This will enable DEBUG and TRACE output from scripts.\n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_DEBUG_OUTPUT" "y" + set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "y" + #DEBUG+TRACE is incompatible with QUIET mode, turn it off + set_user_config "CONFIG_QUIET_MODE" "n" + + whiptail --title 'Config change successful' \ + --msgbox "Debugging and Tracing output enabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + else + if (whiptail --title 'Disable Enable Debugging and Tracing output?' \ + --yesno "This will disable DEBUG and TRACE output from scripts.\n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_DEBUG_OUTPUT" "n" + set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "n" + + whiptail --title 'Config change successful' \ + --msgbox "Debugging and Tracing output disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + "Q") + #Quiet mode: turn off/on console technical output + if [ "$CONFIG_QUIET_MODE" != "y" ]; then + if (whiptail --title 'Enable Quiet mode?' \ + --yesno "This will enable QUIET mode, which will turn off console technical output.\n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_QUIET_MODE" "y" + #DEBUG+TRACE is incompatible with QUIET mode, turn it off + set_user_config "CONFIG_DEBUG_OUTPUT" "n" + set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "n" + whiptail --title 'Config change successful' \ + --msgbox "Quiet mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + else + if (whiptail --title 'Disable Quiet mode?' \ + --yesno "This will disable QUIET mode, which will turn on console technical output.\n\nDo you want to proceed?" 0 80); then + + set_user_config "CONFIG_QUIET_MODE" "n" + whiptail --title 'Config change successful' \ + --msgbox "Quiet mode disabled;\nsave the config change and reboot for it to go into effect." 0 80 + fi + fi + ;; + esac done exit 0 From 08f52af033411286aefd77eca6ec09d993462b7c Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 11:46:37 -0500 Subject: [PATCH 44/81] Deprecate ash in favor of bash shell; /etc/ash_functions: move /etc/ash_functions under /etc/functions, replace TRACE calls by TRACE_FUNC, remove xx30-flash.init Signed-off-by: Thierry Laurion --- initrd/bin/flash.sh | 6 +- initrd/bin/lock_chip | 7 +- initrd/bin/poweroff | 6 +- initrd/bin/reboot | 6 +- initrd/bin/xx30-flash.init | 27 --- initrd/etc/ash_functions | 385 ------------------------------------ initrd/etc/functions | 388 ++++++++++++++++++++++++++++++++++++- initrd/init | 8 +- 8 files changed, 402 insertions(+), 431 deletions(-) delete mode 100755 initrd/bin/xx30-flash.init delete mode 100644 initrd/etc/ash_functions mode change 100755 => 100644 initrd/etc/functions diff --git a/initrd/bin/flash.sh b/initrd/bin/flash.sh index cd5b9a6e1..c5389a11a 100755 --- a/initrd/bin/flash.sh +++ b/initrd/bin/flash.sh @@ -1,14 +1,14 @@ -#!/bin/ash +#!/bin/bash # # NOTE: This script is used on legacy-flash boards and runs with busybox ash, # not bash set -e -o pipefail -. /etc/ash_functions +. /etc/functions . /tmp/config echo -TRACE "Under /bin/flash.sh" +TRACE_FUNC case "$CONFIG_FLASH_OPTIONS" in "" ) diff --git a/initrd/bin/lock_chip b/initrd/bin/lock_chip index 6085b84e9..26c9c1c78 100755 --- a/initrd/bin/lock_chip +++ b/initrd/bin/lock_chip @@ -1,14 +1,13 @@ -#!/bin/sh +#!/bin/bash # For this to work: # - io386 module needs to be enabled in board config # - =Skylake: same as above and CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM=y, CONFIG_SPI_FLASH_SMM=y and mode (eg: CONFIG_BOOTMEDIA_LOCK_WHOLE_RO=y) # - Heads is actually doing the CONFIG_INTEL_CHIPSET_LOCKDOWN equivalent here. -#include ash shell functions (TRACE requires it) -. /etc/ash_functions +. /etc/functions -TRACE "Under /bin/lock_chip" +TRACE_FUNC if [ "$CONFIG_FINALIZE_PLATFORM_LOCKING" = "y" ]; then APM_CNT=0xb2 FIN_CODE=0xcb diff --git a/initrd/bin/poweroff b/initrd/bin/poweroff index ef4bdf863..bbf0a7496 100755 --- a/initrd/bin/poweroff +++ b/initrd/bin/poweroff @@ -1,7 +1,7 @@ -#!/bin/ash -. /etc/ash_functions +#!/bin/bash +. /etc/functions -TRACE "Under /bin/poweroff" +TRACE_FUNC # Shut down TPM if [ "$CONFIG_TPM" = "y" ]; then diff --git a/initrd/bin/reboot b/initrd/bin/reboot index 358931e9c..ce7e6947d 100755 --- a/initrd/bin/reboot +++ b/initrd/bin/reboot @@ -1,7 +1,7 @@ -#!/bin/ash -. /etc/ash_functions +#!/bin/bash +. /etc/functions -TRACE "Under /bin/reboot" +TRACE_FUNC if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then #Generalize user prompt to continue reboot or go to recovery shell diff --git a/initrd/bin/xx30-flash.init b/initrd/bin/xx30-flash.init deleted file mode 100755 index ca2fa8f67..000000000 --- a/initrd/bin/xx30-flash.init +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/ash -# Initialize the USB and network device drivers, -# invoke a recovery shell and prompt the user for how to proceed - -. /etc/ash_functions -. /tmp/config - -TRACE "Under /bin/xx30-flash.init" - -busybox insmod /lib/modules/ehci-hcd.ko -busybox insmod /lib/modules/ehci-pci.ko -busybox insmod /lib/modules/xhci-hcd.ko -busybox insmod /lib/modules/xhci-pci.ko -busybox insmod /lib/modules/e1000e.ko -busybox insmod /lib/modules/usb-storage.ko - -sleep 2 - -echo '***** Starting recovery shell' -echo '' -echo 'To install from flash drive:' -echo '' -echo ' mount -o ro /dev/sdb1 /media' -echo ' flash.sh /media/xx30-legacy.rom' -echo '' - -exec /bin/sh diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions deleted file mode 100644 index e60c58465..000000000 --- a/initrd/etc/ash_functions +++ /dev/null @@ -1,385 +0,0 @@ -#!/bin/sh -# -# Core shell functions that do not require bash. These functions are used with -# busybox ash on legacy-flash boards, and with bash on all other boards. - -die() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo -e " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; - else - echo -e >&2 "!!! ERROR: $* !!!"; - fi - sleep 2; - exit 1; -} - -warn() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo -e " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; - else - echo -e >&2 " *** WARNING: $* ***"; - fi - sleep 1; -} - -DEBUG() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then - # fold -s -w 960 will wrap lines at 960 characters on the last space before the limit - echo "DEBUG: $*" | fold -s -w 960 | while read line; do - echo "$line" | tee -a /tmp/debug.log /dev/kmsg >/dev/null - done - fi -} - -TRACE() { - if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ];then - echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; - fi -} - -# Write directly to the debug log (but not kmsg), never appears on console -LOG() { - # if not CONFIG_QUIET_MODE=y, output to console. If not, output to debug.log - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then - DEBUG "$*" - elif [ "$CONFIG_QUIET_MODE" = "y" ]; then - # if in quiet mode, output solely to debug.log - echo "$*" >> /tmp/debug.log - else - # if not in quiet mode, output to console - echo "$*" - fi -} - -fw_version() { - local FW_VER=$(dmesg | grep 'DMI' | grep -o 'BIOS.*' | cut -f2- -d ' ') - # chop off date, since will always be epoch w/timeless builds - echo "${FW_VER::-10}" -} - -preserve_rom() { - TRACE "Under /etc/ash_functions:preserve_rom" - new_rom="$1" - old_files=`cbfs -t 50 -l 2>/dev/null | grep "^heads/"` - - for old_file in `echo $old_files`; do - new_file=`cbfs.sh -o $1 -l | grep -x $old_file` - if [ -z "$new_file" ]; then - echo "+++ Adding $old_file to $1" - cbfs -t 50 -r $old_file >/tmp/rom.$$ \ - || die "Failed to read cbfs file from ROM" - cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ \ - || die "Failed to write cbfs file to new ROM file" - fi - done -} - -confirm_gpg_card() { - - #TODO: ideally, we ask for confirmation only once per boot session - #TODO: even change logic here to try first and then ask user to confirm if not found - #TODO: or ask GPG user PIN once and cache it for the rest of the boot session for reusal - # This is getting in the way of unattended stuff and GPG prompts are confusing anyway, hide them from user. - - - TRACE "Under /etc/ash_functions:confirm_gpg_card" - #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry - #TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config? - #Toggle to come in next PR, but currently we don't have a way to toggle it back to n if config.user flashed back in rom - if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then - DEBUG "Using known GPG key material Thumb drive backup and keys are unlocked and useable through pinentry" - return - fi - - if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then - message="Please confirm that your GPG card is inserted(Y/n) or your GPG key material (b)backup thumbdrive is inserted [Y/n/b]: " - else - # Generic message if no known key material backup - message="Please confirm that your GPG card is inserted [Y/n]: " - fi - - read \ - -n 1 \ - -p "$message" \ - card_confirm - echo - - if [ "$card_confirm" != "y" \ - -a "$card_confirm" != "Y" \ - -a "$card_confirm" != "b" \ - -a -n "$card_confirm" ] \ - ; then - die "gpg card not confirmed" - fi - - # If user has known GPG key material Thumb drive backup and asked to use it - if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$card_confirm" == "b" ]]; then - #Only mount and import GPG key material thumb drive backup once - if [ ! "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]; then - CR_NONCE="/tmp/secret/cr_nonce" - CR_SIG="$CR_NONCE.sig" - - #Wipe any previous CR_NONCE and CR_SIG - shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true - - #Prompt user for configured GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys - echo - gpg_admin_pin="" - while [ -z "$gpg_admin_pin" ]; do - #TODO: change all passphrase prompts in codebase to include -r to prevent backslash escapes - read -r -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin - echo - done - #prompt user to select the proper encrypted partition, which should the first one on next prompt - warn "Please select encrypted LUKS on GPG key material backup thumb drive (not public labeled one)" - mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with provided GPG Admin PIN" - echo "++++ Testing detach-sign operation and verifiying against fused public key in ROM" - gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 || - die "Unable to import GPG private subkeys" - #Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions - dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 || - die "Unable to create $CR_NONCE to be detach-signed with GPG private signing subkey" - gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 || - die "Unable to detach-sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN" - #verify detached signature against public key in rom - gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \ - echo "++++ Local GPG keyring can be used to sign/encrypt/authenticate in this boot session ++++" || \ - die "Unable to verify $CR_SIG detached signature against public key in ROM" - #Wipe any previous CR_NONCE and CR_SIG - shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true - #TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation - set_user_config "CONFIG_GPG_KEY_BACKUP_IN_USE" "y" - umount /media || die "Unable to unmount USB" - return - fi - fi - - # setup the USB so we can reach the USB Security dongle's OpenPGP smartcard - enable_usb - - echo -e "\nVerifying presence of GPG card...\n" - # ensure we don't exit without retrying - errexit=$(set -o | grep errexit | awk '{print $2}') - set +e - gpg_output=$(gpg --card-status 2>&1) - if [ $? -ne 0 ]; then - # prompt for reinsertion and try a second time - read -n1 -r -p \ - "Can't access GPG key; remove and reinsert, then press Enter to retry. " \ - ignored - # restore prev errexit state - if [ "$errexit" = "on" ]; then - set -e - fi - # retry card status - gpg_output=$(gpg --card-status 2>&1) || - die "gpg card read failed" - fi - # restore prev errexit state - if [ "$errexit" = "on" ]; then - set -e - fi - - # Extract and display GPG PIN retry counters - # output excerpt: "PIN retry counter : 3 0 3" - pin_retry_counters=$(echo "$gpg_output" | grep 'PIN retry counter' | awk -F': ' '{print $2}') - user_pin_retries=$(echo "$pin_retry_counters" | awk '{print $1}') - admin_pin_retries=$(echo "$pin_retry_counters" | awk '{print $3}') - - echo "" - echo "GPG User PIN retry attempts left before becoming locked: $user_pin_retries" - echo "GPG Admin PIN retry attempts left before becoming locked: $admin_pin_retries" - echo "" - warn "Your GPG User PIN, followed by Enter key will be required for input at: 'Please unlock the card' next prompt" - echo "" -} - -gpg_auth() { - if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]]; then - TRACE "Under /etc/ash_functions:gpg_auth" - # If we have a GPG key backup, we can use it to authenticate even if the card is lost - echo >&2 "!!!!! Please authenticate with OpenPGP smartcard/backup media to prove you are the owner of this machine !!!!!" - - # Wipe any existing nonce and signature - shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true - - # In case of gpg_auth, we require confirmation of the card, so loop with confirm_gpg_card until we get it - false - while [ $? -ne 0 ]; do - # Call confirm_gpg_card in subshell to ensure GPG key material presence - ( confirm_gpg_card ) - done - - # Perform a signing-based challenge-response, - # to authencate that the card plugged in holding - # the key to sign the list of boot files. - - CR_NONCE="/tmp/secret/cr_nonce" - CR_SIG="$CR_NONCE.sig" - - # Generate a random nonce - dd \ - if=/dev/urandom \ - of="$CR_NONCE" \ - count=1 \ - bs=20 \ - 2>/dev/null \ - || die "Unable to generate 20 random bytes" - - # Sign the nonce - for tries in 1 2 3; do - if gpg --digest-algo SHA256 \ - --detach-sign \ - -o "$CR_SIG" \ - "$CR_NONCE" > /dev/null 2>&1 \ - && gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \ - ; then - shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true - DEBUG "Under /etc/ash_functions:gpg_auth: success" - return 0 - else - shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true - if [ "$tries" -lt 3 ]; then - echo >&2 "!!!!! GPG authentication failed, please try again !!!!!" - continue - else - die "GPG authentication failed, please reboot and try again" - fi - fi - done - return 1 - fi -} - -recovery() { - TRACE "Under /etc/ash_functions:recovery" - echo >&2 "!!!!! $*" - - # Remove any temporary secret files that might be hanging around - # but recreate the directory so that new tools can use it. - - #safe to always be true. Otherwise "set -e" would make it exit here - shred -n 10 -z -u /tmp/secret/* 2> /dev/null || true - rm -rf /tmp/secret - mkdir -p /tmp/secret - - # ensure /tmp/config exists for recovery scripts that depend on it - touch /tmp/config - . /tmp/config - - DEBUG "Board $CONFIG_BOARD - version $(fw_version)" - - if [ "$CONFIG_TPM" = "y" ]; then - LOG "TPM: Extending PCR[4] to prevent any further secret unsealing" - tpmr extend -ix 4 -ic recovery - fi - - if [ "$CONFIG_RESTRICTED_BOOT" = y ]; then - echo >&2 "Restricted Boot enabled, recovery console disabled, rebooting in 5 seconds" - sleep 5 - /bin/reboot - fi - while [ true ] - do - #Going to recovery shell should be authenticated if supported - gpg_auth - - echo >&2 "!!!!! Starting recovery shell" - sleep 1 - - if [ -x /bin/setsid ]; then - /bin/setsid -c /bin/sh - else - /bin/sh - fi - done -} - -pause_recovery() { - TRACE "Under /etc/ash_functions:pause_recovery" - read -p $'!!! Hit enter to proceed to recovery shell !!!\n' - recovery $* -} - -combine_configs() { - TRACE "Under /etc/ash_functions:combine_configs" - cat /etc/config* > /tmp/config -} - -replace_config() { - TRACE "Under /etc/functions:replace_config" - CONFIG_FILE=$1 - CONFIG_OPTION=$2 - NEW_SETTING=$3 - - touch $CONFIG_FILE - # first pull out the existing option from the global config and place in a tmp file - awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >${CONFIG_FILE}.tmp - awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >>${CONFIG_FILE}.tmp - - # then copy any remaining settings from the existing config file, minus the option you changed - grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >>${CONFIG_FILE}.tmp || true - sort ${CONFIG_FILE}.tmp | uniq >${CONFIG_FILE} - rm -f ${CONFIG_FILE}.tmp -} - -# Set a config variable in a specific file to a given value - replace it if it -# exists, or add it. If added, the variable will be exported. -set_config() { - CONFIG_FILE="$1" - CONFIG_OPTION="$2" - NEW_SETTING="$3" - - if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then - replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING" - else - echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE" - fi -} - -# Set a value in config.user, re-combine configs, and update configs in the -# environment. -set_user_config() { - CONFIG_OPTION="$1" - NEW_SETTING="$2" - - set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING" - combine_configs - . /tmp/config -} - -# Load a config value to a variable, defaulting to empty. Does not fail if the -# config is not set (since it would expand to empty by default). -load_config_value() { - local config_name="$1" - if grep -q "$config_name=" /tmp/config; then - grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"' - fi -} - -enable_usb() -{ - TRACE "Under /etc/ash_functions:enable_usb" - #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning - insmod /lib/modules/ehci-hcd.ko || die "ehci_hcd: module load failed" - - if [ "$CONFIG_LINUX_USB_COMPANION_CONTROLLER" = y ]; then - insmod /lib/modules/uhci-hcd.ko || die "uhci_hcd: module load failed" - insmod /lib/modules/ohci-hcd.ko || die "ohci_hcd: module load failed" - insmod /lib/modules/ohci-pci.ko || die "ohci_pci: module load failed" - fi - insmod /lib/modules/ehci-pci.ko || die "ehci_pci: module load failed" - insmod /lib/modules/xhci-hcd.ko || die "xhci_hcd: module load failed" - insmod /lib/modules/xhci-pci.ko || die "xhci_pci: module load failed" - sleep 2 - - # For resiliency, test CONFIG_USB_KEYBOARD_REQUIRED explicitly rather - # than having it imply CONFIG_USER_USB_KEYBOARD at build time. - # Otherwise, if a user got CONFIG_USER_USB_KEYBOARD=n in their - # config.user by mistake (say, by copying config.user from a laptop to a - # desktop/server), they could lock themselves out, only recoverable by - # hardware flash. - if [ "$CONFIG_USB_KEYBOARD_REQUIRED" = y ] || [ "$CONFIG_USER_USB_KEYBOARD" = y ]; then - insmod /lib/modules/usbhid.ko || die "usbhid: module load failed" - fi -} diff --git a/initrd/etc/functions b/initrd/etc/functions old mode 100755 new mode 100644 index 311644a8c..47ea70ce2 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -1,6 +1,390 @@ #!/bin/bash -# Shell functions for most initialization scripts -. /etc/ash_functions + +# ------- Start of functions coming from /etc/ash_functions + +die() { + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then + echo -e " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + else + echo -e >&2 "!!! ERROR: $* !!!"; + fi + sleep 2; + exit 1; +} + +warn() { + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then + echo -e " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + else + echo -e >&2 " *** WARNING: $* ***"; + fi + sleep 1; +} + +DEBUG() { + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + # fold -s -w 960 will wrap lines at 960 characters on the last space before the limit + echo "DEBUG: $*" | fold -s -w 960 | while read line; do + echo "$line" | tee -a /tmp/debug.log /dev/kmsg >/dev/null + done + fi +} + +TRACE() { + if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ];then + echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + fi +} + +# Write directly to the debug log (but not kmsg), never appears on console +LOG() { + # if not CONFIG_QUIET_MODE=y, output to console. If not, output to debug.log + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + DEBUG "$*" + elif [ "$CONFIG_QUIET_MODE" = "y" ]; then + # if in quiet mode, output solely to debug.log + echo "$*" >> /tmp/debug.log + else + # if not in quiet mode, output to console + echo "$*" + fi +} + +fw_version() { + local FW_VER=$(dmesg | grep 'DMI' | grep -o 'BIOS.*' | cut -f2- -d ' ') + # chop off date, since will always be epoch w/timeless builds + echo "${FW_VER::-10}" +} + +preserve_rom() { + TRACE_FUNC + new_rom="$1" + old_files=`cbfs -t 50 -l 2>/dev/null | grep "^heads/"` + + for old_file in `echo $old_files`; do + new_file=`cbfs.sh -o $1 -l | grep -x $old_file` + if [ -z "$new_file" ]; then + echo "+++ Adding $old_file to $1" + cbfs -t 50 -r $old_file >/tmp/rom.$$ \ + || die "Failed to read cbfs file from ROM" + cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ \ + || die "Failed to write cbfs file to new ROM file" + fi + done +} + +confirm_gpg_card() { + + #TODO: ideally, we ask for confirmation only once per boot session + #TODO: even change logic here to try first and then ask user to confirm if not found + #TODO: or ask GPG user PIN once and cache it for the rest of the boot session for reusal + # This is getting in the way of unattended stuff and GPG prompts are confusing anyway, hide them from user. + + + TRACE_FUNC + #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry + #TODO: probably export CONFIG_GPG_KEY_BACKUP_IN_USE but not under /etc/user.config? + #Toggle to come in next PR, but currently we don't have a way to toggle it back to n if config.user flashed back in rom + if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]]; then + DEBUG "Using known GPG key material Thumb drive backup and keys are unlocked and useable through pinentry" + return + fi + + if [ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]; then + message="Please confirm that your GPG card is inserted(Y/n) or your GPG key material (b)backup thumbdrive is inserted [Y/n/b]: " + else + # Generic message if no known key material backup + message="Please confirm that your GPG card is inserted [Y/n]: " + fi + + read \ + -n 1 \ + -p "$message" \ + card_confirm + echo + + if [ "$card_confirm" != "y" \ + -a "$card_confirm" != "Y" \ + -a "$card_confirm" != "b" \ + -a -n "$card_confirm" ] \ + ; then + die "gpg card not confirmed" + fi + + # If user has known GPG key material Thumb drive backup and asked to use it + if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" && "$card_confirm" == "b" ]]; then + #Only mount and import GPG key material thumb drive backup once + if [ ! "$CONFIG_GPG_KEY_BACKUP_IN_USE" == "y" ]; then + CR_NONCE="/tmp/secret/cr_nonce" + CR_SIG="$CR_NONCE.sig" + + #Wipe any previous CR_NONCE and CR_SIG + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true + + #Prompt user for configured GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys + echo + gpg_admin_pin="" + while [ -z "$gpg_admin_pin" ]; do + #TODO: change all passphrase prompts in codebase to include -r to prevent backslash escapes + read -r -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin + echo + done + #prompt user to select the proper encrypted partition, which should the first one on next prompt + warn "Please select encrypted LUKS on GPG key material backup thumb drive (not public labeled one)" + mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with provided GPG Admin PIN" + echo "++++ Testing detach-sign operation and verifiying against fused public key in ROM" + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 || + die "Unable to import GPG private subkeys" + #Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions + dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 || + die "Unable to create $CR_NONCE to be detach-signed with GPG private signing subkey" + gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 || + die "Unable to detach-sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN" + #verify detached signature against public key in rom + gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \ + echo "++++ Local GPG keyring can be used to sign/encrypt/authenticate in this boot session ++++" || \ + die "Unable to verify $CR_SIG detached signature against public key in ROM" + #Wipe any previous CR_NONCE and CR_SIG + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true + #TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation + set_user_config "CONFIG_GPG_KEY_BACKUP_IN_USE" "y" + umount /media || die "Unable to unmount USB" + return + fi + fi + + # setup the USB so we can reach the USB Security dongle's OpenPGP smartcard + enable_usb + + echo -e "\nVerifying presence of GPG card...\n" + # ensure we don't exit without retrying + errexit=$(set -o | grep errexit | awk '{print $2}') + set +e + gpg_output=$(gpg --card-status 2>&1) + if [ $? -ne 0 ]; then + # prompt for reinsertion and try a second time + read -n1 -r -p \ + "Can't access GPG key; remove and reinsert, then press Enter to retry. " \ + ignored + # restore prev errexit state + if [ "$errexit" = "on" ]; then + set -e + fi + # retry card status + gpg_output=$(gpg --card-status 2>&1) || + die "gpg card read failed" + fi + # restore prev errexit state + if [ "$errexit" = "on" ]; then + set -e + fi + + # Extract and display GPG PIN retry counters + # output excerpt: "PIN retry counter : 3 0 3" + pin_retry_counters=$(echo "$gpg_output" | grep 'PIN retry counter' | awk -F': ' '{print $2}') + user_pin_retries=$(echo "$pin_retry_counters" | awk '{print $1}') + admin_pin_retries=$(echo "$pin_retry_counters" | awk '{print $3}') + + echo "" + echo "GPG User PIN retry attempts left before becoming locked: $user_pin_retries" + echo "GPG Admin PIN retry attempts left before becoming locked: $admin_pin_retries" + echo "" + warn "Your GPG User PIN, followed by Enter key will be required for input at: 'Please unlock the card' next prompt" + echo "" +} + +gpg_auth() { + if [[ "$CONFIG_HAVE_GPG_KEY_BACKUP" == "y" ]]; then + TRACE_FUNC + # If we have a GPG key backup, we can use it to authenticate even if the card is lost + echo >&2 "!!!!! Please authenticate with OpenPGP smartcard/backup media to prove you are the owner of this machine !!!!!" + + # Wipe any existing nonce and signature + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true + + # In case of gpg_auth, we require confirmation of the card, so loop with confirm_gpg_card until we get it + false + while [ $? -ne 0 ]; do + # Call confirm_gpg_card in subshell to ensure GPG key material presence + ( confirm_gpg_card ) + done + + # Perform a signing-based challenge-response, + # to authencate that the card plugged in holding + # the key to sign the list of boot files. + + CR_NONCE="/tmp/secret/cr_nonce" + CR_SIG="$CR_NONCE.sig" + + # Generate a random nonce + dd \ + if=/dev/urandom \ + of="$CR_NONCE" \ + count=1 \ + bs=20 \ + 2>/dev/null \ + || die "Unable to generate 20 random bytes" + + # Sign the nonce + for tries in 1 2 3; do + if gpg --digest-algo SHA256 \ + --detach-sign \ + -o "$CR_SIG" \ + "$CR_NONCE" > /dev/null 2>&1 \ + && gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \ + ; then + shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true + DEBUG "Under /etc/ash_functions:gpg_auth: success" + return 0 + else + shred -n 10 -z -u "$CR_SIG" 2>/dev/null || true + if [ "$tries" -lt 3 ]; then + echo >&2 "!!!!! GPG authentication failed, please try again !!!!!" + continue + else + die "GPG authentication failed, please reboot and try again" + fi + fi + done + return 1 + fi +} + +recovery() { + TRACE_FUNC + echo >&2 "!!!!! $*" + + # Remove any temporary secret files that might be hanging around + # but recreate the directory so that new tools can use it. + + #safe to always be true. Otherwise "set -e" would make it exit here + shred -n 10 -z -u /tmp/secret/* 2> /dev/null || true + rm -rf /tmp/secret + mkdir -p /tmp/secret + + # ensure /tmp/config exists for recovery scripts that depend on it + touch /tmp/config + . /tmp/config + + DEBUG "Board $CONFIG_BOARD - version $(fw_version)" + + if [ "$CONFIG_TPM" = "y" ]; then + LOG "TPM: Extending PCR[4] to prevent any further secret unsealing" + tpmr extend -ix 4 -ic recovery + fi + + if [ "$CONFIG_RESTRICTED_BOOT" = y ]; then + echo >&2 "Restricted Boot enabled, recovery console disabled, rebooting in 5 seconds" + sleep 5 + /bin/reboot + fi + while [ true ] + do + #Going to recovery shell should be authenticated if supported + gpg_auth + + echo >&2 "!!!!! Starting recovery shell" + sleep 1 + + if [ -x /bin/setsid ]; then + /bin/setsid -c /bin/sh + else + /bin/sh + fi + done +} + +pause_recovery() { + TRACE_FUNC + read -p $'!!! Hit enter to proceed to recovery shell !!!\n' + recovery $* +} + +combine_configs() { + TRACE_FUNC + cat /etc/config* > /tmp/config +} + +replace_config() { + TRACE_FUNC + CONFIG_FILE=$1 + CONFIG_OPTION=$2 + NEW_SETTING=$3 + + touch $CONFIG_FILE + # first pull out the existing option from the global config and place in a tmp file + awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >${CONFIG_FILE}.tmp + awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >>${CONFIG_FILE}.tmp + + # then copy any remaining settings from the existing config file, minus the option you changed + grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >>${CONFIG_FILE}.tmp || true + sort ${CONFIG_FILE}.tmp | uniq >${CONFIG_FILE} + rm -f ${CONFIG_FILE}.tmp +} + +# Set a config variable in a specific file to a given value - replace it if it +# exists, or add it. If added, the variable will be exported. +set_config() { + CONFIG_FILE="$1" + CONFIG_OPTION="$2" + NEW_SETTING="$3" + + if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then + replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING" + else + echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE" + fi +} + +# Set a value in config.user, re-combine configs, and update configs in the +# environment. +set_user_config() { + CONFIG_OPTION="$1" + NEW_SETTING="$2" + + set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING" + combine_configs + . /tmp/config +} + +# Load a config value to a variable, defaulting to empty. Does not fail if the +# config is not set (since it would expand to empty by default). +load_config_value() { + local config_name="$1" + if grep -q "$config_name=" /tmp/config; then + grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"' + fi +} + +enable_usb() +{ + TRACE_FUNC + #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning + insmod /lib/modules/ehci-hcd.ko || die "ehci_hcd: module load failed" + + if [ "$CONFIG_LINUX_USB_COMPANION_CONTROLLER" = y ]; then + insmod /lib/modules/uhci-hcd.ko || die "uhci_hcd: module load failed" + insmod /lib/modules/ohci-hcd.ko || die "ohci_hcd: module load failed" + insmod /lib/modules/ohci-pci.ko || die "ohci_pci: module load failed" + fi + insmod /lib/modules/ehci-pci.ko || die "ehci_pci: module load failed" + insmod /lib/modules/xhci-hcd.ko || die "xhci_hcd: module load failed" + insmod /lib/modules/xhci-pci.ko || die "xhci_pci: module load failed" + sleep 2 + + # For resiliency, test CONFIG_USB_KEYBOARD_REQUIRED explicitly rather + # than having it imply CONFIG_USER_USB_KEYBOARD at build time. + # Otherwise, if a user got CONFIG_USER_USB_KEYBOARD=n in their + # config.user by mistake (say, by copying config.user from a laptop to a + # desktop/server), they could lock themselves out, only recoverable by + # hardware flash. + if [ "$CONFIG_USB_KEYBOARD_REQUIRED" = y ] || [ "$CONFIG_USER_USB_KEYBOARD" = y ]; then + insmod /lib/modules/usbhid.ko || die "usbhid: module load failed" + fi +} + +# ------- End of functions coming from /etc/ash_functions + # Print or depending on whether $1 is empty. Useful to mask an # optional password parameter. diff --git a/initrd/init b/initrd/init index 3b308f139..578ec4a59 100755 --- a/initrd/init +++ b/initrd/init @@ -1,4 +1,4 @@ -#! /bin/ash +#! /bin/bash # Note this is used on legacy-flash boards that lack bash, it runs with busybox # ash. Calls to bash scripts must be guarded by checking config. @@ -56,7 +56,7 @@ hwclock -l -s (grep -v '^\texfat$' /proc/filesystems && echo -e '\texfat') >/etc/filesystems # Read the system configuration parameters -. /etc/ash_functions +. /etc/functions . /etc/config # report if we are in quiet mode, tell logs available under /tmp/debug.log @@ -81,7 +81,7 @@ else DEBUG "Debug output enabled from /etc/config.user's CONFIG_DEBUG_OUTPUT=y after combine_configs (Config menu enabled Debug)" fi -TRACE "Under init" +TRACE_FUNC # make sure we have sysctl requirements if [ ! -d /proc/sys ]; then @@ -173,7 +173,7 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y dmesg -n 8 DEBUG "Debug output enabled from /etc/config.user's CONFIG_DEBUG_OUTPUT=y after combine_configs (Config menu enabled Debug)" - TRACE "Under init:after combine_configs" + TRACE_FUNC fi fi From b5c24f24476d8311e19668ab1472c92bec873c7c Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 13:28:34 -0500 Subject: [PATCH 45/81] init+cbfs-init: refactor and explain why quiet mode cannot suppress measurements of cbfs-init extracted+measured TPM stuff if not in board config Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 7 +++ initrd/init | 145 ++++++++++++++++++++----------------------- 2 files changed, 75 insertions(+), 77 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index d89effe5e..a31fc1941 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -2,6 +2,13 @@ set -e -o pipefail . /etc/functions +# CBFS extraction and measurement +# This extraction and measurement cannot be suppressed by quiet mode, since +# config.user is not yet loaded at this point. +# To suppress this output, set CONFIG_QUIET_MODE=y needs be be set in /etc/config +# which is defined at buiid time under board configuration file to be part of initrd.cpio +# This script is called from initrd/init + TRACE_FUNC # Update initrd with CBFS files diff --git a/initrd/init b/initrd/init index 578ec4a59..10838851a 100755 --- a/initrd/init +++ b/initrd/init @@ -3,7 +3,7 @@ # ash. Calls to bash scripts must be guarded by checking config. mknod /dev/ttyprintk c 5 3 -echo "hello world" > /dev/ttyprintk +echo "hello world" >/dev/ttyprintk # Setup our path export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin @@ -43,7 +43,7 @@ mkdir -p /tmp/secret # Now it is safe to print a banner if [ -r /etc/motd ]; then - cat /etc/motd > /dev/tty0 + cat /etc/motd >/dev/tty0 fi # Load the date from the hardware clock, setting it in local time @@ -55,30 +55,67 @@ hwclock -l -s # filesystem after exFAT is iso9660, move exFAT last. (grep -v '^\texfat$' /proc/filesystems && echo -e '\texfat') >/etc/filesystems -# Read the system configuration parameters -. /etc/functions +# Read the system configuration parameters from build time board configuration . /etc/config +# import global functions +. /etc/functions -# report if we are in quiet mode, tell logs available under /tmp/debug.log -if [ "$CONFIG_QUIET_MODE" = "y" ]; then - echo "Quiet mode enabled. To see technical output, do 'cat /tmp/debug.log' from Recovery Shell!" > /dev/tty0 +# export user related content from cbfs +if [ "$CONFIG_COREBOOT" = "y" ]; then + /bin/cbfs-init +fi + +# Override CONFIG_USE_BLOB_JAIL if needed and persist via user config +if lspci -n | grep -E -q "8086:(2723|4df0)"; then + if ! cat /etc/config.user 2>/dev/null | grep -q "USE_BLOB_JAIL"; then + echo "CONFIG_USE_BLOB_JAIL=y" >>/etc/config.user + fi fi -# Board config had CONFIG_DEBUG_OUTPUT=y defined. -# Note that boards's coreboot config kernel command line "debug" option only will have all kernel messages output on console prior of this point +# Override CONFIG_TPM and CONFIG_TPM2_TOOLS from /etc/config with runtime value +# determined above. +# +# Values in user config have higher priority during combining thus effectively +# changing the value for the rest of the scripts which source /tmp/config. + +#Only set CONFIG_TPM and CONFIG_TPM2_TOOLS if they are not already set in /etc/config.user +if ! grep -q 'CONFIG_TPM=' /etc/config.user 2>/dev/null; then + echo "export CONFIG_TPM=\"$CONFIG_TPM\"" >>/etc/config.user +fi +if ! grep -q 'CONFIG_TPM2_TOOLS=' /etc/config.user 2>/dev/null; then + echo "export CONFIG_TPM2_TOOLS=\"$CONFIG_TPM2_TOOLS\"" >>/etc/config.user +fi + +# CONFIG_BASIC was previously CONFIG_PUREBOOT_BASIC in the PureBoot distribution. +# Substitute it in config.user if present for backward compatibility. +sed -i -e 's/^export CONFIG_PUREBOOT_BASIC=/export CONFIG_BASIC=/g' /etc/config.user + +# Combine user configuration overrides from CBFS's /etc/config.user +combine_configs +# Load the user configuration parameters from combined config +. /tmp/config + +# Enable maximum debug info from here if config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then - #Maximize printk messages to output all to console (8=debug) - #DEBUG and TRACE calls will output to /dev/kmsg, outputting both on dmesg and on console - dmesg -n 8 || true - DEBUG "Debug output enabled from board CONFIG_DEBUG_OUTPUT=y option (/etc/config)" -else - # Board config did't have CONFIG_DEBUG_OUTPUT=y defined + #Output all kernel messages to console (8=debug) + #DEBUG and TRACE calls will be in dmesg and on console # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y - # Output only print messages with a priority of 4 (warnings) or lower (errors and critical) kernel messages to console - # This way, "debug" kernel command line option will have all kernel messages output on console prior of this point - # This is useful to debug boot issues but permits qemu board to boot without flooding console with kernel messages by disabling CONFIG_DEBUG_OUTPUT=y in qemu board config - dmesg -n 4 || true - DEBUG "Debug output enabled from /etc/config.user's CONFIG_DEBUG_OUTPUT=y after combine_configs (Config menu enabled Debug)" + dmesg -n 8 + DEBUG "Full debug output enabled from this point. For earlier debug output, enable CONFIG_DEBUG_OUTPUT=y in your board configuration at build time." + TRACE_FUNC +fi + +# report if we are in quiet mode, tell user measurements logs available under /tmp/debug.log +if [ "$CONFIG_QUIET_MODE" = "y" ]; then + # check origin of quiet mode setting =y: if it is under /etc/config.user then early cbfs-init outputs are not suppressible + # if it is under /etc/config then early cbfs-init outputs are suppressible + if ! grep -q 'CONFIG_QUIET_MODE="y"' /etc/config.user 2>/dev/null; then + echo "Quiet mode enabled at build time: see /tmp/debug.log for boot measurements related traces" >/dev/tty0 + else + echo "Quiet mode enabled at runtime by user configuration: see /tmp/debug.log for additional boot measurements traces past this point" >/dev/tty0 + echo "To suppress earlier boot measurements traces, enable CONFIG_QUIET_MODE=y in your board configuration at build time." >/dev/tty0 + " >/dev/tty0 + fi fi TRACE_FUNC @@ -91,15 +128,14 @@ if [ ! -d /proc/sys ]; then warn "Please open an issue" fi -if [ ! -e /proc/sys/vm/panic_on_oom ]; then - warn "BUG!!! Requirements to setup Panic when under Out Of Memory situation through PROC_SYSCTL are missing (panic_on_oom was not enabled)" +if [ ! -e /proc/sys/vm/panic_on_oom ]; then + warn "BUG!!! Requirements to setup Panic when under Out Of Memory situation through PROC_SYSCTL are missing (panic_on_oom was not enabled)" warn "Please open an issue" else DEBUG "Applying panic_on_oom setting to sysctl" - echo 1 > /proc/sys/vm/panic_on_oom + echo 1 >/proc/sys/vm/panic_on_oom fi - # set CONFIG_TPM dynamically before init if [ ! -e /dev/tpm0 ]; then CONFIG_TPM='n' @@ -122,9 +158,6 @@ if [ "$CONFIG_TPM" = "y" ]; then tpmr startsession fi -if [ "$CONFIG_COREBOOT" = "y" ]; then - [ -x /bin/bash ] && /bin/cbfs-init -fi if [ "$CONFIG_LINUXBOOT" = "y" ]; then /bin/uefi-init fi @@ -134,56 +167,14 @@ fi export GPG_TTY=/dev/console # Initialize gpnupg with distro/user keys and setup the keyrings -[ -x /bin/bash ] && /bin/key-init - -# Override CONFIG_USE_BLOB_JAIL if needed and persist via user config -if lspci -n | grep -E -q "8086:(2723|4df0)"; then - if ! cat /etc/config.user 2>/dev/null | grep -q "USE_BLOB_JAIL"; then - echo "CONFIG_USE_BLOB_JAIL=y" >> /etc/config.user - fi -fi - -# Override CONFIG_TPM and CONFIG_TPM2_TOOLS from /etc/config with runtime value -# determined above. -# -# Values in user config have higher priority during combining thus effectively -# changing the value for the rest of the scripts which source /tmp/config. - -#Only set CONFIG_TPM and CONFIG_TPM2_TOOLS if they are not already set in /etc/config.user -if ! grep -q 'CONFIG_TPM=' /etc/config.user 2>/dev/null; then - echo "export CONFIG_TPM=\"$CONFIG_TPM\"" >> /etc/config.user -fi -if ! grep -q 'CONFIG_TPM2_TOOLS=' /etc/config.user 2> /dev/null; then - echo "export CONFIG_TPM2_TOOLS=\"$CONFIG_TPM2_TOOLS\"" >> /etc/config.user -fi - -# CONFIG_BASIC was previously CONFIG_PUREBOOT_BASIC in the PureBoot distribution. -# Substitute it in config.user if present for backward compatibility. -sed -i -e 's/^export CONFIG_PUREBOOT_BASIC=/export CONFIG_BASIC=/g' /etc/config.user - -combine_configs -. /tmp/config - -# Enable maximum debug info from here if config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y -if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then - #Output all kernel messages to console (8=debug) - #DEBUG and TRACE calls will be in dmesg and on console - if ! grep -q 'CONFIG_DEBUG_OUTPUT="y"' /etc/config;then - # Board config did't have CONFIG_DEBUG_OUTPUT=y defined - # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y - dmesg -n 8 - DEBUG "Debug output enabled from /etc/config.user's CONFIG_DEBUG_OUTPUT=y after combine_configs (Config menu enabled Debug)" - TRACE_FUNC - fi -fi - +/bin/key-init # Setup recovery serial shell if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then stty -F "$CONFIG_BOOT_RECOVERY_SERIAL" 115200 pause_recovery 'Serial console recovery shell' \ - < "$CONFIG_BOOT_RECOVERY_SERIAL" \ - > "$CONFIG_BOOT_RECOVERY_SERIAL" 2>&1 & + <"$CONFIG_BOOT_RECOVERY_SERIAL" \ + >"$CONFIG_BOOT_RECOVERY_SERIAL" 2>&1 & fi # load USB modules for boards using a USB keyboard @@ -207,14 +198,14 @@ if [ "$boot_option" = "r" ]; then exit elif [ "$boot_option" = "o" ]; then # Launch OEM Factory Reset mode - echo -e "***** Entering OEM Factory Reset mode\n" > /dev/tty0 + echo -e "***** Entering OEM Factory Reset mode\n" >/dev/tty0 oem-factory-reset --mode oem # just in case... exit fi if [ "$CONFIG_BASIC" = "y" ]; then - echo -e "***** BASIC mode: tamper detection disabled\n" > /dev/tty0 + echo -e "***** BASIC mode: tamper detection disabled\n" >/dev/tty0 fi # export firmware version @@ -223,11 +214,11 @@ export FW_VER=$(fw_version) # Add our boot devices into the /etc/fstab, if they are defined # in the configuration file. if [ ! -z "$CONFIG_BOOT_DEV" ]; then - echo >> /etc/fstab "$CONFIG_BOOT_DEV /boot auto defaults,ro 0 0" + echo >>/etc/fstab "$CONFIG_BOOT_DEV /boot auto defaults,ro 0 0" fi # Set the console font if needed -[ -x /bin/bash ] && setconsolefont.sh +setconsolefont.sh if [ "$CONFIG_BASIC" = "y" ]; then CONFIG_BOOTSCRIPT=/bin/gui-init-basic @@ -257,7 +248,7 @@ else setsid agetty -aroot -l"$CONFIG_BOOTSCRIPT" "$console" linux & done fi - + #Setup a control tty so that all terminals outputs correct tty when tty is called exec cttyhack "$CONFIG_BOOTSCRIPT" else From 60ba06dab2ec2653eae96c764cd055e330861f0a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 16:27:49 -0500 Subject: [PATCH 46/81] DEBUG: inform that output will be both in dmesg and on console from where that measure is enforced in code This is equivalent of passing debug on kernel command line from coreboot config, even is enabled through config options and saved back in CBFS. Signed-off-by: Thierry Laurion --- initrd/init | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/initrd/init b/initrd/init index 10838851a..d577f65fa 100755 --- a/initrd/init +++ b/initrd/init @@ -101,7 +101,7 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then #DEBUG and TRACE calls will be in dmesg and on console # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y dmesg -n 8 - DEBUG "Full debug output enabled from this point. For earlier debug output, enable CONFIG_DEBUG_OUTPUT=y in your board configuration at build time." + DEBUG "Full debug output enabled from this point: output both in dmesg and on console (equivalent of passing debug to kernel cmdline)" TRACE_FUNC fi @@ -114,7 +114,6 @@ if [ "$CONFIG_QUIET_MODE" = "y" ]; then else echo "Quiet mode enabled at runtime by user configuration: see /tmp/debug.log for additional boot measurements traces past this point" >/dev/tty0 echo "To suppress earlier boot measurements traces, enable CONFIG_QUIET_MODE=y in your board configuration at build time." >/dev/tty0 - " >/dev/tty0 fi fi From ef4cdfa77e5c4b07633343282ca5788a314d7b77 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 16:39:12 -0500 Subject: [PATCH 47/81] init: some more comments in code per review Signed-off-by: Thierry Laurion --- initrd/init | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/initrd/init b/initrd/init index d577f65fa..9c9860630 100755 --- a/initrd/init +++ b/initrd/init @@ -100,9 +100,9 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then #Output all kernel messages to console (8=debug) #DEBUG and TRACE calls will be in dmesg and on console # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y + TRACE_FUNC dmesg -n 8 DEBUG "Full debug output enabled from this point: output both in dmesg and on console (equivalent of passing debug to kernel cmdline)" - TRACE_FUNC fi # report if we are in quiet mode, tell user measurements logs available under /tmp/debug.log @@ -135,7 +135,7 @@ else echo 1 >/proc/sys/vm/panic_on_oom fi -# set CONFIG_TPM dynamically before init +# set CONFIG_TPM dynamically off before init if no TPM device is present if [ ! -e /dev/tpm0 ]; then CONFIG_TPM='n' CONFIG_TPM2_TOOLS='n' @@ -158,6 +158,7 @@ if [ "$CONFIG_TPM" = "y" ]; then fi if [ "$CONFIG_LINUXBOOT" = "y" ]; then + # Initialize the UEFI environment for linuxboot boards /bin/uefi-init fi From 91299fd89b3df1f17d338f99889016c68c4cbff7 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 16:47:06 -0500 Subject: [PATCH 48/81] seal-totp: contextualize qr code output for manual input of those without qr scanner app in mobile phone Signed-off-by: Thierry Laurion --- initrd/bin/seal-totp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 1fa24fbc0..cc1147054 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -59,4 +59,6 @@ secret="" DEBUG "TOTP secret output on screen (both URL and QR code)" qrenc "$url" + +echo "TOTP secret for manual input (if no mobile phone) is after the 'secret=' part of the URL:" echo "$url" From 885af7d39f27432c9fdfde340dd2880ae71c2cdd Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 16 Dec 2024 17:47:25 -0500 Subject: [PATCH 49/81] kexec-select-boot+kexec-save-default: Quiet mode; remove last rollback counters printed to console Signed-off-by: Thierry Laurion --- initrd/bin/kexec-save-default | 2 +- initrd/bin/kexec-select-boot | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index 828e7d984..24f3b2076 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -277,7 +277,7 @@ if [ ! -d $paramsdir ]; then fi if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" || + sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" >/dev/null 2>&1 || die "ERROR: Failed to Hash TPM2 primary key handle!" DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE" fi diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 7a45c9f8c..d6b33d6cd 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -61,7 +61,7 @@ paramsdir="${paramsdir%%/}" PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt" if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then if [ -r "$PRIMHASH_FILE" ]; then - sha256sum -c "$PRIMHASH_FILE" || + sha256sum -c "$PRIMHASH_FILE" >/dev/null 2>&1 || { echo "FATAL: Hash of TPM2 primary key handle mismatch!" warn "If you have not intentionally regenerated TPM2 primary key," @@ -116,8 +116,6 @@ verify_rollback_counter() { TRACE_FUNC TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2) - DEBUG "TPM_COUNTER: $TPM_COUNTER found in $TMP_ROLLBACK_FILE" - if [ -z "$TPM_COUNTER" ]; then die "$TMP_ROLLBACK_FILE: TPM counter not found?" fi @@ -125,7 +123,7 @@ verify_rollback_counter() { read_tpm_counter $TPM_COUNTER >/dev/null 2>&1 || die "Failed to read TPM counter" - sha256sum -c $TMP_ROLLBACK_FILE || + sha256sum -c $TMP_ROLLBACK_FILE >/dev/null 2>&1 || die "Invalid TPM counter state. TPM Reset required" valid_rollback="y" From f981ef971c0864d6b355b50296d28e189142ed37 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 17 Dec 2024 13:40:44 -0500 Subject: [PATCH 50/81] init: Quiet mode enablement output string modified; tell users having enabled it through Configuration Settings that earlier suppression requires enabling through board config Signed-off-by: Thierry Laurion --- initrd/init | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/init b/initrd/init index 9c9860630..28e42ca28 100755 --- a/initrd/init +++ b/initrd/init @@ -110,9 +110,9 @@ if [ "$CONFIG_QUIET_MODE" = "y" ]; then # check origin of quiet mode setting =y: if it is under /etc/config.user then early cbfs-init outputs are not suppressible # if it is under /etc/config then early cbfs-init outputs are suppressible if ! grep -q 'CONFIG_QUIET_MODE="y"' /etc/config.user 2>/dev/null; then - echo "Quiet mode enabled at build time: see /tmp/debug.log for boot measurements related traces" >/dev/tty0 + echo "Quiet mode enabled: refer to '/tmp/debug.log' for boot measurements traces" >/dev/tty0 else - echo "Quiet mode enabled at runtime by user configuration: see /tmp/debug.log for additional boot measurements traces past this point" >/dev/tty0 + echo "Runtime Quiet mode: refer to '/tmp/debug.log' for additional boot measurements traces past this point" >/dev/tty0 echo "To suppress earlier boot measurements traces, enable CONFIG_QUIET_MODE=y in your board configuration at build time." >/dev/tty0 fi fi From 71d4260045264be4fb364700fff5fe9d4d393142 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 17 Dec 2024 14:39:54 -0500 Subject: [PATCH 51/81] novacustom_nv4x_adl/novacustom_nv4x_adl.config : add quiet mode for real hardware recording in PR, will comment and generalize in next commit to all maintained boards, leaving this to be overriden by branding downstream for downstream releases exercice and choice Signed-off-by: Thierry Laurion --- boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config index 92ab67d40..607fbaacb 100644 --- a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config +++ b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config @@ -14,6 +14,9 @@ CONFIG_LINUX_CONFIG=config/linux-nitropad-x.config #Enable TPM2 pcap output under /tmp #export CONFIG_TPM2_CAPTURE_PCAP=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y + #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y From 1e6079620a7626693e7dc3ccb9219259b02f0f60 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 17 Dec 2024 16:10:48 -0500 Subject: [PATCH 52/81] TPM2 primary handle debugging once more. Can't wait we get rid of this... Signed-off-by: Thierry Laurion --- initrd/bin/kexec-save-default | 14 ++++++++++---- initrd/bin/kexec-select-boot | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index 24f3b2076..d59b9f9aa 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -223,7 +223,7 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [ -n 1 \ -p "Do you wish to add a disk encryption key to the TPM [y/N]: " \ add_key_confirm - #TODO: still not convinced: disk encryption key? decryption key? everywhere TPM Disk Unlock Key. Confusing even more? + #TODO: still not convinced: disk encryption key? decryption key? everywhere TPM Disk Unlock Key. Confusing even more? echo if [ "$add_key_confirm" = "y" \ @@ -277,9 +277,15 @@ if [ ! -d $paramsdir ]; then fi if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" >/dev/null 2>&1 || - die "ERROR: Failed to Hash TPM2 primary key handle!" - DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE" + if [ -f /tmp/secret/primary.handle ]; then + DEBUG "Hashing TPM2 primary key handle..." + sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" 2>/dev/null || + die "ERROR: Failed to Hash TPM2 primary key handle!" + DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE" + DEBUG "Hash content: $(cat $PRIMHASH_FILE)" + else + die "ERROR: TPM2 primary key handle file does not exist!" + fi fi rm $paramsdir/kexec_default.*.txt 2>/dev/null || true diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index d6b33d6cd..405047735 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -67,6 +67,8 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then warn "If you have not intentionally regenerated TPM2 primary key," warn "your system may have been compromised" DEBUG "Hash of TPM2 primary key handle mismatched for $PRIMHASH_FILE" + DEBUG "Contents of $PRIMHASH_FILE:" + DEBUG "$(cat $PRIMHASH_FILE)" } else warn "Hash of TPM2 primary key handle does not exist" From 02d8ce8d0dc48858442eed1cf03df17a8b678e5f Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 18 Dec 2024 14:57:48 -0500 Subject: [PATCH 53/81] kexec-save-default kexec-select-boot: fix primary handle once more. Can't wait we get rid of this... file must exist and not be empty, and hash output to console must not be silenced Signed-off-by: Thierry Laurion --- initrd/bin/kexec-save-default | 3 +-- initrd/bin/kexec-select-boot | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index d59b9f9aa..22ed28cfa 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -279,10 +279,9 @@ fi if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then if [ -f /tmp/secret/primary.handle ]; then DEBUG "Hashing TPM2 primary key handle..." - sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" 2>/dev/null || + sha256sum /tmp/secret/primary.handle > "$PRIMHASH_FILE" || die "ERROR: Failed to Hash TPM2 primary key handle!" DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE" - DEBUG "Hash content: $(cat $PRIMHASH_FILE)" else die "ERROR: TPM2 primary key handle file does not exist!" fi diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 405047735..e3390ac41 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -60,7 +60,8 @@ paramsdir="${paramsdir%%/}" PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt" if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - if [ -r "$PRIMHASH_FILE" ]; then + if [ -s "$PRIMHASH_FILE" ]; then + #PRIMHASH_FILE (normally /boot/kexec_primhdl_hash.txt) exists and is not empty sha256sum -c "$PRIMHASH_FILE" >/dev/null 2>&1 || { echo "FATAL: Hash of TPM2 primary key handle mismatch!" From 494ba0927052af9909b6c6a4a788498513cb3aa6 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 18 Dec 2024 16:26:34 -0500 Subject: [PATCH 54/81] novacustom-nv4x board config: revert quiet mode enablement Signed-off-by: Thierry Laurion --- boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config | 3 --- 1 file changed, 3 deletions(-) diff --git a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config index 607fbaacb..92ab67d40 100644 --- a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config +++ b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config @@ -14,9 +14,6 @@ CONFIG_LINUX_CONFIG=config/linux-nitropad-x.config #Enable TPM2 pcap output under /tmp #export CONFIG_TPM2_CAPTURE_PCAP=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y From bcd364c28099ca40b87a0fce9fcf1a3f4ade2d21 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 18 Dec 2024 16:27:31 -0500 Subject: [PATCH 55/81] TO REVERT BEFORE MERGE: enable quiet mode in all boards and revert for qemu so only prod_quiet boards have quiet upon revert repro user@localhost:~/heads$ sed -i 's|export CONFIG_BOOTSCRIPT=/bin/gui-init|#Enable quiet mode: technical information logged under /tmp/debug.log\nexport CONFIG_QUIET_MODE=y\nexport CONFIG_BOOTSCRIPT=/bin/gui-init|' boards/*/*.config user@localhost:~/heads$ git restore boards/*qemu*/*.config Signed-off-by: Thierry Laurion --- .../UNMAINTAINED_kgpe-d16_server-whiptail.config | 2 ++ .../UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config | 2 ++ .../UNMAINTAINED_kgpe-d16_workstation.config | 2 ++ boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config | 2 ++ boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config | 2 ++ boards/librem_11/librem_11.config | 2 ++ boards/librem_13v2/librem_13v2.config | 2 ++ boards/librem_13v4/librem_13v4.config | 2 ++ boards/librem_14/librem_14.config | 2 ++ boards/librem_15v3/librem_15v3.config | 2 ++ boards/librem_15v4/librem_15v4.config | 2 ++ boards/librem_l1um/librem_l1um.config | 2 ++ boards/librem_l1um_v2/librem_l1um_v2.config | 2 ++ boards/librem_mini/librem_mini.config | 2 ++ boards/librem_mini_v2/librem_mini_v2.config | 2 ++ boards/nitropad-ns50/nitropad-ns50.config | 2 ++ boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config | 2 ++ .../optiplex-7010_9010-hotp-maximized.config | 2 ++ .../optiplex-7010_9010-maximized.config | 2 ++ .../optiplex-7010_9010_TXT-hotp-maximized.config | 2 ++ .../optiplex-7010_9010_TXT-maximized.config | 2 ++ boards/t420-hotp-maximized/t420-hotp-maximized.config | 2 ++ boards/t420-maximized/t420-maximized.config | 2 ++ boards/t430-hotp-maximized/t430-hotp-maximized.config | 2 ++ boards/t430-maximized/t430-maximized.config | 2 ++ boards/t530-hotp-maximized/t530-hotp-maximized.config | 2 ++ boards/t530-maximized/t530-maximized.config | 2 ++ boards/w530-hotp-maximized/w530-hotp-maximized.config | 2 ++ boards/w530-maximized/w530-maximized.config | 2 ++ boards/x220-hotp-maximized/x220-hotp-maximized.config | 2 ++ boards/x220-maximized/x220-maximized.config | 2 ++ .../x230-hotp-maximized-fhd_edp.config | 2 ++ boards/x230-hotp-maximized/x230-hotp-maximized.config | 2 ++ .../x230-hotp-maximized_usb-kb.config | 2 ++ boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config | 2 ++ boards/x230-maximized/x230-maximized.config | 2 ++ boards/z220-cmt-maximized/z220-cmt-maximized.config | 2 ++ 37 files changed, 74 insertions(+) diff --git a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config index 271affcd0..607daec86 100644 --- a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config +++ b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config @@ -52,6 +52,8 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config index a7555897c..1a44484ae 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config @@ -49,6 +49,8 @@ export CONFIG_USB_KEYBOARD_REQUIRED=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config index fe4b0a944..34c4a2d69 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config @@ -50,6 +50,8 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config index 6ea92e2f6..ebb979ade 100644 --- a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config +++ b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config @@ -34,6 +34,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config index 5c7a27cd8..6ef119933 100644 --- a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config +++ b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config @@ -34,6 +34,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_11/librem_11.config b/boards/librem_11/librem_11.config index 1c50b4ef6..b5847f990 100644 --- a/boards/librem_11/librem_11.config +++ b/boards/librem_11/librem_11.config @@ -30,6 +30,8 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v2/librem_13v2.config b/boards/librem_13v2/librem_13v2.config index c52f16abc..32b3cf2d6 100644 --- a/boards/librem_13v2/librem_13v2.config +++ b/boards/librem_13v2/librem_13v2.config @@ -29,6 +29,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v4/librem_13v4.config b/boards/librem_13v4/librem_13v4.config index fcc515152..338c197f2 100644 --- a/boards/librem_13v4/librem_13v4.config +++ b/boards/librem_13v4/librem_13v4.config @@ -29,6 +29,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_14/librem_14.config b/boards/librem_14/librem_14.config index 6ac128a5c..4e722819e 100644 --- a/boards/librem_14/librem_14.config +++ b/boards/librem_14/librem_14.config @@ -28,6 +28,8 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v3/librem_15v3.config b/boards/librem_15v3/librem_15v3.config index f21c3d677..578a03554 100644 --- a/boards/librem_15v3/librem_15v3.config +++ b/boards/librem_15v3/librem_15v3.config @@ -29,6 +29,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v4/librem_15v4.config b/boards/librem_15v4/librem_15v4.config index 8b9ec201b..515c7f016 100644 --- a/boards/librem_15v4/librem_15v4.config +++ b/boards/librem_15v4/librem_15v4.config @@ -30,6 +30,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um/librem_l1um.config b/boards/librem_l1um/librem_l1um.config index 5684ebe00..e794e5ab7 100644 --- a/boards/librem_l1um/librem_l1um.config +++ b/boards/librem_l1um/librem_l1um.config @@ -29,6 +29,8 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um_v2/librem_l1um_v2.config b/boards/librem_l1um_v2/librem_l1um_v2.config index 6098682b9..57ba360cc 100644 --- a/boards/librem_l1um_v2/librem_l1um_v2.config +++ b/boards/librem_l1um_v2/librem_l1um_v2.config @@ -32,6 +32,8 @@ CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y CONFIG_PRIMARY_KEY_TYPE=ecc +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini/librem_mini.config b/boards/librem_mini/librem_mini.config index 46d0a7388..56372362d 100644 --- a/boards/librem_mini/librem_mini.config +++ b/boards/librem_mini/librem_mini.config @@ -30,6 +30,8 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini_v2/librem_mini_v2.config b/boards/librem_mini_v2/librem_mini_v2.config index 163876e16..72bcf354b 100644 --- a/boards/librem_mini_v2/librem_mini_v2.config +++ b/boards/librem_mini_v2/librem_mini_v2.config @@ -30,6 +30,8 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/nitropad-ns50/nitropad-ns50.config b/boards/nitropad-ns50/nitropad-ns50.config index ffcb94579..4b33a0fbd 100644 --- a/boards/nitropad-ns50/nitropad-ns50.config +++ b/boards/nitropad-ns50/nitropad-ns50.config @@ -68,6 +68,8 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config index 92ab67d40..63a684c99 100644 --- a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config +++ b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config @@ -67,6 +67,8 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config index e695df4ff..67bcbcdc8 100644 --- a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config +++ b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config @@ -74,6 +74,8 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config index 9d4e0e6fd..2882efd2a 100644 --- a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config +++ b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config @@ -74,6 +74,8 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config index 35aa57d10..372e24e8b 100644 --- a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config +++ b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config @@ -74,6 +74,8 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config index 03a711e4f..3a60ce8a6 100644 --- a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config +++ b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config @@ -74,6 +74,8 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t420-hotp-maximized/t420-hotp-maximized.config b/boards/t420-hotp-maximized/t420-hotp-maximized.config index 4ab33a434..acf929140 100644 --- a/boards/t420-hotp-maximized/t420-hotp-maximized.config +++ b/boards/t420-hotp-maximized/t420-hotp-maximized.config @@ -60,6 +60,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t420-maximized/t420-maximized.config b/boards/t420-maximized/t420-maximized.config index 1293dd2d4..121df8d4e 100644 --- a/boards/t420-maximized/t420-maximized.config +++ b/boards/t420-maximized/t420-maximized.config @@ -58,6 +58,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-hotp-maximized/t430-hotp-maximized.config b/boards/t430-hotp-maximized/t430-hotp-maximized.config index 4b64ffefa..f68bd4acb 100644 --- a/boards/t430-hotp-maximized/t430-hotp-maximized.config +++ b/boards/t430-hotp-maximized/t430-hotp-maximized.config @@ -58,6 +58,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-maximized/t430-maximized.config b/boards/t430-maximized/t430-maximized.config index 4164db3d7..8427afeeb 100644 --- a/boards/t430-maximized/t430-maximized.config +++ b/boards/t430-maximized/t430-maximized.config @@ -58,6 +58,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-hotp-maximized/t530-hotp-maximized.config b/boards/t530-hotp-maximized/t530-hotp-maximized.config index bdd005aed..1ddc61095 100644 --- a/boards/t530-hotp-maximized/t530-hotp-maximized.config +++ b/boards/t530-hotp-maximized/t530-hotp-maximized.config @@ -60,6 +60,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-maximized/t530-maximized.config b/boards/t530-maximized/t530-maximized.config index b291fa946..5182f7bd0 100644 --- a/boards/t530-maximized/t530-maximized.config +++ b/boards/t530-maximized/t530-maximized.config @@ -59,6 +59,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-hotp-maximized/w530-hotp-maximized.config b/boards/w530-hotp-maximized/w530-hotp-maximized.config index ddb91dbad..183866f14 100644 --- a/boards/w530-hotp-maximized/w530-hotp-maximized.config +++ b/boards/w530-hotp-maximized/w530-hotp-maximized.config @@ -60,6 +60,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-maximized/w530-maximized.config b/boards/w530-maximized/w530-maximized.config index bb691ad71..d8cc66a76 100644 --- a/boards/w530-maximized/w530-maximized.config +++ b/boards/w530-maximized/w530-maximized.config @@ -59,6 +59,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-hotp-maximized/x220-hotp-maximized.config b/boards/x220-hotp-maximized/x220-hotp-maximized.config index b8dc88e4d..32b4c9f6c 100644 --- a/boards/x220-hotp-maximized/x220-hotp-maximized.config +++ b/boards/x220-hotp-maximized/x220-hotp-maximized.config @@ -60,6 +60,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-maximized/x220-maximized.config b/boards/x220-maximized/x220-maximized.config index 2bd094ec3..0e23166ee 100644 --- a/boards/x220-maximized/x220-maximized.config +++ b/boards/x220-maximized/x220-maximized.config @@ -59,6 +59,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config index 0e8c84202..f8c99c0d4 100644 --- a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config +++ b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config @@ -72,6 +72,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized/x230-hotp-maximized.config b/boards/x230-hotp-maximized/x230-hotp-maximized.config index cdd0c8677..261311ab4 100644 --- a/boards/x230-hotp-maximized/x230-hotp-maximized.config +++ b/boards/x230-hotp-maximized/x230-hotp-maximized.config @@ -74,6 +74,8 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config index 8508baa8e..8d15f4c2c 100644 --- a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config +++ b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config @@ -68,6 +68,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config index 7ca110578..892d74872 100644 --- a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config +++ b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config @@ -71,6 +71,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized/x230-maximized.config b/boards/x230-maximized/x230-maximized.config index 78cc64922..04c0dc580 100644 --- a/boards/x230-maximized/x230-maximized.config +++ b/boards/x230-maximized/x230-maximized.config @@ -62,6 +62,8 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/z220-cmt-maximized/z220-cmt-maximized.config b/boards/z220-cmt-maximized/z220-cmt-maximized.config index c254331d9..580b2cded 100644 --- a/boards/z220-cmt-maximized/z220-cmt-maximized.config +++ b/boards/z220-cmt-maximized/z220-cmt-maximized.config @@ -54,6 +54,8 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n From 97121ab86e5af3159a270e15bb932532eac697db Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 19 Dec 2024 13:54:44 -0500 Subject: [PATCH 56/81] global: finalize switch from ash to bash shell, including recovery shell access Signed-off-by: Thierry Laurion --- initrd/{.ash_history => .bash_history} | 0 initrd/etc/functions | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename initrd/{.ash_history => .bash_history} (100%) diff --git a/initrd/.ash_history b/initrd/.bash_history similarity index 100% rename from initrd/.ash_history rename to initrd/.bash_history diff --git a/initrd/etc/functions b/initrd/etc/functions index 47ea70ce2..e50d1b318 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -287,9 +287,9 @@ recovery() { sleep 1 if [ -x /bin/setsid ]; then - /bin/setsid -c /bin/sh + /bin/setsid -c /bin/bash else - /bin/sh + /bin/bash fi done } From eb63d4d46ae366986d28bc41bafd5b6f89063c9e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 19 Dec 2024 15:10:54 -0500 Subject: [PATCH 57/81] oem-factory-reset: remove duplicate output 'Checking for USB Security dongle...' Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 1 - 1 file changed, 1 deletion(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index b4e33e6c0..b504ec956 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -1202,7 +1202,6 @@ fi # ensure USB Security dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then - echo -e "\nChecking for USB Security dongle...\n" 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." From 07218df9cb7f30fe8bec4cc6c7c6153f5ff0c09e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Dec 2024 14:37:00 -0500 Subject: [PATCH 58/81] initrd/bin/kexec-select-boot: clarify that TPM2 primary handle HASH is created upon setting default boot (was not clear) Signed-off-by: Thierry Laurion --- initrd/bin/kexec-select-boot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index e3390ac41..5b85a0b24 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -73,7 +73,7 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then } else warn "Hash of TPM2 primary key handle does not exist" - warn "Please rebuild the TPM2 primary key handle by settings a default OS to boot." + warn "Please rebuild the TPM2 primary key handle hash by setting a default OS to boot." warn "Select Options-> Boot Options -> Show OS Boot Menu -> -> Make default" #TODO: Simplify/Automatize TPM2 firmware upgrade process. Today: upgrade, reboot, reseal(type TPM owner pass), resign, boot default_failed="y" From e1a263ce3bc620c94b8271779125c3242a911407 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Dec 2024 14:51:19 -0500 Subject: [PATCH 59/81] init: warn user that if CONFIG_QUIET_MODE was enabled in board config at build time but disabled through Configuration Settings applied override, early measurement output got suppressed Also tell user that those early suppressed messages can be seen under /tmp/debug.txt Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 4 ++-- initrd/init | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index a31fc1941..c82e8a239 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -6,8 +6,8 @@ set -e -o pipefail # This extraction and measurement cannot be suppressed by quiet mode, since # config.user is not yet loaded at this point. # To suppress this output, set CONFIG_QUIET_MODE=y needs be be set in /etc/config -# which is defined at buiid time under board configuration file to be part of initrd.cpio -# This script is called from initrd/init +# which is defined at build time under board configuration file to be part of initrd.cpio +# This script is called from initrd/init so really early in the boot process to put files in place in initramfs TRACE_FUNC diff --git a/initrd/init b/initrd/init index 28e42ca28..1b1044fa3 100755 --- a/initrd/init +++ b/initrd/init @@ -109,12 +109,21 @@ fi if [ "$CONFIG_QUIET_MODE" = "y" ]; then # check origin of quiet mode setting =y: if it is under /etc/config.user then early cbfs-init outputs are not suppressible # if it is under /etc/config then early cbfs-init outputs are suppressible - if ! grep -q 'CONFIG_QUIET_MODE="y"' /etc/config.user 2>/dev/null; then + if grep -q 'CONFIG_QUIET_MODE="y"' /etc/config 2>/dev/null; then echo "Quiet mode enabled: refer to '/tmp/debug.log' for boot measurements traces" >/dev/tty0 else echo "Runtime Quiet mode: refer to '/tmp/debug.log' for additional boot measurements traces past this point" >/dev/tty0 echo "To suppress earlier boot measurements traces, enable CONFIG_QUIET_MODE=y in your board configuration at build time." >/dev/tty0 fi +# If CONFIG_QUIET_MODE enabled in board config but disabled from Config->Configuration Settings +# warn that early boot measurements output was suppressed prior of this point +elif [ "$CONFIG_QUIET_MODE" = "n" ]; then + # if CONFIG_QUIET_MODE=n in /etc/config.user but CONFIG_QUIET_MODE=y in /etc/config then early cbfs-init outputs are suppressed + # both needs to be checked to determine if early boot measurements traces were suppressed + if grep -q 'CONFIG_QUIET_MODE="y"' /etc/config 2>/dev/null && grep -q 'CONFIG_QUIET_MODE="n"' /etc/config.user 2>/dev/null; then + echo "Early boot measurements traces were suppressed per CONFIG_QUIET_MODE=y in your board configuration at build time (/etc/config)" >/dev/tty0 + echo "Runtime Quiet mode disabled: refer to '/tmp/debug.log' for cbfs-init related traces prior of this point" >/dev/tty0 + fi fi TRACE_FUNC From 283553956f90283ffaf483eecbbf5a11cb28d7d9 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:53:48 -0500 Subject: [PATCH 60/81] initrd/init: Delete outdated comment about ash Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/init | 2 -- 1 file changed, 2 deletions(-) diff --git a/initrd/init b/initrd/init index 1b1044fa3..735a30846 100755 --- a/initrd/init +++ b/initrd/init @@ -1,6 +1,4 @@ #! /bin/bash -# Note this is used on legacy-flash boards that lack bash, it runs with busybox -# ash. Calls to bash scripts must be guarded by checking config. mknod /dev/ttyprintk c 5 3 echo "hello world" >/dev/ttyprintk From 516f7b6924afe03aed6b1c5acc992e77af03a3ca Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:54:06 -0500 Subject: [PATCH 61/81] etc/functions: Fix SINK_LOG blank lines, add more dev doc Add examples for capturing stderr or both stdout+stderr. Trace blank lines with LOG like non-blank lines. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/etc/functions | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index e50d1b318..4da1087a4 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -402,6 +402,15 @@ mask_param() { # # For example: # ls /boot/vmlinux* | SINK_LOG "/boot kernels" +# +# To capture stderr: +# cryptsetup open /dev/sda1 media-crypt 2> >(SINK_LOG "LUKS unlock sda1 errors") +# (Note: the space between '>' is necessary in '2> >(SINK_LOG ...)') +# +# To capture both: +# tpm reset > >(SINK_LOG "tpm reset") 2>&1 +# (Note: 2>&1 must follow the stdout redirection, and space between '>' is +# necessary) SINK_LOG() { local name="$1" local line haveblank @@ -413,7 +422,7 @@ SINK_LOG() { cat echo ) | while IFS= read -r line; do - [[ -n "$haveblank" ]] && DEBUG "$name: " # Emit buffered blank line + [[ -n "$haveblank" ]] && LOG "$name: " # Emit buffered blank line if [[ -z "$line" ]]; then haveblank=y else From c4bb4107ab701c3f20a5e6af9bdaa1838b344a07 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:55:29 -0500 Subject: [PATCH 62/81] tpmr: Use SINK_LOG rather than temp file, avoid doubled log output Use SINK_LOG to capture tpm2 unseal rather than a temp file. Don't double up output from tpm "$@" to log; DO_WITH_DEBUG already captures it. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 14e595fc1..dc205e541 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -611,16 +611,9 @@ tpm2_unseal() { fi # tpm2 unseal will write the unsealed data to stdout and any errors to - # stderr. We capture the unsealed data to $file, but still log the errors for quiet mode. - # In case of unseal error, caller will also report on TOTP not being able to be unsealed. - TMP_ERR_FILE=$(mktemp) + # stderr; capture stderr to log. if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ - -S "$ENC_SESSION_FILE" >"$file" 2>"$TMP_ERR_FILE"; then - # Log the contents of the temporary error file - while IFS= read -r line; do - LOG "tpm2 stderr: $line" - done <"$TMP_ERR_FILE" - rm -f "$TMP_ERR_FILE" + -S "$ENC_SESSION_FILE" >"$file" 2> >(SINK_LOG "tpm2 stderr"); then LOG "Unable to unseal secret from TPM NVRAM" # should succeed, exit if it doesn't @@ -810,13 +803,9 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then TRACE_FUNC LOG "TPM: Extending PCR[$3] with hash $hash" - # Redirect the output of DO_WITH_DEBUG to a temporary file so we can LOG it in quiet mode - TMP_DEBUG_FILE=$(mktemp) - DO_WITH_DEBUG exec tpm "$@" >"$TMP_DEBUG_FILE" 2>&1 - while IFS= read -r line; do - LOG "$line" - done <"$TMP_DEBUG_FILE" - rm -f "$TMP_DEBUG_FILE" + # Silence stdout/stderr, they're only useful for debugging + # and DO_WITH_DEBUG captures them + DO_WITH_DEBUG exec tpm "$@" &>/dev/null ;; seal) shift From a06ead69bcf7e83b8f04c439ba7528a68fd1dd19 Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:56:46 -0500 Subject: [PATCH 63/81] tpmr: Don't continue blindly if a TPM reset step fails If a TPM reset step fails, don't blindly continue onto the other steps. Use DO_WITH_DEBUG to trace failures, so they're visible in the log but we still exit due to set -e. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index dc205e541..84626e886 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -665,15 +665,15 @@ tpm2_reset() { # output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" - tpm2 clear -c platform >/dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy" - tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change owner password" - tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change endorsement password" - tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \ - -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to create primary key" - tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \ - -P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to evict primary key" - shred -u "$SECRET_DIR/primary.ctx" >/dev/null 2>&1 - tpm2_startsession >/dev/null 2>&1 || LOG "Unable to start session" + DO_WITH_DEBUG tpm2 clear -c platform &>/dev/null + DO_WITH_DEBUG tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" &>/dev/null + DO_WITH_DEBUG tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" &>/dev/null + DO_WITH_DEBUG tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \ + -c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" &>/dev/null + DO_WITH_DEBUG tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \ + -P "$(tpm2_password_hex "$tpm_owner_password")" &>/dev/null + shred -u "$SECRET_DIR/primary.ctx" &>/dev/null + DO_WITH_DEBUG tpm2_startsession &>/dev/null # Set the dictionary attack parameters. TPM2 defaults vary widely, we # want consistent behavior on any TPM. @@ -715,17 +715,17 @@ tpm1_reset() { DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password" echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password" # Make sure the TPM is ready to be reset - tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence" - tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" - tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM" - tpm forceclear >/dev/null 2>&1 || LOG "Unable to clear TPM" - tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" - tpm takeown -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to take ownership of TPM" + DO_WITH_DEBUG tpm physicalpresence -s &>/dev/null + DO_WITH_DEBUG tpm physicalenable &>/dev/null + DO_WITH_DEBUG tpm physicalsetdeactivated -c &>/dev/null + DO_WITH_DEBUG tpm forceclear &>/dev/null + DO_WITH_DEBUG tpm physicalenable &>/dev/null + DO_WITH_DEBUG tpm takeown -pwdo "$tpm_owner_password" &>/dev/null # And now turn it all back on - tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence" - tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM" - tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM physical presence requirement" + DO_WITH_DEBUG tpm physicalpresence -s &>/dev/null + DO_WITH_DEBUG tpm physicalenable &>/dev/null + DO_WITH_DEBUG tpm physicalsetdeactivated -c &>/dev/null } # Perform final cleanup before boot and lock the platform heirarchy. From 8e630e0e4db5bc18dcae0ae3e56e89dd0d42b91d Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:58:16 -0500 Subject: [PATCH 64/81] seal-totp: Print plain secret instead of URL for manual entry Don't print the URL and then explain how to get the secret out of it, just print the secret. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/bin/seal-totp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index cc1147054..3c593d697 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -55,10 +55,9 @@ tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PAS shred -n 10 -z -u "$TOTP_SEALED" 2>/dev/null url="otpauth://totp/$HOST?secret=$secret" -secret="" DEBUG "TOTP secret output on screen (both URL and QR code)" qrenc "$url" -echo "TOTP secret for manual input (if no mobile phone) is after the 'secret=' part of the URL:" -echo "$url" +echo "TOTP secret for manual input (device without camera): $secret" +secret="" From 0825b57e2909bc6c1f4bb6b864a05f38e437312f Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Fri, 20 Dec 2024 16:58:45 -0500 Subject: [PATCH 65/81] config-gui.sh: Combine quiet mode / debug output to one output setting These two settings are exclusive, so they would disable each other if enabled. Present them as one setting with three output levels. Signed-off-by: Jonathon Hall Signed-off-by: Thierry Laurion --- initrd/bin/config-gui.sh | 67 +++++++++++++--------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index f3299d1aa..2f4117712 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -80,12 +80,7 @@ while true; do # Debugging option always available dynamic_config_options+=( - 'Z' " $(get_config_display_action "$CONFIG_DEBUG_OUTPUT") $CONFIG_BRAND_NAME debug and function tracing output" - ) - - # Quiet option always available - dynamic_config_options+=( - 'Q' " $(get_config_display_action "$CONFIG_QUIET_MODE") $CONFIG_BRAND_NAME quiet mode" + 'Z' " Configure $CONFIG_BRAND_NAME informational / debug output" ) [ "$CONFIG_FINALIZE_PLATFORM_LOCKING" = "y" ] && dynamic_config_options+=( @@ -553,52 +548,34 @@ while true; do fi ;; "Z") - if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then - if (whiptail --title 'Enable Debugging and Tracing output?' \ - --yesno "This will enable DEBUG and TRACE output from scripts.\n\nDo you want to proceed?" 0 80); then - - set_user_config "CONFIG_DEBUG_OUTPUT" "y" - set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "y" - #DEBUG+TRACE is incompatible with QUIET mode, turn it off - set_user_config "CONFIG_QUIET_MODE" "n" - - whiptail --title 'Config change successful' \ - --msgbox "Debugging and Tracing output enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable Enable Debugging and Tracing output?' \ - --yesno "This will disable DEBUG and TRACE output from scripts.\n\nDo you want to proceed?" 0 80); then + unset output_choice + whiptail_type $BG_COLOR_MAIN_MENU --title "Informational / Debug Output" \ + --menu "$CONFIG_BRAND_NAME can display informational or debug output.\n\nChoose the output level:" 0 80 10 \ + 0 'None - Show no extra output' \ + 1 "Info - Show information about operations in $CONFIG_BRAND_NAME" \ + 2 "Debug - Show detailed information suitable for debugging $CONFIG_BRAND_NAME" \ + 2>/tmp/whiptail || recovery "GUI menu failed" + output_choice=$(cat /tmp/whiptail) + case "$output_choice" in + 0) set_user_config "CONFIG_DEBUG_OUTPUT" "n" set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "n" - - whiptail --title 'Config change successful' \ - --msgbox "Debugging and Tracing output disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi - ;; - "Q") - #Quiet mode: turn off/on console technical output - if [ "$CONFIG_QUIET_MODE" != "y" ]; then - if (whiptail --title 'Enable Quiet mode?' \ - --yesno "This will enable QUIET mode, which will turn off console technical output.\n\nDo you want to proceed?" 0 80); then - set_user_config "CONFIG_QUIET_MODE" "y" - #DEBUG+TRACE is incompatible with QUIET mode, turn it off + ;; + 1) set_user_config "CONFIG_DEBUG_OUTPUT" "n" set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "n" - whiptail --title 'Config change successful' \ - --msgbox "Quiet mode enabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - else - if (whiptail --title 'Disable Quiet mode?' \ - --yesno "This will disable QUIET mode, which will turn on console technical output.\n\nDo you want to proceed?" 0 80); then - set_user_config "CONFIG_QUIET_MODE" "n" - whiptail --title 'Config change successful' \ - --msgbox "Quiet mode disabled;\nsave the config change and reboot for it to go into effect." 0 80 - fi - fi + ;; + 2) + set_user_config "CONFIG_DEBUG_OUTPUT" "y" + set_user_config "CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" "y" + set_user_config "CONFIG_QUIET_MODE" "n" + ;; + esac + whiptail --title 'Config change successful' \ + --msgbox "Output level changed.\nSave the config change and reboot for it to go into effect." 0 80 ;; esac done From 89309f0523c40201bc2f6706f78dca3923d4bada Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 20 Dec 2024 19:53:45 -0500 Subject: [PATCH 66/81] init: clarify origin of quiet mode once more after merge conflict resolution Signed-off-by: Thierry Laurion --- initrd/init | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/initrd/init b/initrd/init index 735a30846..9419d9ed4 100755 --- a/initrd/init +++ b/initrd/init @@ -108,9 +108,9 @@ if [ "$CONFIG_QUIET_MODE" = "y" ]; then # check origin of quiet mode setting =y: if it is under /etc/config.user then early cbfs-init outputs are not suppressible # if it is under /etc/config then early cbfs-init outputs are suppressible if grep -q 'CONFIG_QUIET_MODE="y"' /etc/config 2>/dev/null; then - echo "Quiet mode enabled: refer to '/tmp/debug.log' for boot measurements traces" >/dev/tty0 + echo "Quiet mode enabled from board configuration: refer to '/tmp/debug.log' for boot measurements traces" >/dev/tty0 else - echo "Runtime Quiet mode: refer to '/tmp/debug.log' for additional boot measurements traces past this point" >/dev/tty0 + echo "Runtime applied Quiet mode: refer to '/tmp/debug.log' for additional boot measurements traces past this point" >/dev/tty0 echo "To suppress earlier boot measurements traces, enable CONFIG_QUIET_MODE=y in your board configuration at build time." >/dev/tty0 fi # If CONFIG_QUIET_MODE enabled in board config but disabled from Config->Configuration Settings @@ -120,7 +120,7 @@ elif [ "$CONFIG_QUIET_MODE" = "n" ]; then # both needs to be checked to determine if early boot measurements traces were suppressed if grep -q 'CONFIG_QUIET_MODE="y"' /etc/config 2>/dev/null && grep -q 'CONFIG_QUIET_MODE="n"' /etc/config.user 2>/dev/null; then echo "Early boot measurements traces were suppressed per CONFIG_QUIET_MODE=y in your board configuration at build time (/etc/config)" >/dev/tty0 - echo "Runtime Quiet mode disabled: refer to '/tmp/debug.log' for cbfs-init related traces prior of this point" >/dev/tty0 + echo "Runtime applied Quiet mode disabled: refer to '/tmp/debug.log' for cbfs-init related traces prior of this point" >/dev/tty0 fi fi From 574cd97a2f5efc10c7084bbdd080afca59c924ad Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 10:05:03 -0500 Subject: [PATCH 67/81] Revert "TO REVERT BEFORE MERGE: enable quiet mode in all boards and revert for qemu so only prod_quiet boards have quiet upon revert" This reverts commit 65d6fc48ee4f9e8b61bd59f102b60cd01f7a3a39. Signed-off-by: Thierry Laurion --- .../UNMAINTAINED_kgpe-d16_server-whiptail.config | 2 -- .../UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config | 2 -- .../UNMAINTAINED_kgpe-d16_workstation.config | 2 -- boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config | 2 -- boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config | 2 -- boards/librem_11/librem_11.config | 2 -- boards/librem_13v2/librem_13v2.config | 2 -- boards/librem_13v4/librem_13v4.config | 2 -- boards/librem_14/librem_14.config | 2 -- boards/librem_15v3/librem_15v3.config | 2 -- boards/librem_15v4/librem_15v4.config | 2 -- boards/librem_l1um/librem_l1um.config | 2 -- boards/librem_l1um_v2/librem_l1um_v2.config | 2 -- boards/librem_mini/librem_mini.config | 2 -- boards/librem_mini_v2/librem_mini_v2.config | 2 -- boards/nitropad-ns50/nitropad-ns50.config | 2 -- boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config | 2 -- .../optiplex-7010_9010-hotp-maximized.config | 2 -- .../optiplex-7010_9010-maximized.config | 2 -- .../optiplex-7010_9010_TXT-hotp-maximized.config | 2 -- .../optiplex-7010_9010_TXT-maximized.config | 2 -- boards/t420-hotp-maximized/t420-hotp-maximized.config | 2 -- boards/t420-maximized/t420-maximized.config | 2 -- boards/t430-hotp-maximized/t430-hotp-maximized.config | 2 -- boards/t430-maximized/t430-maximized.config | 2 -- boards/t530-hotp-maximized/t530-hotp-maximized.config | 2 -- boards/t530-maximized/t530-maximized.config | 2 -- boards/w530-hotp-maximized/w530-hotp-maximized.config | 2 -- boards/w530-maximized/w530-maximized.config | 2 -- boards/x220-hotp-maximized/x220-hotp-maximized.config | 2 -- boards/x220-maximized/x220-maximized.config | 2 -- .../x230-hotp-maximized-fhd_edp.config | 2 -- boards/x230-hotp-maximized/x230-hotp-maximized.config | 2 -- .../x230-hotp-maximized_usb-kb.config | 2 -- boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config | 2 -- boards/x230-maximized/x230-maximized.config | 2 -- boards/z220-cmt-maximized/z220-cmt-maximized.config | 2 -- 37 files changed, 74 deletions(-) diff --git a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config index 607daec86..271affcd0 100644 --- a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config +++ b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config @@ -52,8 +52,6 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config index 1a44484ae..a7555897c 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config @@ -49,8 +49,6 @@ export CONFIG_USB_KEYBOARD_REQUIRED=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config index 34c4a2d69..fe4b0a944 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config @@ -50,8 +50,6 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config index ebb979ade..6ea92e2f6 100644 --- a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config +++ b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config @@ -34,8 +34,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config index 6ef119933..5c7a27cd8 100644 --- a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config +++ b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config @@ -34,8 +34,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_11/librem_11.config b/boards/librem_11/librem_11.config index b5847f990..1c50b4ef6 100644 --- a/boards/librem_11/librem_11.config +++ b/boards/librem_11/librem_11.config @@ -30,8 +30,6 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v2/librem_13v2.config b/boards/librem_13v2/librem_13v2.config index 32b3cf2d6..c52f16abc 100644 --- a/boards/librem_13v2/librem_13v2.config +++ b/boards/librem_13v2/librem_13v2.config @@ -29,8 +29,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v4/librem_13v4.config b/boards/librem_13v4/librem_13v4.config index 338c197f2..fcc515152 100644 --- a/boards/librem_13v4/librem_13v4.config +++ b/boards/librem_13v4/librem_13v4.config @@ -29,8 +29,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_14/librem_14.config b/boards/librem_14/librem_14.config index 4e722819e..6ac128a5c 100644 --- a/boards/librem_14/librem_14.config +++ b/boards/librem_14/librem_14.config @@ -28,8 +28,6 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v3/librem_15v3.config b/boards/librem_15v3/librem_15v3.config index 578a03554..f21c3d677 100644 --- a/boards/librem_15v3/librem_15v3.config +++ b/boards/librem_15v3/librem_15v3.config @@ -29,8 +29,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v4/librem_15v4.config b/boards/librem_15v4/librem_15v4.config index 515c7f016..8b9ec201b 100644 --- a/boards/librem_15v4/librem_15v4.config +++ b/boards/librem_15v4/librem_15v4.config @@ -30,8 +30,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um/librem_l1um.config b/boards/librem_l1um/librem_l1um.config index e794e5ab7..5684ebe00 100644 --- a/boards/librem_l1um/librem_l1um.config +++ b/boards/librem_l1um/librem_l1um.config @@ -29,8 +29,6 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um_v2/librem_l1um_v2.config b/boards/librem_l1um_v2/librem_l1um_v2.config index 57ba360cc..6098682b9 100644 --- a/boards/librem_l1um_v2/librem_l1um_v2.config +++ b/boards/librem_l1um_v2/librem_l1um_v2.config @@ -32,8 +32,6 @@ CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y CONFIG_PRIMARY_KEY_TYPE=ecc -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini/librem_mini.config b/boards/librem_mini/librem_mini.config index 56372362d..46d0a7388 100644 --- a/boards/librem_mini/librem_mini.config +++ b/boards/librem_mini/librem_mini.config @@ -30,8 +30,6 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini_v2/librem_mini_v2.config b/boards/librem_mini_v2/librem_mini_v2.config index 72bcf354b..163876e16 100644 --- a/boards/librem_mini_v2/librem_mini_v2.config +++ b/boards/librem_mini_v2/librem_mini_v2.config @@ -30,8 +30,6 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/nitropad-ns50/nitropad-ns50.config b/boards/nitropad-ns50/nitropad-ns50.config index 4b33a0fbd..ffcb94579 100644 --- a/boards/nitropad-ns50/nitropad-ns50.config +++ b/boards/nitropad-ns50/nitropad-ns50.config @@ -68,8 +68,6 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config index 63a684c99..92ab67d40 100644 --- a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config +++ b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config @@ -67,8 +67,6 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config index 67bcbcdc8..e695df4ff 100644 --- a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config +++ b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config @@ -74,8 +74,6 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config index 2882efd2a..9d4e0e6fd 100644 --- a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config +++ b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config @@ -74,8 +74,6 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config index 372e24e8b..35aa57d10 100644 --- a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config +++ b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config @@ -74,8 +74,6 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config index 3a60ce8a6..03a711e4f 100644 --- a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config +++ b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config @@ -74,8 +74,6 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t420-hotp-maximized/t420-hotp-maximized.config b/boards/t420-hotp-maximized/t420-hotp-maximized.config index acf929140..4ab33a434 100644 --- a/boards/t420-hotp-maximized/t420-hotp-maximized.config +++ b/boards/t420-hotp-maximized/t420-hotp-maximized.config @@ -60,8 +60,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t420-maximized/t420-maximized.config b/boards/t420-maximized/t420-maximized.config index 121df8d4e..1293dd2d4 100644 --- a/boards/t420-maximized/t420-maximized.config +++ b/boards/t420-maximized/t420-maximized.config @@ -58,8 +58,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-hotp-maximized/t430-hotp-maximized.config b/boards/t430-hotp-maximized/t430-hotp-maximized.config index f68bd4acb..4b64ffefa 100644 --- a/boards/t430-hotp-maximized/t430-hotp-maximized.config +++ b/boards/t430-hotp-maximized/t430-hotp-maximized.config @@ -58,8 +58,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-maximized/t430-maximized.config b/boards/t430-maximized/t430-maximized.config index 8427afeeb..4164db3d7 100644 --- a/boards/t430-maximized/t430-maximized.config +++ b/boards/t430-maximized/t430-maximized.config @@ -58,8 +58,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-hotp-maximized/t530-hotp-maximized.config b/boards/t530-hotp-maximized/t530-hotp-maximized.config index 1ddc61095..bdd005aed 100644 --- a/boards/t530-hotp-maximized/t530-hotp-maximized.config +++ b/boards/t530-hotp-maximized/t530-hotp-maximized.config @@ -60,8 +60,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-maximized/t530-maximized.config b/boards/t530-maximized/t530-maximized.config index 5182f7bd0..b291fa946 100644 --- a/boards/t530-maximized/t530-maximized.config +++ b/boards/t530-maximized/t530-maximized.config @@ -59,8 +59,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-hotp-maximized/w530-hotp-maximized.config b/boards/w530-hotp-maximized/w530-hotp-maximized.config index 183866f14..ddb91dbad 100644 --- a/boards/w530-hotp-maximized/w530-hotp-maximized.config +++ b/boards/w530-hotp-maximized/w530-hotp-maximized.config @@ -60,8 +60,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-maximized/w530-maximized.config b/boards/w530-maximized/w530-maximized.config index d8cc66a76..bb691ad71 100644 --- a/boards/w530-maximized/w530-maximized.config +++ b/boards/w530-maximized/w530-maximized.config @@ -59,8 +59,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-hotp-maximized/x220-hotp-maximized.config b/boards/x220-hotp-maximized/x220-hotp-maximized.config index 32b4c9f6c..b8dc88e4d 100644 --- a/boards/x220-hotp-maximized/x220-hotp-maximized.config +++ b/boards/x220-hotp-maximized/x220-hotp-maximized.config @@ -60,8 +60,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-maximized/x220-maximized.config b/boards/x220-maximized/x220-maximized.config index 0e23166ee..2bd094ec3 100644 --- a/boards/x220-maximized/x220-maximized.config +++ b/boards/x220-maximized/x220-maximized.config @@ -59,8 +59,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config index f8c99c0d4..0e8c84202 100644 --- a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config +++ b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config @@ -72,8 +72,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized/x230-hotp-maximized.config b/boards/x230-hotp-maximized/x230-hotp-maximized.config index 261311ab4..cdd0c8677 100644 --- a/boards/x230-hotp-maximized/x230-hotp-maximized.config +++ b/boards/x230-hotp-maximized/x230-hotp-maximized.config @@ -74,8 +74,6 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config index 8d15f4c2c..8508baa8e 100644 --- a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config +++ b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config @@ -68,8 +68,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config index 892d74872..7ca110578 100644 --- a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config +++ b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config @@ -71,8 +71,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized/x230-maximized.config b/boards/x230-maximized/x230-maximized.config index 04c0dc580..78cc64922 100644 --- a/boards/x230-maximized/x230-maximized.config +++ b/boards/x230-maximized/x230-maximized.config @@ -62,8 +62,6 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/z220-cmt-maximized/z220-cmt-maximized.config b/boards/z220-cmt-maximized/z220-cmt-maximized.config index 580b2cded..c254331d9 100644 --- a/boards/z220-cmt-maximized/z220-cmt-maximized.config +++ b/boards/z220-cmt-maximized/z220-cmt-maximized.config @@ -54,8 +54,6 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n From 27b3e3a0a0f2c044feb9f039142a5474f8c9176a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 10:11:43 -0500 Subject: [PATCH 68/81] qemu-*-prod_quiet board configs: move debug(n)+tracing(n)+pcap(n)+quiet(y) just prior of gui-init to attempt to unify to all boards Signed-off-by: Thierry Laurion --- ...eboot-fbwhiptail-tpm1-hotp-prod_quiet.config | 17 +++++++---------- ...eboot-fbwhiptail-tpm2-hotp-prod_quiet.config | 16 +++++++--------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config index bbda97069..6bca66b21 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm1-hotp-prod_quiet.config @@ -18,15 +18,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -85,6 +76,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -95,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config index cf8491f58..05422e305 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config @@ -17,14 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - -#Enable quiet mode: technical information logged under /tmp/debug.log -export CONFIG_QUIET_MODE=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -84,6 +76,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -94,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu From ff94d78c03e74e2d8402213363515471645b213a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 10:45:58 -0500 Subject: [PATCH 69/81] all maintained boards: add debug(n)+tracing(n)+pcap(n)+quiet(y) just prior of bootscript to unify to all boards with exception of - qemu boards not being *quiet: quiet=n - qemu boards not being *prod* having pcap=y - qemy boards not being *prod* have debug+tracing=y - qemu tpm1 boards have '#pcap=n' Signed-off-by: Thierry Laurion --- .../UNMAINTAINED_kgpe-d16_server-whiptail.config | 7 +++++++ .../UNMAINTAINED_kgpe-d16_server.config | 7 +++++++ ...TAINED_kgpe-d16_workstation-usb_keyboard.config | 7 +++++++ .../UNMAINTAINED_kgpe-d16_workstation.config | 7 +++++++ .../UNTESTED_t440p-maximized.config | 7 +++++++ boards/UNTESTED_talos-2/UNTESTED_talos-2.config | 7 +++++++ .../UNTESTED_w541-maximized.config | 7 +++++++ boards/librem_11/librem_11.config | 7 +++++++ boards/librem_13v2/librem_13v2.config | 7 +++++++ boards/librem_13v4/librem_13v4.config | 7 +++++++ boards/librem_14/librem_14.config | 7 +++++++ boards/librem_15v3/librem_15v3.config | 7 +++++++ boards/librem_15v4/librem_15v4.config | 7 +++++++ boards/librem_l1um/librem_l1um.config | 7 +++++++ boards/librem_l1um_v2/librem_l1um_v2.config | 7 +++++++ boards/librem_mini/librem_mini.config | 7 +++++++ boards/librem_mini_v2/librem_mini_v2.config | 7 +++++++ boards/nitropad-ns50/nitropad-ns50.config | 14 +++++++------- .../novacustom_nv4x_adl/novacustom_nv4x_adl.config | 14 +++++++------- .../optiplex-7010_9010-hotp-maximized.config | 11 +++++++---- .../optiplex-7010_9010-maximized.config | 11 +++++++---- .../optiplex-7010_9010_TXT-hotp-maximized.config | 11 +++++++---- .../optiplex-7010_9010_TXT-maximized.config | 11 +++++++---- .../qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config | 10 ++++++++-- .../qemu-coreboot-fbwhiptail-tpm1-hotp.config | 14 +++++++------- .../qemu-coreboot-fbwhiptail-tpm1-prod.config | 10 ++++++++-- .../qemu-coreboot-fbwhiptail-tpm1.config | 14 +++++++------- .../qemu-coreboot-fbwhiptail-tpm2-hotp-prod.config | 14 +++++++------- ...coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config | 1 - .../qemu-coreboot-fbwhiptail-tpm2-hotp.config | 13 +++++++------ .../qemu-coreboot-fbwhiptail-tpm2-prod.config | 14 +++++++------- .../qemu-coreboot-fbwhiptail-tpm2.config | 13 +++++++------ .../qemu-coreboot-whiptail-tpm1-hotp-prod.config | 10 ++++++++-- .../qemu-coreboot-whiptail-tpm1-hotp.config | 14 +++++++------- .../qemu-coreboot-whiptail-tpm1-prod.config | 10 ++++++++-- .../qemu-coreboot-whiptail-tpm1.config | 14 +++++++------- .../qemu-coreboot-whiptail-tpm2-hotp-prod.config | 14 +++++++------- .../qemu-coreboot-whiptail-tpm2-hotp.config | 13 +++++++------ .../qemu-coreboot-whiptail-tpm2-prod.config | 14 +++++++------- .../qemu-coreboot-whiptail-tpm2.config | 12 +++++++----- .../t420-hotp-maximized/t420-hotp-maximized.config | 7 +++++++ boards/t420-maximized/t420-maximized.config | 7 +++++++ .../t430-hotp-maximized/t430-hotp-maximized.config | 7 +++++++ boards/t430-maximized/t430-maximized.config | 7 +++++++ .../t530-hotp-maximized/t530-hotp-maximized.config | 7 +++++++ boards/t530-maximized/t530-maximized.config | 7 +++++++ .../w530-hotp-maximized/w530-hotp-maximized.config | 7 +++++++ boards/w530-maximized/w530-maximized.config | 7 +++++++ .../x220-hotp-maximized/x220-hotp-maximized.config | 7 +++++++ boards/x220-maximized/x220-maximized.config | 7 +++++++ .../x230-hotp-maximized-fhd_edp.config | 7 +++++++ .../x230-hotp-maximized/x230-hotp-maximized.config | 11 +++++++---- .../x230-hotp-maximized_usb-kb.config | 11 +++++++---- .../x230-maximized-fhd_edp.config | 7 +++++++ boards/x230-maximized/x230-maximized.config | 11 +++++++---- .../z220-cmt-maximized/z220-cmt-maximized.config | 7 +++++++ 56 files changed, 389 insertions(+), 130 deletions(-) diff --git a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config index 271affcd0..27dccb6bf 100644 --- a/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config +++ b/boards/UNMAINTAINED_kgpe-d16_server-whiptail/UNMAINTAINED_kgpe-d16_server-whiptail.config @@ -51,6 +51,13 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y #export CONFIG_BOOTSCRIPT=/bin/generic-init export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_server/UNMAINTAINED_kgpe-d16_server.config b/boards/UNMAINTAINED_kgpe-d16_server/UNMAINTAINED_kgpe-d16_server.config index be247d9f5..8ed475d76 100644 --- a/boards/UNMAINTAINED_kgpe-d16_server/UNMAINTAINED_kgpe-d16_server.config +++ b/boards/UNMAINTAINED_kgpe-d16_server/UNMAINTAINED_kgpe-d16_server.config @@ -43,6 +43,13 @@ CONFIG_LINUX_E1000E=y export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y #BOOT SCRIPT SELECTION export CONFIG_BOOTSCRIPT=/bin/generic-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config index a7555897c..f5c4bfb85 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard/UNMAINTAINED_kgpe-d16_workstation-usb_keyboard.config @@ -49,6 +49,13 @@ export CONFIG_USB_KEYBOARD_REQUIRED=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config index fe4b0a944..0615434b7 100644 --- a/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config +++ b/boards/UNMAINTAINED_kgpe-d16_workstation/UNMAINTAINED_kgpe-d16_workstation.config @@ -50,6 +50,13 @@ export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y export CONFIG_TPM=y #BOOT SCRIPT SELECTION #export CONFIG_BOOTSCRIPT=/bin/generic-init +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init #export CONFIG_BOOTSCRIPT_NETWORK=/bin/network-init-recovery diff --git a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config index 6ea92e2f6..2d54aeb35 100644 --- a/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config +++ b/boards/UNTESTED_t440p-maximized/UNTESTED_t440p-maximized.config @@ -34,6 +34,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/UNTESTED_talos-2/UNTESTED_talos-2.config b/boards/UNTESTED_talos-2/UNTESTED_talos-2.config index 9751df12f..a68149d0b 100644 --- a/boards/UNTESTED_talos-2/UNTESTED_talos-2.config +++ b/boards/UNTESTED_talos-2/UNTESTED_talos-2.config @@ -41,6 +41,13 @@ export CONFIG_USB_KEYBOARD_REQUIRED=y export CONFIG_BOOT_EXTRA_TTYS="tty0" export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/talos-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config index 5c7a27cd8..00383ad5d 100644 --- a/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config +++ b/boards/UNTESTED_w541-maximized/UNTESTED_w541-maximized.config @@ -34,6 +34,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_11/librem_11.config b/boards/librem_11/librem_11.config index 1c50b4ef6..79cca98cf 100644 --- a/boards/librem_11/librem_11.config +++ b/boards/librem_11/librem_11.config @@ -30,6 +30,13 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v2/librem_13v2.config b/boards/librem_13v2/librem_13v2.config index c52f16abc..706a6dadb 100644 --- a/boards/librem_13v2/librem_13v2.config +++ b/boards/librem_13v2/librem_13v2.config @@ -29,6 +29,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_13v4/librem_13v4.config b/boards/librem_13v4/librem_13v4.config index fcc515152..643375ff0 100644 --- a/boards/librem_13v4/librem_13v4.config +++ b/boards/librem_13v4/librem_13v4.config @@ -29,6 +29,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_14/librem_14.config b/boards/librem_14/librem_14.config index 6ac128a5c..4d9189059 100644 --- a/boards/librem_14/librem_14.config +++ b/boards/librem_14/librem_14.config @@ -28,6 +28,13 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v3/librem_15v3.config b/boards/librem_15v3/librem_15v3.config index f21c3d677..7de9fdc37 100644 --- a/boards/librem_15v3/librem_15v3.config +++ b/boards/librem_15v3/librem_15v3.config @@ -29,6 +29,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_15v4/librem_15v4.config b/boards/librem_15v4/librem_15v4.config index 8b9ec201b..3f2bf5e8b 100644 --- a/boards/librem_15v4/librem_15v4.config +++ b/boards/librem_15v4/librem_15v4.config @@ -30,6 +30,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um/librem_l1um.config b/boards/librem_l1um/librem_l1um.config index 5684ebe00..4ab33819a 100644 --- a/boards/librem_l1um/librem_l1um.config +++ b/boards/librem_l1um/librem_l1um.config @@ -29,6 +29,13 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_l1um_v2/librem_l1um_v2.config b/boards/librem_l1um_v2/librem_l1um_v2.config index 6098682b9..fde0be749 100644 --- a/boards/librem_l1um_v2/librem_l1um_v2.config +++ b/boards/librem_l1um_v2/librem_l1um_v2.config @@ -32,6 +32,13 @@ CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y CONFIG_PRIMARY_KEY_TYPE=ecc +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini/librem_mini.config b/boards/librem_mini/librem_mini.config index 46d0a7388..3ca17433d 100644 --- a/boards/librem_mini/librem_mini.config +++ b/boards/librem_mini/librem_mini.config @@ -30,6 +30,13 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/librem_mini_v2/librem_mini_v2.config b/boards/librem_mini_v2/librem_mini_v2.config index 163876e16..dba61447f 100644 --- a/boards/librem_mini_v2/librem_mini_v2.config +++ b/boards/librem_mini_v2/librem_mini_v2.config @@ -30,6 +30,13 @@ CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/nitropad-ns50/nitropad-ns50.config b/boards/nitropad-ns50/nitropad-ns50.config index ffcb94579..de4512a55 100644 --- a/boards/nitropad-ns50/nitropad-ns50.config +++ b/boards/nitropad-ns50/nitropad-ns50.config @@ -8,12 +8,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-nitropad-ns50.config CONFIG_LINUX_CONFIG=config/linux-nitropad-x.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -68,6 +62,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n @@ -75,4 +76,3 @@ export CONFIG_BOOT_KERNEL_ADD="" export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOARD_NAME="Nitropad NS50" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 diff --git a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config index 92ab67d40..c389f555e 100644 --- a/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config +++ b/boards/novacustom_nv4x_adl/novacustom_nv4x_adl.config @@ -8,12 +8,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-novacustom_nv4x_adl.config CONFIG_LINUX_CONFIG=config/linux-nitropad-x.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -67,6 +61,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n @@ -74,4 +75,3 @@ export CONFIG_BOOT_KERNEL_ADD="" export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOARD_NAME="NovaCustom NV4x 12th Gen" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 diff --git a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config index e695df4ff..f890345f1 100644 --- a/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config +++ b/boards/optiplex-7010_9010-hotp-maximized/optiplex-7010_9010-hotp-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-optiplex-7019_9010-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -74,6 +70,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config index 9d4e0e6fd..293a28198 100644 --- a/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config +++ b/boards/optiplex-7010_9010-maximized/optiplex-7010_9010-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-optiplex-7019_9010-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -74,6 +70,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config index 35aa57d10..3122197c7 100644 --- a/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config +++ b/boards/optiplex-7010_9010_TXT-hotp-maximized/optiplex-7010_9010_TXT-hotp-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-optiplex-7019_9010_TXT-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -74,6 +70,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config index 03a711e4f..f12614c99 100644 --- a/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config +++ b/boards/optiplex-7010_9010_TXT-maximized/optiplex-7010_9010_TXT-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-optiplex-7019_9010_TXT-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -74,6 +70,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config index 255357084..dd76f5875 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config @@ -22,7 +22,7 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #export CONFIG_DEBUG_OUTPUT=y #export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y +#export CONFIG_TPM2_CAPTURE_PCAP=n #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -82,6 +82,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -92,6 +99,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.config b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.config index d24ff7ab2..8e74f1c39 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp/qemu-coreboot-fbwhiptail-tpm1-hotp.config @@ -18,12 +18,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -82,6 +76,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -92,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config index 04c0c6477..c2eefb677 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config @@ -20,7 +20,7 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #export CONFIG_DEBUG_OUTPUT=y #export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y +#export CONFIG_TPM2_CAPTURE_PCAP=n #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -80,6 +80,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +97,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config index 7e07c23a1..d64d95d52 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1/qemu-coreboot-fbwhiptail-tpm1.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -80,6 +74,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +91,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm1" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod/qemu-coreboot-fbwhiptail-tpm2-hotp-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod/qemu-coreboot-fbwhiptail-tpm2-hotp-prod.config index fd1b23d4a..2c907376d 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod/qemu-coreboot-fbwhiptail-tpm2-hotp-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod/qemu-coreboot-fbwhiptail-tpm2-hotp-prod.config @@ -17,12 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -81,6 +75,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -91,6 +92,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config index 05422e305..552caccc4 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet/qemu-coreboot-fbwhiptail-tpm2-hotp-prod_quiet.config @@ -17,7 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp/qemu-coreboot-fbwhiptail-tpm2-hotp.config b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp/qemu-coreboot-fbwhiptail-tpm2-hotp.config index fc397409a..61299f32d 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2-hotp/qemu-coreboot-fbwhiptail-tpm2-hotp.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-hotp/qemu-coreboot-fbwhiptail-tpm2-hotp.config @@ -17,11 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -export CONFIG_TPM2_CAPTURE_PCAP=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -81,6 +76,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -91,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2-prod/qemu-coreboot-fbwhiptail-tpm2-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm2-prod/qemu-coreboot-fbwhiptail-tpm2-prod.config index 188d67027..ed9bc4171 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2-prod/qemu-coreboot-fbwhiptail-tpm2-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2-prod/qemu-coreboot-fbwhiptail-tpm2-prod.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -80,6 +74,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +91,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config index e67dc951e..1d7b8c5f7 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm2/qemu-coreboot-fbwhiptail-tpm2.config @@ -16,11 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -export CONFIG_TPM2_CAPTURE_PCAP=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -80,6 +75,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +92,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-fbwhiptail-tpm2" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config b/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config index aeb1b4fa1..1e3ffe80e 100644 --- a/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config @@ -22,7 +22,7 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #export CONFIG_DEBUG_OUTPUT=y #export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y +#export CONFIG_TPM2_CAPTURE_PCAP=n #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -82,6 +82,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -92,6 +99,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm1-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm1-hotp/qemu-coreboot-whiptail-tpm1-hotp.config b/boards/qemu-coreboot-whiptail-tpm1-hotp/qemu-coreboot-whiptail-tpm1-hotp.config index e47260ce6..097454066 100644 --- a/boards/qemu-coreboot-whiptail-tpm1-hotp/qemu-coreboot-whiptail-tpm1-hotp.config +++ b/boards/qemu-coreboot-whiptail-tpm1-hotp/qemu-coreboot-whiptail-tpm1-hotp.config @@ -18,12 +18,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -82,6 +76,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -92,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm1-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config b/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config index 0038b8a9f..ee8d56fd5 100644 --- a/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config @@ -20,7 +20,7 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #export CONFIG_DEBUG_OUTPUT=y #export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y +#export CONFIG_TPM2_CAPTURE_PCAP=n #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -80,6 +80,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +97,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm1" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config index d47a783a4..12160387c 100644 --- a/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config +++ b/boards/qemu-coreboot-whiptail-tpm1/qemu-coreboot-whiptail-tpm1.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -80,6 +74,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +#export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +91,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm1" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm2-hotp-prod/qemu-coreboot-whiptail-tpm2-hotp-prod.config b/boards/qemu-coreboot-whiptail-tpm2-hotp-prod/qemu-coreboot-whiptail-tpm2-hotp-prod.config index 10f051f94..9e9a9cba8 100644 --- a/boards/qemu-coreboot-whiptail-tpm2-hotp-prod/qemu-coreboot-whiptail-tpm2-hotp-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm2-hotp-prod/qemu-coreboot-whiptail-tpm2-hotp-prod.config @@ -17,12 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -81,6 +75,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -91,6 +92,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm2-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm2-hotp/qemu-coreboot-whiptail-tpm2-hotp.config b/boards/qemu-coreboot-whiptail-tpm2-hotp/qemu-coreboot-whiptail-tpm2-hotp.config index b9fba2971..b00843895 100644 --- a/boards/qemu-coreboot-whiptail-tpm2-hotp/qemu-coreboot-whiptail-tpm2-hotp.config +++ b/boards/qemu-coreboot-whiptail-tpm2-hotp/qemu-coreboot-whiptail-tpm2-hotp.config @@ -17,11 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -export CONFIG_TPM2_CAPTURE_PCAP=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -81,6 +76,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -91,6 +93,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm2-hotp" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm2-prod/qemu-coreboot-whiptail-tpm2-prod.config b/boards/qemu-coreboot-whiptail-tpm2-prod/qemu-coreboot-whiptail-tpm2-prod.config index 2db24f733..3fe0d382b 100644 --- a/boards/qemu-coreboot-whiptail-tpm2-prod/qemu-coreboot-whiptail-tpm2-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm2-prod/qemu-coreboot-whiptail-tpm2-prod.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -80,6 +74,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init @@ -90,6 +91,5 @@ export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm2" #export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -#export CONFIG_AUTO_BOOT_TIMEOUT=5 BOARD_TARGETS := qemu diff --git a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config index a6ac751a8..466814f67 100644 --- a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config +++ b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config @@ -16,11 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -export CONFIG_TPM2_CAPTURE_PCAP=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y @@ -80,6 +75,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=y +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init diff --git a/boards/t420-hotp-maximized/t420-hotp-maximized.config b/boards/t420-hotp-maximized/t420-hotp-maximized.config index 4ab33a434..ff6392fa1 100644 --- a/boards/t420-hotp-maximized/t420-hotp-maximized.config +++ b/boards/t420-hotp-maximized/t420-hotp-maximized.config @@ -60,6 +60,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t420-maximized/t420-maximized.config b/boards/t420-maximized/t420-maximized.config index 1293dd2d4..5426da7d2 100644 --- a/boards/t420-maximized/t420-maximized.config +++ b/boards/t420-maximized/t420-maximized.config @@ -58,6 +58,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-hotp-maximized/t430-hotp-maximized.config b/boards/t430-hotp-maximized/t430-hotp-maximized.config index 4b64ffefa..e68535813 100644 --- a/boards/t430-hotp-maximized/t430-hotp-maximized.config +++ b/boards/t430-hotp-maximized/t430-hotp-maximized.config @@ -58,6 +58,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t430-maximized/t430-maximized.config b/boards/t430-maximized/t430-maximized.config index 4164db3d7..7b6e72618 100644 --- a/boards/t430-maximized/t430-maximized.config +++ b/boards/t430-maximized/t430-maximized.config @@ -58,6 +58,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-hotp-maximized/t530-hotp-maximized.config b/boards/t530-hotp-maximized/t530-hotp-maximized.config index bdd005aed..62bee8d37 100644 --- a/boards/t530-hotp-maximized/t530-hotp-maximized.config +++ b/boards/t530-hotp-maximized/t530-hotp-maximized.config @@ -60,6 +60,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/t530-maximized/t530-maximized.config b/boards/t530-maximized/t530-maximized.config index b291fa946..1c3e58c85 100644 --- a/boards/t530-maximized/t530-maximized.config +++ b/boards/t530-maximized/t530-maximized.config @@ -59,6 +59,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-hotp-maximized/w530-hotp-maximized.config b/boards/w530-hotp-maximized/w530-hotp-maximized.config index ddb91dbad..4b8f2ff48 100644 --- a/boards/w530-hotp-maximized/w530-hotp-maximized.config +++ b/boards/w530-hotp-maximized/w530-hotp-maximized.config @@ -60,6 +60,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/w530-maximized/w530-maximized.config b/boards/w530-maximized/w530-maximized.config index bb691ad71..282e2a2bc 100644 --- a/boards/w530-maximized/w530-maximized.config +++ b/boards/w530-maximized/w530-maximized.config @@ -59,6 +59,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-hotp-maximized/x220-hotp-maximized.config b/boards/x220-hotp-maximized/x220-hotp-maximized.config index b8dc88e4d..ff2a0cc8d 100644 --- a/boards/x220-hotp-maximized/x220-hotp-maximized.config +++ b/boards/x220-hotp-maximized/x220-hotp-maximized.config @@ -60,6 +60,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x220-maximized/x220-maximized.config b/boards/x220-maximized/x220-maximized.config index 2bd094ec3..3053aad1b 100644 --- a/boards/x220-maximized/x220-maximized.config +++ b/boards/x220-maximized/x220-maximized.config @@ -59,6 +59,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=n +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config index 0e8c84202..6052d5142 100644 --- a/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config +++ b/boards/x230-hotp-maximized-fhd_edp/x230-hotp-maximized-fhd_edp.config @@ -72,6 +72,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized/x230-hotp-maximized.config b/boards/x230-hotp-maximized/x230-hotp-maximized.config index cdd0c8677..8d9a17120 100644 --- a/boards/x230-hotp-maximized/x230-hotp-maximized.config +++ b/boards/x230-hotp-maximized/x230-hotp-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-x230-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -74,6 +70,13 @@ export CONFIG_AUTO_BOOT_TIMEOUT=5 #export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config index 8508baa8e..cd88741c1 100644 --- a/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config +++ b/boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config @@ -15,10 +15,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-x230-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -68,6 +64,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config index 7ca110578..6d50c67f8 100644 --- a/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config +++ b/boards/x230-maximized-fhd_edp/x230-maximized-fhd_edp.config @@ -71,6 +71,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/x230-maximized/x230-maximized.config b/boards/x230-maximized/x230-maximized.config index 78cc64922..41d1f2e99 100644 --- a/boards/x230-maximized/x230-maximized.config +++ b/boards/x230-maximized/x230-maximized.config @@ -13,10 +13,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-x230-maximized.config CONFIG_LINUX_CONFIG=config/linux-x230-maximized.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y - #Additional hardware support CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y @@ -62,6 +58,13 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n diff --git a/boards/z220-cmt-maximized/z220-cmt-maximized.config b/boards/z220-cmt-maximized/z220-cmt-maximized.config index c254331d9..f958a4e0f 100644 --- a/boards/z220-cmt-maximized/z220-cmt-maximized.config +++ b/boards/z220-cmt-maximized/z220-cmt-maximized.config @@ -54,6 +54,13 @@ CONFIG_LINUX_USB=y CONFIG_MOBILE_TETHERING=y export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n From d2b84597bf21ede32cad17b86ac700752b82641e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 11:19:01 -0500 Subject: [PATCH 70/81] tpmr: check for CONFIG_TPM2_CAPTURE_PCAP=y to export TPM comms under /tmp/tpm0.pcap (not just check for existence of CONFIG_TPM2_CAPTURE_PCAP under env) So that export CONFIG_TPM2_CAPTURE_PCAP=n across all boards doesn't break and so that its easy for auditors to just toggle on in board configs Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 84626e886..0572adbbb 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -17,7 +17,7 @@ PCR_SIZE= # Export CONFIG_TPM2_CAPTURE_PCAP=y from your board config to capture tpm2 pcaps to # /tmp/tpm0.pcap; Wireshark can inspect these. (This must be enabled at build # time so the pcap TCTI driver is included.) -if [ -n "$CONFIG_TPM2_CAPTURE_PCAP" ]; then +if [ "$CONFIG_TPM2_CAPTURE_PCAP" == "y" ]; then export TPM2TOOLS_TCTI="pcap:device:/dev/tpmrm0" export TCTI_PCAP_FILE="/tmp/tpm0.pcap" fi From 696ecf54cd38d278495a3119ca8afcd627d6d2bb Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 12:32:45 -0500 Subject: [PATCH 71/81] initrd/bin/seal-hotpkey: fix regression of hotp_verification 1.7+ version bump output parsing for --- initrd/bin/seal-hotpkey | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 7600d03fd..3eb71e549 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -108,7 +108,8 @@ if lsusb | grep -q "20a0:42b2"; then admin_pin_retries=$(echo "$hotp_token_info" | grep "Secrets app PIN counter:" | cut -d ':' -f 2 | tr -d ' ') prompt_message="Secrets app" else - admin_pin_retries=$(echo "$hotp_token_info" | grep "Card counters: Admin" | cut -d ':' -f 2 | tr -d ' ') + # Date: Sat, 21 Dec 2024 13:51:44 -0500 Subject: [PATCH 72/81] seal-hotpkey: change warning when default GPG Admin PIN/Secrets app PIN is detected Additional 0.5h for applying changes linked to code review under https://github.com/linuxboot/heads/pull/1875 Linked to Nitrokey unacknowledged RfP https://github.com/linuxboot/heads/issues/1866 that continues to grow past the 40h (now near 42... but unpaid because 'unplanned'... As if this was planned on my side.) Signed-off-by: Thierry Laurion --- initrd/bin/seal-hotpkey | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index 3eb71e549..6ef5319d5 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -167,10 +167,7 @@ if [ "$admin_pin_status" -ne 0 ]; then fi else # remind user to change admin password - warn "Weak OEM default PINs are under use to enforce remote attestation/encryption/signature operations" - warn "$CONFIG_BRAND_NAME security is compromised until the ownership of this device is re-established by changing secrets by non-default values" - warn "You must change current default secrets through 'Options -> OEM Factory Reset/Re-Ownership' menu and not accept the default options" - warn "You will be asked to answer a questionnaire to re-own your device and USB security dongles with new secrets" + warn "Default $prompt_message PIN detected. Please change this as soon as possible with Options > OEM Factory Reset / Re-Ownership" fi # HOTP key no longer needed From af59704bc5c274f247e0c83df194ce0118663dfd Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 21 Dec 2024 15:05:46 -0500 Subject: [PATCH 73/81] TODOs: remove no more relevant ones code per review Signed-off-by: Thierry Laurion --- initrd/bin/tpmr | 1 - modules/linux | 1 - 2 files changed, 2 deletions(-) diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 0572adbbb..391687984 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -644,7 +644,6 @@ tpm1_unseal() { -sz "$sealed_size" \ -of "$sealed_file" || die "Unable to read sealed file from TPM NVRAM" - # TODO: Cannot log + exit instead of dying!?! PASS_ARGS=() if [ "$pass" ]; then diff --git a/modules/linux b/modules/linux index 416d2b8d0..f380ce38f 100644 --- a/modules/linux +++ b/modules/linux @@ -40,7 +40,6 @@ endif linux_base_dir := linux-$(linux_version) -# TODO: fixup the patch process # input file in the heads config/ dir # Allow board config to specialize Linux configuration if necessary linux_kconfig := $(or $(CONFIG_LINUX_CONFIG),config/linux.config) From 618ff26d28edd55faf498563d293842f41124c71 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 9 Jan 2025 13:46:44 -0500 Subject: [PATCH 74/81] functions: remove DO_WITH_DEBUG call for kexec-parse-boot which redirects output to file used to show boot options in GUI Thanks @3hhh for bug in PR bug report at https://github.com/linuxboot/heads/pull/1875#issuecomment-2580660074 This bug is present for all DO_WITH_DEBUG calls to functions redirecting output to file. Signed-off-by: Thierry Laurion --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 4da1087a4..db56d3d57 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -1176,7 +1176,7 @@ scan_boot_options() { if [ -r $option_file ]; then rm $option_file; fi for i in $(find $bootdir -name "$config"); do - DO_WITH_DEBUG kexec-parse-boot "$bootdir" "$i" >>$option_file + kexec-parse-boot "$bootdir" "$i" >>$option_file done # FC29/30+ may use BLS format grub config files # https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault From 8f7b1c41283a3b518ba3f171fa01721d86a88f68 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 13 Jan 2025 10:50:42 -0500 Subject: [PATCH 75/81] Revert "functions: remove DO_WITH_DEBUG call for kexec-parse-boot which redirects output to file used to show boot options in GUI" This reverts commit 618ff26d28edd55faf498563d293842f41124c71. This is not the proper way. Signed-off-by: Thierry Laurion --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index db56d3d57..4da1087a4 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -1176,7 +1176,7 @@ scan_boot_options() { if [ -r $option_file ]; then rm $option_file; fi for i in $(find $bootdir -name "$config"); do - kexec-parse-boot "$bootdir" "$i" >>$option_file + DO_WITH_DEBUG kexec-parse-boot "$bootdir" "$i" >>$option_file done # FC29/30+ may use BLS format grub config files # https://fedoraproject.org/wiki/Changes/BootLoaderSpecByDefault From 930d3e611481e4ef3583853f2367b7121ea5d264 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 13 Jan 2025 10:57:34 -0500 Subject: [PATCH 76/81] BUGFIX: replace direct calls from LOG to INFO, so that only DO_WITH_DEBUG uses LOG. INFO manages console output to log or console Quiet mode introduced output reduction to console to limit technical info provided to end users. Previous informational output (previous default) now outputs this now considered additional information through INFO() calls, which either outputs to console, or debug.log Only DO_WITH_DEBUG should call LOG directly, so that stderr+stdout output is prepended with LOG into debug.log This fixes previous implementation which called LOG in DO_WITH_DEBUG calls and modified expected output to files, which was observed by @3hhh in output of GRUB entries when selecting boot option. Signed-off-by: Thierry Laurion --- initrd/bin/cbfs-init | 4 +- initrd/bin/gui-init | 2 +- initrd/bin/kexec-insert-key | 2 +- initrd/bin/kexec-select-boot | 10 +- initrd/bin/qubes-measure-luks | 2 +- initrd/bin/tpmr | 8 +- initrd/etc/functions | 184 +++++++++++++++++----------------- initrd/init | 2 + initrd/sbin/insmod | 6 +- 9 files changed, 112 insertions(+), 108 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index c82e8a239..651b9eaf0 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -24,12 +24,12 @@ for cbfsname in `echo $cbfsfiles`; do if [ ! -z "$filename" ]; then mkdir -p `dirname $filename` \ || die "$filename: mkdir failed" - LOG "Extracting CBFS file $cbfsname into $filename" + INFO "Extracting CBFS file $cbfsname into $filename" cbfs -t 50 $CBFS_ARG -r $cbfsname > "$filename" \ || die "$filename: cbfs file read failed" if [ "$CONFIG_TPM" = "y" ]; then TRACE_FUNC - LOG "TPM: Extending PCR[$CONFIG_PCR] with filename $filename and then its content" + INFO "TPM: Extending PCR[$CONFIG_PCR] with filename $filename and then its content" # Measure both the filename and its content. This # ensures that renaming files or pivoting file content # will still affect the resulting PCR measurement. diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1311963cb..7d4bf2eaa 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -553,7 +553,7 @@ reset_tpm() { mount -o rw,remount /boot #TODO: this is really problematic, we should really remove the primary handle hash - LOG "Removing rollback and primary handle hash under /boot" + INFO "Removing rollback and primary handle hash under /boot" rm -f /boot/kexec_rollback.txt rm -f /boot/kexec_primhdl_hash.txt diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 68b9bed2c..ff95c1943 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -66,7 +66,7 @@ fi # Override PCR 4 so that user can't read the key TRACE_FUNC -LOG "TPM: Extending PCR[4] to prevent any future secret unsealing" +INFO "TPM: Extending PCR[4] to prevent any future secret unsealing" tpmr extend -ix 4 -ic generic || die 'Unable to scramble PCR' diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 5b85a0b24..6a0edc6a7 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -82,10 +82,10 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then fi verify_global_hashes() { - LOG "+++ Checking verified boot hash file " + INFO "+++ Checking verified boot hash file " # Check the hashes of all the files if verify_checksums "$bootdir" "$gui_menu"; then - LOG "+++ Verified boot hashes " + INFO "+++ Verified boot hashes " valid_hash='y' valid_global_hash='y' else @@ -208,7 +208,7 @@ parse_option() { } scan_options() { - LOG "+++ Scanning for unsigned boot options" + INFO "+++ Scanning for unsigned boot options" option_file="/tmp/kexec_options.txt" scan_boot_options "$bootdir" "$config" "$option_file" if [ ! -s $option_file ]; then @@ -272,7 +272,7 @@ default_select() { if [ "$CONFIG_BASIC" != "y" ]; then # Enforce that default option hashes are valid - LOG "+++ Checking verified default boot hash file " + INFO "+++ Checking verified default boot hash file " # Check the hashes of all the files if (cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" >/tmp/hash_output); then echo "+++ Verified default boot hashes " @@ -390,7 +390,7 @@ while true; do if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible TRACE_FUNC - LOG "TPM: Extending PCR[4] to prevent further secret unsealing" + INFO "TPM: Extending PCR[4] to prevent further secret unsealing" tpmr extend -ix 4 -ic generic || die "Failed to extend TPM PCR[4]" fi diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index cc94c9c81..fc6ef2227 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -20,6 +20,6 @@ DEBUG "Removing /tmp/lukshdr-*" rm /tmp/lukshdr-* TRACE_FUNC -LOG "TPM: Extending PCR[6] with hash of LUKS headers from /tmp/luksDump.txt" +INFO "TPM: Extending PCR[6] with hash of LUKS headers from /tmp/luksDump.txt" tpmr extend -ix 6 -if /tmp/luksDump.txt || die "Unable to extend PCR" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 391687984..756050e77 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -257,7 +257,7 @@ tpm2_extend() { esac done tpm2 pcrextend "$index:sha256=$hash" - LOG $(tpm2 pcrread "sha256:$index" 2>&1) + INFO $(tpm2 pcrread "sha256:$index" 2>&1) TRACE_FUNC DEBUG "TPM: Extended PCR[$index] with hash $hash" @@ -614,7 +614,7 @@ tpm2_unseal() { # stderr; capture stderr to log. if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \ -S "$ENC_SESSION_FILE" >"$file" 2> >(SINK_LOG "tpm2 stderr"); then - LOG "Unable to unseal secret from TPM NVRAM" + INFO "Unable to unseal secret from TPM NVRAM" # should succeed, exit if it doesn't exit 1 @@ -800,7 +800,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then fi TRACE_FUNC - LOG "TPM: Extending PCR[$3] with hash $hash" + INFO "TPM: Extending PCR[$3] with hash $hash" # Silence stdout/stderr, they're only useful for debugging # and DO_WITH_DEBUG captures them @@ -845,7 +845,7 @@ calcfuturepcr) ;; extend) TRACE_FUNC - LOG "TPM: Extending PCR[$2] with $4" + INFO "TPM: Extending PCR[$2] with $4" tpm2_extend "$@" ;; counter_read) diff --git a/initrd/etc/functions b/initrd/etc/functions index 4da1087a4..4bf449b0b 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -3,22 +3,22 @@ # ------- Start of functions coming from /etc/ash_functions die() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo -e " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + echo -e " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg >/dev/null else - echo -e >&2 "!!! ERROR: $* !!!"; + echo -e "!!! ERROR: $* !!!" >&2 fi - sleep 2; - exit 1; + sleep 2 + exit 1 } warn() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo -e " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + echo -e " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg >/dev/null else - echo -e >&2 " *** WARNING: $* ***"; + echo -e " *** WARNING: $* ***" >&2 fi - sleep 1; + sleep 1 } DEBUG() { @@ -31,25 +31,31 @@ DEBUG() { } TRACE() { - if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ];then - echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ]; then + echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg >/dev/null fi } -# Write directly to the debug log (but not kmsg), never appears on console -LOG() { +# Function to manage information output level to the console/debug.log +INFO() { + #TODO: add colors to output, here green for INFO? + # if not CONFIG_QUIET_MODE=y, output to console. If not, output to debug.log if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then - DEBUG "$*" - elif [ "$CONFIG_QUIET_MODE" = "y" ]; then - # if in quiet mode, output solely to debug.log - echo "$*" >> /tmp/debug.log + echo "$*" | tee -a /tmp/debug.log /dev/kmsg >/dev/null + elif [ "$CONFIG_QUIET_MODE" = "y" ]; then + echo "$*" >>/tmp/debug.log else - # if not in quiet mode, output to console echo "$*" fi } +# Write directly to the debug log (but not kmsg), never appears on console +# Main consumer is DO_WITH_DEBUG, which uses this to log command output +LOG() { + echo "LOG: $*" >>/tmp/debug.log +} + fw_version() { local FW_VER=$(dmesg | grep 'DMI' | grep -o 'BIOS.*' | cut -f2- -d ' ') # chop off date, since will always be epoch w/timeless builds @@ -59,16 +65,16 @@ fw_version() { preserve_rom() { TRACE_FUNC new_rom="$1" - old_files=`cbfs -t 50 -l 2>/dev/null | grep "^heads/"` + old_files=$(cbfs -t 50 -l 2>/dev/null | grep "^heads/") - for old_file in `echo $old_files`; do - new_file=`cbfs.sh -o $1 -l | grep -x $old_file` + for old_file in $(echo $old_files); do + new_file=$(cbfs.sh -o $1 -l | grep -x $old_file) if [ -z "$new_file" ]; then echo "+++ Adding $old_file to $1" - cbfs -t 50 -r $old_file >/tmp/rom.$$ \ - || die "Failed to read cbfs file from ROM" - cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ \ - || die "Failed to write cbfs file to new ROM file" + cbfs -t 50 -r $old_file >/tmp/rom.$$ || + die "Failed to read cbfs file from ROM" + cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ || + die "Failed to write cbfs file to new ROM file" fi done } @@ -79,7 +85,6 @@ confirm_gpg_card() { #TODO: even change logic here to try first and then ask user to confirm if not found #TODO: or ask GPG user PIN once and cache it for the rest of the boot session for reusal # This is getting in the way of unattended stuff and GPG prompts are confusing anyway, hide them from user. - TRACE_FUNC #Skip prompts if we are currently using a known GPG key material Thumb drive backup and keys are unlocked pinentry @@ -141,9 +146,9 @@ confirm_gpg_card() { gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 || die "Unable to detach-sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN" #verify detached signature against public key in rom - gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \ - echo "++++ Local GPG keyring can be used to sign/encrypt/authenticate in this boot session ++++" || \ - die "Unable to verify $CR_SIG detached signature against public key in ROM" + gpg --verify "$CR_SIG" "$CR_NONCE" >/dev/null 2>&1 && + echo "++++ Local GPG keyring can be used to sign/encrypt/authenticate in this boot session ++++" || + die "Unable to verify $CR_SIG detached signature against public key in ROM" #Wipe any previous CR_NONCE and CR_SIG shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true #TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation @@ -184,8 +189,8 @@ confirm_gpg_card() { pin_retry_counters=$(echo "$gpg_output" | grep 'PIN retry counter' | awk -F': ' '{print $2}') user_pin_retries=$(echo "$pin_retry_counters" | awk '{print $1}') admin_pin_retries=$(echo "$pin_retry_counters" | awk '{print $3}') - - echo "" + + echo "" echo "GPG User PIN retry attempts left before becoming locked: $user_pin_retries" echo "GPG Admin PIN retry attempts left before becoming locked: $admin_pin_retries" echo "" @@ -201,18 +206,18 @@ gpg_auth() { # Wipe any existing nonce and signature shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true - + # In case of gpg_auth, we require confirmation of the card, so loop with confirm_gpg_card until we get it false while [ $? -ne 0 ]; do # Call confirm_gpg_card in subshell to ensure GPG key material presence - ( confirm_gpg_card ) + (confirm_gpg_card) done # Perform a signing-based challenge-response, # to authencate that the card plugged in holding # the key to sign the list of boot files. - + CR_NONCE="/tmp/secret/cr_nonce" CR_SIG="$CR_NONCE.sig" @@ -222,17 +227,17 @@ gpg_auth() { of="$CR_NONCE" \ count=1 \ bs=20 \ - 2>/dev/null \ - || die "Unable to generate 20 random bytes" - + 2>/dev/null || + die "Unable to generate 20 random bytes" + # Sign the nonce for tries in 1 2 3; do if gpg --digest-algo SHA256 \ --detach-sign \ -o "$CR_SIG" \ - "$CR_NONCE" > /dev/null 2>&1 \ - && gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \ - ; then + "$CR_NONCE" >/dev/null 2>&1 && + gpg --verify "$CR_SIG" "$CR_NONCE" >/dev/null 2>&1 \ + ; then shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true DEBUG "Under /etc/ash_functions:gpg_auth: success" return 0 @@ -246,7 +251,7 @@ gpg_auth() { fi fi done - return 1 + return 1 fi } @@ -258,7 +263,7 @@ recovery() { # but recreate the directory so that new tools can use it. #safe to always be true. Otherwise "set -e" would make it exit here - shred -n 10 -z -u /tmp/secret/* 2> /dev/null || true + shred -n 10 -z -u /tmp/secret/* 2>/dev/null || true rm -rf /tmp/secret mkdir -p /tmp/secret @@ -269,7 +274,7 @@ recovery() { DEBUG "Board $CONFIG_BOARD - version $(fw_version)" if [ "$CONFIG_TPM" = "y" ]; then - LOG "TPM: Extending PCR[4] to prevent any further secret unsealing" + INFO "TPM: Extending PCR[4] to prevent any further secret unsealing" tpmr extend -ix 4 -ic recovery fi @@ -278,14 +283,13 @@ recovery() { sleep 5 /bin/reboot fi - while [ true ] - do + while [ true ]; do #Going to recovery shell should be authenticated if supported - gpg_auth + gpg_auth echo >&2 "!!!!! Starting recovery shell" sleep 1 - + if [ -x /bin/setsid ]; then /bin/setsid -c /bin/bash else @@ -302,66 +306,65 @@ pause_recovery() { combine_configs() { TRACE_FUNC - cat /etc/config* > /tmp/config + cat /etc/config* >/tmp/config } replace_config() { - TRACE_FUNC - CONFIG_FILE=$1 - CONFIG_OPTION=$2 - NEW_SETTING=$3 - - touch $CONFIG_FILE - # first pull out the existing option from the global config and place in a tmp file - awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >${CONFIG_FILE}.tmp - awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >>${CONFIG_FILE}.tmp - - # then copy any remaining settings from the existing config file, minus the option you changed - grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >>${CONFIG_FILE}.tmp || true - sort ${CONFIG_FILE}.tmp | uniq >${CONFIG_FILE} - rm -f ${CONFIG_FILE}.tmp + TRACE_FUNC + CONFIG_FILE=$1 + CONFIG_OPTION=$2 + NEW_SETTING=$3 + + touch $CONFIG_FILE + # first pull out the existing option from the global config and place in a tmp file + awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >${CONFIG_FILE}.tmp + awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >>${CONFIG_FILE}.tmp + + # then copy any remaining settings from the existing config file, minus the option you changed + grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >>${CONFIG_FILE}.tmp || true + sort ${CONFIG_FILE}.tmp | uniq >${CONFIG_FILE} + rm -f ${CONFIG_FILE}.tmp } # Set a config variable in a specific file to a given value - replace it if it # exists, or add it. If added, the variable will be exported. set_config() { - CONFIG_FILE="$1" - CONFIG_OPTION="$2" - NEW_SETTING="$3" - - if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then - replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING" - else - echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE" - fi + CONFIG_FILE="$1" + CONFIG_OPTION="$2" + NEW_SETTING="$3" + + if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then + replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING" + else + echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE" + fi } # Set a value in config.user, re-combine configs, and update configs in the # environment. set_user_config() { - CONFIG_OPTION="$1" - NEW_SETTING="$2" + CONFIG_OPTION="$1" + NEW_SETTING="$2" - set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING" - combine_configs - . /tmp/config + set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING" + combine_configs + . /tmp/config } # Load a config value to a variable, defaulting to empty. Does not fail if the # config is not set (since it would expand to empty by default). load_config_value() { - local config_name="$1" - if grep -q "$config_name=" /tmp/config; then - grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"' - fi + local config_name="$1" + if grep -q "$config_name=" /tmp/config; then + grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"' + fi } -enable_usb() -{ +enable_usb() { TRACE_FUNC - #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning + #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning insmod /lib/modules/ehci-hcd.ko || die "ehci_hcd: module load failed" - + if [ "$CONFIG_LINUX_USB_COMPANION_CONTROLLER" = y ]; then insmod /lib/modules/uhci-hcd.ko || die "uhci_hcd: module load failed" insmod /lib/modules/ohci-hcd.ko || die "ohci_hcd: module load failed" @@ -385,7 +388,6 @@ enable_usb() # ------- End of functions coming from /etc/ash_functions - # Print or depending on whether $1 is empty. Useful to mask an # optional password parameter. mask_param() { @@ -761,11 +763,11 @@ check_tpm_counter() { if [ -r "$1" ]; then TPM_COUNTER=$(grep counter- "$1" | cut -d- -f2) else - LOG "$1 does not exist; creating new TPM counter" + INFO "$1 does not exist; creating new TPM counter" tpmr counter_create \ -pwdc '' \ -la $LABEL | - tee /tmp/counter > /dev/null 2>&1 || + tee /tmp/counter >/dev/null 2>&1 || die "Unable to create TPM counter" TPM_COUNTER=$(cut -d: -f1 /dev/null 2>&1 || + tpmr counter_read -ix "$1" | tee "/tmp/counter-$1" >/dev/null 2>&1 || die "Counter read failed" } @@ -786,7 +788,7 @@ read_tpm_counter() { increment_tpm_counter() { TRACE_FUNC tpmr counter_increment -ix "$1" -pwdc '' | - tee /tmp/counter-$1 > /dev/null 2>&1 || + tee /tmp/counter-$1 >/dev/null 2>&1 || die "TPM counter increment failed for rollback prevention. Please reset the TPM" } @@ -816,7 +818,7 @@ check_config() { fi fi - LOG "+++ Found verified kexec boot params" + INFO "+++ Found verified kexec boot params" cp $1/kexec*.txt /tmp/kexec || die "Failed to copy kexec boot params to tmp" } @@ -1291,7 +1293,7 @@ generate_passphrase() { # level. 4 bytes with modulus 1296 results in 0.000003% bias # toward the first 1263 words. random="$(dd if=/dev/random bs=4 count=1 status=none | hexdump -e '1/4 "%u\n"')" - ((random%=lines)) + ((random %= lines)) ((++random)) # tail's line count is 1-based tail -n +"$random" "$dictionary_file" | head -1 | cut -d$'\t' -f2 } diff --git a/initrd/init b/initrd/init index 9419d9ed4..33b473a56 100755 --- a/initrd/init +++ b/initrd/init @@ -98,9 +98,11 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then #Output all kernel messages to console (8=debug) #DEBUG and TRACE calls will be in dmesg and on console # config.user extracted and combined from CBFS had CONFIG_DEBUG_OUTPUT=y + # DO_WITH_DEBUG redirects stderr and stdout to /tmp/debug.log to not clog console TRACE_FUNC dmesg -n 8 DEBUG "Full debug output enabled from this point: output both in dmesg and on console (equivalent of passing debug to kernel cmdline)" + DEBUG "NOTE: DO_WITH_DEBUG std_err and std_out will be redirected to /tmp/debug.log" fi # report if we are in quiet mode, tell user measurements logs available under /tmp/debug.log diff --git a/initrd/sbin/insmod b/initrd/sbin/insmod index 95e2303c6..b079fcc0c 100755 --- a/initrd/sbin/insmod +++ b/initrd/sbin/insmod @@ -39,19 +39,19 @@ if [ ! -r /sys/class/tpm/tpm0/pcrs -o ! -x /bin/tpm ]; then fi if [ -z "$tpm_missing" ]; then - LOG "TPM: Extending PCR[$MODULE_PCR] with $MODULE and parameters '$*' before loading" + INFO "TPM: Extending PCR[$MODULE_PCR] with $MODULE and parameters '$*' before loading" # Extend with the module parameters (even if they are empty) and the # module. Changing the parameters or the module content will result in a # different PCR measurement. if [ -n "$*" ]; then TRACE_FUNC - LOG "Extending with module parameters and the module's content" + INFO "Extending with module parameters and the module's content" tpmr extend -ix "$MODULE_PCR" -ic "$*" tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ || die "$MODULE: tpm extend failed" else TRACE_FUNC - LOG "No module parameters, extending only with the module's content" + INFO "No module parameters, extending only with the module's content" tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ || die "$MODULE: tpm extend failed" fi From 69037fc0bb5b9de3403c93451f2cf333b3a8ee1b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 15 Jan 2025 15:38:58 -0500 Subject: [PATCH 77/81] BOARD_TESTERS.md: revise board names, add v560tu, add testers expected to answer testing calls Signed-off-by: Thierry Laurion --- BOARD_TESTERS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BOARD_TESTERS.md b/BOARD_TESTERS.md index 4e79f8a26..81ba001d7 100644 --- a/BOARD_TESTERS.md +++ b/BOARD_TESTERS.md @@ -44,8 +44,8 @@ Librems: Clevo: === - [ ] Nitropad NS50 (AlderLake) : @daringer -- [ ] Nitropad NV41 (AlderLake) : @tlaurion @daringer - +- [ ] Novacustom NV4x (AlderLake) : @tlaurion @daringer +- [ ] Novacustom v560tu (MeteorLake) : @tlaurion @daringer @mkopec Desktops/Servers == From bab46bc97b3e602431d0905ab5c91e5e6e5efc5d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 15 Jan 2025 15:41:22 -0500 Subject: [PATCH 78/81] novacustom-v560tu board config: set board to have quiet mode enabled by default Signed-off-by: Thierry Laurion --- boards/novacustom-v560tu/novacustom-v560tu.config | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/boards/novacustom-v560tu/novacustom-v560tu.config b/boards/novacustom-v560tu/novacustom-v560tu.config index 5a216b39d..feeb6ae31 100644 --- a/boards/novacustom-v560tu/novacustom-v560tu.config +++ b/boards/novacustom-v560tu/novacustom-v560tu.config @@ -12,12 +12,6 @@ export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-novacustom-v560tu.config CONFIG_LINUX_CONFIG=config/linux-novacustom-common.config -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=y - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y @@ -71,6 +65,13 @@ export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y +#Enable DEBUG output +export CONFIG_DEBUG_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log +export CONFIG_QUIET_MODE=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n From 392d4561f326b6a96fe0e4a17f3c4cb271b2b8d1 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 15 Jan 2025 21:58:30 -0500 Subject: [PATCH 79/81] typo: s01x -> s0ix Signed-off-by: Thierry Laurion --- boards/novacustom-v560tu/novacustom-v560tu.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/novacustom-v560tu/novacustom-v560tu.config b/boards/novacustom-v560tu/novacustom-v560tu.config index feeb6ae31..f2efdb6bf 100644 --- a/boards/novacustom-v560tu/novacustom-v560tu.config +++ b/boards/novacustom-v560tu/novacustom-v560tu.config @@ -3,7 +3,7 @@ # This excludes gbe from internal flashing, otherwise mac address would revert to '88:88:88:88:87:88' see https://github.com/linuxboot/heads/pull/1871#discussion_r1870134788 # Same options should be used when externally flashing the first time, otherwise Intel GBE region (Ethernet config blob) will be overwitten and MAC reverted to '88:88:88:88:87:88' -# Meteor Lake (Intel Gen 14) is not supposed to support s3 but coincidently does. In case s3 is broken, user must configure settings to not suspend or otherwise enable ME/CSME for s01x to work (unsupported by QubesOS when writing those lines) or use Hibernate (Not supported by QubesOS either) +# Meteor Lake (Intel Gen 14) is not supposed to support s3 but coincidently does. In case s3 is broken, user must configure settings to not suspend or otherwise enable ME/CSME for s0ix to work (unsupported by QubesOS when writing those lines) or use Hibernate (Not supported by QubesOS either) export CONFIG_COREBOOT=y export CONFIG_COREBOOT_VERSION=dasharo From 2872f4462162963a5f88585c1fba07f4b7a3f8ba Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 16 Jan 2025 10:57:03 -0500 Subject: [PATCH 80/81] v560tu: unify board config, remove debug cmdline passed from coreboot to linux kernel Note: qemu coreboot config still pass debug (non quiet, non prod board = debug) config/coreboot-qemu-tpm1.config:173:CONFIG_LINUX_COMMAND_LINE="debug console=ttyS0,115200 console=tty" config/coreboot-qemu-tpm2.config:170:CONFIG_LINUX_COMMAND_LINE="debug console=ttyS0,115200 console=tty" Signed-off-by: Thierry Laurion --- boards/novacustom-v560tu/novacustom-v560tu.config | 1 - .../qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config | 6 ------ .../qemu-coreboot-fbwhiptail-tpm1-prod.config | 6 ------ .../qemu-coreboot-whiptail-tpm1-hotp-prod.config | 6 ------ .../qemu-coreboot-whiptail-tpm1-prod.config | 6 ------ config/coreboot-novacustom-v560tu.config | 2 +- 6 files changed, 1 insertion(+), 26 deletions(-) diff --git a/boards/novacustom-v560tu/novacustom-v560tu.config b/boards/novacustom-v560tu/novacustom-v560tu.config index f2efdb6bf..fb5c172ff 100644 --- a/boards/novacustom-v560tu/novacustom-v560tu.config +++ b/boards/novacustom-v560tu/novacustom-v560tu.config @@ -79,4 +79,3 @@ export CONFIG_BOOT_KERNEL_ADD="" export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOARD_NAME="NovaCustom V560TU" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal --ifd -i bios -i me -i fd" -export CONFIG_AUTO_BOOT_TIMEOUT=5 diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config index dd76f5875..aae15a997 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-hotp-prod/qemu-coreboot-fbwhiptail-tpm1-hotp-prod.config @@ -18,12 +18,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=n - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y diff --git a/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config b/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config index c2eefb677..0fffc9705 100644 --- a/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config +++ b/boards/qemu-coreboot-fbwhiptail-tpm1-prod/qemu-coreboot-fbwhiptail-tpm1-prod.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=n - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y diff --git a/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config b/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config index 1e3ffe80e..3e43e98b8 100644 --- a/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm1-hotp-prod/qemu-coreboot-whiptail-tpm1-hotp-prod.config @@ -18,12 +18,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=n - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y diff --git a/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config b/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config index ee8d56fd5..0c0d57a83 100644 --- a/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config +++ b/boards/qemu-coreboot-whiptail-tpm1-prod/qemu-coreboot-whiptail-tpm1-prod.config @@ -16,12 +16,6 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing)) #export CONFIG_HAVE_GPG_KEY_BACKUP=y -#Enable DEBUG output -#export CONFIG_DEBUG_OUTPUT=y -#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y -#Enable TPM2 pcap output under /tmp -#export CONFIG_TPM2_CAPTURE_PCAP=n - #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y diff --git a/config/coreboot-novacustom-v560tu.config b/config/coreboot-novacustom-v560tu.config index ccc35a770..b2e129646 100644 --- a/config/coreboot-novacustom-v560tu.config +++ b/config/coreboot-novacustom-v560tu.config @@ -216,7 +216,7 @@ CONFIG_PC_CMOS_BASE_PORT_BANK1=0x72 CONFIG_FSP_TEMP_RAM_SIZE=0x20000 CONFIG_EC_GPE_SCI=0x50 CONFIG_TPM_MEASURED_BOOT=y -CONFIG_LINUX_COMMAND_LINE="debug" +CONFIG_LINUX_COMMAND_LINE="quiet loglevel=2" CONFIG_BOARD_ROMSIZE_KB_32768=y # CONFIG_COREBOOT_ROMSIZE_KB_256 is not set # CONFIG_COREBOOT_ROMSIZE_KB_512 is not set From 22a86e6d48977e87344460dc3618768486e7fcba Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Thu, 16 Jan 2025 09:55:16 -0500 Subject: [PATCH 81/81] oem-factory-reset: Only badger user to record passphrases if generated There are many flows through oem-factory-reset that use passwords provided by the user or basic defaults to be changed later. We don't need to badger the user to record those passwords. Still do this if we generated diceware passwords though, as the user does not know them yet. Signed-off-by: Jonathon Hall --- initrd/bin/oem-factory-reset | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index b504ec956..db8b330ef 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -42,6 +42,10 @@ GPG_ALGO="RSA" # Default RSA key length is 3072 bits for OEM key gen. 4096 are way longer to generate in smartcard RSA_KEY_LENGTH=3072 +# If we use complex generated passphrases, we will really try hard to make the +# user record them +MAKE_USER_RECORD_PASSPHRASES= + # Function to handle --mode parameter handle_mode() { local mode=$1 @@ -52,6 +56,8 @@ handle_mode() { USER_PIN=$CUSTOM_SINGLE_PASS ADMIN_PIN=$CUSTOM_SINGLE_PASS TPM_PASS=$CUSTOM_SINGLE_PASS + # User doesn't know this password, really badger them to record it + MAKE_USER_RECORD_PASSPHRASES=y title_text="OEM Factory Reset Mode" ;; @@ -60,6 +66,8 @@ handle_mode() { USER_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) ADMIN_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) TPM_PASS=$ADMIN_PIN + # User doesn't know this password, really badger them to record it + MAKE_USER_RECORD_PASSPHRASES=y title_text="User Re-Ownership Mode" ;; @@ -1078,6 +1086,10 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then if [ -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then luks_new_Disk_Recovery_Key_passphrase=${CUSTOM_SINGLE_PASS} fi + + # The user knows this password, we don't need to badger them to + # record it + MAKE_USER_RECORD_PASSPHRASES= else echo -e -n "Would you like to set distinct PINs/passwords to configure previously stated security components? [y/N]: " read -n 1 prompt_output @@ -1108,6 +1120,9 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then done fi echo + # The user knows these passwords, we don't need to + # badger them to record them + MAKE_USER_RECORD_PASSPHRASES= fi fi @@ -1429,6 +1444,11 @@ fi while true; do whiptail --msgbox "$(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ $HEIGHT $WIDTH --title "Configured secrets" + if [ "$MAKE_USER_RECORD_PASSPHRASES" != y ]; then + # Passwords were user-supplied or not complex, we do not need to + # badger the user to record them + break + fi #Tell user to scan the QR code containing all configured secrets echo -e "\nScan the QR code below to save the secrets to a secure location" qrenc "$(echo -e "$passphrases")"