#!/bin/sh # Boot a Qubes installation that has already been setup. # This depends on the PCR 4 being "normal-boot": # f8fa3b6e32e7c6fe04c366e74636e505b28f3b0d # which is only set if the top level /init script has started # without user intervention or dropping into a recovery shell. . /etc/functions . /etc/config if [ "$1" = "recovery" ]; then warn "Recovery mode boot; ignoring key failures" RECOVERY=1 fi # TODO: Allow /boot to be encrypted? # This would require a different TPM key, a user passphrase to decrypt it, # or loading the USB modules to talk to a Yubikey to get the thing. if ! grep -q /boot /proc/mounts ; then mount -o ro "$CONFIG_QUBES_BOOT_DEV" /boot \ || recovery '$CONFIG_BOOT_DEV: Unable to mount /boot' fi BOOT_HASHES=/boot/boot.hashes if [ ! -r "$BOOT_HASHES" ]; then recovery "$BOOT_HASHES does not exist; re-run qubes-update" fi # Verify the signature on the hashes gpgv "$BOOT_HASHES.asc" "$BOOT_HASHES" \ || recovery 'boot hashes signature failed' # Retrieve the TPM counter ID and generate its current value TPM_COUNTER=`grep counter $BOOT_HASHES | cut -d- -f2` if [ -z "$TPM_COUNTER" ]; then recovery "$BOOT_HASHES: TPM counter not found?" fi tpm counter_read -ix "$TPM_COUNTER" | tee "/tmp/counter-$TPM_COUNTER" # Check the hashes of all the files sha256sum -c "$BOOT_HASHES" \ || recovery "$BOOT_HASHES: hash mismatch" XEN=`grep /boot/xen $BOOT_HASHES | cut -d\ -f3 | tail -1` KERNEL=`grep /boot/vmlin $BOOT_HASHES | cut -d\ -f3 | tail -1` INITRD=`grep /boot/initram $BOOT_HASHES | cut -d\ -f3 | tail -1` # 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 /dev/$CONFIG_QUBES_VG/* \ || recovery "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? if ! unseal-key "$INITRD_DIR/secret.key" ; then warn 'Unseal disk key failed' if [ -z "$RECOVERY" ]; then recovery 'Starting recovery shell' fi fi # Override PCR 4 so that user can't read the key tpm extend -ix 4 -ic qubes \ || recovery 'Unable to scramble PCR' echo '+++ Building initrd' ( cd "$INITRD_DIR" ; find . | cpio -H newc -o ) > "$SECRET_CPIO" cat "$INITRD" >> "$SECRET_CPIO" /bin/qubes-boot "$XEN" "$KERNEL" "$SECRET_CPIO" recovery "Something failed..."