mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-18 20:47:55 +00:00
7cec25542d
Closes issue #226 Also changed to procedure to show LVM volume groups and block device ids to aid in choosing the right combination during the TPM LUKS key sealing process.
82 lines
2.3 KiB
Bash
Executable File
82 lines
2.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# Unseal a disk key from TPM and add to a new initramfs
|
|
set -e -o pipefail
|
|
. /etc/functions
|
|
|
|
TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt"
|
|
TMP_KEY_LVM="/tmp/kexec/kexec_key_lvm.txt"
|
|
|
|
INITRD="$1"
|
|
|
|
if [ -z "$INITRD" ]; then
|
|
die "Usage: $0 /boot/initramfs... "
|
|
fi
|
|
|
|
if [ ! -r "$TMP_KEY_DEVICES" ]; then
|
|
die "No devices defined for disk encryption"
|
|
fi
|
|
|
|
if [ -r "$TMP_KEY_LVM" ]; then
|
|
# Activate the LVM volume group
|
|
VOLUME_GROUP=`cat $TMP_KEY_LVM`
|
|
if [ -z "$TMP_KEY_LVM" ]; then
|
|
die "No LVM volume group defined for activation"
|
|
fi
|
|
lvm vgchange -a y $VOLUME_GROUP \
|
|
|| die "$VOLUME_GROUP: unable to activate volume group"
|
|
fi
|
|
|
|
# Measure the LUKS headers before we unseal the disk key
|
|
cat "$TMP_KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \
|
|
|| die "LUKS measure failed"
|
|
|
|
# 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/secret/initrd
|
|
SECRET_CPIO=/tmp/secret/initrd.cpio
|
|
mkdir -p "$INITRD_DIR/etc"
|
|
|
|
# Attempt to unseal the disk 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 "!!! Failed to unseal the TPM LUKS disk key"
|
|
fi
|
|
|
|
# Override PCR 4 so that user can't read the key
|
|
tpm extend -ix 4 -ic generic \
|
|
|| die 'Unable to scramble PCR'
|
|
|
|
# Check to continue
|
|
if [ "$unseal_failed" = "y" ]; then
|
|
confirm_boot="n"
|
|
read \
|
|
-n 1 \
|
|
-p "Do you wish to boot and use the disk recovery key? [Y/n] " \
|
|
confirm_boot
|
|
|
|
if [ "$confirm_boot" != 'y' \
|
|
-a "$confirm_boot" != 'Y' \
|
|
-a -n "$confirm_boot" ] \
|
|
; then
|
|
die "!!! Aborting boot due to failure to unseal TPM disk key"
|
|
fi
|
|
fi
|
|
|
|
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 \
|
|
|| die "Failed to copy initrd to /tmp"
|
|
|
|
if [ "$unseal_failed" = "n" ]; then
|
|
# overwrite /etc/crypttab to mirror the behavior for in seal-key
|
|
for uuid in `cat "$TMP_KEY_DEVICES" | cut -d\ -f2`; do
|
|
echo "luks-$uuid UUID=$uuid /secret.key" >> "$INITRD_DIR/etc/crypttab"
|
|
done
|
|
( cd "$INITRD_DIR" ; find . -type f | cpio -H newc -o ) >> "$SECRET_CPIO"
|
|
fi
|