From c9c4e6e2c4d4e6d41f4ffe81bf1c9eebf1d805aa Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 22 Apr 2024 17:09:36 -0400 Subject: [PATCH] Fix HOTP verification logic (and counter increment) in gui-init and oem-factory-reset scripts --- initrd/bin/gui-init | 3 ++- initrd/bin/oem-factory-reset | 16 ++++++++++--- initrd/bin/unseal-hotp | 46 ++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index cd69e87c..dfd412f2 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -250,8 +250,8 @@ update_totp() update_hotp() { TRACE_FUNC + HOTP="Unverified" if [ -x /bin/hotp_verification ]; then - HOTP=`unseal-hotp` if ! hotp_verification info ; then if [ "$skip_to_menu" = "true" ]; then return 1 # Already asked to skip to menu from a prior error @@ -265,6 +265,7 @@ update_hotp() return fi fi + HOTP=`unseal-hotp` # Don't output HOTP codes to screen, so as to make replay attacks harder hotp_verification check "$HOTP" case "$?" in diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 6b597fc0..c368eef9 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -783,12 +783,22 @@ report_integrity_measurements() { # Check and report on HOTP status if [ -x /bin/hotp_verification ]; then - HOTP=$(unseal-hotp) >/dev/null 2>&1 + HOTP="Unverified" enable_usb - if ! hotp_verification info >/dev/null 2>&1; then - whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security Dongle' --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + for attempt in 1 2 3; do + if ! hotp_verification info >/dev/null 2>&1; then + whiptail $CONFIG_WARNING_BG_COLOR --title "WARNING: Please insert your HOTP enabled USB Security Dongle (Attempt $attempt/3)" --msgbox "Your HOTP enabled USB Security Dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + else + break + fi + done + + if [ $attempt -eq 3 ]; then + die "No HOTP enabled USB Security Dongle detected. Please disable 'CONFIG_HOTPKEY' in the board config and rebuild." fi + # Don't output HOTP codes to screen, so as to make replay attacks harder + HOTP=$(unseal-hotp) >/dev/null 2>&1 hotp_verification check $HOTP case "$?" in 0) diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 031c6d27..8565ac61 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -6,13 +6,12 @@ HOTP_SECRET="/tmp/secret/hotp.key" HOTP_COUNTER="/boot/kexec_hotp_counter" -mount_boot_or_die() -{ +mount_boot_or_die() { TRACE_FUNC # Mount local disk if it is not already mounted - if ! grep -q /boot /proc/mounts ; then - mount -o ro /boot \ - || die "Unable to mount /boot" + if ! grep -q /boot /proc/mounts; then + mount -o ro /boot || + die "Unable to mount /boot" fi } @@ -38,34 +37,35 @@ fi #counter_value=$(printf "%d" 0x${counter_value}) if [ "$CONFIG_TPM" = "y" ]; then - DEBUG "Unsealing HOTP secret reuses TOTP sealed secret..." - tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" || die "Unable to unseal HOTP secret" + DEBUG "Unsealing HOTP secret reuses TOTP sealed secret..." + tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" || die "Unable to unseal HOTP secret" else - # without a TPM, generate a secret based on the SHA-256 of the ROM - secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed" + # without a TPM, generate a secret based on the SHA-256 of the ROM + secret_from_rom_hash >"$HOTP_SECRET" || die "Reading ROM failed" fi # Truncate the secret if it is longer than the maximum HOTP secret truncate_max_bytes 20 "$HOTP_SECRET" -if ! hotp $counter_value < "$HOTP_SECRET"; then - shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null - die 'Unable to compute HOTP hash?' +if ! hotp $counter_value <"$HOTP_SECRET"; then + shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null + die 'Unable to compute HOTP hash?' fi -shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null - -#increment_tpm_counter $counter > /dev/null \ -#|| die "Unable to increment tpm counter" +shred -n 10 -z -u "$HOTP_SECRET" 2>/dev/null +#Incrementing counter under $HOTP_COUNTER +# +# If for whatever reason, this counter is 5 counts different then on HOTP USB Security dongle, HOTP unseal fails. +#Note: HOTP_COUNTER="/boot/kexec_hotp_counter" is not detached signed under kexec.sig since it changes +# +# TODO: figure out a better alternative then a counter that can be modified on disk +# As of now, this counter isincreased only in the validated presence of the HOTP dongle being connected per callers mount -o remount,rw /boot - -counter_value=`expr $counter_value + 1` -echo $counter_value > $HOTP_COUNTER \ -|| die "Unable to create hotp counter file" - -#sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ -#|| die "Unable to create hotp counter file" +DEBUG "Incrementing HOTP counter under $HOTP_COUNTER" +counter_value=$(expr $counter_value + 1) +echo $counter_value >$HOTP_COUNTER || + die "Unable to create hotp counter file" mount -o remount,ro /boot exit 0