TPM Disk Unlock Key sealing/renewal cleanup (Triggered automatically when resealing TOTP)

Changes:
- As per master: when TOTP cannot unseal TOTP, user is prompted to either reset or regenerate TOTP
- Now, when either is done and a previous TPM Disk Unlock Key was setuped, the user is guided into:
  - Regenerating checksums and signing them
  - Regenerating TPM disk Unlock Key and resealing TPM disk Unlock Key with passphrase into TPM
  - LUKS header being modified, user is asked to resign kexec.sig one last time prior of being able to default boot
- When no previous Disk Unlock Key was setuped, the user is guided into:
  - The above, plus
    - Detection of LUKS containers,suggesting only relevant partitions

- Addition of TRACE and DEBUG statements to troubleshoot actual vs expected behavior while coding
  - Were missing under TPM Disk Unlock Key setup codepaths

- Fixes for #645 : We now check if only one slots exists and we do not use it if its slot1.
  - Also shows in DEBUG traces now

Unrelated staged changes
- ash_functions: warn and die now contains proper spacing and eye attaction
- all warn and die calls modified if containing warnings and too much punctuation
- unify usage of term TPM Disk Unlock Key and Disk Recovery Key
This commit is contained in:
Thierry Laurion 2023-08-22 14:34:29 -04:00
parent 45a4f9d0f3
commit 4910c1188f
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
14 changed files with 255 additions and 94 deletions

2
FAQ.md
View File

@ -110,7 +110,7 @@ to deceive you and steal your login password? Maybe! It wouldn't get
your disk password, which is perhaps an improvement.
Disk key in TPM or user passphrase?
Disk key in TPM (TPM Disk Unlock Key) or user passphrase?
---
Depends on your threat model. With the disk key in the TPM an attacker
would need to have the entire machine (or a backdoor in the TPM)

View File

@ -14,5 +14,5 @@ sha256sum /tmp/kgpe-d16-openbmc.rom
flashrom --programmer="ast1100:spibus=2,cpu=reset" -c "S25FL128P......0" -w /tmp/kgpe-d16-openbmc.rom \
|| die "$ROM: Flash failed"
warn "Reboot and hopefully it works..."
warn "Reboot and hopefully it works"
exit 0

View File

@ -173,7 +173,8 @@ generate_totp_hotp()
# clear screen
printf "\033c"
else
warn "Unsealing TOTP/HOTP secret from previous sealed measurements failed. Try "Generate new HOTP/TOTP secret" option if you updated firmware content."
warn "Unsealing TOTP/HOTP secret from previous sealed measurements failed"
warn "Try "Generate new HOTP/TOTP secret" option if you updated firmware content"
fi
}
@ -229,6 +230,7 @@ update_totp()
if (whiptail $BG_COLOR_WARNING --title 'Generate new TOTP/HOTP secret' \
--yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then
generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU=""
reseal_tpm_disk_decryption_key
fi
;;
i )
@ -237,6 +239,7 @@ update_totp()
;;
p )
reset_tpm && update_totp && BG_COLOR_MAIN_MENU=""
reseal_tpm_disk_decryption_key
;;
x )
recovery "User requested recovery shell"
@ -298,6 +301,7 @@ update_hotp()
if (whiptail $BG_COLOR_WARNING --title 'Generate new TOTP/HOTP secret' \
--yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then
generate_totp_hotp && BG_COLOR_MAIN_MENU=""
reseal_tpm_disk_decryption_key
fi
;;
i )
@ -523,9 +527,11 @@ show_tpm_totp_hotp_options_menu()
case "$option" in
g )
generate_totp_hotp
reseal_tpm_disk_decryption_key
;;
r )
reset_tpm
reseal_tpm_disk_decryption_key
;;
t )
prompt_totp_mismatch
@ -571,8 +577,10 @@ reset_tpm()
# now that the TPM is reset, remove invalid TPM counter files
mount_boot
mount -o rw,remount /boot
warn "Removing rollback and primary handle hash under /boot"
rm -f /boot/kexec_rollback.txt
rm -f /boot/kexec_primhdl_hash.txt
#TODO: When primhdl_hash is gone but not recreated and signed: fail at TPM Disk Unlock Key for TPM2....
# create Heads TPM counter before any others
check_tpm_counter /boot/kexec_rollback.txt "" "$key_password" \

View File

@ -158,7 +158,9 @@ if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then
#Repeat kexec command that will be executed since in debug
DEBUG "kexeccmd= $kexeccmd"
read -n 1 -p "[DEBUG] Continue booting? [Y/n]: " debug_boot_confirm
#Ask user if they want to continue booting without echoing back the input (-s)
read -s -n 1 -p "[DEBUG] Continue booting? [Y/n]: " debug_boot_confirm
echo
if [ "${debug_boot_confirm^^}" = N ]; then
# abort
die "Boot aborted"

View File

@ -8,10 +8,10 @@ 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" ;;
b) bootdir="$OPTARG" ;;
d) paramsdev="$OPTARG" ;;
p) paramsdir="$OPTARG" ;;
i) index="$OPTARG" ;;
esac
done
@ -35,21 +35,53 @@ TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt"
ENTRY_FILE="$paramsdir/kexec_default.$index.txt"
HASH_FILE="$paramsdir/kexec_default_hashes.txt"
PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt"
KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
KEY_LVM="$paramsdir/kexec_key_lvm.txt"
lvm_suggest=$(lvm vgscan | awk -F '"' {'print $1'} | tail -n +2)
num_lvm=$(echo "$lvm_suggest" | wc -l)
if [ "$num_lvm" -eq 1 ] && [ -n "$lvm_suggest" ]; then
lvm_volume_group="$lvm_suggest"
elif [ -z "$lvm_suggest" ]; then
num_lvm=0
fi
DEBUG "LVM num_lvm: $num_lvm, lvm_suggest: $lvm_suggest"
# get all LUKS container devices
devices_suggest=$(blkid | cut -d ':' -f 1 | while read device; do
cryptsetup isLuks "$device"
if [ $(echo $?) == 0 ]; then echo "$device"; fi
done | sort)
num_devices=$(echo "$devices_suggest" | wc -l)
if [ "$num_devices" -eq 1 ] && [ -s "$devices_suggest" ]; then
key_devices=$devices_suggest
else
devices_suggest=$(echo $devices_suggest)
fi
DEBUG "LUKS num_devices: $num_devices, devices_suggest: $devices_suggest"
if [ "$num_lvm" -eq 0 ] && [ "$num_devices" -eq 0 ]; then
#No encrypted partition found.
no_encrypted_partition=1
fi
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`
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" ] && [ "$CONFIG_BASIC" != y ]; then
DEBUG "TPM is enabled and TPM_NO_LUKS_DISK_UNLOCK is not set"
DEBUG "Checking if a a TPM Disk Unlock Key was previously setuped from $KEY_DEVICES"
if [ ! -r "$KEY_DEVICES" ]; then
DEBUG "No previous TPM Disk Unlock Key was setuped 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]: " \
@ -58,11 +90,11 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [
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"
DEBUG "User confirmed to add a disk encryption to the TPM"
save_key="y"
fi
else
DEBUG "Previous TPM Disk Unlock Key was setuped for LUKS devices"
read \
-n 1 \
-p "Do you want to reseal a disk key to the TPM [y/N]: " \
@ -73,36 +105,85 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "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
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
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'"
lvm_suggest="$old_lvm_volume_group"
devices_suggest="$old_key_devices"
save_key="y"
fi
fi
if [ "$save_key" = "y" ]; then
echo "+++ LVM volume groups (lvm vgscan): "
lvm vgscan || true
if [ -n "$old_key_devices" ] || [ -n "$old_lvm_volume_group" ]; then
DEBUG "Previous TPM Disk Unlock Key was setuped for LUKS devices $old_key_devices $old_lvm_volume_group"
read \
-n 1 \
-p "Do you want to reuse configured Encrypted LVM groups/Block devices? (Y/n):" \
reuse_past_devices
echo
if [ "$reuse_past_devices" = "y" ] || [ "$reuse_past_devices" = "Y" ] || [ -z "$reuse_past_devices" ]; then
if [ -z "$key_devices" ] && [ -n "$old_key_devices" ]; then
key_devices="$old_key_devices"
fi
if [ -z "$lvm_volume_group" ] && [ -n "$old_lvm_volume_group" ]; then
lvm_volume_group="$old_lvm_volume_group"
fi
fi
else
DEBUG "No previous TPM Disk Unlock Key was setuped for LUKS devices, setting up new ones"
if [ "$num_lvm" -gt 1 ]; then
DEBUG "Multiple LVM groups found"
//untested
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
read \
-p "LVM group containing Encrypted LVs (retype to keep)? ($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
echo "+++ Block devices (blkid): "
blkid || true
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
read \
-p "Encrypted devices (retype to keep)? ($devices_suggest): " \
key_devices
result=$(echo "$devices_suggest" | grep -q "$key_devices") || selected_luksdev_not_existing=1
if [ $? == 0 ]; 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
save_key_params="-s -p $paramsdev"
if [ -n "$lvm_volume_group" ]; then
@ -110,9 +191,8 @@ if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [
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"
kexec-save-key $save_key_params ||
die "Failed to save the disk key"
fi
fi
@ -120,19 +200,20 @@ fi
mount -o rw,remount $paramsdev
if [ ! -d $paramsdir ]; then
mkdir -p $paramsdir \
|| die "Failed to create params directory"
mkdir -p $paramsdir ||
die "Failed to create params directory"
fi
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
sha256sum /tmp/primary.handle > "$PRIMHASH_FILE" \
|| die "ERROR: Failed to Hash TPM2 primary key handle!"
sha256sum /tmp/primary.handle >"$PRIMHASH_FILE" ||
die "ERROR: Failed to Hash TPM2 primary key handle!"
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 \
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"
@ -144,19 +225,19 @@ if [ "$save_key" = "y" ]; then
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
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
cpio -id --quiet $crypttab_files <$initrd_decompressed 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
@ -165,7 +246,7 @@ if [ "$save_key" = "y" ]; then
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
echo "$filepath:$single_modified_filepath_entry" >>$bootdir/kexec_initrd_crypttab_overrides.txt
done
done
@ -189,14 +270,14 @@ fi
# sign and auto-roll config counter
extparam=
if [ "$CONFIG_TPM" = "y" ];then
if [ "$CONFIG_TPM" = "y" ]; then
if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then
extparam=-r
fi
fi
if [ "$CONFIG_BASIC" != "y" ]; then
kexec-sign-config -p $paramsdir $extparam \
|| die "Failed to sign default config"
kexec-sign-config -p $paramsdir $extparam ||
die "Failed to sign default config"
fi
# switch back to ro mode
mount -o ro,remount $paramsdev

View File

@ -1,5 +1,9 @@
#!/bin/bash
# Generate a TPM key used to unlock LUKS disks
. /etc/functions
TRACE "kexec-save-key: start"
set -e -o pipefail
. /etc/functions
@ -13,20 +17,28 @@ while getopts "sp:d:l:" arg; do
l) lvm_volume_group="$OPTARG" ;;
esac
done
DEBUG "kexec-save-key prior of parsing: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group"
shift `expr $OPTIND - 1`
key_devices="$@"
DEBUG "kexec-save-key: key_devices: $key_devices"
if [ -z "$paramsdir" ]; then
die "Usage: $0 [-s] -p /boot [-l qubes_dom0] [/dev/sda2 /dev/sda5 ...] "
fi
if [ -z "$paramsdev" ]; then
paramsdev="$paramsdir"
DEBUG "kexec-save-key: paramsdev modified to : $paramsdev"
fi
paramsdev="${paramsdev%%/}"
paramsdir="${paramsdir%%/}"
DEBUG "kexec-save-key prior of last override: paramsdir: $paramsdir, paramsdev: $paramsdev, lvm_volume_group: $lvm_volume_group"
if [ -n "$lvm_volume_group" ]; then
lvm vgchange -a y $lvm_volume_group \
|| die "Failed to activate the LVM group"
@ -45,14 +57,17 @@ mount -o rw,remount $paramsdev
rm -f $paramsdir/kexec_key_lvm.txt || true
if [ -n "$lvm_volume_group" ]; then
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 \
|| die "Failed to write lvm group to key config "
fi
rm -f $paramsdir/kexec_key_devices.txt || true
for dev in $key_devices; do
DEBUG "gettinmg uuid for $dev"
uuid=`cryptsetup luksUUID "$dev" 2>/dev/null` \
|| die "Failed to get UUID for device $dev"
DEBUG "saving under $paramsdir/kexec_key_devices.txt : dev: $dev, uuid: $uuid"
echo "$dev $uuid" >> $paramsdir/kexec_key_devices.txt \
|| die "Failed to add $dev:$uuid to key devices config"
done
@ -71,4 +86,4 @@ if [ "$skip_sign" != "y" ]; then
fi
# switch back to ro mode
mount -o ro,remount $paramsdev
mount -o ro,remount $paramsdev

View File

@ -26,16 +26,20 @@ KEY_LVM="$paramsdir/kexec_key_lvm.txt"
if [ ! -r "$KEY_DEVICES" ]; then
die "No devices defined for disk encryption"
else
DEBUG "Devices defined for disk encryption: $(cat "$KEY_DEVICES" | cut -d\ -f1)"
fi
if [ -r "$KEY_LVM" ]; then
# Activate the LVM volume group
VOLUME_GROUP=`cat $KEY_LVM`
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"
lvm vgchange -a y $VOLUME_GROUP ||
die "$VOLUME_GROUP: unable to activate volume group"
else
DEBUG "No LVM volume group defined for activation"
fi
DEBUG "$(pcrs)"
@ -43,50 +47,69 @@ DEBUG "$(pcrs)"
# LUKS Key slot 0 is the manual recovery pass phrase
# that they user entered when they installed OS,
# 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"
read -s -p "Enter disk recovery key/passphrase: " disk_password
echo -n "$disk_password" >"$RECOVERY_KEY"
echo
read -s -p "New disk unlock password for booting: " key_password
read -s -p "New TPM Disk Unlock Key passphrase for booting: " key_password
echo
read -s -p "Repeat unlock code: " key_password2
read -s -p "Repeat TPM Disk Unlock key passphrase: " key_password2
echo
if [ "$key_password" != "$key_password2" ]; then
die "Key passwords do not match"
die "Key passphrases do not match"
fi
# Generate key file
echo "++++++ Generating new randomized 128 bytes key file that will be unsealed by TPM Disk Unlock Key passphrase"
dd \
if=/dev/urandom \
of="$KEY_FILE" \
bs=1 \
count=128 \
2>/dev/null \
|| die "Unable to generate 128 random bytes"
2>/dev/null ||
die "Unable to generate 128 random bytes"
# Count the number of slots used on each device
for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do
DEBUG "Checking number of slots used on $dev"
#check if the device is a LUKS device with luks[1,2]
slots_used=$(cryptsetup luksDump $dev | grep -c 'luks[0-9]*' || die "Unable to get number of slots used on $dev")
DEBUG "Number of slots used on $dev: $slots_used"
# If slot1 is the only one used, warn and die with proper messages
if [ $slots_used -eq 1 ]; then
# Check if slot 1 is the only one existing
if cryptsetup luksDump $dev | grep -q "Slot 1: ENABLED"; then
warn "Slot 1 is the only one existing on $dev. Heads cannot use it to store TPM sealed LUKS Disk Unlock Key"
die "Slot 1 should not be the only one existing on $dev. Fix your custom setup"
fi
else
DEBUG "Slot 1 is not the only one existing on $dev. It is safe to use it to store TPM sealed LUKS Disk Unlock Key"
fi
done
# Remove all the old keys from slot 1
for dev in `cat "$KEY_DEVICES" | cut -d\ -f1`; do
echo "++++++ $dev: Removing old key slot"
for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do
echo "++++++ $dev: Removing old key slot 1"
cryptsetup luksKillSlot \
--key-file "$RECOVERY_KEY" \
$dev 1 \
|| warn "$dev: ignoring problem"
$dev 1 ||
warn "$dev: removal of key in slot 1 failed: might not exist. Continuing"
echo "++++++ $dev: Adding key"
echo "++++++ $dev: Adding key to slot 1"
cryptsetup luksAddKey \
--key-file "$RECOVERY_KEY" \
--key-slot 1 \
$dev "$KEY_FILE" \
|| die "$dev: Unable to add key"
$dev "$KEY_FILE" ||
die "$dev: Unable to add key to slot 1"
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"
cat "$KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks ||
die "Unable to measure the LUKS headers"
pcrf="/tmp/secret/pcrf.bin"
tpmr pcrread 0 "$pcrf"
@ -94,19 +117,19 @@ tpmr pcrread -a 1 "$pcrf"
tpmr pcrread -a 2 "$pcrf"
tpmr pcrread -a 3 "$pcrf"
# Note that PCR 4 needs to be set with the "normal-boot" path value, read it from event log.
tpmr calcfuturepcr 4 >> "$pcrf"
tpmr calcfuturepcr 4 >>"$pcrf"
if [ "$CONFIG_USB_KEYBOARD" = "y" -o -r /lib/modules/libata.ko -o -x /bin/hotp_verification ]; then
DEBUG "Sealing TPM disk unlock key with PCR5 involvement (additional kernel modules are loaded per board config)..."
DEBUG "Sealing TPM Disk Unlock key with PCR5 involvement (additional kernel modules are loaded per board config)..."
# Here, we take pcr 5 into consideration if modules are expected to be measured+loaded
tpmr pcrread -a 5 "$pcrf"
else
DEBUG "Sealing TPM disk unlock key with PCR5=0 (NO additional kernel modules are loaded per board config)..."
DEBUG "Sealing TPM Disk Unlock Key with PCR5=0 (NO additional kernel modules are loaded per board config)..."
#no kernel modules are expected to be measured+loaded
tpmr calcfuturepcr 5 >> "$pcrf"
tpmr calcfuturepcr 5 >>"$pcrf"
fi
# Precompute the value for pcr 6
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of TPM disk unlock key..."
tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >> "$pcrf"
DEBUG "Precomputing TPM future value for PCR6 sealing/unsealing of TPM Disk Unlock Key..."
tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf"
# We take into consideration user files in cbfs
tpmr pcrread -a 7 "$pcrf"
@ -115,9 +138,12 @@ DO_WITH_DEBUG --mask-position 7 \
"$TPM_SIZE" "$key_password"
# should be okay if this fails
shred -n 10 -z -u "$pcrf".* 2> /dev/null || true
shred -n 10 -z -u "$KEY_FILE" 2> /dev/null \
|| warn "Failed to delete key file - continuing"
shred -n 10 -z -u "$pcrf" 2>/dev/null ||
warn "Failed to delete pcrf file - continuing"
shred -n 10 -z -u "$KEY_FILE" 2>/dev/null ||
warn "Failed to delete key file - continuing"
cp /tmp/luksDump.txt "$paramsdir/kexec_lukshdr_hash.txt" \
|| warn "Failed to have hashes of LUKS header - continuing"
mount -o rw,remount $paramsdir || die "Failed to remount $paramsdir in RW - continuing"
cp -f /tmp/luksDump.txt "$paramsdir/kexec_lukshdr_hash.txt" ||
die "Failed to copy LUKS header hashes to /boot - continuing"
mount -o ro,remount $paramsdir || die "Failed to remount $paramsdir in RO - continuing"

View File

@ -57,7 +57,7 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
|| {
echo "FATAL: Hash of TPM2 primary key handle mismatch!";
echo "If you have not intentionally regenerated TPM2 primary key,";
warn "your system may have been compromised!";
warn "your system may have been compromised";
}
else
echo "WARNING: Hash of TPM2 primary key handle does not exist!"
@ -252,7 +252,7 @@ default_select() {
whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Entry Has Changed' \
--msgbox "The list of boot entries has changed\n\nPlease set a new default" 0 80
fi
warn "!!! Boot entry has changed - please set a new default"
warn "Boot entry has changed - please set a new default"
return
fi
parse_option

View File

@ -26,7 +26,7 @@ DEBUG "Show PCRs"
DEBUG "$(pcrs)"
for tries in 1 2 3; do
read -s -p "Enter unlock password (blank to abort): " tpm_password
read -s -p "Enter LUKS Disk Unlock Key passphrase (blank to abort): " tpm_password
echo
if [ -z "$tpm_password" ]; then
die "Aborting unseal disk encryption key"

View File

@ -9,7 +9,7 @@ HOTP_KEY="/boot/kexec_hotp_key"
mount_boot()
{
TRACE "Under /bin/seal-htopkey:mount_boot"
TRACE "Under /bin/seal-hotpkey:mount_boot"
# Mount local disk if it is not already mounted
if ! grep -q /boot /proc/mounts ; then
mount -o ro /boot \

View File

@ -495,13 +495,13 @@ tpm1_seal() {
# The permissions are 0 since there is nothing special
# about the sealed file
tpm physicalpresence -s \
|| warn "Warning: Unable to assert physical presence"
|| warn "Unable to assert physical presence"
prompt_tpm_password
tpm nv_definespace -in "$index" -sz "$sealed_size" \
-pwdo "$tpm_password" -per 0 \
|| warn "Warning: Unable to define NVRAM space; trying anyway"
|| warn "Unable to define NVRAM space; trying anyway"
tpm nv_writevalue -in "$index" -if "$sealed_file" \
@ -595,7 +595,7 @@ tpm2_reset() {
TRACE "Under /bin/tpmr:tpm2_reset"
key_password="$1"
mkdir -p "$SECRET_DIR"
tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy!"
tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy"
tpm2 changeauth -c owner "$(tpm2_password_hex "$key_password")"
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$key_password")"
tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \
@ -673,7 +673,7 @@ tpm2_kexec_finalize() {
echo "Locking TPM2 platform hierarchy..."
randpass=$(dd if=/dev/urandom bs=4 count=1 status=none | xxd -p)
tpm2 changeauth -c platform "$randpass" \
|| warn "Failed to lock platform hierarchy of TPM2!"
|| warn "Failed to lock platform hierarchy of TPM2"
}
tpm2_shutdown() {

View File

@ -4,13 +4,13 @@
# busybox ash on legacy-flash boards, and with bash on all other boards.
die() {
echo >&2 "$*";
echo >&2 " !!! ERROR: $* !!!";
sleep 2;
exit 1;
}
warn() {
echo >&2 "$*";
echo >&2 " *** WARNING: $* ***";
sleep 1;
}

View File

@ -81,6 +81,36 @@ confirm_totp()
echo
}
reseal_tpm_disk_decryption_key()
{
TRACE "Under /etc/functions:reseal_tpm_disk_decryption_key"
#Can be called only on resealing, not on tpm reset:
#otherise primary handle and rollback would change.
if ! grep -q /boot /proc/mounts ; then
mount -o ro /boot \
|| recovery "Unable to mount /boot"
fi
if [ -s /boot/kexec_key_devices.txt ] || [ -s /boot/kexec_key_lvm.txt ]; then
warn "A TPM disk decryption key previoulsy sealed is now invalid since firmware measurements cannot be unsealed"
warn "Renewing LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
while ! kexec-seal-key /boot; do
warn "Recovery disk encryption key passphrase invalid. Try again!"
done
warn "LUKS header hash changed under of /boot/kexec_luks_hdr_hash.txt"
warn "Updating checksums and signing all files under /boot/kexec.sig"
while ! update_checksums; do
warn "Checksums were not signed. Bad GPG PIN provided?"
warn "Please update checksums and provide a valid GPG PIN"
done
warn "Rebooting in 3 seconds to enable booting default boot option"
sleep 3
reboot
else
DEBUG "No TPM disk decryption key to reseal"
fi
}
# Enable USB storage (if not already enabled), and wait for storage devices to
# be detected. If USB storage was already enabled, no wait occurs, this would
# have happened already when USB storage was enabled.

View File

@ -246,7 +246,6 @@ select_luks_container()
mount -o remount,ro /boot
fi
else
warn "No encrypted device found."
return 1
fi