#!/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 . /tmp/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` # HOTP USB Secrity Dongle loads USB modules which changes PCR5. # In the event HOTP USB Security Dongle is enabled, skip verification of PCR5 if [ -x /bin/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" shred -n 10 -z -u "$KEY_FILE" 2> /dev/null \ || 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 shred -n 10 -z -u "$TPM_SEALED" 2> /dev/null \ || warn "Failed to delete the sealed secret - continuing"