heads/initrd/bin/kexec-unseal-key
Jonathon Hall e6acaad215
tpmr: Fix sealing/unsealing file with both PCRs and passwords
When sealing/unsealing with a password, use a policy including both the
specified PCRs and the object password.  Fixes sealing and unsealing
disk unlock key.

tpm2 seems to have a bug in parameter decryption when using a policy
session and password in this way, disable encryption in the policy
session as a workaround.

Flags still need to be set on the sealed object correctly, as the
password is normally allowed on its own as an alternative to policy
auth.

Add -Q to some tpm2 invocations to silence diagnostics on stdout.

Pass filename for unsealed secret rather than capturing from stdout
for robustness against tpm2 diagnostics on stdout.

Fix unseal result check in kexec-unseal-key.

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
2023-03-08 12:45:48 -05:00

69 lines
1.5 KiB
Bash
Executable File

#!/bin/bash
# This will unseal and unecncrypt the drive encryption key from the TPM
# The TOTP secret will be shown to the user on each encryption attempt.
# It will then need to be bundled into initrd that is booted with Qubes.
set -e -o pipefail
. /etc/functions
TPM_INDEX=3
TPM_SIZE=312
. /etc/functions
TRACE "Under kexec-unseal-key"
mkdir -p /tmp/secret
sealed_file="/tmp/secret/sealed.key"
key_file="$1"
if [ -z "$key_file" ]; then
key_file="/tmp/secret/secret.key"
fi
# TPM1 only - read the sealed value first manually
if [ "$CONFIG_TPM2_TOOLS" != "y" ]; then
tpm nv_readvalue \
-in "$TPM_INDEX" \
-sz "$TPM_SIZE" \
-of "$sealed_file" \
|| die "Unable to read key from TPM NVRAM"
fi
echo "DEBUG: CONFIG_TPM: $CONFIG_TPM"
echo "DEBUG: CONFIG_TPM2_TOOLS: $CONFIG_TPM2_TOOLS"
echo "DEBUG: Show PCRs"
pcrs
for tries in 1 2 3; do
read -s -p "Enter unlock password (blank to abort): " tpm_password
echo
if [ -z "$tpm_password" ]; then
die "Aborting unseal disk encryption key"
fi
unseal_result=1
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
tpmr unseal "0x8100000$TPM_INDEX" "sha256:0,1,2,3,4,5,6,7" "$key_file" "$tpm_password"
unseal_result="$?"
else
tpm unsealfile \
-if "$sealed_file" \
-of "$key_file" \
-pwdd "$tpm_password" \
-hk 40000000 \
|| unseal_result="$?"
fi
shred -n 10 -z -u "$sealed_file" 2> /dev/null || true
if [ "$unseal_result" -eq 0 ]; then
exit 0
fi
pcrs
warn "Unable to unseal disk encryption key"
done
die "Retry count exceeded..."