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
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!"
DEBUG "TPM2 primary key handle hash saved to $PRIMHASH_FILE"
fi
rm $paramsdir/kexec_default.*.txt 2>/dev/null || true

View File

@ -19,18 +19,25 @@ force_boot="n"
skip_confirm="n"
while getopts "b:d:p:a:r:c:uimgfs" arg; do
case $arg in
b) bootdir="$OPTARG" ;;
d) paramsdev="$OPTARG" ;;
p) paramsdir="$OPTARG" ;;
a) add="$OPTARG" ;;
r) remove="$OPTARG" ;;
c) config="$OPTARG" ;;
u) unique="y" ;;
m) force_menu="y" ;;
i) valid_hash="y"; valid_rollback="y" ;;
g) gui_menu="y" ;;
f) force_boot="y"; valid_hash="y"; valid_rollback="y" ;;
s) skip_confirm="y" ;;
b) bootdir="$OPTARG" ;;
d) paramsdev="$OPTARG" ;;
p) paramsdir="$OPTARG" ;;
a) add="$OPTARG" ;;
r) remove="$OPTARG" ;;
c) config="$OPTARG" ;;
u) unique="y" ;;
m) force_menu="y" ;;
i)
valid_hash="y"
valid_rollback="y"
;;
g) gui_menu="y" ;;
f)
force_boot="y"
valid_hash="y"
valid_rollback="y"
;;
s) skip_confirm="y" ;;
esac
done
@ -50,30 +57,28 @@ bootdir="${bootdir%%/}"
paramsdev="${paramsdev%%/}"
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"
#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()
{
verify_global_hashes() {
echo "+++ Checking verified boot hash file "
# 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 "
valid_hash='y'
valid_global_hash='y'
@ -85,44 +90,43 @@ verify_global_hashes()
fi
die "$TMP_HASH_FILE: boot hash mismatch"
fi
# If user enables it, check root hashes before boot as well
if [[ "$CONFIG_ROOT_CHECK_AT_BOOT" = "y" && "$force_menu" == "n" ]]; then
if root-hashes-gui.sh -c; then
echo "+++ Verified root hashes, continuing boot "
# if user re-signs, it wipes out saved options, so scan the boot directory and generate
if [ ! -r "$TMP_MENU_FILE" ]; then
scan_options
fi
else
# root-hashes-gui.sh handles the GUI error menu, just die here
if [ "$gui_menu" = "y" ]; then
whiptail $BG_COLOR_ERROR --title 'ERROR: Root Hash Mismatch' \
--msgbox "The root hash check failed!\nExiting to a recovery shell" 0 80
fi
die "root hash mismatch, see /tmp/hash_output_mismatches for details"
fi
fi
# If user enables it, check root hashes before boot as well
if [[ "$CONFIG_ROOT_CHECK_AT_BOOT" = "y" && "$force_menu" == "n" ]]; then
if root-hashes-gui.sh -c; then
echo "+++ Verified root hashes, continuing boot "
# if user re-signs, it wipes out saved options, so scan the boot directory and generate
if [ ! -r "$TMP_MENU_FILE" ]; then
scan_options
fi
else
# root-hashes-gui.sh handles the GUI error menu, just die here
if [ "$gui_menu" = "y" ]; then
whiptail $BG_COLOR_ERROR --title 'ERROR: Root Hash Mismatch' \
--msgbox "The root hash check failed!\nExiting to a recovery shell" 0 80
fi
die "root hash mismatch, see /tmp/hash_output_mismatches for details"
fi
fi
}
verify_rollback_counter()
{
TPM_COUNTER=`grep counter $TMP_ROLLBACK_FILE | cut -d- -f2`
verify_rollback_counter() {
TPM_COUNTER=$(grep counter $TMP_ROLLBACK_FILE | cut -d- -f2)
if [ -z "$TPM_COUNTER" ]; then
die "$TMP_ROLLBACK_FILE: TPM counter not found?"
fi
read_tpm_counter $TPM_COUNTER \
|| die "Failed to read TPM counter"
read_tpm_counter $TPM_COUNTER ||
die "Failed to read TPM counter"
sha256sum -c $TMP_ROLLBACK_FILE \
|| die "Invalid TPM counter state"
sha256sum -c $TMP_ROLLBACK_FILE ||
die "Invalid TPM counter state"
valid_rollback="y"
}
first_menu="y"
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
die "No boot options"
fi
@ -132,13 +136,12 @@ get_menu_option() {
elif [ "$gui_menu" = "y" ]; then
MENU_OPTIONS=""
n=0
while read option
do
while read option; do
parse_option
n=`expr $n + 1`
n=$(expr $n + 1)
name=$(echo $name | tr " " "_")
MENU_OPTIONS="$MENU_OPTIONS $n ${name} "
done < $TMP_MENU_FILE
done <$TMP_MENU_FILE
whiptail --title "Select your boot option" \
--menu "Choose the boot option [1-$n, a to abort]:" 0 80 8 \
@ -149,12 +152,11 @@ get_menu_option() {
else
echo "+++ Select your boot option:"
n=0
while read option
do
while read option; do
parse_option
n=`expr $n + 1`
n=$(expr $n + 1)
echo "$n. $name [$kernel]"
done < $TMP_MENU_FILE
done <$TMP_MENU_FILE
read \
-p "Choose the boot option [1-$n, a to abort]: " \
@ -166,7 +168,7 @@ get_menu_option() {
fi
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
}
@ -175,7 +177,7 @@ confirm_menu_option() {
default_text="Make default"
[[ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" = "y" ]] && default_text="${default_text} and boot"
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" \
2>/tmp/whiptail || die "Aborting boot attempt"
@ -193,8 +195,8 @@ confirm_menu_option() {
}
parse_option() {
name=`echo $option | cut -d\| -f1`
kernel=`echo $option | cut -d\| -f3`
name=$(echo $option | cut -d\| -f1)
kernel=$(echo $option | cut -d\| -f3)
}
scan_options() {
@ -205,7 +207,7 @@ scan_options() {
die "Failed to parse any boot options"
fi
if [ "$unique" = 'y' ]; then
sort -r $option_file | uniq > $TMP_MENU_FILE
sort -r $option_file | uniq >$TMP_MENU_FILE
else
cp $option_file $TMP_MENU_FILE
fi
@ -227,7 +229,7 @@ save_default_option() {
-d "$paramsdev" \
-p "$paramsdir" \
-i "$option_index" \
; then
; then
echo "+++ Saved defaults to device"
sleep 2
default_failed="n"
@ -245,11 +247,11 @@ default_select() {
# Attempt boot with expected parameters
# 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
expectedoption=`cat $TMP_DEFAULT_FILE`
option=`head -n $default_index $TMP_MENU_FILE | tail -1`
expectedoption=$(cat $TMP_DEFAULT_FILE)
option=$(head -n $default_index $TMP_MENU_FILE | tail -1)
if [ "$option" != "$expectedoption" ]; then
if [ "$gui_menu" = "y" ]; then
whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Entry Has Changed' \
@ -264,7 +266,7 @@ default_select() {
# Enforce that default option hashes are valid
echo "+++ Checking verified default boot hash file "
# 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 "
valid_hash='y'
else
@ -285,10 +287,9 @@ user_select() {
# No default expected boot parameters, ask user
option_confirm=""
while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ]
do
while [ "$option_confirm" != "y" -a "$option_confirm" != "d" ]; do
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
do_boot
else
@ -308,8 +309,8 @@ user_select() {
echo "+++ Rebooting to start the new default option"
sleep 2
if [ "$CONFIG_DEBUG_OUTPUT" != "y" ]; then
reboot \
|| die "!!! Failed to reboot system"
reboot ||
die "!!! Failed to reboot system"
else
DEBUG "Rebooting is required prior of booting default boot entry"
# Instead of rebooting, drop to a recovery shell
@ -322,8 +323,7 @@ user_select() {
do_boot
}
do_boot()
{
do_boot() {
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_BOOT_REQ_ROLLBACK" = "y" ] && [ "$valid_rollback" = "n" ]; then
die "!!! Missing required rollback counter state"
fi
@ -333,31 +333,31 @@ do_boot()
fi
if [ "$CONFIG_BASIC" != y ] && [ "$CONFIG_TPM" = "y" ] && [ -r "$TMP_KEY_DEVICES" ]; then
INITRD=`kexec-boot -b "$bootdir" -e "$option" -i` \
|| die "!!! Failed to extract the initrd from boot option"
INITRD=$(kexec-boot -b "$bootdir" -e "$option" -i) ||
die "!!! Failed to extract the initrd from boot option"
if [ -z "$INITRD" ]; then
die "!!! No initrd file found in boot option"
fi
kexec-insert-key $INITRD \
|| die "!!! Failed to insert disk key into a new initrd"
kexec-insert-key $INITRD ||
die "!!! Failed to insert disk key into a new initrd"
kexec-boot -b "$bootdir" -e "$option" \
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" \
|| die "!!! Failed to boot w/ options: $option"
-a "$add" -r "$remove" -o "/tmp/secret/initrd.cpio" ||
die "!!! Failed to boot w/ options: $option"
else
kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" \
|| die "!!! Failed to boot w/ options: $option"
kexec-boot -b "$bootdir" -e "$option" -a "$add" -r "$remove" ||
die "!!! Failed to boot w/ options: $option"
fi
}
while true; do
if [ "$force_boot" = "y" -o "$CONFIG_BASIC" = "y" ]; then
check_config $paramsdir force
check_config $paramsdir force
else
check_config $paramsdir
check_config $paramsdir
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_HASH_FILE="/tmp/kexec/kexec_hashes.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_LVM="/tmp/kexec/kexec_key_lvm.txt"
# Allow a way for users to ignore warnings and boot into their systems
# even if hashes don't match
# Allow a way for users to ignore warnings and boot into their systems
# even if hashes don't match
if [ "$force_boot" = "y" ]; then
scan_options
if [ "$CONFIG_BASIC" != "y" ]; then
@ -381,8 +381,8 @@ while true; do
if [ "$CONFIG_TPM" = "y" ]; then
if [ ! -r "$TMP_KEY_DEVICES" ]; then
# Extend PCR4 as soon as possible
tpmr extend -ix 4 -ic generic \
|| die "Failed to extend PCR 4"
tpmr extend -ix 4 -ic generic ||
die "Failed to extend PCR 4"
fi
fi
@ -415,7 +415,7 @@ while true; do
-a "$force_menu" = "n" \
-a -r "$TMP_DEFAULT_FILE" \
-a -r "$TMP_DEFAULT_HASH_FILE" ] \
; then
; then
default_select
default_failed="y"
else