Address review for: first set up of TPM DUK and renewal after firmware upg

This commit is contained in:
Thierry Laurion 2023-09-01 15:18:36 -04:00
parent 64ad01f333
commit 4a7e23b4c6
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
5 changed files with 169 additions and 94 deletions

View File

@ -45,6 +45,8 @@ if [ "$num_lvm" -eq 1 ] && [ -n "$lvm_suggest" ]; then
elif [ -z "$lvm_suggest" ]; then elif [ -z "$lvm_suggest" ]; then
num_lvm=0 num_lvm=0
fi fi
# $lvm_suggest is a multiline string, we need to convert it to a space separated string
lvm_suggest=$(echo "$lvm_suggest" | xargs)
DEBUG "LVM num_lvm: $num_lvm, lvm_suggest: $lvm_suggest" DEBUG "LVM num_lvm: $num_lvm, lvm_suggest: $lvm_suggest"
# get all LUKS container devices # get all LUKS container devices
@ -55,9 +57,11 @@ num_devices=$(echo "$devices_suggest" | wc -l)
if [ "$num_devices" -eq 1 ] && [ -s "$devices_suggest" ]; then if [ "$num_devices" -eq 1 ] && [ -s "$devices_suggest" ]; then
key_devices=$devices_suggest key_devices=$devices_suggest
else elif [ -z "$devices_suggest" ]; then
devices_suggest=$(echo $devices_suggest) num_devices=0
fi fi
# $devices_suggest is a multiline string, we need to convert it to a space separated string
devices_suggest=$(echo "$devices_suggest" | xargs)
DEBUG "LUKS num_devices: $num_devices, devices_suggest: $devices_suggest" DEBUG "LUKS num_devices: $num_devices, devices_suggest: $devices_suggest"
if [ "$num_lvm" -eq 0 ] && [ "$num_devices" -eq 0 ]; then if [ "$num_lvm" -eq 0 ] && [ "$num_devices" -eq 0 ]; then
@ -65,6 +69,113 @@ if [ "$num_lvm" -eq 0 ] && [ "$num_devices" -eq 0 ]; then
no_encrypted_partition=1 no_encrypted_partition=1
fi fi
#Reusable function when user wants to define new TPM DUK for lvms/disks
prompt_for_existing_encrypted_lvms_or_disks() {
TRACE "Under kexec-save-default:prompt_for_existing_encrypted_lvms_or_disks"
DEBUG "num_lvm: $num_lvm, lvm_suggest: $lvm_suggest, num_devices: $num_devices, devices_suggest: $devices_suggest"
# Create an associative array to store the suggested LVMs and their paths
declare -A lvms_array
# Loop through the suggested LVMs and add them to the array
for lvm in $lvm_suggest; do
lvms_array[$lvm]=$lvm
done
# Get the number of suggested LVMs
num_lvms=${#lvms_array[@]}
if [ "$num_lvms" -gt 1 ]; then
DEBUG "Multiple LVMs found: $lvm_suggest"
selected_lvms_not_existing=1
# Create an array to store the selected LVMs
declare -a key_lvms_array
while [ $selected_lvms_not_existing -ne 0 ]; do
{
# Read the user input and store it in a variable
read \
-p "Encrypted LVMs? (choose between/all: $lvm_suggest): " \
key_lvms
# Split the user input by spaces and add each element to the array
IFS=' ' read -r -a key_lvms_array <<<"$key_lvms"
# Loop through the array and check if each element is in the lvms_array
valid=1
for lvm in "${key_lvms_array[@]}"; do
if [[ ! ${lvms_array[$lvm]+_} ]]; then
# If not found, set the flag to indicate invalid input
valid=0
break
fi
done
# If valid, set the flag to indicate valid input
if [[ $valid -eq 1 ]]; then
selected_lvms_not_existing=0
fi
}
done
elif [ "$num_lvms" -eq 1 ]; then
echo "Single Encrypted LVM found at $lvm_suggest."
key_lvms=$lvm_suggest
else
echo "No encrypted LVMs found."
fi
# Create an associative array to store the suggested devices and their paths
declare -A devices_array
# Loop through the suggested devices and add them to the array
for device in $devices_suggest; do
devices_array[$device]=$device
done
# Get the number of suggested devices
num_devices=${#devices_array[@]}
if [ "$num_devices" -gt 1 ]; then
DEBUG "Multiple LUKS devices found: $devices_suggest"
selected_luksdevs_not_existing=1
# Create an array to store the selected devices
declare -a key_devices_array
while [ $selected_luksdevs_not_existing -ne 0 ]; do
{
# Read the user input and store it in a variable
read \
-p "Encrypted devices? (choose between/all: $devices_suggest): " \
key_devices
# Split the user input by spaces and add each element to the array
IFS=' ' read -r -a key_devices_array <<<"$key_devices"
# Loop through the array and check if each element is in the devices_array
valid=1
for device in "${key_devices_array[@]}"; do
if [[ ! ${devices_array[$device]+_} ]]; then
# If not found, set the flag to indicate invalid input
valid=0
break
fi
done
# If valid, set the flag to indicate valid input
if [[ $valid -eq 1 ]]; then
selected_luksdevs_not_existing=0
fi
}
done
elif [ "$num_devices" -eq 1 ]; then
echo "Single Encrypted Disk found at $devices_suggest."
key_devices=$devices_suggest
else
echo "No encrypted devices found."
fi
DEBUG "Multiple LUKS devices selected: $key_devices"
}
if [ ! -r "$TMP_MENU_FILE" ]; then if [ ! -r "$TMP_MENU_FILE" ]; then
die "No menu options available, please run kexec-select-boot" die "No menu options available, please run kexec-select-boot"
fi fi
@ -75,24 +186,13 @@ if [ -z "$entry" ]; then
fi fi
save_key="n" save_key="n"
if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [ "$CONFIG_BASIC" != y ]; then if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [ "$CONFIG_BASIC" != y ]; then
DEBUG "TPM is enabled and TPM_NO_LUKS_DISK_UNLOCK is not set" DEBUG "TPM is enabled and TPM_NO_LUKS_DISK_UNLOCK is not set"
DEBUG "Checking if a a TPM Disk Unlock Key was previously set up from $KEY_DEVICES" DEBUG "Checking if a a TPM Disk Unlock Key was previously set up from $KEY_DEVICES"
if [ ! -r "$KEY_DEVICES" ]; then #check if $KEY_DEVICES file exists and is not empty
DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, confirming to add a disk encryption to the TPM" if [ -r "$KEY_DEVICES" ] && [ -s "$KEY_DEVICES" ]; then
read \ DEBUG "TPM Disk Unlock Key was previously set up from $KEY_DEVICES"
-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
DEBUG "User confirmed to add a disk encryption to the TPM"
save_key="y"
fi
else
DEBUG "Previous TPM Disk Unlock Key was set up for LUKS devices"
read \ read \
-n 1 \ -n 1 \
-p "Do you want to reseal a disk key to the TPM [y/N]: " \ -p "Do you want to reseal a disk key to the TPM [y/N]: " \
@ -117,6 +217,19 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [
devices_suggest="$old_key_devices" devices_suggest="$old_key_devices"
save_key="y" save_key="y"
fi fi
else
DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, confirming to add a disk encryption to the TPM"
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
DEBUG "User confirmed to add a disk encryption to the TPM"
save_key="y"
fi
fi fi
if [ "$save_key" = "y" ]; then if [ "$save_key" = "y" ]; then
@ -134,54 +247,13 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [
if [ -z "$lvm_volume_group" ] && [ -n "$old_lvm_volume_group" ]; then if [ -z "$lvm_volume_group" ] && [ -n "$old_lvm_volume_group" ]; then
lvm_volume_group="$old_lvm_volume_group" lvm_volume_group="$old_lvm_volume_group"
fi fi
#User doesn't want to reuse past devices, so we need to prompt him from devices_suggest and lvm_suggest
else
prompt_for_existing_encrypted_lvms_or_disks
fi fi
else else
DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, setting up new ones" DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, setting up new ones"
if [ "$num_lvm" -gt 1 ]; then prompt_for_existing_encrypted_lvms_or_disks
DEBUG "Multiple LVM groups found"
# TODO: untested codepath. What uses lvm+LUKS on top nowadays?!?
selected_lvmdev_not_existing=1
while [ $selected_lvmdev_not_existing -ne 0 ]; do
{
read \
-p "Encrypted LVM group? choose between: '$lvm_suggest': " \
lvm_volume_group
result=$(echo "$lvm_suggest" | grep -q "$lvm_volume_group") || selected_lvmdev_not_existing=1
if [ $? == 0 ]; then
selected_lvmdev_not_existing=0
fi
}
done
elif [ "$num_lvm" -eq 1 ] && [ -s $lvm_suggest ]; then
echo "Single Encrypted LVM group found at $lvm_suggest."
lvm_volume_group=$lvm_suggest
else
echo "No encrypted LVM Group found."
fi
if [ "$num_devices" -gt 1 ]; then
DEBUG "Multiple LUKS devices found"
selected_luksdev_not_existing=1
while [ $selected_luksdev_not_existing -ne 0 ]; do
{
read \
-p "Encrypted devices? (choose between: '$devices_suggest'): " \
key_devices
result=$(echo "$devices_suggest" | grep -q "$key_devices") || selected_luksdev_not_existing=1
#if result is not empty, then the device exists
if [ -n "$result" ]; then
selected_luksdev_not_existing=0
fi
}
done
elif [ "$num_devices" -eq 1 ]; then
echo "Single Encrypted Disk found at $devices_suggest."
key_devices=$devices_suggest
else
echo "No encrypted devices found."
fi
fi fi
save_key_params="-s -p $paramsdev" save_key_params="-s -p $paramsdev"

View File

@ -20,7 +20,7 @@ done
DEBUG "kexec-save-key prior of parsing: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group" DEBUG "kexec-save-key prior of parsing: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group"
shift `expr $OPTIND - 1` shift $(expr $OPTIND - 1)
key_devices="$@" key_devices="$@"
DEBUG "kexec-save-key: key_devices: $key_devices" DEBUG "kexec-save-key: key_devices: $key_devices"
@ -40,9 +40,9 @@ paramsdir="${paramsdir%%/}"
DEBUG "kexec-save-key prior of last override: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group" DEBUG "kexec-save-key prior of last override: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group"
if [ -n "$lvm_volume_group" ]; then if [ -n "$lvm_volume_group" ]; then
lvm vgchange -a y $lvm_volume_group \ lvm vgchange -a y $lvm_volume_group ||
|| die "Failed to activate the LVM group" die "Failed to activate the LVM group"
#TODO: why reuse key_devices for lvm devices?
for dev in /dev/$lvm_volume_group/*; do for dev in /dev/$lvm_volume_group/*; do
key_devices="$key_devices $dev" key_devices="$key_devices $dev"
done done
@ -58,22 +58,22 @@ mount -o rw,remount $paramsdev
rm -f $paramsdir/kexec_key_lvm.txt || true rm -f $paramsdir/kexec_key_lvm.txt || true
if [ -n "$lvm_volume_group" ]; then if [ -n "$lvm_volume_group" ]; then
DEBUG "kexec-save-key saving under $paramsdir/kexec_key_lvm.txt : lvm_volume_group: $lvm_volume_group" DEBUG "kexec-save-key saving under $paramsdir/kexec_key_lvm.txt : lvm_volume_group: $lvm_volume_group"
echo "$lvm_volume_group" > $paramsdir/kexec_key_lvm.txt \ echo "$lvm_volume_group" >$paramsdir/kexec_key_lvm.txt ||
|| die "Failed to write lvm group to key config " die "Failed to write lvm group to key config "
fi fi
rm -f $paramsdir/kexec_key_devices.txt || true rm -f $paramsdir/kexec_key_devices.txt || true
for dev in $key_devices; do for dev in $key_devices; do
DEBUG "gettinmg uuid for $dev" DEBUG "Getting UUID for $dev"
uuid=`cryptsetup luksUUID "$dev" 2>/dev/null` \ uuid=$(cryptsetup luksUUID "$dev" 2>/dev/null) ||
|| die "Failed to get UUID for device $dev" die "Failed to get UUID for device $dev"
DEBUG "saving under $paramsdir/kexec_key_devices.txt : dev: $dev, uuid: $uuid" DEBUG "Saving under $paramsdir/kexec_key_devices.txt : dev: $dev, uuid: $uuid"
echo "$dev $uuid" >> $paramsdir/kexec_key_devices.txt \ echo "$dev $uuid" >>$paramsdir/kexec_key_devices.txt ||
|| die "Failed to add $dev:$uuid to key devices config" die "Failed to add $dev:$uuid to key devices config"
done done
kexec-seal-key $paramsdir \ kexec-seal-key $paramsdir ||
|| die "Failed to save and generate key in TPM" die "Failed to save and generate key in TPM"
if [ "$skip_sign" != "y" ]; then if [ "$skip_sign" != "y" ]; then
extparam= extparam=
@ -81,8 +81,8 @@ if [ "$skip_sign" != "y" ]; then
extparam=-r extparam=-r
fi fi
# sign and auto-roll config counter # sign and auto-roll config counter
kexec-sign-config -p $paramsdir $extparam \ kexec-sign-config -p $paramsdir $extparam ||
|| die "Failed to sign updated config" die "Failed to sign updated config"
fi fi
# switch back to ro mode # switch back to ro mode

View File

@ -27,7 +27,7 @@ KEY_LVM="$paramsdir/kexec_key_lvm.txt"
if [ ! -r "$KEY_DEVICES" ]; then if [ ! -r "$KEY_DEVICES" ]; then
die "No devices defined for disk encryption" die "No devices defined for disk encryption"
else else
DEBUG "Devices defined for disk encryption: $(cat "$KEY_DEVICES" | cut -d\ -f1)" DEBUG "Devices defined for disk encryption: $(cat "$KEY_DEVICES" | cut -d\ -f1 | tr '\n' ' ')"
fi fi
if [ -r "$KEY_LVM" ]; then if [ -r "$KEY_LVM" ]; then

View File

@ -1,21 +1,24 @@
#!/bin/bash #!/bin/bash
# Measure all of the luks disk encryption headers into # Measure all of the LUKS Disk Encryption headers into
# a PCR so that we can detect disk swap attacks. # a PCR so that we can detect disk swap attacks.
. /etc/functions . /etc/functions
TRACE "Under /bin/qubes-measure-luks" TRACE "Under /bin/qubes-measure-luks"
DEBUG "Arguments passed to qubes-measure-luks: $@"
die() { echo >&2 "$@"; exit 1; } # Measure the LUKS headers into PCR 6
# Measure the luks headers into PCR 6
for dev in "$@"; do for dev in "$@"; do
DEBUG "Storing LUKS header for $dev into /tmp/lukshdr-$(echo "$dev" | sed 's/\//_/g')"
cryptsetup luksHeaderBackup $dev \ cryptsetup luksHeaderBackup $dev \
--header-backup-file /tmp/lukshdr-$(echo "$dev" | sed 's/\//_/g') \ --header-backup-file /tmp/lukshdr-$(echo "$dev" | sed 's/\//_/g') ||
|| die "$dev: Unable to read luks header" die "$dev: Unable to read LUKS header"
done done
sha256sum /tmp/lukshdr-* > /tmp/luksDump.txt || die "Unable to hash luks headers" DEBUG "Hashing luks headers into /tmp/luksDump.txt"
sha256sum /tmp/lukshdr-* >/tmp/luksDump.txt || die "Unable to hash luks headers"
DEBUG "Removing /tmp/lukshdr-*"
rm /tmp/lukshdr-* rm /tmp/lukshdr-*
tpmr extend -ix 6 -if /tmp/luksDump.txt \ DEBUG "Extending PCR 6 with /tmp/luksDump.txt"
|| die "Unable to extend PCR" tpmr extend -ix 6 -if /tmp/luksDump.txt ||
die "Unable to extend PCR"

View File

@ -83,7 +83,7 @@ confirm_totp() {
reseal_tpm_disk_decryption_key() { reseal_tpm_disk_decryption_key() {
TRACE "Under /etc/functions:reseal_tpm_disk_decryption_key" TRACE "Under /etc/functions:reseal_tpm_disk_decryption_key"
#For robustness, exit early if TPM Disk Unlock Key is prohibited in board configs #For robustness, exit early if TPM Disk Unlock Key is prohibited in board configs
if [ "$CONFIG_TPM_DISK_UNLOCK_KEY" != "y" ]; then if [ "$CONFIG_TPM_DISK_UNLOCK_KEY" == "n" ]; then
DEBUG "TPM Disk Unlock Key is prohibited in board configs" DEBUG "TPM Disk Unlock Key is prohibited in board configs"
return return
else else