TPM2: add DEBUG and fix path for TPM2 primary key handle hash.

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion 2023-11-02 14:17:38 -04:00
parent 19c5d16e40
commit 6d7f9be414
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
2 changed files with 101 additions and 100 deletions

View File

@ -276,8 +276,9 @@ if [ ! -d $paramsdir ]; then
fi fi
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
sha256sum /tmp/primary.handle >"$PRIMHASH_FILE" || sha256sum /tmp/secret/primary.handle >"$PRIMHASH_FILE" ||
die "ERROR: Failed to Hash TPM2 primary key handle!" die "ERROR: Failed to Hash TPM2 primary key handle!"
DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE"
fi fi
rm $paramsdir/kexec_default.*.txt 2>/dev/null || true rm $paramsdir/kexec_default.*.txt 2>/dev/null || true

View File

@ -27,9 +27,16 @@ while getopts "b:d:p:a:r:c:uimgfs" arg; do
c) config="$OPTARG" ;; c) config="$OPTARG" ;;
u) unique="y" ;; u) unique="y" ;;
m) force_menu="y" ;; m) force_menu="y" ;;
i) valid_hash="y"; valid_rollback="y" ;; i)
valid_hash="y"
valid_rollback="y"
;;
g) gui_menu="y" ;; g) gui_menu="y" ;;
f) force_boot="y"; valid_hash="y"; valid_rollback="y" ;; f)
force_boot="y"
valid_hash="y"
valid_rollback="y"
;;
s) skip_confirm="y" ;; s) skip_confirm="y" ;;
esac esac
done done
@ -50,30 +57,28 @@ bootdir="${bootdir%%/}"
paramsdev="${paramsdev%%/}" paramsdev="${paramsdev%%/}"
paramsdir="${paramsdir%%/}" paramsdir="${paramsdir%%/}"
PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt"
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
if [ -r "$PRIMHASH_FILE" ]; then
sha256sum -c "$PRIMHASH_FILE" ||
{
echo "FATAL: Hash of TPM2 primary key handle mismatch!"
warn "If you have not intentionally regenerated TPM2 primary key,"
warn "your system may have been compromised"
DEBUG "Hash of TPM2 primary key handle mismatched for $PRIMHASH_FILE"
}
else
warn "Hash of TPM2 primary key handle does not exist"
warn "Please rebuild the boot hash tree"
default_failed="y"
DEBUG "Hash of TPM2 primary key handle does not exist under $PRIMHASH_FILE"
fi
fi
#PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt" verify_global_hashes() {
#if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
# if [ -r "$PRIMHASH_FILE" ]; then
# sha256sum -c "$PRIMHASH_FILE" \
# || {
# echo "FATAL: Hash of TPM2 primary key handle mismatch!";
# warn "If you have not intentionally regenerated TPM2 primary key,";
# warn "your system may have been compromised";
# }
# else
# warn "Hash of TPM2 primary key handle does not exist"
# warn "Please rebuild the boot hash tree"
# default_failed="y"
# fi
#fi
#TODO: Readd when this can work successfully by simply resealing TOTP/HOTP without having to reset TPM2, this is a major pain point for users
#And acutally don't work as intended, even more with TPM DUK
verify_global_hashes()
{
echo "+++ Checking verified boot hash file " echo "+++ Checking verified boot hash file "
# Check the hashes of all the files # Check the hashes of all the files
if verify_checksums "$bootdir" "$gui_menu" ; then if verify_checksums "$bootdir" "$gui_menu"; then
echo "+++ Verified boot hashes " echo "+++ Verified boot hashes "
valid_hash='y' valid_hash='y'
valid_global_hash='y' valid_global_hash='y'
@ -104,25 +109,24 @@ verify_global_hashes()
fi fi
} }
verify_rollback_counter() verify_rollback_counter() {
{ TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2)
TPM_COUNTER=`grep counter $TMP_ROLLBACK_FILE | cut -d- -f2`
if [ -z "$TPM_COUNTER" ]; then if [ -z "$TPM_COUNTER" ]; then
die "$TMP_ROLLBACK_FILE: TPM counter not found?" die "$TMP_ROLLBACK_FILE: TPM counter not found?"
fi fi
read_tpm_counter $TPM_COUNTER \ read_tpm_counter $TPM_COUNTER ||
|| die "Failed to read TPM counter" die "Failed to read TPM counter"
sha256sum -c $TMP_ROLLBACK_FILE \ sha256sum -c $TMP_ROLLBACK_FILE ||
|| die "Invalid TPM counter state" die "Invalid TPM counter state"
valid_rollback="y" valid_rollback="y"
} }
first_menu="y" first_menu="y"
get_menu_option() { get_menu_option() {
num_options=`cat $TMP_MENU_FILE | wc -l` num_options=$(cat $TMP_MENU_FILE | wc -l)
if [ $num_options -eq 0 ]; then if [ $num_options -eq 0 ]; then
die "No boot options" die "No boot options"
fi fi
@ -132,13 +136,12 @@ get_menu_option() {
elif [ "$gui_menu" = "y" ]; then elif [ "$gui_menu" = "y" ]; then
MENU_OPTIONS="" MENU_OPTIONS=""
n=0 n=0
while read option while read option; do
do
parse_option parse_option
n=`expr $n + 1` n=$(expr $n + 1)
name=$(echo $name | tr " " "_") name=$(echo $name | tr " " "_")
MENU_OPTIONS="$MENU_OPTIONS $n ${name} " MENU_OPTIONS="$MENU_OPTIONS $n ${name} "
done < $TMP_MENU_FILE done <$TMP_MENU_FILE
whiptail --title "Select your boot option" \ whiptail --title "Select your boot option" \
--menu "Choose the boot option [1-$n, a to abort]:" 0 80 8 \ --menu "Choose the boot option [1-$n, a to abort]:" 0 80 8 \
@ -149,12 +152,11 @@ get_menu_option() {
else else
echo "+++ Select your boot option:" echo "+++ Select your boot option:"
n=0 n=0
while read option while read option; do
do
parse_option parse_option
n=`expr $n + 1` n=$(expr $n + 1)
echo "$n. $name [$kernel]" echo "$n. $name [$kernel]"
done < $TMP_MENU_FILE done <$TMP_MENU_FILE
read \ read \
-p "Choose the boot option [1-$n, a to abort]: " \ -p "Choose the boot option [1-$n, a to abort]: " \
@ -166,7 +168,7 @@ get_menu_option() {
fi fi
first_menu="n" first_menu="n"
option=`head -n $option_index $TMP_MENU_FILE | tail -1` option=$(head -n $option_index $TMP_MENU_FILE | tail -1)
parse_option parse_option
} }
@ -175,7 +177,7 @@ confirm_menu_option() {
default_text="Make default" default_text="Make default"
[[ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" = "y" ]] && default_text="${default_text} and boot" [[ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" = "y" ]] && default_text="${default_text} and boot"
whiptail $BG_COLOR_WARNING --title "Confirm boot details" \ whiptail $BG_COLOR_WARNING --title "Confirm boot details" \
--menu "Confirm the boot details for $name:\n\n$(echo $kernel| fold -s -w 80) \n\n" 0 80 8 \ --menu "Confirm the boot details for $name:\n\n$(echo $kernel | fold -s -w 80) \n\n" 0 80 8 \
-- 'd' "${default_text}" 'y' "Boot one time" \ -- 'd' "${default_text}" 'y' "Boot one time" \
2>/tmp/whiptail || die "Aborting boot attempt" 2>/tmp/whiptail || die "Aborting boot attempt"
@ -193,8 +195,8 @@ confirm_menu_option() {
} }
parse_option() { parse_option() {
name=`echo $option | cut -d\| -f1` name=$(echo $option | cut -d\| -f1)
kernel=`echo $option | cut -d\| -f3` kernel=$(echo $option | cut -d\| -f3)
} }
scan_options() { scan_options() {
@ -205,7 +207,7 @@ scan_options() {
die "Failed to parse any boot options" die "Failed to parse any boot options"
fi fi
if [ "$unique" = 'y' ]; then if [ "$unique" = 'y' ]; then
sort -r $option_file | uniq > $TMP_MENU_FILE sort -r $option_file | uniq >$TMP_MENU_FILE
else else
cp $option_file $TMP_MENU_FILE cp $option_file $TMP_MENU_FILE
fi fi
@ -245,11 +247,11 @@ default_select() {
# Attempt boot with expected parameters # Attempt boot with expected parameters
# Check that entry matches that which is expected from menu # Check that entry matches that which is expected from menu
default_index=`basename "$TMP_DEFAULT_FILE" | cut -d. -f 2` default_index=$(basename "$TMP_DEFAULT_FILE" | cut -d. -f 2)
# Check to see if entries have changed - useful for detecting grub update # Check to see if entries have changed - useful for detecting grub update
expectedoption=`cat $TMP_DEFAULT_FILE` expectedoption=$(cat $TMP_DEFAULT_FILE)
option=`head -n $default_index $TMP_MENU_FILE | tail -1` option=$(head -n $default_index $TMP_MENU_FILE | tail -1)
if [ "$option" != "$expectedoption" ]; then if [ "$option" != "$expectedoption" ]; then
if [ "$gui_menu" = "y" ]; then if [ "$gui_menu" = "y" ]; then
whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Entry Has Changed' \ whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Entry Has Changed' \
@ -264,7 +266,7 @@ default_select() {
# Enforce that default option hashes are valid # Enforce that default option hashes are valid
echo "+++ Checking verified default boot hash file " echo "+++ Checking verified default boot hash file "
# Check the hashes of all the files # Check the hashes of all the files
if ( cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" > /tmp/hash_output ); then if (cd $bootdir && sha256sum -c "$TMP_DEFAULT_HASH_FILE" >/tmp/hash_output); then
echo "+++ Verified default boot hashes " echo "+++ Verified default boot hashes "
valid_hash='y' valid_hash='y'
else else
@ -285,8 +287,7 @@ user_select() {
# No default expected boot parameters, ask user # No default expected boot parameters, ask user
option_confirm="" option_confirm=""
while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ] while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ]; do
do
get_menu_option get_menu_option
# In force boot mode, no need offer the option to set a default, just boot # In force boot mode, no need offer the option to set a default, just boot
if [[ "$force_boot" = "y" || "$skip_confirm" = "y" ]]; then if [[ "$force_boot" = "y" || "$skip_confirm" = "y" ]]; then
@ -308,8 +309,8 @@ user_select() {
echo "+++ Rebooting to start the new default option" echo "+++ Rebooting to start the new default option"
sleep 2 sleep 2
if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then
reboot \ reboot ||
|| die "!!! Failed to reboot system" die "!!! Failed to reboot system"
else else
DEBUG "Rebooting is required prior of booting default boot entry" DEBUG "Rebooting is required prior of booting default boot entry"
# Instead of rebooting, drop to a recovery shell # Instead of rebooting, drop to a recovery shell
@ -322,8 +323,7 @@ user_select() {
do_boot do_boot
} }
do_boot() do_boot() {
{
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_BOOT_REQ_ROLLBACK" = "y" ] && [ "$valid_rollback" = "n" ]; then if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_BOOT_REQ_ROLLBACK" = "y" ] && [ "$valid_rollback" = "n" ]; then
die "!!! Missing required rollback counter state" die "!!! Missing required rollback counter state"
fi fi
@ -333,21 +333,21 @@ do_boot()
fi fi
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_TPM" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_TPM" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then
INITRD=`kexec-boot -b "$bootdir" -e "$option" -i` \ INITRD=$(kexec-boot -b "$bootdir" -e "$option" -i) ||
|| die "!!! Failed to extract the initrd from boot option" die "!!! Failed to extract the initrd from boot option"
if [ -z "$INITRD" ]; then if [ -z "$INITRD" ]; then
die "!!! No initrd file found in boot option" die "!!! No initrd file found in boot option"
fi fi
kexec-insert-key $INITRD \ kexec-insert-key $INITRD ||
|| die "!!! Failed to insert disk key into a new initrd" die "!!! Failed to insert disk key into a new initrd"
kexec-boot -b "$bootdir" -e "$option" \ kexec-boot -b "$bootdir" -e "$option" \
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" \ -a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" ||
|| die "!!! Failed to boot w/ options: $option" die "!!! Failed to boot w/ options: $option"
else else
kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" \ kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" ||
|| die "!!! Failed to boot w/ options: $option" die "!!! Failed to boot w/ options: $option"
fi fi
} }
@ -357,7 +357,7 @@ while true; do
else else
check_config $paramsdir check_config $paramsdir
fi fi
TMP_DEFAULT_FILE=`find /tmp/kexec/kexec_default.*.txt 2>/dev/null | head -1` || true TMP_DEFAULT_FILE=$(find /tmp/kexec/kexec_default.*.txt 2>/dev/null | head -1) || true
TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt" TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt"
TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt"
TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt"
@ -366,8 +366,8 @@ while true; do
TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt" TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt"
TMP_KEY_LVM="/tmp/kexec/kexec_key_lvm.txt" TMP_KEY_LVM="/tmp/kexec/kexec_key_lvm.txt"
# Allow a way for users to ignore warnings and boot into their systems # Allow a way for users to ignore warnings and boot into their systems
# even if hashes don't match # even if hashes don't match
if [ "$force_boot" = "y" ]; then if [ "$force_boot" = "y" ]; then
scan_options scan_options
if [ "$CONFIG_BASIC" != "y" ]; then if [ "$CONFIG_BASIC" != "y" ]; then
@ -381,8 +381,8 @@ while true; do
if [ "$CONFIG_TPM" = "y" ]; then if [ "$CONFIG_TPM" = "y" ]; then
if [ ! -r "$TMP_KEY_DEVICES" ]; then if [ ! -r "$TMP_KEY_DEVICES" ]; then
# Extend PCR4 as soon as possible # Extend PCR4 as soon as possible
tpmr extend -ix 4 -ic generic \ tpmr extend -ix 4 -ic generic ||
|| die "Failed to extend PCR 4" die "Failed to extend PCR 4"
fi fi
fi fi