TPM disk encryption keys for Qubes.

Issue #123: This streamline Qubes startup experience by
making it possible to have a single-password decryption.

Issue #29: The disk keys in `/secret.key` are passed to the systemd
in initramfs through `/etc/crypttab`, which is generated on each boot.
This is slow; need to look at alternate ways.

Issue #110: By using LVM instead of partitions it is now
possible to find the root filesystem in a consistent way.

Issue #80: LVM is now included in the ROM.
This commit is contained in:
Trammell Hudson 2017-04-03 17:18:11 -04:00
parent 3d79f51e4a
commit 39cb4031f4
Failed to extract signature
3 changed files with 58 additions and 18 deletions

View File

@ -16,6 +16,11 @@ die() {
}
warn() { echo >&2 "$@"; }
# Activate the LVM volume group
VOLUME_GROUP=qubes_dom0
lvm vgchange -a y $VOLUME_GROUP \
|| die "$VOLUME_GROUP: unable to activate volume group"
# Key slot 0 is the manual recovery pass phrase
# that they user entered when they installed Qubes,
# key slot 1 is the one that we've generated.
@ -23,7 +28,8 @@ read -s -p "Enter disk recovery key: " disk_password
echo -n "$disk_password" > /tmp/recovery.key
echo
for dev in $CONFIG_QUBES_DEVS; do
# Remove all the old keys from slot 1
for dev in /dev/$VOLUME_GROUP/*; do
echo "++++++ $dev: Removing old key slot"
cryptsetup luksKillSlot \
--key-file /tmp/recovery.key \
@ -48,7 +54,7 @@ dd \
2>/dev/null \
|| die "Unable to generate 128 random bytes"
for dev in $CONFIG_QUBES_DEVS; do
for dev in /dev/$VOLUME_GROUP/*; do
echo "+++++ $dev: Adding key"
cryptsetup luksAddKey \
--key-file /tmp/recovery.key \
@ -58,7 +64,7 @@ for dev in $CONFIG_QUBES_DEVS; do
done
# Now that we have setup the new keys, measure the PCRs
/bin/qubes-measure-luks $CONFIG_QUBES_DEVS \
/bin/qubes-measure-luks /dev/$VOLUME_GROUP/* \
|| die "Unable to measure the LUKS headers"
# Note that PCR 4 needs to be set with the "normal-boot"

View File

@ -16,14 +16,14 @@
#
XEN=/boot/xen-4.6.4.heads
INITRD=/boot/initramfs-4.4.38-11.pvops.qubes.x86_64.img
KERNEL=/boot/vmlinuz-4.4.38-11.pvops.qubes.x86_64
INITRD=/boot/initramfs-4.4.14-11.pvops.qubes.x86_64.img
KERNEL=/boot/vmlinuz-4.4.14-11.pvops.qubes.x86_64
recovery() {
echo >&2 "!!!!! $@"
rm -f /tmp/secret.key
tpm extend -ix 4 -if recovery
rm -f /tmp/secret.key /initrd.gz
tpm extend -ix 4 -ic recovery
echo >&2 "!!!!! Starting recovery shell"
exec /bin/ash
@ -43,21 +43,54 @@ echo "+++ Checking $KERNEL"
gpgv "${KERNEL}.asc" "${KERNEL}" \
|| recovery 'Kernel signature failed'
# Activate the dom0 group
lvm vgchange -a y "$CONFIG_QUBES_VG" \
|| recovery "$CONFIG_QUBES_VG: LVM volume group activate failed"
# Measure the LUKS headers before we unseal the disk key
qubes-measure-luks $CONFIG_QUBES_DEVS \
qubes-measure-luks /dev/$CONFIG_QUBES_VG/* \
|| recovery "LUKS measure failed"
# get the UUID of the root file system
# busybox blkid doesn't have a "just the UUID" option
ROOT_UUID=`blkid /dev/$CONFIG_QUBES_VG/00 | cut -d\" -f2`
if [ -z "$ROOT_UUID" ]; then
recovery "$CONFIG_QUBES_VG/00: No UUID for /"
fi
echo "$CONFIG_QUBES_VG/00: UUID=$ROOT_UUID"
# Attempt to unseal the disk key from the TPM
# should we give this some number of tries?
unseal-key \
|| recovery 'Unseal disk key failed. Starting recovery shell'
# Unpack the initrd and fixup the /etc/crypttab
# this is a hack to split it into two parts since
# we know that the first 0x3400 bytes are the microcode
INITRD_DIR=/tmp/initrd
echo '+++ Unpacking initrd'
mkdir -p $INITRD_DIR
dd if="$INITRD" bs=256 count=52 | ( cd $INITRD_DIR ; cpio -i )
dd if="$INITRD" bs=256 skip=52 | zcat | ( cd $INITRD_DIR ; cpio -i )
# Update the /etc/crypttab in the initrd and install our key
for dev in /dev/$CONFIG_QUBES_VG/*; do
uuid=`blkid $dev | cut -d\" -f2`
echo luks-$uuid /dev/disk/by-uuid/$uuid /secret.key
done > $INITRD_DIR/etc/crypttab
mv /tmp/secret.key $INITRD_DIR/
echo '+++ Repacking initrd'
( cd $INITRD_DIR ; find . | cpio -H newc -o ) | gzip > /initrd.gz
# command line arguments are include in the signature on this script,
# although the root UUID should be specified in some better manner.
echo '+++ Loading kernel and initrd'
kexec \
-l \
--module "${KERNEL} root=UUID=257b593f-d4ae-46ee-b499-14bc9ffd37d4 ro rd.qubes.hide_all_usb" \
--module "${INITRD}" \
--module "${KERNEL} root=/dev/mapper/luks-$ROOT_UUID ro rd.qubes.hide_all_usb" \
--module /initrd.gz \
--command-line "no-real-mode reboot=no" \
"${XEN}" \
|| recovery "kexec load failed"
@ -67,4 +100,5 @@ tpm extend -ix 4 -ic qubes \
|| recovery 'Unable to scramble PCR'
echo "+++ Starting Qubes..."
sleep 2
exec kexec -e

View File

@ -1,10 +1,10 @@
-----BEGIN PGP SIGNATURE-----
iQEVAwUAWOGvZA+UgFLd7L5oAQIeEggA1MAF+Tb+ArEbUsJrvPF7104c+tXzPQXU
7w0cSiJvmsMxLGwg4hAGLcy3ptqTzrVEngmkblCnl2+b2O7Vy0N64t0ptfXj8FCA
FoEMdmwiMNN7W2CglXgwaEmymc0cE8GrppZK6LRSUdngtKQftgyPRCicX+J7xH1Y
0Lnien+/qgIFHM8QVgVi8s8KFcY0OXKYVOFYWiHUE32/hQTSUllTaj+hW3+NCEnZ
K+HMydkQM7rdL974KFZn+0VMLnruD6c//ITXY0kE5I6XCdkOu3KaUm5QP6rIAydk
MM+47hJTnXThMK9wTBfvrJE0BZvK7t90bl+r6QPVErwLOpC0r00S/w==
=OJy5
iQEUAwUAWOK7zw+UgFLd7L5oAQJ/vwf4yf9zRGeKC2pwDJcMoBww1A4E8LbxW8FF
jdbojg8r5uvfuPeF0V7+BjnE5RItr1UiaClxryXpSwElSXNLoyQPdKbUaYr+w5R1
jmwZpXxPkoCkUPpzsFl2JAvHe00d4isOU3rLOH6SJjN1VZDeOFGBkAeH5rr0kBpt
A0WaMW1Qe9RIFDHbyx6sxWXTzMTwHxvskqd5oJojJRiRFlgsOhPY7FGCop0ajEAA
PlYpupMtJQhJGpF4d/vF6nPTC2Trm5FSfK8lgrLwryxI4nSmPpPfXCfdscoid+2L
bJuThLvSdV/0DE1rsNcxxMZmhrPK4AnKK6tvTXA/CK3nwEkNQhgn
=OWVi
-----END PGP SIGNATURE-----