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 cdcd3946c..2b46cf46a 100644 --- a/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config +++ b/boards/qemu-coreboot-whiptail-tpm2/qemu-coreboot-whiptail-tpm2.config @@ -17,10 +17,10 @@ CONFIG_LINUX_CONFIG=config/linux-qemu.config #export CONFIG_HAVE_GPG_KEY_BACKUP=y #Enable DEBUG output -export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y +#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=y #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y diff --git a/initrd/bin/cbfs-init b/initrd/bin/cbfs-init index 09456198d..c54991f41 100755 --- a/initrd/bin/cbfs-init +++ b/initrd/bin/cbfs-init @@ -15,17 +15,19 @@ cbfsfiles=`cbfs -t 50 -l 2>/dev/null | grep "^heads/initrd/"` for cbfsname in `echo $cbfsfiles`; do filename=${cbfsname:12} if [ ! -z "$filename" ]; then - echo "Loading $filename from CBFS" mkdir -p `dirname $filename` \ || die "$filename: mkdir failed" - cbfs -t 50 -r $cbfsname > "$filename" \ + echo "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 - TMPFILE=/tmp/cbfs.$$ - echo "$filename" > $TMPFILE - cat $filename >> $TMPFILE - DEBUG "Extending TPM PCR $CONFIG_PCR with $filename" - tpmr extend -ix "$CONFIG_PCR" -if $TMPFILE \ + TRACE_FUNC + echo "TPM: Extending PCR[$CONFIG_PCR] with $filename" + # Measure both the filename and its content. This + # ensures that renaming files or pivoting file content + # will still affect the resulting PCR measurement. + tpmr extend -ix "$CONFIG_PCR" -ic "$filename" + tpmr extend -ix "$CONFIG_PCR" -if "$filename" \ || die "$filename: tpm extend failed" fi fi diff --git a/initrd/bin/flash.sh b/initrd/bin/flash.sh index 00f2801f1..845d46617 100755 --- a/initrd/bin/flash.sh +++ b/initrd/bin/flash.sh @@ -48,9 +48,9 @@ flash_rom() { dd if=/tmp/pchstrp9.bin bs=1 count=4 seek=292 of=/tmp/${CONFIG_BOARD}.rom conv=notrunc >/dev/null 2>&1 fi - warn "Do not power off computer. Updating firmware, this will take a few minutes..." + warn "Do not power off computer. Updating firmware, this will take a few minutes" flashrom $CONFIG_FLASHROM_OPTIONS -w /tmp/${CONFIG_BOARD}.rom 2>&1 \ - || die "$ROM: Flash failed" + || recovery "$ROM: Flash failed" fi } diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 8f7cd502b..0028e348e 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -65,7 +65,8 @@ if ! kexec-unseal-key "$INITRD_DIR/secret.key"; then fi # Override PCR 4 so that user can't read the key -DEBUG "Extending TPM PCR 4 to prevent further secret unsealing" +TRACE_FUNC +echo "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 a58972662..b3b55c302 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -384,9 +384,10 @@ while true; do if [ "$CONFIG_TPM" = "y" ]; then if [ ! -r "$TMP_KEY_DEVICES" ]; then # Extend PCR4 as soon as possible - DEBUG "Extending TPM PCR 4 to prevent further secret unsealing" + TRACE_FUNC + DEBUG "TPM: Extending PCR[4] to prevent further secret unsealing" tpmr extend -ix 4 -ic generic || - die "Failed to extend PCR 4" + die "Failed to extend TPM PCR[4]" fi fi diff --git a/initrd/bin/qubes-measure-luks b/initrd/bin/qubes-measure-luks index 4f0ca281e..bef6fb102 100755 --- a/initrd/bin/qubes-measure-luks +++ b/initrd/bin/qubes-measure-luks @@ -19,6 +19,7 @@ sha256sum /tmp/lukshdr-* >/tmp/luksDump.txt || die "Unable to hash LUKS headers" DEBUG "Removing /tmp/lukshdr-*" rm /tmp/lukshdr-* -DEBUG "Extending TPM PCR 6 with hash of LUKS headers from /tmp/luksDump.txt" +TRACE_FUNC +echo "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 a740d4a03..78b71ea1f 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -29,11 +29,11 @@ else . /etc/config fi -TRACE_FUNC # 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() { + TRACE_FUNC sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf } @@ -43,6 +43,7 @@ hex2bin() { # as a file still chokes if the password begins with 'hex:', oddly tpm2-tools # accepts 'hex:' in the file content.) tpm2_password_hex() { + TRACE_FUNC echo "hex:$(echo -n "$1" | xxd -p | tr -d ' \n')" } @@ -61,7 +62,7 @@ tpm2_pcrread() { if [ -z "$APPEND" ]; then # Don't append - truncate file now so real command always - # appends + # overwrites true >"$file" fi @@ -79,7 +80,7 @@ tpm1_pcrread() { if [ -z "$APPEND" ]; then # Don't append - truncate file now so real command always - # appends + # overwrites true >"$file" fi @@ -100,11 +101,12 @@ is_hash() { # extend_pcr_state - extend a PCR state value with more hashes or raw data (which is hashed) # usage: -# extend_pcr_state +# extend_pcr_state # alg - either 'sha1' or 'sha256' to specify algorithm -# initial_state - a hash value setting the initial state +# state - a hash value setting the initial state # files/hashes... - any number of files or hashes, state is extended once for each item extend_pcr_state() { + TRACE_FUNC local alg="$1" local state="$2" local next extend @@ -233,14 +235,20 @@ tpm2_extend() { while true; do case "$1" in -ix) + # store index and shift so -ic and -if can be processed index="$2" shift 2 ;; -ic) + string=$(echo -n "$2") hash="$(echo -n "$2" | sha256sum | cut -d' ' -f1)" + TRACE_FUNC + DEBUG "TPM: Will extend PCR[$index] with hash of string $string" shift 2 ;; -if) + TRACE_FUNC + DEBUG "TPM: Will extend PCR[$index] with hash of file content $2" hash="$(sha256sum "$2" | cut -d' ' -f1)" shift 2 ;; @@ -250,7 +258,10 @@ tpm2_extend() { esac done tpm2 pcrextend "$index:sha256=$hash" - DO_WITH_DEBUG tpm2 pcrread "sha256:$index" + tpm2 pcrread "sha256:$index" + + TRACE_FUNC + DEBUG "TPM: Extended PCR[$index] with hash $hash" } tpm2_counter_read() { @@ -348,9 +359,9 @@ tpm2_startsession() { die "tpm2_flushcontext: unable to flush saved session" tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE" #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" 2>&1 > /dev/null + 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" 2>&1 > /dev/null + 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" } @@ -381,6 +392,7 @@ cleanup_shred() { # tpm2_destroy: Destroy a sealed file in the TPM. The mechanism differs by # TPM version - TPM2 evicts the file object, so it no longer exists. tpm2_destroy() { + TRACE_FUNC index="$1" # Index of the sealed file size="$2" # Size of zeroes to overwrite for TPM1 (unused in TPM2) @@ -396,6 +408,7 @@ tpm2_destroy() { # TPM version - TPM1 overwrites the file with zeroes, since this can be done # without authorization. (Deletion requires authorization.) tpm1_destroy() { + TRACE_FUNC index="$1" # Index of the sealed file size="$2" # Size of zeroes to overwrite for TPM1 @@ -761,6 +774,21 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then shift tpm1_destroy "$@" ;; + extend) + #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)" + elif [ "$4" = "-ic" ]; then + string=$(echo -n "$5") + DEBUG "TPM: Will extend PCR[$3] with hash of filename $string" + hash="$(echo -n "$5" | sha1sum | cut -d' ' -f1)" + fi + + TRACE_FUNC + DEBUG "TPM: Extending PCR[$3] with hash $hash" + DO_WITH_DEBUG exec tpm "$@" + ;; seal) shift tpm1_seal "$@" @@ -799,6 +827,8 @@ calcfuturepcr) replay_pcr "sha256" "$@" ;; extend) + TRACE_FUNC + DEBUG "TPM: Extending PCR[$2] with $4" tpm2_extend "$@" ;; counter_read) diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 54b721085..f8b9f79ea 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -241,7 +241,8 @@ recovery() { DEBUG "Board $CONFIG_BOARD - version $(fw_version)" if [ "$CONFIG_TPM" = "y" ]; then - DEBUG "Extending TPM PCR 4 for recovery shell access" + TRACE_FUNC + echo "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 97614fc65..359bf68f6 100755 --- a/initrd/sbin/insmod +++ b/initrd/sbin/insmod @@ -28,7 +28,7 @@ fi # Unify lsmod output to use - instead of _ for comparison module_name=$(basename "$MODULE" | sed 's/_/-/g' | sed 's/\.ko$//') if lsmod | sed 's/_/-/g' | grep -q "^$module_name\\b"; then - DEBUG "$MODULE: already loaded" + DEBUG "$MODULE: already loaded, skipping" exit 0 fi @@ -39,18 +39,22 @@ if [ ! -r /sys/class/tpm/tpm0/pcrs -o ! -x /bin/tpm ]; then fi if [ -z "$tpm_missing" ]; then - DEBUG "Extending TPM PCR $MODULE_PCR with $MODULE prior of usage" - tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ - || die "$MODULE: tpm extend failed" -fi - -if [ ! -z "$*" -a -z "$tpm_missing" ]; then - DEBUG "Extending TPM PCR $MODULE_PCR with $*" - TMPFILE=/tmp/insmod.$$ - echo "$@" > $TMPFILE - DEBUG "Extending TPM PCR $MODULE_PCR with $MODULE prior of usage" - tpmr extend -ix "$MODULE_PCR" -if $TMPFILE \ - || die "$MODULE: tpm extend on arguments failed" + echo "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" + 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" + tpmr extend -ix "$MODULE_PCR" -if "$MODULE" \ + || die "$MODULE: tpm extend failed" + fi fi # Since we have replaced the real insmod, we must invoke