mirror of
https://github.com/linuxboot/heads.git
synced 2025-01-02 19:26:45 +00:00
108 lines
3.1 KiB
Bash
108 lines
3.1 KiB
Bash
#!/bin/sh
|
|
# /boot/boot.sh -- Startup Qubes
|
|
#
|
|
# The signature on this script will be verified by the ROM,
|
|
# and this script lives on the /boot partition to allow
|
|
# the system owner to change the specific Qubes boot parameters
|
|
#
|
|
# 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.
|
|
#
|
|
# To sign this script and the other bootable components:
|
|
#
|
|
# gpg -a --sign --detach-sign boot.sh
|
|
#
|
|
|
|
XEN=/boot/xen-4.6.4.heads
|
|
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 /initrd.gz
|
|
tpm extend -ix 4 -ic recovery
|
|
|
|
echo >&2 "!!!!! Starting recovery shell"
|
|
exec /bin/ash
|
|
}
|
|
|
|
. /config
|
|
|
|
echo "+++ Checking $XEN"
|
|
gpgv "${XEN}.asc" "${XEN}" \
|
|
|| recovery 'Xen signature failed'
|
|
|
|
echo "+++ Checking $INITRD"
|
|
gpgv "${INITRD}.asc" "${INITRD}" \
|
|
|| recovery 'Initrd signature failed'
|
|
|
|
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 /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/etc
|
|
#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 )
|
|
|
|
mv /tmp/secret.key $INITRD_DIR/
|
|
|
|
## Update the /etc/crypttab in the initrd and install our key
|
|
## This is no longer required, now that dom0 /etc/crypttab has
|
|
## the /secret.key specified.
|
|
#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
|
|
|
|
echo '+++ Repacking initrd'
|
|
( cd $INITRD_DIR ; find . | cpio -H newc -o ) > /initrd.cpio
|
|
cat "$INITRD" >> /initrd.cpio
|
|
|
|
# command line arguments are include in the signature on this script,
|
|
echo '+++ Loading kernel and initrd'
|
|
kexec \
|
|
-l \
|
|
--module "${KERNEL} root=/dev/mapper/luks-$ROOT_UUID ro rd.qubes.hide_all_usb" \
|
|
--module /initrd.cpio \
|
|
--command-line "no-real-mode reboot=no" \
|
|
"${XEN}" \
|
|
|| recovery "kexec load failed"
|
|
|
|
# Last step is to override PCR 4 so that user can't read the key
|
|
tpm extend -ix 4 -ic qubes \
|
|
|| recovery 'Unable to scramble PCR'
|
|
|
|
echo "+++ Starting Qubes..."
|
|
sleep 2
|
|
exec kexec -e
|