WiP: Clean cached /tmp/secret/tpm_password when sealing fails, otherwise reuse it on TPM Reset/TOTP+HOTP Sealing once for TPM1/TPM2+TPM Disk Unlock Key

gui-init: make sure that reseal_tpm_disk_decryption_key happens only on successful TOTP/HOTP sealing, reusing cached TPM Owner password

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion 2023-10-23 15:18:28 -04:00
parent 911eb07565
commit 3fb84f0b42
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
6 changed files with 38 additions and 27 deletions

View File

@ -229,8 +229,7 @@ update_totp()
g )
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
generate_totp_hotp && update_totp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
fi
;;
i )
@ -238,8 +237,7 @@ update_totp()
return 1
;;
p )
reset_tpm && update_totp && BG_COLOR_MAIN_MENU=""
reseal_tpm_disk_decryption_key
reset_tpm && update_totp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
;;
x )
recovery "User requested recovery shell"
@ -300,8 +298,7 @@ update_hotp()
g )
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
generate_totp_hotp && BG_COLOR_MAIN_MENU="" && reseal_tpm_disk_decryption_key
fi
;;
i )
@ -526,12 +523,10 @@ show_tpm_totp_hotp_options_menu()
option=$(cat /tmp/whiptail)
case "$option" in
g )
generate_totp_hotp
reseal_tpm_disk_decryption_key
generate_totp_hotp && reseal_tpm_disk_decryption_key
;;
r )
reset_tpm
reseal_tpm_disk_decryption_key
reset_tpm && reseal_tpm_disk_decryption_key
;;
t )
prompt_totp_mismatch

View File

@ -137,7 +137,11 @@ tpmr pcrread -a 7 "$pcrf"
DO_WITH_DEBUG --mask-position 7 \
tpmr seal "$KEY_FILE" "$TPM_INDEX" 0,1,2,3,4,5,6,7 "$pcrf" \
"$TPM_SIZE" "$key_password"
"$TPM_SIZE" "$key_password" || {
shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null
:
die "Unable to write TPM Disk Unlock Key to NVRAM"
}
# should be okay if this fails
shred -n 10 -z -u "$pcrf" 2>/dev/null ||

View File

@ -25,10 +25,10 @@ dd \
of="$TOTP_SECRET" \
count=1 \
bs=20 \
2>/dev/null \
|| die "Unable to generate 20 random bytes"
2>/dev/null ||
die "Unable to generate 20 random bytes"
secret="`base32 < $TOTP_SECRET`"
secret="$(base32 <$TOTP_SECRET)"
pcrf="/tmp/secret/pcrf.bin"
DEBUG "Sealing TOTP with actual state of PCR0-3"
tpmr pcrread 0 "$pcrf"
@ -36,20 +36,26 @@ tpmr pcrread -a 1 "$pcrf"
tpmr pcrread -a 2 "$pcrf"
tpmr pcrread -a 3 "$pcrf"
DEBUG "Sealing TOTP with boot state of PCR4 (Going to recovery shell extends PCR4)"
# pcr 4 is expected to either:
# pcr 4 is expected to either:
# zero on bare coreboot+linuxboot on x86 (boot mode: init)
# already extended on ppc64 per BOOTKERNEL (skiboot) which boots heads.
# Read from event log to catch both cases, even when called from recovery shell.
tpmr calcfuturepcr 4 >> "$pcrf"
tpmr calcfuturepcr 4 >>"$pcrf"
# pcr 5 (kernel modules loaded) is not measured at sealing/unsealing of totp
DEBUG "Sealing TOTP neglecting PCR5 involvement (Dynamically loaded kernel modules are not firmware integrity attestation related)"
# pcr 6 (drive LUKS header) is not measured at sealing/unsealing of totp
DEBUG "Sealing TOTP without PCR6 involvement (LUKS header consistency is not firmware integrity attestation related)"
# pcr 7 is containing measurements of user injected stuff in cbfs
tpmr pcrread -a 7 "$pcrf"
tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PASSWORD" \
|| die "Unable to write sealed secret to NVRAM"
shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null
#Make sure we clear the TPM Owner Password from memory in case it failed to be used to seal TOTP
tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PASSWORD" ||
{
shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null
:
die "Unable to write sealed secret to NVRAM"
}
#Make sure we clear TPM TOTP sealed if we succeed to seal TOTP
shred -n 10 -z -u "$TOTP_SEALED" 2>/dev/null
url="otpauth://totp/$HOST?secret=$secret"
secret=""

View File

@ -533,6 +533,7 @@ tpm2_unseal() {
# can't do anything without a primary handle.
if [ ! -f "/tmp/$PRIMARY_HANDLE_FILE" ]; then
DEBUG "tpm2_unseal: No primary handle, cannot attempt to unseal"
warn "No TPM primary handle. You must reset TPM to seal secret"
exit 1
fi

View File

@ -8,14 +8,14 @@ TOTP_SECRET="/tmp/secret/totp.key"
TRACE "Under /bin/unseal-totp"
if [ "$CONFIG_TPM" = "y" ]; then
tpmr unseal 4d47 0,1,2,3,4,7 312 "$TOTP_SECRET" \
|| die "Unable to unseal totp secret"
fi
tpmr unseal 4d47 0,1,2,3,4,7 312 "$TOTP_SECRET" ||
die "Unable to unseal TOTP secret"
fi
if ! totp -q < "$TOTP_SECRET"; then
shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null
if ! totp -q <"$TOTP_SECRET"; then
shred -n 10 -z -u "$TOTP_SECRET" 2>/dev/null
die 'Unable to compute TOTP hash?'
fi
shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null
shred -n 10 -z -u "$TOTP_SECRET" 2>/dev/null
exit 0

View File

@ -99,7 +99,7 @@ reseal_tpm_disk_decryption_key() {
warn "TPM sealed Disk Unlock Key secret needs to be resealed alongside TOTP/HOTP secret"
echo "Resealing TPM 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!"
warn "Recovery Disk Encryption key passphrase/TPM Owner Password may be invalid. Please try again"
done
warn "LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt"
echo "Updating checksums and signing all files under /boot/kexec.sig"
@ -206,6 +206,11 @@ prompt_tpm_password() {
read -s -p "TPM Owner Password: " tpm_password
echo # new line after password prompt
# Cache the password externally to be reused by who needs it
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password"
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret"
}
# Prompt for a new owner password when resetting the TPM. Returned in
@ -232,7 +237,7 @@ prompt_new_owner_password() {
# Cache the password externally to be reused by who needs it
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password"
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
echo "$key_password" > /tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret"
echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret"
}
check_tpm_counter() {