heads/initrd/bin/unseal-key

93 lines
1.7 KiB
Bash
Executable File

#!/bin/sh
# 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.
TPM_INDEX=3
TPM_SIZE=312
. /etc/functions
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
tpm nv_readvalue \
-in "$TPM_INDEX" \
-sz "$TPM_SIZE" \
-of "$sealed_file" \
|| die "Unable to read key from TPM NVRAM"
get_password()
{
last_half=X
while true; do
# update the TOTP code every thirty seconds
date=`date "+%Y-%m-%d %H:%M:%S"`
seconds=`date "+%s"`
half=`expr \( $seconds % 60 \) / 30`
if [ "$half" != "$last_half" ]; then
last_half=$half;
TOTP=`unseal-totp` \
|| die "TOTP code generation failed"
fi
echo -n "$date $TOTP: "
# read the first character, non-blocking
read \
-t 1 \
-n 1 \
-s \
-p "Enter unlock password: " \
tpm_password_1 \
&& break
# nothing typed, redraw the line
echo -ne '\r'
done
# they have started typing, read the rest, blocking
if [ -z "$tpm_password_1" ]; then
# they hit enter; we should exit gracefully
tpm_password=""
else
# they hit something else, read the rest of the line
read \
-s \
-p '' \
tpm_password_2
tpm_password="$tpm_password_1$tpm_password_2"
fi
# clean up with a newline
echo
}
for tries in 1 2 3; do
get_password
if tpm unsealfile \
-if "$sealed_file" \
-of "$key_file" \
-pwdd "$tpm_password" \
-hk 40000000 \
; then
rm -f /tmp/secret/sealed
exit 0
fi
pcrs
warn "Unable to unseal disk encryption key"
done
die "Retry count exceeded..."