-
-
Notifications
You must be signed in to change notification settings - Fork 195
HOTP asked to be resealed even if TOTP good (Picks up on a reinstalled OS even if firmware measurements haven't changed) #1935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
1f6a975
f9def6b
b5cb7ae
c4b7fef
0d3b3b6
68da322
03c5d39
6d90480
08c8862
4ef7473
d9730be
9c7ef3f
d10a424
19d400a
67a7fd9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,9 @@ find /boot/kexec*.txt | gpg --verify /boot/kexec.sig - | |
#remove invalid kexec_* signed files | ||
mount /dev/sda1 /boot && mount -o remount,rw /boot && rm /boot/kexec* && mount -o remount,ro /boot | ||
#Generate keys on OpenPGP smartcard: | ||
mount-usb && gpg --home=/.gnupg/ --card-edit | ||
mount-usb --mode rw && gpg --home=/.gnupg/ --card-edit | ||
#Copy generated public key, private_subkey, trustdb and artifacts to external media for backup: | ||
mount -o remount,rw /media && mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor [email protected] > /media/gpg_keys/private.key && gpg --export --armor [email protected] > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null | ||
mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor [email protected] > /media/gpg_keys/private.key && gpg --export --armor [email protected] > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null | ||
#Insert public key and trustdb export into reproducible rom: | ||
cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/public.key" -f /media/gpg_keys/public.key && cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/otrust.txt" -f /media/gpg_keys/otrust.txt | ||
#Flush changes to external media: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,16 +150,21 @@ generate_totp_hotp() { | |
TRACE_FUNC | ||
tpm_owner_password="$1" # May be empty, will prompt if needed and empty | ||
if [ "$CONFIG_TPM" != "y" ] && [ -x /bin/hotp_verification ]; then | ||
# If we don't have a TPM, but we have a HOTP USB Security dongle | ||
TRACE_FUNC | ||
echo "Generating new HOTP secret" | ||
/bin/seal-hotpkey | ||
/bin/seal-hotpkey || | ||
die "Failed to generate HOTP secret" | ||
elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_owner_password"; then | ||
echo | ||
if [ -x /bin/hotp_verification ]; then | ||
# If we have a TPM and a HOTP USB Security dongle | ||
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then | ||
echo "Once you have scanned the QR code, hit Enter to configure your HOTP USB Security dongle (e.g. Librem Key or Nitrokey)" | ||
read | ||
fi | ||
/bin/seal-hotpkey | ||
TRACE_FUNC | ||
/bin/seal-hotpkey || die "Failed to generate HOTP secret" | ||
else | ||
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then | ||
echo "Once you have scanned the QR code, hit Enter to continue" | ||
|
@@ -183,17 +188,6 @@ update_totp() { | |
TOTP="NO TPM" | ||
else | ||
TOTP=$(unseal-totp) | ||
# On platforms using CONFIG_BOOT_EXTRA_TTYS multiple processes may try to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No more 3 attempts on boot to unseal TPMTOTP: if multiple consoles (Eg Talos-2 with display console + BMC, at worst we could intruduce small delay if race condition still happening, while die asks user to press Enter now, guiding to reseal TPMTOTP or reset TPM if unable to access TPM NVRAM. |
||
# access TPM at the same time, failing with EBUSY. The order of execution | ||
# is unpredictable, so the error may appear on main console, secondary one, | ||
# or neither of them if the calls are sufficiently staggered. Try up to | ||
# three times (including previous one) with small delays in case of error, | ||
# instead of immediately scaring users with "you've been pwned" message. | ||
while [ $? -ne 0 ] && [ $tries -lt 2 ]; do | ||
sleep 0.5 | ||
((tries++)) | ||
TOTP=$(unseal-totp) | ||
done | ||
if [ $? -ne 0 ]; then | ||
BG_COLOR_MAIN_MENU="error" | ||
if [ "$skip_to_menu" = "true" ]; then | ||
|
@@ -280,7 +274,10 @@ update_hotp() { | |
HOTP='N/A' | ||
fi | ||
|
||
if [[ "$CONFIG_TPM" = n && "$HOTP" = "Invalid code" ]]; then | ||
if [[ "$HOTP" = "Invalid code" ]]; then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check only verified if HOTP was invalid if no TPM was in use. So now, if there is no /boot/kexec_hotp_counter and TPMTOTP can unseal, user is promoted to reseal HOTP alone (OS reinstall use case without firmware upgrade) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But what is we have kexec_rollback.txt? All of this doesn't make any sense: user should reset TPM here of more logic needs to be refactored. |
||
#Do not propose to generate a new secret if there is no /boot/kexec_hotp_counter | ||
# tpm unseal succeeded: so the sealed secret is correct: we should propose to reset TPM if not already | ||
# Here: the OS was most probably reinstalled since TPM can still unseal the secret | ||
whiptail_error --title "ERROR: HOTP Validation Failed!" \ | ||
--menu "ERROR: $CONFIG_BRAND_NAME couldn't validate the HOTP code.\n\nIf you just reflashed your BIOS, you should generate a new TOTP/HOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 0 80 4 \ | ||
'g' ' Generate new TOTP/HOTP secret' \ | ||
|
@@ -553,21 +550,30 @@ reset_tpm() { | |
mount -o rw,remount /boot | ||
#TODO: this is really problematic, we should really remove the primary handle hash | ||
|
||
INFO "Removing rollback and primary handle hash under /boot" | ||
INFO "Removing rollback and primary handle hashes under /boot" | ||
|
||
DEBUG "Removing /boot/kexec_rollback.txt and /boot/kexec_primhdl_hash.txt" | ||
rm -f /boot/kexec_rollback.txt | ||
rm -f /boot/kexec_primhdl_hash.txt | ||
|
||
# create Heads TPM counter before any others | ||
check_tpm_counter /boot/kexec_rollback.txt "" "$tpm_owner_password" || | ||
die "Unable to find/create tpm counter" | ||
counter="$TPM_COUNTER" | ||
|
||
increment_tpm_counter $counter >/dev/null 2>&1 || | ||
TRACE_FUNC | ||
|
||
TPM_COUNTER=$(cut -d: -f1 </tmp/counter) | ||
DEBUG "TPM_COUNTER: $TPM_COUNTER" | ||
#TODO was counter supposed to be empty and that was ok?!?!?! | ||
|
||
DO_WITH_DEBUG increment_tpm_counter $TPM_COUNTER>/dev/null 2>&1 || | ||
die "Unable to increment tpm counter" | ||
|
||
sha256sum /tmp/counter-$counter >/boot/kexec_rollback.txt || | ||
#TODO: should this be here? | ||
DO_WITH_DEBUG sha256sum /tmp/counter-$TPM_COUNTER >/boot/kexec_rollback.txt || | ||
die "Unable to create rollback file" | ||
|
||
TRACE_FUNC | ||
# As a countermeasure for existing primary handle hash, we will now force sign /boot without it | ||
if (whiptail --title 'TPM Reset Successfully' \ | ||
--yesno "Would you like to update the checksums and sign all of the files in /boot?\n\nYou will need your GPG key to continue and this will modify your disk.\n\nOtherwise the system will reboot immediately." 0 80); then | ||
|
@@ -576,7 +582,8 @@ reset_tpm() { | |
--msgbox "Failed to update checksums / sign default config" 0 80 | ||
fi | ||
else | ||
die "TPM reset successful, but user chose not to update checksums" | ||
warn "TPM reset successful, but user chose not to update+sign /boot checksums. Rebooting" | ||
reboot | ||
fi | ||
mount -o ro,remount /boot | ||
|
||
|
@@ -593,7 +600,7 @@ select_os_boot_option() { | |
TRACE_FUNC | ||
mount_boot | ||
if verify_global_hashes; then | ||
kexec-select-boot -m -b /boot -c "grub.cfg" -g | ||
DO_WITH_DEBUG kexec-select-boot -m -b /boot -c "grub.cfg" -g | ||
fi | ||
} | ||
|
||
|
@@ -606,11 +613,13 @@ attempt_default_boot() { | |
fi | ||
DEFAULT_FILE=$(find /boot/kexec_default.*.txt 2>/dev/null | head -1) | ||
if [ -r "$DEFAULT_FILE" ]; then | ||
kexec-select-boot -b /boot -c "grub.cfg" -g || | ||
TRACE_FUNC | ||
DO_WITH_DEBUG kexec-select-boot -b /boot -c "grub.cfg" -g || | ||
recovery "Failed default boot" | ||
elif (whiptail_warning --title 'No Default Boot Option Configured' \ | ||
--yesno "There is no default boot option configured yet.\nWould you like to load a menu of boot options?\nOtherwise you will return to the main menu." 0 80); then | ||
kexec-select-boot -m -b /boot -c "grub.cfg" -g | ||
TRACE_FUNC | ||
DO_WITH_DEBUG kexec-select-boot -m -b /boot -c "grub.cfg" -g | ||
fi | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bash history now promotes mount-usb --mode rw. nitpick