diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1ab178f3..a9bfc417 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -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 diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index c8a1891a..881797a5 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -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 || diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index 374e1eab..d3953ce4 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -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="" diff --git a/initrd/bin/tpmr b/initrd/bin/tpmr index 20ac4a47..ddcf5e88 100755 --- a/initrd/bin/tpmr +++ b/initrd/bin/tpmr @@ -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 diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index 32db3192..ed8f18af 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -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 diff --git a/initrd/etc/functions b/initrd/etc/functions index 816eb902..60ff97c7 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -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() {