mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-30 09:48:56 +00:00
79a09e7424
When the Librem Key is enabled, the kernel loads USB modules at boot, this causes PCR5 to change and breaks unsealing the LUKS key (if set). This change retains the protection of the PCR5 check unless Librem Key is enabled.
155 lines
4.0 KiB
Bash
Executable File
155 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# This will generate a disk encryption key and seal / ecncrypt
|
|
# with the current PCRs and then store it in the TPM NVRAM.
|
|
# It will then need to be bundled into initrd that is booted.
|
|
set -e -o pipefail
|
|
|
|
TPM_INDEX=3
|
|
TPM_SIZE=312
|
|
KEY_FILE="/tmp/secret/secret.key"
|
|
TPM_SEALED="/tmp/secret/secret.sealed"
|
|
RECOVERY_KEY="/tmp/secret/recovery.key"
|
|
|
|
. /etc/functions
|
|
. /etc/config
|
|
|
|
paramsdir=$1
|
|
if [ -z "$paramsdir" ]; then
|
|
die "Usage $0 /boot"
|
|
fi
|
|
|
|
KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
|
|
KEY_LVM="$paramsdir/kexec_key_lvm.txt"
|
|
|
|
if [ ! -r "$KEY_DEVICES" ]; then
|
|
die "No devices defined for disk encryption"
|
|
fi
|
|
|
|
if [ -r "$KEY_LVM" ]; then
|
|
# Activate the LVM volume group
|
|
VOLUME_GROUP=`cat $KEY_LVM`
|
|
if [ -z "$VOLUME_GROUP" ]; 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
|
|
|
|
# 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.
|
|
read -s -p "Enter disk recovery key: " disk_password
|
|
echo -n "$disk_password" > "$RECOVERY_KEY"
|
|
echo
|
|
|
|
read -s -p "New disk unlock password for booting: " key_password
|
|
echo
|
|
read -s -p "Repeat unlock code: " key_password2
|
|
echo
|
|
|
|
if [ "$key_password" != "$key_password2" ]; then
|
|
die "Key passwords do not match"
|
|
fi
|
|
|
|
# Generate key file
|
|
dd \
|
|
if=/dev/urandom \
|
|
of="$KEY_FILE" \
|
|
bs=1 \
|
|
count=128 \
|
|
2>/dev/null \
|
|
|| die "Unable to generate 128 random bytes"
|
|
|
|
# Remove all the old keys from slot 1
|
|
for dev in `cat "$KEY_DEVICES" | cut -d\ -f1`; do
|
|
echo "++++++ $dev: Removing old key slot"
|
|
cryptsetup luksKillSlot \
|
|
--key-file "$RECOVERY_KEY" \
|
|
$dev 1 \
|
|
|| warn "$dev: ignoring problem"
|
|
|
|
echo "++++++ $dev: Adding key"
|
|
cryptsetup luksAddKey \
|
|
--key-file "$RECOVERY_KEY" \
|
|
--key-slot 1 \
|
|
$dev "$KEY_FILE" \
|
|
|| die "$dev: Unable to add key"
|
|
done
|
|
|
|
# Now that we have setup the new keys, measure the PCRs
|
|
# We don't care what ends up in PCR 6; we just want
|
|
# to get the /tmp/luksDump.txt file. We use PCR16
|
|
# since it should still be zero
|
|
cat "$KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \
|
|
|| die "Unable to measure the LUKS headers"
|
|
luks_pcr=`tpm calcfuturepcr -ix 16 -if /tmp/luksDump.txt`
|
|
|
|
# Librem Key loads USB modules which changes PCR5.
|
|
# In the event Librem Key is enabled, skip verification of PCR5
|
|
if [ -x /bin/libremkey_hotp_verification ]; then
|
|
pcr_5="X"
|
|
else
|
|
pcr_5="0000000000000000000000000000000000000000"
|
|
fi
|
|
|
|
# Note that PCR 4 needs to be set with the "normal-boot"
|
|
# path value, which we do not have right now since we are
|
|
# in a recovery shell.
|
|
# used to be -ix 4 f8fa3b6e32e7c6fe04c366e74636e505b28f3b0d \
|
|
# now just all zeros in a normal boot
|
|
# PCR 5 must be all zero since no kernel modules should have
|
|
# been loaded during a normal boot, but might have been
|
|
# loaded in the recovery shell.
|
|
# Otherwise use the current values of the PCRs, which will be read
|
|
# from the TPM as part of the sealing ("X").
|
|
tpm sealfile2 \
|
|
-if "$KEY_FILE" \
|
|
-of "$TPM_SEALED" \
|
|
-pwdd "$key_password" \
|
|
-hk 40000000 \
|
|
-ix 0 X \
|
|
-ix 1 X \
|
|
-ix 2 X \
|
|
-ix 3 X \
|
|
-ix 4 0000000000000000000000000000000000000000 \
|
|
-ix 5 $pcr_5 \
|
|
-ix 6 $luks_pcr \
|
|
-ix 7 X \
|
|
|| die "Unable to seal secret"
|
|
|
|
rm -f "$KEY_FILE" \
|
|
|| die "Failed to delete key file"
|
|
|
|
# try it without the owner password first
|
|
if ! tpm nv_writevalue \
|
|
-in $TPM_INDEX \
|
|
-if "$TPM_SEALED" \
|
|
; then
|
|
# to create an nvram space we need the TPM owner password
|
|
# and the TPM physical presence must be asserted.
|
|
#
|
|
# The permissions are 0 since there is nothing special
|
|
# about the sealed file
|
|
tpm physicalpresence -s \
|
|
|| warn "Warning: Unable to assert physical presence"
|
|
|
|
read -s -p "TPM Owner password: " tpm_password
|
|
echo
|
|
|
|
tpm nv_definespace \
|
|
-in $TPM_INDEX \
|
|
-sz $TPM_SIZE \
|
|
-pwdo "$tpm_password" \
|
|
-per 0 \
|
|
|| warn "Warning: Unable to define NVRAM space; trying anyway"
|
|
|
|
|
|
tpm nv_writevalue \
|
|
-in $TPM_INDEX \
|
|
-if "$TPM_SEALED" \
|
|
|| die "Unable to write sealed secret to NVRAM"
|
|
fi
|
|
|
|
rm "$TPM_SEALED" \
|
|
|| warn "Failed to delete the sealed secret - continuing"
|