From b5005053123bc234d4481f96475cd6e89e71778b Mon Sep 17 00:00:00 2001 From: Jonathon Hall Date: Wed, 22 Feb 2023 16:30:07 -0500 Subject: [PATCH] tpm2-tools: Change sense of CONFIG_TPM to mean any TPM, not just TPM1. Most logic throughout Heads doesn't need to know TPM1 versus TPM2 (and shouldn't, the differences should be localized). Some checks were incorrect and are fixed by this change. Most checks are now unchanged relative to master. There are not that many places outside of tpmr that need to differentiate TPM1 and TPM2. Some of those are duplicate code that should be consolidated (seal-hotpkey, unseal-totp, unseal-hotp), and some more are probably good candidates for abstracting in tpmr so the business logic doesn't have to know TPM1 vs. TPM2. Previously, CONFIG_TPM could be variously 'y', 'n', or empty. Now it is always 'y' or 'n', and 'y' means "any TPM". Board configs are unchanged, setting CONFIG_TPM2_TOOLS=y implies CONFIG_TPM=y so this doesn't have to be duplicated and can't be mistakenly mismatched. There were a few checks for CONFIG_TPM = n that only coincidentally worked for TPM2 because CONFIG_TPM was empty (not 'n'). This test is now OK, but the checks were also cleaned up to '!= "y"' for robustness. Signed-off-by: Jonathon Hall --- initrd/bin/cbfs-init | 2 +- initrd/bin/config-gui.sh | 2 +- initrd/bin/gui-init | 4 ++-- initrd/bin/kexec-save-default | 4 ++-- initrd/bin/kexec-seal-key | 2 +- initrd/bin/kexec-select-boot | 6 ++--- initrd/bin/kexec-unseal-key | 44 +++++++++++++++++------------------ initrd/bin/oem-factory-reset | 14 +++++------ initrd/bin/seal-hotpkey | 2 +- initrd/bin/seal-totp | 2 +- initrd/bin/tpm-reset | 8 +++---- initrd/bin/tpmr | 9 ++++--- initrd/bin/uefi-init | 2 +- initrd/bin/unseal-hotp | 6 ++--- initrd/bin/unseal-totp | 8 +++---- initrd/bin/usb-init | 2 +- initrd/etc/functions | 12 +++++----- initrd/init | 8 ++++--- modules/tpm2-tools | 7 ++++++ 19 files changed, 75 insertions(+), 69 deletions(-) diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 4125257a..5343db7a 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -20,7 +20,7 @@ for cbfsname in `echo $cbfsfiles`; do || die "$filename: mkdir failed" cbfs -t 50 -r $cbfsname > "$filename" \ || die "$filename: cbfs file read failed" - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then TMPFILE=/tmp/cbfs.$$ echo "$filename" > $TMPFILE cat $filename >> $TMPFILE diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index e2407eb9..071248ba 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -126,7 +126,7 @@ while true; do # flash cleared ROM /bin/flash.sh -c /tmp/config-gui.rom # reset TPM if present - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then /bin/tpm-reset fi whiptail --title 'Configuration Reset Updated Successfully' \ diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 640347b2..5b772f77 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -173,7 +173,7 @@ update_totp() TRACE "Under /bin/gui-init:update_totp" # update the TOTP code date=`date "+%Y-%m-%d %H:%M:%S %Z"` - if [ "$CONFIG_TPM" = n ]; then + if [ "$CONFIG_TPM" != "y" ]; then TOTP="NO TPM" else TOTP=`unseal-totp` @@ -513,7 +513,7 @@ prompt_totp_mismatch() reset_tpm() { TRACE "Under /bin/gui-init:reset_tpm" - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then if (whiptail $BG_COLOR_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 /bin/tpm-reset diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index 75db0fec..42617877 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -48,7 +48,7 @@ fi KEY_DEVICES="$paramsdir/kexec_key_devices.txt" KEY_LVM="$paramsdir/kexec_key_lvm.txt" save_key="n" -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ]; then +if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ]; then if [ ! -r "$KEY_DEVICES" ]; then read \ -n 1 \ @@ -186,7 +186,7 @@ fi # sign and auto-roll config counter extparam= -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ];then +if [ "$CONFIG_TPM" = "y" ];then if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then extparam=-r fi diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 6d7ebf5b..828b7fbb 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -91,7 +91,7 @@ done cat "$KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \ || die "Unable to measure the LUKS headers" -if [ "$CONFIG_TPM" = "y" ];then +if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM2_TOOLS" != "y" ]; then luks_pcr=`tpm calcfuturepcr -ix 16 -if /tmp/luksDump.txt` # HOTP USB Secrity Dongle loads USB modules which changes PCR5. # In the event HOTP USB Security Dongle is enabled, skip verification of PCR5 diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 756b7d55..b71f5b22 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -315,7 +315,7 @@ do_boot() die "!!! Missing required boot hashes" fi - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then + if [ "$CONFIG_TPM" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then INITRD=`kexec-boot -b "$bootdir" -e "$option" -i` \ || die "!!! Failed to extract the initrd from boot option" if [ -z "$INITRD" ]; then @@ -359,7 +359,7 @@ while true; do user_select fi - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible tpmr extend -ix 4 -ic generic \ @@ -372,7 +372,7 @@ while true; do scan_options fi - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then # Optionally enforce device file hashes if [ -r "$TMP_HASH_FILE" ]; then valid_global_hash="n" diff --git a/initrd/bin/kexec-unseal-key b/initrd/bin/kexec-unseal-key index 7db78ac7..2949a54c 100755 --- a/initrd/bin/kexec-unseal-key +++ b/initrd/bin/kexec-unseal-key @@ -23,7 +23,28 @@ echo "DEBUG: CONFIG_TPM2_TOOLS: $CONFIG_TPM2_TOOLS" echo "DEBUG: Show PCRs" pcrs -if [ "$CONFIG_TPM" = "y" ];then +if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_ATTEST_TOOLS" = "y" ]; then + echo "Bring up network for remote attestation" + network-init-recovery + fi + for tries in 1 2 3; do + if [ "$CONFIG_AUTO_UNLOCK" = "y" ]; then + tpmr unseal "0x8100000$TPM_INDEX" "sha256:0,1,2,3,4,5,6,7" > "$key_file" + else + tpmr unseal "0x8100000$TPM_INDEX" "sha256:0,1,2,3,4,5,6,7" "file:-" > "$key_file" + fi + + if [ $? -eq 0 ]; then + # should be okay if this fails + shred -n 10 -z -u /tmp/secret/sealed 2> /dev/null || true + exit 0 + fi + + pcrs + warn "Unable to unseal disk encryption key" + done +elif [ "$CONFIG_TPM" = "y" ]; then tpm nv_readvalue \ -in "$TPM_INDEX" \ -sz "$TPM_SIZE" \ @@ -59,27 +80,6 @@ if [ "$CONFIG_TPM" = "y" ];then pcrs warn "Unable to unseal disk encryption key" done -elif [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - if [ "$CONFIG_ATTEST_TOOLS" = "y" ]; then - echo "Bring up network for remote attestation" - network-init-recovery - fi - for tries in 1 2 3; do - if [ "$CONFIG_AUTO_UNLOCK" = "y" ]; then - tpmr unseal "0x8100000$TPM_INDEX" "sha256:0,1,2,3,4,5,6,7" > "$key_file" - else - tpmr unseal "0x8100000$TPM_INDEX" "sha256:0,1,2,3,4,5,6,7" "file:-" > "$key_file" - fi - - if [ $? -eq 0 ]; then - # should be okay if this fails - shred -n 10 -z -u /tmp/secret/sealed 2> /dev/null || true - exit 0 - fi - - pcrs - warn "Unable to unseal disk encryption key" -done fi die "Retry count exceeded..." diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 2871e7f4..74f1cc6e 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -184,7 +184,7 @@ generate_checksums() rm /boot/kexec* 2>/dev/null # create Heads TPM counter - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ];then + if [ "$CONFIG_TPM" = "y" ];then if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then tpmr counter_create \ -pwdo "$TPM_PASS_DEF" \ @@ -309,7 +309,7 @@ report_integrity_measurements() date=`date "+%Y-%m-%d %H:%M:%S %Z"` seconds=`date "+%s"` half=`expr \( $seconds % 60 \) / 30` - if [ "$CONFIG_TPM" != "y" -a "$CONFIG_TPM2_TOOLS" != "y" ]; then + if [ "$CONFIG_TPM" != "y" ]; then TOTP="NO TPM" elif [ "$half" != "$last_half" ]; then last_half=$half; @@ -372,7 +372,7 @@ else fi # show warning prompt -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ]; then TPM_STR=" * ERASE the TPM and own it with a password\n" else TPM_STR="" @@ -418,7 +418,7 @@ fi 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" fi -if [ "$CONFIG_TPM" = "y" ] || [ "$CONFIG_TPM2_TOOLS" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ]; then CUSTOM_PASS_AFFECTED_COMPONENTS="$CUSTOM_PASS_AFFECTED_COMPONENTS TPM Ownership password" fi @@ -461,7 +461,7 @@ else ; then echo -e "\nThey must be each at least 8 characters in length.\n" echo - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then while [[ ${#TPM_PASS} -lt 8 ]] ; do echo -e -n "Enter desired TPM Ownership password: " read TPM_PASS @@ -608,7 +608,7 @@ elif [ -z "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_K fi ## reset TPM and set password -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ]; then echo -e "\nResetting TPM...\n" { echo $TPM_PASS @@ -723,7 +723,7 @@ else $luks_new_Disk_Recovery_Key_passphrase" fi -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ]; then tpm_password_changed=" TPM Owner Password: $TPM_PASS\n" else diff --git a/initrd/bin/seal-hotpkey b/initrd/bin/seal-hotpkey index dc14dee5..cd4a0157 100755 --- a/initrd/bin/seal-hotpkey +++ b/initrd/bin/seal-hotpkey @@ -27,7 +27,7 @@ else HOTPKEY_BRANDING="HOTP USB Security Dongle" fi -if [ "$CONFIG_TPM" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM2_TOOLS" != "y" ]; then tpm nv_readvalue \ -in 4d47 \ -sz 312 \ diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 6213edb0..53bd89b6 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -28,7 +28,7 @@ dd \ || die "Unable to generate 20 random bytes" secret="`base32 < $TOTP_SECRET`" -if [ "$CONFIG_TPM" = "y" ];then +if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM2_TOOLS" != "y" ]; then # Use the current values of the PCRs, which will be read # from the TPM as part of the sealing ("X"). # PCR4 == 0 means that we are still in the boot process and diff --git a/initrd/bin/tpm-reset b/initrd/bin/tpm-reset index a7d3aab5..220e15a9 100755 --- a/initrd/bin/tpm-reset +++ b/initrd/bin/tpm-reset @@ -20,7 +20,9 @@ if [ "$key_password" != "$key_password2" ]; then die "Key passwords do not match" fi -if [ "$CONFIG_TPM" = "y" ]; then +if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then + tpmr reset "$key_password" +elif [ "$CONFIG_TPM" = "y" ]; then # Make sure the TPM is ready to be reset tpm physicalpresence -s tpm physicalenable @@ -34,7 +36,3 @@ if [ "$CONFIG_TPM" = "y" ]; then tpm physicalenable tpm physicalsetdeactivated -c fi - -if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - tpmr reset "$key_password" -fi diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 714d9ef9..65b36b01 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -16,12 +16,11 @@ else . /etc/config fi -# tpm1 does not need to convert options -if [ "$CONFIG_TPM" = "y" ]; then - exec tpm "$@" -fi - if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then + # tpm1 does not need to convert options + if [ "$CONFIG_TPM" = "y" ]; then + exec tpm "$@" + fi echo >&2 "No TPM2!" exit 1 fi diff --git a/initrd/bin/uefi-init b/initrd/bin/uefi-init index e7c63b99..8f9de1b3 100755 --- a/initrd/bin/uefi-init +++ b/initrd/bin/uefi-init @@ -18,7 +18,7 @@ if [ -n "GUID" ]; then uefi -r $GUID | gunzip -c > $TMPFILE \ || die "Failed to read config GUID from ROM" - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then tpmr extend -ix "$CONFIG_PCR" -if $TMPFILE \ || die "$filename: tpm extend failed" fi diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 8772d069..70ff37bd 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -38,7 +38,9 @@ if [ "$counter_value" == "" ]; then fi #counter_value=$(printf "%d" 0x${counter_value}) -if [ "$CONFIG_TPM" = "y" ]; then +if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then + tpmr unseal 0x81004d47 sha256:0,1,2,3,4,7 >> "$HOTP_SECRET" +elif [ "$CONFIG_TPM" = "y" ]; then tpm nv_readvalue \ -in 4d47 \ -sz 312 \ @@ -50,8 +52,6 @@ if [ "$CONFIG_TPM" = "y" ]; then -if "$HOTP_SEALED" \ -of "$HOTP_SECRET" \ || die "Unable to unseal HOTP secret" -elif [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - tpmr unseal 0x81004d47 sha256:0,1,2,3,4,7 >> "$HOTP_SECRET" fi shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index 88f17736..44ad8c9e 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -8,7 +8,10 @@ TOTP_SECRET="/tmp/secret/totp.key" TRACE "Under /bin/unseal-totp" -if [ "$CONFIG_TPM" = "y" ]; then +if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then + tpmr unseal 0x81004d47 sha256:0,1,2,3,4,7 > "$TOTP_SECRET" \ + || die "Unable to unseal totp secret" +elif [ "$CONFIG_TPM" = "y" ]; then tpm nv_readvalue \ -in 4d47 \ -sz 312 \ @@ -20,9 +23,6 @@ if [ "$CONFIG_TPM" = "y" ]; then -if "$TOTP_SEALED" \ -of "$TOTP_SECRET" \ || die "Unable to unseal totp secret" -elif [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - tpmr unseal 0x81004d47 sha256:0,1,2,3,4,7 > "$TOTP_SECRET" \ - || die "Unable to unseal totp secret" fi shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null diff --git a/initrd/bin/usb-init b/initrd/bin/usb-init index 5ac53409..b2d3783f 100755 --- a/initrd/bin/usb-init +++ b/initrd/bin/usb-init @@ -6,7 +6,7 @@ TRACE "Under /bin/usb-init" -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then +if [ "$CONFIG_TPM" = "y" ]; then # Extend PCR4 as soon as possible tpmr extend -ix 4 -ic usb fi diff --git a/initrd/etc/functions b/initrd/etc/functions index 56a9cf0a..3591b056 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -41,7 +41,7 @@ recovery() { # ensure /tmp/config exists for recovery scripts that depend on it touch /tmp/config - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then tpmr extend -ix 4 -ic recovery fi @@ -65,10 +65,10 @@ pause_recovery() { } pcrs() { - if [ "$CONFIG_TPM" = "y" ]; then - head -8 /sys/class/tpm/tpm0/pcrs - elif [ "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then tpm2 pcrread sha256 + elif [ "$CONFIG_TPM" = "y" ]; then + head -8 /sys/class/tpm/tpm0/pcrs fi } @@ -85,7 +85,7 @@ confirm_totp() date=`date "+%Y-%m-%d %H:%M:%S"` seconds=`date "+%s"` half=`expr \( $seconds % 60 \) / 30` - if [ "$CONFIG_TPM" != "y" -a "$CONFIG_TPM2_TOOLS" != "y" ]; then + if [ "$CONFIG_TPM" != "y" ]; then TOTP="NO TPM" elif [ "$half" != "$last_half" ]; then last_half=$half; @@ -362,7 +362,7 @@ update_checksums() # sign and auto-roll config counter extparam= - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ];then + if [ "$CONFIG_TPM" = "y" ];then if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then extparam=-r fi diff --git a/initrd/init b/initrd/init index 07b3b249..f4cf78a6 100755 --- a/initrd/init +++ b/initrd/init @@ -115,18 +115,20 @@ if [ "$boot_option" = "r" ]; then # Start an interactive shell recovery 'User requested recovery shell' # just in case... - if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = "y" ]; then + if [ "$CONFIG_TPM" = "y" ]; then tpmr extend -ix 4 -ic recovery fi exec /bin/bash exit fi -# Override CONFIG_TPM from /etc/config with runtime value determined above. +# 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. echo "export CONFIG_TPM=\"$CONFIG_TPM\"" >> /etc/config.user +echo "export CONFIG_TPM2_TOOLS=\"$CONFIG_TPM2_TOOLS\"" >> /etc/config.user combine_configs . /tmp/config @@ -172,7 +174,7 @@ else fi # belts and suspenders, just in case... -if [ "$CONFIG_TPM" = "y" -o "$CONFIG_TPM2_TOOLS" = y ]; then +if [ "$CONFIG_TPM" = "y" ]; then tpmr extend -ix 4 -ic recovery fi exec /bin/bash diff --git a/modules/tpm2-tools b/modules/tpm2-tools index 54384376..98711195 100644 --- a/modules/tpm2-tools +++ b/modules/tpm2-tools @@ -1,6 +1,13 @@ # TPM2 tools program modules-$(CONFIG_TPM2_TOOLS) += tpm2-tools +# CONFIG_TPM means any TPM version. (CONFIG_TPM2_TOOLS differentiates them when +# they must be handled differently, which should be localized.) Boards setting +# CONFIG_TPM2_TOOLS=y imply CONFIG_TPM=y. +ifeq "$(CONFIG_TPM2_TOOLS)" "y" + export CONFIG_TPM=y +endif + tpm2-tools_version := 5.2 #tpm2-tools_version := 78a7681 #tpm2-tools_repo := https://github.com/tpm2-software/tpm2-tools.git