Skip to content

Commit

Permalink
Merge pull request #1625 from tlaurion:LUKS_header_change_validation_…
Browse files Browse the repository at this point in the history
…upon_sealing_and_unsealing

LUKS header change validation upon sealing and unsealing ops
  • Loading branch information
tlaurion authored Apr 25, 2024
2 parents ba63b18 + fb5cbf4 commit b2629f8
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 13 deletions.
4 changes: 2 additions & 2 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ your disk password, which is perhaps an improvement.

Disk key in TPM (LUKS TPM Disk Unlock Key) or user passphrase?
---
Depends on your threat model. With the disk key in the TPM an attacker
would need to have the entire machine (or a backdoor in the TPM)
Depends on your threat model. With the Disk Unlock Key in the TPM an
attacker would need to have the entire machine (or a backdoor in the TPM)
to get the key and their attempts to unlock it can be rate limited
by the TPM hardware.

Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -793,3 +793,5 @@ real.clean:
fi; \
done
cd install && rm -rf -- *
real.gitclean:
git clean -fxd
25 changes: 20 additions & 5 deletions initrd/bin/kexec-insert-key
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Unseal a disk key from TPM and add to a new initramfs
# Unseal a LUKS Disk Unlock Key from TPM and add to a new initramfs
set -e -o pipefail
. /etc/functions

Expand Down Expand Up @@ -28,7 +28,7 @@ if [ -r "$TMP_KEY_LVM" ]; then
die "$VOLUME_GROUP: unable to activate volume group"
fi

# Measure the LUKS headers before we unseal the disk key
# Measure the LUKS headers before we unseal the LUKS Disk Unlock Key from TPM
cat "$TMP_KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks ||
die "LUKS measure failed"

Expand All @@ -40,13 +40,28 @@ SECRET_CPIO=/tmp/secret/initrd.cpio
bootdir=$(dirname "$INITRD")
mkdir -p "$INITRD_DIR/etc"

# Attempt to unseal the disk key from the TPM
if [ -e /boot/kexec_lukshdr_hash.txt ] && [ -e /tmp/luksDump.txt ]; then
if ! cmp -s /boot/kexec_lukshdr_hash.txt /tmp/luksDump.txt >/dev/null 2>&1; then
#LUKS header hash part of detached signed hash digest under boot doesn't match qubes-measure-luks tmp file
warn "Encrypted disk keys have changed since the TPM Disk Unlock Key was sealed. If you did not make this change, the disk may be compromised"
exit 1
else
#LUKS header hash part of detached signed hash digest matches
echo "+++ Encrypted disk keys have not been changed since sealed in TPM Disk Unlock Key"
#TODO: remove "+++" with boot info helper when added, same with "!!!" currently for info.
fi
else
warn "Could not check for tampering of Encrypted disk keys"
warn "Re-seal the TPM Disk Unlock Key by re-selecting your default boot option to enable this check (Options -> Boot Options -> Show OS boot menu)."
fi

# Attempt to unseal the Disk Unlock Key from the TPM
# should we give this some number of tries?
unseal_failed="n"
if ! kexec-unseal-key "$INITRD_DIR/secret.key"; then
unseal_failed="y"
echo
echo "!!! Failed to unseal the TPM LUKS disk key"
echo "!!! Failed to unseal the TPM LUKS Disk Unlock Key"
fi

# Override PCR 4 so that user can't read the key
Expand All @@ -67,7 +82,7 @@ if [ "$unseal_failed" = "y" ]; then
-a "$confirm_boot" != 'Y' \
-a -n "$confirm_boot" ] \
; then
die "!!! Aborting boot due to failure to unseal TPM disk key"
die "!!! Aborting boot due to failure to unseal TPM Disk Unlock Key"
fi
fi

Expand Down
2 changes: 1 addition & 1 deletion initrd/bin/kexec-save-default
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [
DEBUG "LUKS TPM Disk Unlock Key was previously set up from $KEY_DEVICES"
read \
-n 1 \
-p "Do you want to reseal a disk key to the TPM [y/N]: " \
-p "Do you want to reseal a Disk Unlock Key in the TPM [y/N]: " \
change_key_confirm
echo

Expand Down
4 changes: 3 additions & 1 deletion initrd/bin/kexec-select-boot
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
else
warn "Hash of TPM2 primary key handle does not exist"
warn "Please rebuild the boot hash tree"
warn "Select Options-> Update checksums and sign all files in /boot"
#TODO: Simplify/Automatize TPM2 firmware upgrade process. Today: upgrade, reboot, reseal(type TPM owner pass), resign, boot
default_failed="y"
DEBUG "Hash of TPM2 primary key handle does not exist under $PRIMHASH_FILE"
fi
Expand Down Expand Up @@ -340,7 +342,7 @@ do_boot() {
fi

kexec-insert-key $INITRD ||
die "!!! Failed to insert disk key into a new initrd"
die "!!! Failed to prepare TPM Disk Unlock Key for boot"

kexec-boot -b "$bootdir" -e "$option" \
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" ||
Expand Down
3 changes: 1 addition & 2 deletions initrd/bin/kexec-unseal-key
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ for tries in 1 2 3; do
exit 0
fi

DEBUG $(pcrs)
warn "Unable to unseal disk encryption key"
warn "Unable to unseal LUKS Disk Unlock Key from TPM"
done

die "Retry count exceeded..."
2 changes: 1 addition & 1 deletion initrd/bin/oem-factory-reset
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
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 encrypted disk key, content and passphrase
# 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
Expand Down
2 changes: 1 addition & 1 deletion initrd/init
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
# running out of the ram disk. There are no fileysstems mounted.
# It is important to have a way to invoke a recovery shell in case
# the boot scripts are messed up, but also important to modify the
# PCRs if this happens to prevent the TPM disk keys from being revealed.
# PCRs if this happens to prevent the TPM Disk Unlock Keys from being revealed.

# First thing it is vital to mount the /dev and other system directories
mkdir /proc /sys /dev /tmp /boot /media 2>&- 1>&-
Expand Down

0 comments on commit b2629f8

Please sign in to comment.