#!/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..."