WiP: provide proper info/warn/die messages explaining causes of errors linked to detach signing errors

Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
Thierry Laurion 2023-10-20 14:12:16 -04:00
parent 2c55338be5
commit eceb97aa4d
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93
3 changed files with 23 additions and 53 deletions

View File

@ -72,20 +72,21 @@ dd \
# Count the number of slots used on each device
for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do
DEBUG "Checking number of slots used on $dev"
DEBUG "Checking number of slots used on $dev LUKS header"
#check if the device is a LUKS device with luks[1,2]
slots_used=$(cryptsetup luksDump $dev | grep -c 'luks[0-9]*' || die "Unable to get number of slots used on $dev")
DEBUG "Number of slots used on $dev: $slots_used"
DEBUG "Number of slots used on $dev LUKS header: $slots_used"
# If slot1 is the only one used, warn and die with proper messages
if [ $slots_used -eq 1 ]; then
# Check if slot 1 is the only one existing
if cryptsetup luksDump $dev | grep -q "Slot 1: ENABLED"; then
warn "Slot 1 is the only one existing on $dev. Heads cannot use it to store TPM sealed LUKS Disk Unlock Key"
die "Slot 1 should not be the only slot existing on $dev. Fix your custom setup"
warn "Slot 1 is the only one existing on $dev LUKS header. Heads cannot use it to store TPM sealed LUKS Disk Unlock Key"
warn "Slot 1 should not be the only slot existing on $dev LUKS header. Slot 0 should be used to store Disk Recovery Key/passphrase"
die "You can safely fix this before continuing through Heads recovery shell: cryptsetup luksAddKey $dev"
fi
else
DEBUG "Slot 1 is not the only existing slot on $dev"
DEBUG "$dev Slot 1 will be used to store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase"
DEBUG "Slot 1 is not the only existing slot on $dev LUKS header."
DEBUG "$dev LUKS header's slot 1 will store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase"
fi
done

View File

@ -96,20 +96,24 @@ confirm_gpg_card() {
#Prompt user for provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys
echo
read -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin
#TODO: change all passphrase prompts in codebase to include -r to prevent backslash escapes
read -r -s -p "Please enter GPG Admin PIN needed to use the GPG backup thumb drive: " gpg_admin_pin
echo
#prompt user to select the proper encrypted partition, which should the first one on next prompt
echo -e "Please select encrypted LUKS container partition (not the public one)\n"
warn "Please select encrypted LUKS on GPG key material backup thumb drive (not public labeled one)"
mount-usb --pass "$gpg_admin_pin" || die "Unable to mount USB with GPG Admin PIN"
warn "Testing detach-sign operation and verifiying against fused public key in ROM"
echo "++++ Testing detach-sign operation and verifiying against fused public key in ROM"
gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --import /media/subkeys.sec >/dev/null 2>&1 ||
die "Unable to import GPG private subkeys"
#Do a detach signature to ensure gpg material is usable and cache passphrase to sign /boot from caller functions
dd if=/dev/urandom of="$CR_NONCE" bs=20 count=1 >/dev/null 2>&1 ||
die "Unable to create $CR_NONCE to be signed with GPG private signing subkey"
die "Unable to create $CR_NONCE to be detach-signed with GPG private signing subkey"
gpg --pinentry-mode=loopback --passphrase-file <(echo -n "${gpg_admin_pin}") --detach-sign "$CR_NONCE" >/dev/null 2>&1 ||
die "Unable to sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN"
die "Unable to detach-sign $CR_NONCE with GPG private signing subkey using GPG Admin PIN"
#verify detached signature against public key in rom
gpg --verify "$CR_SIG" "$CR_NONCE" || die "Unable to verify $CR_SIG detached signature against public key in ROM"
gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 && \
echo "++++ Imported private subkeys match public key fused in rom and can be used under Heads" || \
die "Unable to verify $CR_SIG detached signature against public key in ROM"
#Wipe any previous CR_NONCE and CR_SIG
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true
#TODO: maybe just an export instead of setting /etc/user.config otherwise could be flashed in weird corner case situation
@ -177,8 +181,8 @@ gpg_auth() {
if gpg --digest-algo SHA256 \
--detach-sign \
-o "$CR_SIG" \
"$CR_NONCE" \
&& gpgv "$CR_SIG" "$CR_NONCE" \
"$CR_NONCE" > /dev/null 2>&1 \
&& gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \
; then
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
DEBUG "Under /etc/ash_functions:gpg_auth: success"

View File

@ -96,16 +96,15 @@ reseal_tpm_disk_decryption_key() {
fi
if [ -s /boot/kexec_key_devices.txt ] || [ -s /boot/kexec_key_lvm.txt ]; then
warn "A TPM Disk Unlock Key previously sealed is now invalid since firmware measurements could not unseal TOTP"
echo "Renewing LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
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!"
done
warn "LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt"
echo "Updating checksums and signing all files under /boot/kexec.sig"
while ! update_checksums; do
warn "Checksums were not signed. Bad GPG PIN provided?"
warn "Please update checksums and provide a valid GPG PIN"
warn "Checksums were not signed. Preceding errors should explain possible causes"
done
warn "Rebooting in 3 seconds to enable booting default boot option"
sleep 3
@ -257,7 +256,7 @@ increment_tpm_counter() {
TRACE "Under /etc/functions:increment_tpm_counter"
tpmr counter_increment -ix "$1" -pwdc '' |
tee /tmp/counter-$1 ||
die "Counter increment failed"
die "TPM counter increment failed for rollback prevention. Please reflash firmware and choose TPM Reset reset option"
}
check_config() {
@ -318,40 +317,6 @@ replace_config() {
rm -f ${CONFIG_FILE}.tmp
}
# Set a config variable in a specific file to a given value - replace it if it
# exists, or add it. If added, the variable will be exported.
set_config() {
CONFIG_FILE="$1"
CONFIG_OPTION="$2"
NEW_SETTING="$3"
if grep -q "$CONFIG_OPTION" "$CONFIG_FILE"; then
replace_config "$CONFIG_FILE" "$CONFIG_OPTION" "$NEW_SETTING"
else
echo "export $CONFIG_OPTION=\"$NEW_SETTING\"" >>"$CONFIG_FILE"
fi
}
# Set a value in config.user, re-combine configs, and update configs in the
# environment.
set_user_config() {
CONFIG_OPTION="$1"
NEW_SETTING="$2"
set_config /etc/config.user "$CONFIG_OPTION" "$NEW_SETTING"
combine_configs
. /tmp/config
}
# Load a config value to a variable, defaulting to empty. Does not fail if the
# config is not set (since it would expand to empty by default).
load_config_value() {
local config_name="$1"
if grep -q "$config_name=" /tmp/config; then
grep "$config_name=" /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"'
fi
}
# Generate a secret for TPM-less HOTP by reading the ROM. Output is the
# sha256sum of the ROM (binary, not printable), which can be truncated to the
# supported secret length.