heads/initrd/bin/kexec-save-default

202 lines
6.4 KiB
Plaintext
Raw Normal View History

#!/bin/bash
# Save these options to be the persistent default
set -e -o pipefail
. /tmp/config
. /etc/functions
TRACE "Under /bin/kexec-save-default"
while getopts "b:d:p:i:" arg; do
case $arg in
b) bootdir="$OPTARG" ;;
d) paramsdev="$OPTARG" ;;
p) paramsdir="$OPTARG" ;;
i) index="$OPTARG" ;;
esac
done
if [ -z "$bootdir" -o -z "$index" ]; then
die "Usage: $0 -b /boot -i menu_option "
fi
if [ -z "$paramsdev" ]; then
paramsdev="$bootdir"
fi
if [ -z "$paramsdir" ]; then
paramsdir="$bootdir"
fi
bootdir="${bootdir%%/}"
paramsdev="${paramsdev%%/}"
paramsdir="${paramsdir%%/}"
TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt"
ENTRY_FILE="$paramsdir/kexec_default.$index.txt"
HASH_FILE="$paramsdir/kexec_default_hashes.txt"
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt"
if [ ! -r "$TMP_MENU_FILE" ]; then
die "No menu options available, please run kexec-select-boot"
fi
entry=`head -n $index $TMP_MENU_FILE | tail -1`
if [ -z "$entry" ]; then
die "Invalid menu index $index"
fi
KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
KEY_LVM="$paramsdir/kexec_key_lvm.txt"
save_key="n"
if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ]; then
if [ ! -r "$KEY_DEVICES" ]; then
read \
-n 1 \
-p "Do you wish to add a disk encryption to the TPM [y/N]: " \
add_key_confirm
echo
if [ "$add_key_confirm" = "y" \
-o "$add_key_confirm" = "Y" ]; then
lvm_suggest="e.g. qubes_dom0 or blank"
devices_suggest="e.g. /dev/sda2 or blank"
save_key="y"
fi
else
read \
-n 1 \
-p "Do you want to reseal a disk key to the TPM [y/N]: " \
change_key_confirm
echo
if [ "$change_key_confirm" = "y" \
-o "$change_key_confirm" = "Y" ]; then
old_lvm_volume_group=""
if [ -r "$KEY_LVM" ]; then
old_lvm_volume_group=`cat $KEY_LVM` || true
old_key_devices=`cat $KEY_DEVICES \
| cut -d\ -f1 \
| grep -v "$old_lvm_volume_group" \
| xargs` || true
else
old_key_devices=`cat $KEY_DEVICES \
| cut -d\ -f1 | xargs` || true
fi
lvm_suggest="was '$old_lvm_volume_group'"
devices_suggest="was '$old_key_devices'"
save_key="y"
fi
fi
if [ "$save_key" = "y" ]; then
echo "+++ LVM volume groups (lvm vgscan): "
lvm vgscan || true
read \
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
-p "LVM group containing Encrypted LVs (retype to keep)? ($lvm_suggest): " \
lvm_volume_group
echo "+++ Block devices (blkid): "
blkid || true
read \
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
-p "Encrypted devices (retype to keep)? ($devices_suggest): " \
key_devices
save_key_params="-s -p $paramsdev"
if [ -n "$lvm_volume_group" ]; then
save_key_params="$save_key_params -l $lvm_volume_group $key_devices"
else
save_key_params="$save_key_params $key_devices"
fi
echo "Running kexec-save-key with params: $save_key_params"
kexec-save-key $save_key_params \
|| die "Failed to save the disk key"
fi
fi
# try to switch to rw mode
mount -o rw,remount $paramsdev
if [ ! -d $paramsdir ]; then
mkdir -p $paramsdir \
|| die "Failed to create params directory"
fi
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
sha256sum /tmp/primary.handle > "$PRIMHASH_FILE" \
|| die "ERROR: Failed to Hash TPM2 primary key handle!"
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
fi
rm $paramsdir/kexec_default.*.txt 2>/dev/null || true
echo "$entry" > $ENTRY_FILE
( cd $bootdir && kexec-boot -b "$bootdir" -e "$entry" -f| \
xargs sha256sum > $HASH_FILE \
) || die "Failed to create hashes of boot files"
if [ ! -r $ENTRY_FILE -o ! -r $HASH_FILE ]; then
die "Failed to write default config"
fi
if [ "$save_key" = "y" ]; then
# logic to parse OS initrd to extract crypttab, its filepaths and its OS defined options
mkdir -p /tmp/initrd_extract
cd /tmp/initrd_extract
# Get initrd filename selected to be default initrd that OS could be using to configure LUKS on boot by deploying crypttab files
current_default_initrd=$(cat /boot/kexec_default_hashes.txt | grep initr | awk -F " " {'print $NF'} | sed 's/\.\//\/boot\//g')
# Get crypttab files paths from initrd
echo "+++ Checking current selected default boot's $current_default_initrd for existing crypttab files..."
# First either decompress or use the original if it's not compressed
initrd_decompressed="/tmp/initrd_extract/initrd_decompressed.cpio"
zcat < "$current_default_initrd" > "$initrd_decompressed" 2> /dev/null || initrd_decompressed="$current_default_initrd"
crypttab_files=$(cpio --list --quiet < "$initrd_decompressed" | grep crypttab 2> /dev/null) || true
if [ ! -z "$crypttab_files" ]; then
echo "+++ Extracting current selected default boot's $current_default_initrd for found crypttab files analysis..."
cpio -id --quiet < $initrd_decompressed $crypttab_files 2> /dev/null
rm -f $bootdir/kexec_initrd_crypttab_overrides.txt || true
#Parsing each crypttab file found
echo "$crypttab_files" | while read filepath; do
# Keep only non-commented lines
current_filepath_entries=$(cat "$filepath" | grep -v "^#")
# Modify each retained crypttab line to contain to be injected /secret.key at next default boots
modified_filepath_entries=$(echo "$current_filepath_entries" | sed 's/none/\/secret.key/g')
echo "$modified_filepath_entries" | while read single_modified_filepath_entry; do
# Append each found filepath:entry into additional kexec_ file that will be part of detached signed digest
echo "$filepath:$single_modified_filepath_entry" >> $bootdir/kexec_initrd_crypttab_overrides.txt
done
done
#insert current default boot's initrd crypttab locations into tracking file to be overwritten into initramfs at kexec-inject-key
echo "+++ The following OS crypttab file:entry were modified from default boot's initrd:"
cat $bootdir/kexec_initrd_crypttab_overrides.txt
echo "+++ Heads added /secret.key in those entries and saved them under $bootdir/kexec_initrd_crypttab_overrides.txt"
echo "+++ Those overrides will be part of detached signed digests and used to prepare cpio injected at kexec of selected default boot entry."
else
echo "+++ No crypttab file found in extracted initrd. A generic crypttab will be generated"
if [ -e "$bootdir/kexec_initrd_crypttab_overrides.txt" ]; then
echo "+++ Removing $bootdir/kexec_initrd_crypttab_overrides.txt"
rm -f "$bootdir/kexec_initrd_crypttab_overrides.txt"
fi
fi
# Cleanup
cd /
rm -rf /tmp/initrd_extract || true
fi
# sign and auto-roll config counter
extparam=
if [ "$CONFIG_TPM" = "y" ];then
Addition of qemu-(fb)whiptail-tpm2(-hotp) boards -coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations) -swtpm set to be launched under TPM v2.0 mode under board config -Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized) This is skeleton for TPM v2 integration under Heads ------------- WiP TODO: - libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built - Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing - init tries to bind fd and fails currently - Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output - When no OS' /boot can be mounted, do not try to TPM reset (will fail) - seal-hotpkey is not working properly - setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM) - We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase. - primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup - would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only - tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help. - Implementing them would be better - REVIEW TODOS IN CODE - READD CIRCLECI CONFIG Current state: - TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid) - TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without. - TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails. - Current tests are with fbwhiptail (no clear called so having traces on command line of what happens) - Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
2022-08-25 18:43:31 +00:00
if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then
extparam=-r
fi
fi
kexec-sign-config -p $paramsdir $extparam \
|| die "Failed to sign default config"
# switch back to ro mode
mount -o ro,remount $paramsdev