From 286303d95cc8d17504516bb181ea4e8d76fab2bd Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 24 May 2019 11:50:27 -0500 Subject: [PATCH] libremkey-hotp-verification: pass in key file directly Reading the file into a variable and then redirecting to stdin via echo() can cause the binary data to be truncated, leading to an invalid base32 value and failure to properly generate and validate the HOTP code. To resolve this, pass the file directly to hotp(), and ensure it is removed properly regardless of success or failure to prevent leakage. Fixes "Invalid base32 string" error seen when attempting to generate a new TOTP secret. Signed-off-by: Matt DeVillier --- initrd/bin/seal-libremkey | 21 +++++++++------- patches/libremkey-hotp-verification.patch | 29 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/initrd/bin/seal-libremkey b/initrd/bin/seal-libremkey index 7203b719..ebab6766 100755 --- a/initrd/bin/seal-libremkey +++ b/initrd/bin/seal-libremkey @@ -29,8 +29,6 @@ tpm unsealfile \ || die "Unable to unseal HOTP secret" shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null -secret="`cat $HOTP_SECRET`" -shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots @@ -54,21 +52,28 @@ enable_usb if ! libremkey_hotp_verification info ; then echo "Insert your Librem Key and press Enter to configure it" read - libremkey_hotp_verification info \ - || die "Unable to find Librem Key" + if ! libremkey_hotp_verification info ; then + # don't leak key on failure + shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null + die "Unable to find Librem Key" + fi fi read -s -p "Enter your Librem Key Admin PIN" admin_pin echo -libremkey_hotp_initialize $admin_pin $secret $counter_value +libremkey_hotp_initialize $admin_pin $HOTP_SECRET $counter_value if [ $? -ne 0 ]; then read -s -p "Error setting HOTP secret, re-enter Admin PIN and try again:" admin_pin - libremkey_hotp_initialize $admin_pin $secret $counter_value \ - || die "Setting HOTP secret failed" + if ! libremkey_hotp_initialize $admin_pin $HOTP_SECRET $counter_value ; then + # don't leak key on failure + shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null + die "Setting HOTP secret failed" + fi fi -secret="" +# HOTP key no longer needed +shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null # Make sure our counter is incremented ahead of the next check #increment_tpm_counter $counter > /dev/null \ diff --git a/patches/libremkey-hotp-verification.patch b/patches/libremkey-hotp-verification.patch index 5376da03..fadcc4d5 100644 --- a/patches/libremkey-hotp-verification.patch +++ b/patches/libremkey-hotp-verification.patch @@ -29,4 +29,33 @@ +static const int CONNECTION_ATTEMPTS_COUNT = 2; static const int CONNECTION_ATTEMPT_DELAY_MICRO_SECONDS = 1000*1000/2; + +--- libremkey-hotp-verification/libremkey_hotp_initialize ++++ libremkey-hotp-verification-b/libremkey_hotp_initialize +@@ -14,7 +14,7 @@ fi + PIN=$1 + SECRET=$2 + COUNTER=$3 +-SECRET_B32=$(echo -n $SECRET | base32) ++SECRET_B32=$(cat $SECRET | base32) + libremkey_hotp_verification set $SECRET_B32 $PIN + if [ $? -ne 0 ]; then +@@ -25,7 +25,7 @@ fi + i=9 + while [ "$i" -lt "$COUNTER" ]; do + echo "Updating counter to $i" +- HOTP_CODE=$(echo $SECRET | hotp $i) ++ HOTP_CODE=$(hotp $i < $SECRET) + libremkey_hotp_verification check $HOTP_CODE > /dev/null + if [ $? -ne 0 ]; then + echo "HOTP check failed for counter=$i, code=$HOTP_CODE" +@@ -34,7 +34,7 @@ while [ "$i" -lt "$COUNTER" ]; do + let "i += 10" + done + +-HOTP_CODE=$(echo $SECRET | hotp $COUNTER) ++HOTP_CODE=$(hotp $COUNTER < $SECRET) + libremkey_hotp_verification check $HOTP_CODE > /dev/null + if [ $? -ne 0 ]; then + echo "HOTP check failed for counter=$COUNTER, code=$HOTP_CODE"