Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion 2024-12-09 12:48:16 -05:00
parent 4ba7cc5495
commit abc97fe1be
No known key found for this signature in database
GPG Key ID: 9A53E1BB3FF00461
9 changed files with 166 additions and 106 deletions

View File

@ -162,7 +162,7 @@ generate_totp_hotp()
echo
if [ -x /bin/hotp_verification ]; then
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)"
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
@ -644,7 +644,7 @@ TRACE_FUNC
if [ -r /boot/kexec_hotp_key ]; then
HOTPKEY_BRANDING="$(cat /boot/kexec_hotp_key)"
else
HOTPKEY_BRANDING="HOTP USB Security Dongle"
HOTPKEY_BRANDING="HOTP USB Security dongle"
fi
if [ -x /bin/hotp_verification ]; then

View File

@ -92,7 +92,7 @@ echo '+++ Building initrd'
# pad the initramfs (dracut doesn't pad the last gz blob)
# without this the kernel init/initramfs.c fails to read
# the subsequent uncompressed/compressed cpio
dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync ||
dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync > /dev/null 2>&1 ||
die "Failed to copy initrd to /tmp"
if [ "$unseal_failed" = "n" ]; then

View File

@ -143,15 +143,26 @@ mount_boot() {
reset_nk3_secret_app() {
TRACE_FUNC
# Reset Nitrokey 3 Secrets App
# Reset Nitrokey 3 Secrets app with $ADMIN_PIN (default 12345678, or customised)
if lsusb | grep -q "20a0:42b2"; then
echo
warn "Resetting Nitrokey 3 Secrets App PIN. Physical presence (touch) will be required"
#TODO, change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed
warn "Resetting Nitrokey 3 Secrets App with PIN. Physical presence (touch) will be required"
# TODO: change message when https://github.com/Nitrokey/nitrokey-hotp-verification/issues/41 is fixed
# Reset Nitrokey 3 secret app with PIN
if ! /bin/hotp_verification reset "${ADMIN_PIN}"; then
whiptail_error_die "Failed to reset Nitrokey 3 Secrets App with error code $?, contact Nitrokey support"
fi
# Do 3 attempts to reset Nitrokey 3 Secrets App if return code is 3 (no touch)
for attempt in 1 2 3; do
if /bin/hotp_verification reset "${ADMIN_PIN}"; then
echo
return 0
else
error_code=$?
if [ $error_code -eq 3 ] && [ $attempt -lt 3 ]; then
whiptail --msgbox "Nitrokey 3 requires physical presence: touch the dongle when requested" $HEIGHT $WIDTH --title "Nk3 cecrets app reset attempt: $attempt/3"
else
whiptail_error_die "Nitrokey 3 secrets app reset failed with error:$error_code. Contact Nitrokey support"
fi
fi
done
fi
}
@ -323,7 +334,7 @@ generate_inmemory_p256_master_and_subkeys() {
keytocard_subkeys_to_smartcard() {
TRACE_FUNC
#make sure usb ready and USB Security Dongle ready to communicate with
#make sure usb ready and USB Security dongle ready to communicate with
enable_usb
enable_usb_storage
gpg --card-status >/dev/null 2>&1 || die "Error getting GPG card status"
@ -541,7 +552,7 @@ gpg_key_factory_reset() {
reset_nk3_secret_app
# Factory reset GPG card
echo "GPG factory reset of USB Security Dongle's smartcard..."
echo "GPG factory reset of USB Security dongle's OpenPGP smartcard..."
{
echo admin # admin menu
echo factory-reset # factory reset smartcard
@ -595,7 +606,7 @@ gpg_key_factory_reset() {
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "Setting key to NIST-P256 in USB Security Dongle failed."
whiptail_error_die "Setting key to NIST-P256 in USB Security dongle failed."
fi
# fallback to RSA key generation by default
elif [ "$GPG_ALGO" = "RSA" ]; then
@ -617,7 +628,7 @@ gpg_key_factory_reset() {
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security Dongle failed."
whiptail_error_die "Setting key attributed to RSA ${RSA_KEY_LENGTH} bits in USB Security dongle failed."
fi
else
#Unknown GPG_ALGO
@ -631,7 +642,7 @@ generate_OEM_gpg_keys() {
TRACE_FUNC
#This function simply generates subkeys in smartcard following smarcard config from gpg_key_factory_reset
echo "Generating GPG keys in USB Security Dongle's smartcard..."
echo "Generating GPG keys in USB Security dongle's OpenPGP smartcard..."
{
echo admin # admin menu
echo generate # generate keys
@ -645,6 +656,11 @@ generate_OEM_gpg_keys() {
echo ${USER_PIN_DEF} # Default user PIN since we just factory reset
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
#This outputs to console \
# "gpg: checking the trustdb"
# "gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model"
# "gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u"
#TODO: Suppress this output to console (stdout shown in DEBUG mode)?
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR"
@ -704,7 +720,7 @@ generate_checksums() {
tpmr counter_create \
-pwdc '' \
-la -3135106223 |
tee /tmp/counter ||
tee /tmp/counter >/dev/null 2>&1 ||
whiptail_error_die "Unable to create TPM counter"
TPM_COUNTER=$(cut -d: -f1 </tmp/counter)
@ -850,14 +866,14 @@ report_integrity_measurements() {
enable_usb
for attempt in 1 2 3; do
if ! hotp_verification info >/dev/null 2>&1; then
whiptail_warning --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
whiptail_warning --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."
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
@ -872,7 +888,7 @@ report_integrity_measurements() {
BG_COLOR_MAIN_MENU="error"
;;
*)
HOTP="Error checking code, Insert USB Security Dongle and retry"
HOTP="Error checking code, Insert USB Security dongle and retry"
BG_COLOR_MAIN_MENU="warning"
;;
esac
@ -997,21 +1013,21 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
; then
GPG_GEN_KEY_IN_MEMORY="y"
echo " ++++ Master key and subkeys will be generated in memory, backed up to dedicated LUKS container +++"
echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security Dongle's smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: "
echo -e -n "Would you like in-memory generated subkeys to be copied to USB Security dongle's OpenPGP smartcard?\n (Highly recommended so the smartcard is used on daily basis and backup is kept safe, but not required) [Y/n]: "
read -n 1 prompt_output
echo
if [ "$prompt_output" == "n" \
-o "$prompt_output" == "N" ]; then
warn "Subkeys will NOT be copied to USB Security Dongle's smartcard"
warn "Subkeys will NOT be copied to USB Security dongle's OpenPGP smartcard"
warn "Your GPG key material backup thumb drive should be cloned to a second thumb drive for redundancy for production environements"
GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n"
else
echo "++++ Subkeys will be copied to USB Security Dongle's smartcard ++++"
echo "++++ Subkeys will be copied to USB Security dongle's OpenPGP smartcard ++++"
warn "Please keep your GPG key material backup thumb drive safe"
GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="y"
fi
else
echo "GPG key material will be generated on USB Security Dongle's smartcard without backup"
echo "GPG key material will be generated on USB Security dongle's OpenPGP smartcard without backup"
GPG_GEN_KEY_IN_MEMORY="n"
GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n"
fi
@ -1177,24 +1193,24 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" ]; then
fi
else
GPG_EXPORT=0
# needed for USB Security Dongle below and is ensured via mount-usb in case of GPG_EXPORT=1
# needed for USB Security dongle below and is ensured via mount-usb in case of GPG_EXPORT=1
enable_usb
fi
fi
# ensure USB Security Dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y
# ensure USB Security dongle connected if GPG_GEN_KEY_IN_MEMORY=n or if GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD=y
if [ "$GPG_GEN_KEY_IN_MEMORY" = "n" -o "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then
echo -e "\nChecking for USB Security Dongle...\n"
echo -e "\nChecking for USB Security dongle...\n"
enable_usb
if ! gpg --card-status >/dev/null 2>&1; then
local_whiptail_error "Can't access USB Security Dongle; \nPlease remove and reinsert, then press Enter."
local_whiptail_error "Can't access USB Security dongle; \nPlease remove and reinsert, then press Enter."
if ! gpg --card-status >/dev/null 2>/tmp/error; then
ERROR=$(tail -n 1 /tmp/error | fold -s)
whiptail_error_die "Unable to detect USB Security Dongle:\n\n${ERROR}"
whiptail_error_die "Unable to detect USB Security dongle:\n\n${ERROR}"
fi
fi
#Now that USB Security Dongle is detected, we can check its capabilities and limitations
#Now that USB Security dongle is detected, we can check its capabilities and limitations
usb_security_token_capabilities_check
fi
@ -1266,7 +1282,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
fi
else
#Generate GPG key and subkeys on smartcard only
echo -e "\nResetting USB Security Dongle's GPG smartcard...\n(this will take around 3 minutes...)\n"
echo -e "\nResetting USB Security dongle's GPG smartcard...\n(this will take around 3 minutes...)\n"
gpg_key_factory_reset
generate_OEM_gpg_keys
fi
@ -1389,7 +1405,7 @@ fi
#if nk3 detected, we add the NK3 Secre App PIN. Detect by product ID
if lsusb | grep -q "20a0:42b2"; then
passphrases+="Nitrokey 3 Secrets App PIN: ${ADMIN_PIN}\n"
passphrases+="Nitrokey 3 Secrets app PIN: ${ADMIN_PIN}\n"
fi
#GPG PINs output

View File

@ -1,5 +1,5 @@
#!/bin/bash
# Retrieve the sealed TOTP secret and initialize a USB Security Dongle with it
# Retrieve the sealed TOTP secret and initialize a USB Security dongle with it
. /etc/functions
. /etc/gui_functions
@ -34,7 +34,7 @@ fatal_error() {
if [ -r /boot/kexec_hotp_key ]; then
HOTPKEY_BRANDING="$(cat /boot/kexec_hotp_key)"
else
HOTPKEY_BRANDING="HOTP USB Security Dongle"
HOTPKEY_BRANDING="HOTP USB Security dongle"
fi
if [ "$CONFIG_TPM" = "y" ]; then
@ -77,13 +77,13 @@ if ! hotp_token_info="$(hotp_verification info)"; then
fi
fi
# Set HOTP USB Security Dongle branding based on VID
# Set HOTP USB Security dongle branding based on VID
if lsusb | grep -q "20a0:"; then
HOTPKEY_BRANDING="Nitrokey"
elif lsusb | grep -q "316d:"; then
HOTPKEY_BRANDING="Librem Key"
else
HOTPKEY_BRANDING="HOTP USB Security Dongle"
HOTPKEY_BRANDING="HOTP USB Security dongle"
fi
# Truncate the secret if it is longer than the maximum HOTP secret
@ -175,7 +175,7 @@ counter_value=$(expr $counter_value + 1)
echo $counter_value >$HOTP_COUNTER ||
fatal_error "Unable to create hotp counter file"
# Store/overwrite HOTP USB Security Dongle branding found out beforehand
# Store/overwrite HOTP USB Security dongle branding found out beforehand
echo $HOTPKEY_BRANDING >$HOTP_KEY ||
die "Unable to store hotp key file"

View File

@ -29,7 +29,6 @@ else
. /etc/config
fi
# Busybox xxd lacks -r, and we get hex dumps from TPM1 commands. This converts
# a hex dump to binary data using sed and printf
hex2bin() {
@ -258,7 +257,7 @@ tpm2_extend() {
esac
done
tpm2 pcrextend "$index:sha256=$hash"
LOG $(tpm2 pcrread "sha256:$index" 2>&1)
LOG $(tpm2 pcrread "sha256:$index" 2>&1)
TRACE_FUNC
DEBUG "TPM: Extended PCR[$index] with hash $hash"
@ -307,7 +306,7 @@ tpm1_counter_create() {
# other parameters for TPM1 are passed directly, and TPM2 mimics the
# TPM1 interface.
prompt_tpm_owner_password
if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@"; then
if ! tpm counter_create -pwdo "$(cat "/tmp/secret/tpm_owner_password")" "$@" >/dev/null 2>&1; then
DEBUG "Failed to create counter from tpm1_counter_create. Wiping /tmp/secret/tpm_owner_password"
shred -n 10 -z -u /tmp/secret/tpm_owner_password
die "Unable to create counter from tpm1_counter_create"
@ -334,7 +333,7 @@ tpm2_counter_create() {
prompt_tpm_owner_password
rand_index="1$(dd if=/dev/urandom bs=1 count=3 2>/dev/null | xxd -pc3)"
tpm2 nvdefine -C o -s 8 -a "ownerread|authread|authwrite|nt=1" \
-P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/console ||
-P "$(tpm2_password_hex "$(cat "/tmp/secret/tpm_owner_password")")" "0x$rand_index" >/dev/null 2>&1 ||
{
DEBUG "Failed to create counter from tpm2_counter_create. Wiping /tmp/secret/tpm_owner_password"
shred -n 10 -z -u /tmp/secret/tpm_owner_password
@ -357,12 +356,13 @@ tpm2_startsession() {
tpm2 flushcontext -Q \
--saved-session ||
die "tpm2_flushcontext: unable to flush saved session"
tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE"
#TODO: readpublic cannot be silenced even if redirected to /dev/null with both stderr and stdout redirected?
tpm2 readpublic -Q -c "$PRIMARY_HANDLE" -t "$PRIMARY_HANDLE_FILE" >/dev/null 2>&1
#TODO: do the right thing to not have to suppress "WARN: check public portion the tpmkey manually" see https://github.com/linuxboot/heads/pull/1630#issuecomment-2075120429
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE" > /dev/null 2>&1
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$ENC_SESSION_FILE" >/dev/null 2>&1
#TODO: do the right thing to not have to suppress "WARN: check public portion the tpmkey manually" see https://github.com/linuxboot/heads/pull/1630#issuecomment-2075120429
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$DEC_SESSION_FILE" > /dev/null 2>&1
tpm2 sessionconfig -Q --disable-encrypt "$DEC_SESSION_FILE"
tpm2 startauthsession -Q -c "$PRIMARY_HANDLE_FILE" --hmac-session -S "$DEC_SESSION_FILE" >/dev/null 2>&1
tpm2 sessionconfig -Q --disable-encrypt "$DEC_SESSION_FILE" >/dev/null 2>&1
}
# Use cleanup_session() with at_exit to release a TPM2 session and delete the
@ -412,7 +412,7 @@ tpm1_destroy() {
index="$1" # Index of the sealed file
size="$2" # Size of zeroes to overwrite for TPM1
dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero > /dev/null 2>&1
dd if=/dev/zero bs="$size" count=1 of=/tmp/wipe-totp-zero >/dev/null 2>&1
tpm nv_writevalue -in "$index" -if /tmp/wipe-totp-zero ||
die "Unable to wipe sealed secret from TPM NVRAM"
}
@ -502,7 +502,7 @@ tpm1_seal() {
pcrl="$3" #0,1,2,3,4,5,6,7 (does not include algorithm prefix)
pcrf="$4"
sealed_size="$5"
pass="$6" # May be empty to seal with no password
pass="$6" # May be empty to seal with no password
tpm_owner_password="$7" # Owner password - will prompt if needed and not empty
sealed_file="$SECRET_DIR/tpm1_seal_sealed.bin"
@ -512,7 +512,6 @@ tpm1_seal() {
DEBUG "tpm1_seal arguments: file=$file index=$index pcrl=$pcrl pcrf=$pcrf sealed_size=$sealed_size pass=$(mask_param "$pass") tpm_password=$(mask_param "$tpm_password")"
# If a password was given, add it to the policy arguments
if [ "$pass" ]; then
POLICY_ARGS+=(-pwdd "$pass")
@ -534,7 +533,7 @@ tpm1_seal() {
-of "$sealed_file" \
-hk 40000000 \
"${POLICY_ARGS[@]}"
# try it without the TPM Owner Password first
if ! tpm nv_writevalue -in "$index" -if "$sealed_file"; then
# to create an nvram space we need the TPM Owner Password
@ -605,9 +604,22 @@ tpm2_unseal() {
UNSEAL_PASS_SUFFIX="+$(tpm2_password_hex "$pass")"
fi
tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \
-S "$ENC_SESSION_FILE" >"$file"
# tpm2 unseal will write the unsealed data to stdout and any errors to
# stderr. We capture the unsealed data to $file, but still log the errors for quiet mode.
# In case of unseal error, caller will also report on TOTP not being able to be unsealed.
TMP_ERR_FILE=$(mktemp)
if ! tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \
-S "$ENC_SESSION_FILE" >"$file" 2>"$TMP_ERR_FILE"; then
# Log the contents of the temporary error file
while IFS= read -r line; do
LOG "tpm2 stderr: $line"
done <"$TMP_ERR_FILE"
rm -f "$TMP_ERR_FILE"
die "Unable to unseal secret from TPM NVRAM with tpm2 unseal"
fi
rm -f "$TMP_ERR_FILE"
}
tpm1_unseal() {
TRACE_FUNC
index="$1"
@ -650,15 +662,15 @@ tpm2_reset() {
# output TPM Owner Password to a file to be reused in this boot session until recovery shell/reboot
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password"
tpm2 clear -c platform > /dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy"
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change owner password"
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to change endorsement password"
tpm2 clear -c platform >/dev/null 2>&1 || LOG "Unable to clear TPM on platform hierarchy"
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change owner password"
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to change endorsement password"
tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to create primary key"
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to create primary key"
tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \
-P "$(tpm2_password_hex "$tpm_owner_password")" > /dev/null 2>&1 || LOG "Unable to evict primary key"
shred -u "$SECRET_DIR/primary.ctx" > /dev/null 2>&1
tpm2_startsession > /dev/null 2>&1 || LOG "Unable to start session"
-P "$(tpm2_password_hex "$tpm_owner_password")" >/dev/null 2>&1 || LOG "Unable to evict primary key"
shred -u "$SECRET_DIR/primary.ctx" >/dev/null 2>&1
tpm2_startsession >/dev/null 2>&1 || LOG "Unable to start session"
# Set the dictionary attack parameters. TPM2 defaults vary widely, we
# want consistent behavior on any TPM.
@ -681,7 +693,7 @@ tpm2_reset() {
--max-tries=10 \
--recovery-time=3600 \
--lockout-recovery-time=0 \
--auth="session:$ENC_SESSION_FILE" > /dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters"
--auth="session:$ENC_SESSION_FILE" >/dev/null 2>&1 || LOG "Unable to set dictionary lockout parameters"
# Set a random DA lockout password, so the DA lockout can't be cleared
# with a password. Heads doesn't offer dictionary attach reset, instead
@ -690,7 +702,7 @@ tpm2_reset() {
# The default lockout password is empty, so we must set this, and we
# don't need to provide any auth (use the default empty password).
tpm2 changeauth -Q -c lockout \
"hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" > /dev/null 2>&1 || LOG "Unable to set lockout password"
"hex:$(dd if=/dev/urandom bs=32 count=1 status=none 2>/dev/null | xxd -p | tr -d ' \n')" >/dev/null 2>&1 || LOG "Unable to set lockout password"
}
tpm1_reset() {
TRACE_FUNC
@ -700,17 +712,17 @@ tpm1_reset() {
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
echo -n "$tpm_owner_password" >"$SECRET_DIR/tpm_owner_password"
# Make sure the TPM is ready to be reset
tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable > /dev/null 2>&1 || >LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM"
tpm forceclear -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to clear TPM"
tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM"
tpm takeown -pwdo "$tpm_owner_password" > /dev/null 2>&1 || LOG "Unable to take ownership of TPM"
tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM"
tpm forceclear -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to clear TPM"
tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM"
tpm takeown -pwdo "$tpm_owner_password" >/dev/null 2>&1 || LOG "Unable to take ownership of TPM"
# And now turn it all back on
tpm physicalpresence -s > /dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable > /dev/null 2>&1 || LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c > /dev/null 2>&1 || LOG "Unable to deactivate TPM"
tpm physicalpresence -s >/dev/null 2>&1 || LOG "Unable to assert physical presence"
tpm physicalenable >/dev/null 2>&1 || LOG "Unable to enable TPM"
tpm physicalsetdeactivated -c >/dev/null 2>&1 || LOG "Unable to deactivate TPM physical presence requirement"
}
# Perform final cleanup before boot and lock the platform heirarchy.
@ -784,7 +796,7 @@ if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
DEBUG "TPM: Will extend PCR[$3] with hash of filename $string"
hash="$(echo -n "$5" | sha1sum | cut -d' ' -f1)"
fi
TRACE_FUNC
LOG "TPM: Extending PCR[$3] with hash $hash"
DO_WITH_DEBUG exec tpm "$@"

View File

@ -147,7 +147,7 @@ confirm_gpg_card() {
fi
fi
# setup the USB so we can reach the USB Security Dongle's smartcard
# setup the USB so we can reach the USB Security dongle's OpenPGP smartcard
enable_usb
echo -e "\nVerifying presence of GPG card...\n"

View File

@ -181,7 +181,7 @@ fi
# Setup recovery serial shell
if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then
stty -F "$CONFIG_BOOT_RECOVERY_SERIAL" 115200
pause_recovery 'Console recovery shell' \
pause_recovery 'Serial console recovery shell' \
< "$CONFIG_BOOT_RECOVERY_SERIAL" \
> "$CONFIG_BOOT_RECOVERY_SERIAL" 2>&1 &
fi
@ -207,6 +207,7 @@ if [ "$boot_option" = "r" ]; then
exit
elif [ "$boot_option" = "o" ]; then
# Launch OEM Factory Reset mode
echo -e "***** Entering OEM Factory Reset mode\n" > /dev/tty0
oem-factory-reset --mode oem
# just in case...
exit

View File

@ -2,12 +2,12 @@ modules-$(CONFIG_HOTPKEY) += hotp-verification
hotp-verification_depends := libusb $(musl_dep)
# v1.6
hotp-verification_version := e9050e0c914e7a8ffef5d1c82a014e0e2bf79346
# v1.6 + patches for nk3 reset + info fixes (no version bump yet)
hotp-verification_version := 05ac293dfef8abe463ccea8f248066e8686ce62d
hotp-verification_dir := hotp-verification-$(hotp-verification_version)
hotp-verification_tar := nitrokey-hotp-verification-$(hotp-verification_version).tar.gz
hotp-verification_url := https://github.com/Nitrokey/nitrokey-hotp-verification/archive/$(hotp-verification_version).tar.gz
hotp-verification_hash := 480c978d3585eee73b9aa5186b471d4caeeeeba411217e1544eef7cfd90312ac
hotp-verification_hash := 1095640fdae77938ce2d2ce294c7ecb8c27b77060975af8d838b6fd056ed5068
hotp-verification_target := \
$(MAKE_JOBS) \

View File

@ -1,7 +1,7 @@
From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001
From 45fb0932c3a45978d894fcaae2c242ffa93516f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com>
Date: Mon, 25 Nov 2024 17:04:47 +0100
Subject: [PATCH 1/3] Add reset command for nitrokey 3
Subject: [PATCH 1/4] Add reset command for nitrokey 3
---
src/main.c | 10 ++++++++--
@ -10,7 +10,7 @@ Subject: [PATCH 1/3] Add reset command for nitrokey 3
3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/main.c b/src/main.c
index 059069e..b80b71d 100644
index ed26932..41b1692 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,6 +21,7 @@
@ -20,8 +20,8 @@ index 059069e..b80b71d 100644
+#include "operations_ccid.h"
#include "return_codes.h"
#include "utils.h"
#include "version.h"
@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) {
#include "operations_ccid.h"
@@ -161,8 +162,13 @@ int parse_cmd_and_run(int argc, char *const *argv) {
}
break;
case 'r':
@ -38,7 +38,7 @@ index 059069e..b80b71d 100644
default:
break;
diff --git a/src/operations_ccid.c b/src/operations_ccid.c
index eb46124..574155d 100644
index 1ca6f54..cdaf940 100644
--- a/src/operations_ccid.c
+++ b/src/operations_ccid.c
@@ -32,6 +32,47 @@
@ -90,47 +90,48 @@ index eb46124..574155d 100644
TLV tlvs[] = {
{
diff --git a/src/operations_ccid.h b/src/operations_ccid.h
index b26b3c7..ec0070c 100644
index 77a6fdc..20415c0 100644
--- a/src/operations_ccid.h
+++ b/src/operations_ccid.h
@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN);
int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter);
@@ -12,6 +12,7 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c
int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify);
int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number);
int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response);
int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin);
+int nk3_reset(struct Device *dev);
#endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H
From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001
From 12ba32eb823a3d895ce77052022f8da3e40172ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com>
Date: Mon, 2 Dec 2024 10:29:59 +0100
Subject: [PATCH 2/3] Add optional new pin when resetting
Subject: [PATCH 2/4] Add optional new pin when resetting
---
src/main.c | 9 +++++----
src/operations_ccid.c | 6 +++++-
src/operations_ccid.h | 5 ++++-
3 files changed, 14 insertions(+), 6 deletions(-)
src/main.c | 11 +++++++----
src/operations_ccid.c | 6 +++++-
src/operations_ccid.h | 5 ++++-
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/main.c b/src/main.c
index b80b71d..3f4a1cc 100644
index 41b1692..84c0afe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,9 +38,10 @@ void print_help(char *app_name) {
"\t%s info\n"
"\t%s version\n"
@@ -41,8 +41,11 @@ void print_help(char *app_name) {
"\t%s check <HOTP CODE>\n"
- "\t%s regenerate <ADMIN PIN>\n"
"\t%s regenerate <ADMIN PIN>\n"
"\t%s set <BASE32 HOTP SECRET> <ADMIN PIN> [COUNTER]\n"
- "\t%s nk3-change-pin <old-pin> <new-pin>\n",
- app_name, app_name, app_name, app_name, app_name, app_name, app_name);
+ "\t%s nk3-change-pin <old-pin> <new-pin>\n"
+ "\t%s reset [ADMIN PIN]\n"
+ "\t%s regenerate\n"
"\t%s set <BASE32 HOTP SECRET> <ADMIN PIN> [COUNTER]\n",
- app_name, app_name, app_name, app_name, app_name, app_name);
+ app_name, app_name, app_name, app_name, app_name, app_name, app_name);
+ "\t%s set <BASE32 HOTP SECRET> <ADMIN PIN> [COUNTER]\n",
+ app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name);
}
@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) {
@@ -163,8 +166,8 @@ int parse_cmd_and_run(int argc, char *const *argv) {
break;
case 'r':
if (strncmp(argv[1], "reset", 15) == 0) {
@ -142,7 +143,7 @@ index b80b71d..3f4a1cc 100644
if (argc != 3) break;
res = regenerate_AES_key(&dev, argv[2]);
diff --git a/src/operations_ccid.c b/src/operations_ccid.c
index 574155d..07834ce 100644
index cdaf940..8b6ba77 100644
--- a/src/operations_ccid.c
+++ b/src/operations_ccid.c
@@ -33,7 +33,7 @@
@ -166,13 +167,13 @@ index 574155d..07834ce 100644
}
diff --git a/src/operations_ccid.h b/src/operations_ccid.h
index ec0070c..61cad72 100644
index 20415c0..4d55ad8 100644
--- a/src/operations_ccid.h
+++ b/src/operations_ccid.h
@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN);
int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter);
@@ -12,7 +12,10 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c
int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify);
int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number);
int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response);
int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin);
-int nk3_reset(struct Device *dev);
+// new_pin can be `null`
+//
@ -182,17 +183,17 @@ index ec0070c..61cad72 100644
#endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H
From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001
From 0bbc6ea354b1f807a4d7ad4c0cd57f9cbab25a8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com>
Date: Tue, 3 Dec 2024 10:48:27 +0100
Subject: [PATCH 3/3] Fix null pointer bug on non nk3
Subject: [PATCH 3/4] Fix null pointer bug on non nk3
---
src/operations_ccid.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/operations_ccid.c b/src/operations_ccid.c
index 07834ce..538d434 100644
index 8b6ba77..1221764 100644
--- a/src/operations_ccid.c
+++ b/src/operations_ccid.c
@@ -36,6 +36,12 @@
@ -217,3 +218,33 @@ index 07834ce..538d434 100644
}
From 0c5bd3da36ea8de5b8adf7878e9260b079bc110b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com>
Date: Mon, 9 Dec 2024 17:42:54 +0100
Subject: [PATCH 4/4] Print warning when device is not an NK3
---
src/operations_ccid.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/operations_ccid.c b/src/operations_ccid.c
index 1221764..356a1b4 100644
--- a/src/operations_ccid.c
+++ b/src/operations_ccid.c
@@ -39,6 +39,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) {
if (!dev->mp_devhandle_ccid) {
// Not an NK3
+ printf("No Nitrokey 3 found. No operation performed\n");
return RET_NO_ERROR;
}
@@ -52,6 +53,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) {
if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) {
+ printf("No Nitrokey 3 found. No operation performed\n");
return RET_NO_ERROR;
}