mirror of
https://github.com/linuxboot/heads.git
synced 2025-03-10 22:43:57 +00:00
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:
parent
2c55338be5
commit
eceb97aa4d
@ -72,20 +72,21 @@ dd \
|
|||||||
|
|
||||||
# Count the number of slots used on each device
|
# Count the number of slots used on each device
|
||||||
for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do
|
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]
|
#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")
|
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 slot1 is the only one used, warn and die with proper messages
|
||||||
if [ $slots_used -eq 1 ]; then
|
if [ $slots_used -eq 1 ]; then
|
||||||
# Check if slot 1 is the only one existing
|
# Check if slot 1 is the only one existing
|
||||||
if cryptsetup luksDump $dev | grep -q "Slot 1: ENABLED"; then
|
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"
|
warn "Slot 1 is the only one existing on $dev LUKS header. 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 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
|
fi
|
||||||
else
|
else
|
||||||
DEBUG "Slot 1 is not the only existing slot on $dev"
|
DEBUG "Slot 1 is not the only existing slot on $dev LUKS header."
|
||||||
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 "$dev LUKS header's slot 1 will store LUKS Disk Unlock Key that TPM will seal/unseal with TPM Disk Unlock Key passphrase"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -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
|
#Prompt user for provisioned GPG Admin PIN that will be passed along to mount-usb and to import gpg subkeys
|
||||||
echo
|
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
|
#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"
|
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 ||
|
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"
|
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
|
#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 ||
|
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 ||
|
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
|
#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
|
#Wipe any previous CR_NONCE and CR_SIG
|
||||||
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" >/dev/null 2>&1 || true
|
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
|
#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 \
|
if gpg --digest-algo SHA256 \
|
||||||
--detach-sign \
|
--detach-sign \
|
||||||
-o "$CR_SIG" \
|
-o "$CR_SIG" \
|
||||||
"$CR_NONCE" \
|
"$CR_NONCE" > /dev/null 2>&1 \
|
||||||
&& gpgv "$CR_SIG" "$CR_NONCE" \
|
&& gpg --verify "$CR_SIG" "$CR_NONCE" > /dev/null 2>&1 \
|
||||||
; then
|
; then
|
||||||
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
|
shred -n 10 -z -u "$CR_NONCE" "$CR_SIG" 2>/dev/null || true
|
||||||
DEBUG "Under /etc/ash_functions:gpg_auth: success"
|
DEBUG "Under /etc/ash_functions:gpg_auth: success"
|
||||||
|
@ -96,16 +96,15 @@ reseal_tpm_disk_decryption_key() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -s /boot/kexec_key_devices.txt ] || [ -s /boot/kexec_key_lvm.txt ]; then
|
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"
|
warn "TPM sealed Disk Unlock Key secret needs to be resealed alongside TOTP/HOTP secret"
|
||||||
echo "Renewing LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
|
echo "Resealing TPM LUKS Disk Unlock Key to be unsealed by TPM Disk Unlock Key passphrase"
|
||||||
while ! kexec-seal-key /boot; do
|
while ! kexec-seal-key /boot; do
|
||||||
warn "Recovery Disk Encryption key passphrase invalid. Try again!"
|
warn "Recovery Disk Encryption key passphrase invalid. Try again!"
|
||||||
done
|
done
|
||||||
warn "LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt"
|
warn "LUKS header hash changed under /boot/kexec_luks_hdr_hash.txt"
|
||||||
echo "Updating checksums and signing all files under /boot/kexec.sig"
|
echo "Updating checksums and signing all files under /boot/kexec.sig"
|
||||||
while ! update_checksums; do
|
while ! update_checksums; do
|
||||||
warn "Checksums were not signed. Bad GPG PIN provided?"
|
warn "Checksums were not signed. Preceding errors should explain possible causes"
|
||||||
warn "Please update checksums and provide a valid GPG PIN"
|
|
||||||
done
|
done
|
||||||
warn "Rebooting in 3 seconds to enable booting default boot option"
|
warn "Rebooting in 3 seconds to enable booting default boot option"
|
||||||
sleep 3
|
sleep 3
|
||||||
@ -257,7 +256,7 @@ increment_tpm_counter() {
|
|||||||
TRACE "Under /etc/functions:increment_tpm_counter"
|
TRACE "Under /etc/functions:increment_tpm_counter"
|
||||||
tpmr counter_increment -ix "$1" -pwdc '' |
|
tpmr counter_increment -ix "$1" -pwdc '' |
|
||||||
tee /tmp/counter-$1 ||
|
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() {
|
check_config() {
|
||||||
@ -318,40 +317,6 @@ replace_config() {
|
|||||||
rm -f ${CONFIG_FILE}.tmp
|
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
|
# 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
|
# sha256sum of the ROM (binary, not printable), which can be truncated to the
|
||||||
# supported secret length.
|
# supported secret length.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user