mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-18 20:47:55 +00:00
TPM2 DUK and TOTP/HOTP reseal fix, refactoring and ifferenciating tpm_password into tpm_owner_password and reusing correctly
i TODO: fix all TODO in PR prior of review + squash Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
parent
729f2b17b8
commit
27c457f04b
@ -11,11 +11,12 @@ export CONFIG_LINUX_VERSION=5.10.5
|
||||
#export CONFIG_BASIC=y
|
||||
|
||||
#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing))
|
||||
#TODO: comment following line prior of pushing final version
|
||||
export CONFIG_HAVE_GPG_KEY_BACKUP=y
|
||||
|
||||
#Enable DEBUG output
|
||||
#export CONFIG_DEBUG_OUTPUT=y
|
||||
#export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y
|
||||
|
||||
CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm1.config
|
||||
CONFIG_LINUX_CONFIG=config/linux-qemu.config
|
||||
|
@ -151,12 +151,12 @@ prompt_update_checksums()
|
||||
|
||||
generate_totp_hotp()
|
||||
{
|
||||
tpm_password="$1" # May be empty, will prompt if needed and empty
|
||||
TRACE "Under /bin/gui-init:generate_totp_hotp"
|
||||
TRACE "Under /bin/gui-init:generate_totp_hotp"
|
||||
tpm_owner_password="$1" # May be empty, will prompt if needed and empty
|
||||
if [ "$CONFIG_TPM" != "y" ] && [ -x /bin/hotp_verification ]; then
|
||||
echo "Generating new HOTP secret"
|
||||
/bin/seal-hotpkey
|
||||
elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_password"; then
|
||||
elif echo -e "Generating new TOTP secret...\n\n" && /bin/seal-totp "$BOARD_NAME" "$tpm_owner_password"; then
|
||||
echo
|
||||
if [ -x /bin/hotp_verification ]; then
|
||||
if [ "$CONFIG_TOTP_SKIP_QRCODE" != y ]; then
|
||||
@ -567,7 +567,7 @@ reset_tpm()
|
||||
return 1
|
||||
fi
|
||||
|
||||
tpmr reset "$key_password"
|
||||
tpmr reset "$tpm_owner_password"
|
||||
|
||||
# now that the TPM is reset, remove invalid TPM counter files
|
||||
mount_boot
|
||||
@ -577,7 +577,7 @@ reset_tpm()
|
||||
rm -f /boot/kexec_primhdl_hash.txt
|
||||
|
||||
# create Heads TPM counter before any others
|
||||
check_tpm_counter /boot/kexec_rollback.txt "" "$key_password" \
|
||||
check_tpm_counter /boot/kexec_rollback.txt "" "$tpm_owner_password" \
|
||||
|| die "Unable to find/create tpm counter"
|
||||
counter="$TPM_COUNTER"
|
||||
|
||||
@ -588,7 +588,7 @@ reset_tpm()
|
||||
|| die "Unable to create rollback file"
|
||||
mount -o ro,remount /boot
|
||||
|
||||
generate_totp_hotp "$key_password"
|
||||
generate_totp_hotp "$tpm_owner_password"
|
||||
else
|
||||
echo "Returning to the main menu"
|
||||
fi
|
||||
|
@ -136,13 +136,13 @@ tpmr calcfuturepcr 6 "/tmp/luksDump.txt" >>"$pcrf"
|
||||
tpmr pcrread -a 7 "$pcrf"
|
||||
|
||||
DEBUG "TODO: REMOVE THIS: key_password=$key_password here"
|
||||
DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_password: $(cat /tmp/secret/tpm_password) here"
|
||||
DEBUG "TODO: REMOVE THIS: content of /tmp/secret/tpm_owner_password: $(cat /tmp/secret/tpm_owner_password) here"
|
||||
|
||||
|
||||
DO_WITH_DEBUG --mask-position 7 \
|
||||
tpmr seal "$KEY_FILE" "$TPM_INDEX" 0,1,2,3,4,5,6,7 "$pcrf" \
|
||||
"$TPM_SIZE" "$key_password" || {
|
||||
shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null
|
||||
:
|
||||
die "Unable to write TPM Disk Unlock Key to NVRAM"
|
||||
}
|
||||
|
@ -1114,16 +1114,16 @@ else
|
||||
fi
|
||||
|
||||
if [ "$CONFIG_TPM" = "y" ]; then
|
||||
tpm_password_changed="
|
||||
tpm_owner_password_changed="
|
||||
TPM Owner Password: $TPM_PASS\n"
|
||||
else
|
||||
tpm_password_changed=""
|
||||
tpm_owner_password_changed=""
|
||||
fi
|
||||
|
||||
## Show to user current provisioned secrets prior of rebooting
|
||||
whiptail --msgbox "
|
||||
$luks_passphrase_changed
|
||||
$tpm_password_changed
|
||||
$tpm_owner_password_changed
|
||||
GPG Admin PIN: $ADMIN_PIN\n
|
||||
GPG User PIN: $USER_PIN\n\n" \
|
||||
$HEIGHT $WIDTH --title "Provisioned secrets"
|
||||
@ -1139,6 +1139,6 @@ whiptail --msgbox "
|
||||
# Clean LUKS secrets
|
||||
luks_secrets_cleanup
|
||||
unset luks_passphrase_changed
|
||||
unset tpm_password_changed
|
||||
unset tpm_owner_password_changed
|
||||
|
||||
reboot
|
||||
|
@ -50,7 +50,7 @@ tpmr pcrread -a 7 "$pcrf"
|
||||
#Make sure we clear the TPM Owner Password from memory in case it failed to be used to seal TOTP
|
||||
tpmr seal "$TOTP_SECRET" "$TPM_NVRAM_SPACE" 0,1,2,3,4,7 "$pcrf" 312 "" "$TPM_PASSWORD" ||
|
||||
{
|
||||
shred -n 10 -z -u /tmp/secret/tpm_password 2>/dev/null
|
||||
shred -n 10 -z -u /tmp/secret/tpm_owner_password 2>/dev/null
|
||||
:
|
||||
die "Unable to write sealed secret to NVRAM"
|
||||
}
|
||||
|
@ -7,4 +7,4 @@ echo '*****'
|
||||
|
||||
prompt_new_owner_password
|
||||
|
||||
tpmr reset "$key_password"
|
||||
tpmr reset "$tpm_owner_password"
|
||||
|
@ -393,6 +393,7 @@ tpm2_seal() {
|
||||
tpm_password="$7" # Owner password - will prompt if needed and not empty
|
||||
# TPM Owner Password is always needed for TPM2.
|
||||
|
||||
DEBUG "TODO REMOVE THIS. tpm2_seal: pass=$pass tpm_password=$tpm_password"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
bname="`basename $file`"
|
||||
|
||||
@ -442,12 +443,12 @@ tpm2_seal() {
|
||||
tpm2 load -Q -C "/tmp/$PRIMARY_HANDLE_FILE" \
|
||||
-u "$SECRET_DIR/$bname.priv" -r "$SECRET_DIR/$bname.pub" \
|
||||
-c "$SECRET_DIR/$bname.seal.ctx"
|
||||
prompt_tpm_password
|
||||
prompt_tpm_owner_password
|
||||
# remove possible data occupying this handle
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_password")" \
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \
|
||||
-c "$handle" 2>/dev/null || true
|
||||
DO_WITH_DEBUG --mask-position 6 \
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_password")" \
|
||||
tpm2 evictcontrol -Q -C o -P "$(tpm2_password_hex "$tpm_owner_password")" \
|
||||
-c "$SECRET_DIR/$bname.seal.ctx" "$handle"
|
||||
}
|
||||
tpm1_seal() {
|
||||
@ -497,7 +498,7 @@ tpm1_seal() {
|
||||
tpm physicalpresence -s \
|
||||
|| warn "Unable to assert physical presence"
|
||||
|
||||
prompt_tpm_password
|
||||
prompt_tpm_owner_password
|
||||
|
||||
tpm nv_definespace -in "$index" -sz "$sealed_size" \
|
||||
-pwdo "$tpm_password" -per 0 \
|
||||
@ -554,6 +555,8 @@ tpm2_unseal() {
|
||||
UNSEAL_PASS_SUFFIX="+$(tpm2_password_hex "$pass")"
|
||||
fi
|
||||
|
||||
DEBUG "TODO REMOVE THIS. tpm2_unseal: pass=$pass UNSEAL_PASS_SUFFIX=$UNSEAL_PASS_SUFFIX"
|
||||
|
||||
tpm2 unseal -Q -c "$handle" -p "session:$POLICY_SESSION$UNSEAL_PASS_SUFFIX" \
|
||||
-S "/tmp/$ENC_SESSION_FILE" > "$file"
|
||||
}
|
||||
@ -594,18 +597,18 @@ tpm1_unseal() {
|
||||
|
||||
tpm2_reset() {
|
||||
TRACE "Under /bin/tpmr:tpm2_reset"
|
||||
key_password="$1"
|
||||
tpm_owner_password="$1"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
# output TPM Owner Password key_password to a file to be reused in this boot session until recovery shell/reboot
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password"
|
||||
echo "$key_password" > "$SECRET_DIR/tpm_password"
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
|
||||
echo -n "$tpm_owner_password" > "$SECRET_DIR/tpm_owner_password"
|
||||
tpm2 clear -c platform || warn "Unable to clear TPM on platform hierarchy"
|
||||
tpm2 changeauth -c owner "$(tpm2_password_hex "$key_password")"
|
||||
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$key_password")"
|
||||
tpm2 changeauth -c owner "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 changeauth -c endorsement "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 createprimary -C owner -g sha256 -G "${CONFIG_PRIMARY_KEY_TYPE:-rsa}" \
|
||||
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$key_password")"
|
||||
-c "$SECRET_DIR/primary.ctx" -P "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
tpm2 evictcontrol -C owner -c "$SECRET_DIR/primary.ctx" "$PRIMARY_HANDLE" \
|
||||
-P "$(tpm2_password_hex "$key_password")"
|
||||
-P "$(tpm2_password_hex "$tpm_owner_password")"
|
||||
shred -u "$SECRET_DIR/primary.ctx"
|
||||
tpm2_startsession
|
||||
|
||||
@ -643,18 +646,18 @@ tpm2_reset() {
|
||||
}
|
||||
tpm1_reset() {
|
||||
TRACE "Under /bin/tpmr:tpm1_reset"
|
||||
key_password="$1"
|
||||
tpm_owner_password="$1"
|
||||
mkdir -p "$SECRET_DIR"
|
||||
# output key_password to a file to be reused in this boot session until recovery shell/reboot
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_password"
|
||||
echo "$key_password" > "$SECRET_DIR/tpm_password"
|
||||
# output tpm_owner_password to a file to be reused in this boot session until recovery shell/reboot
|
||||
DEBUG "Caching TPM Owner Password to $SECRET_DIR/tpm_owner_password"
|
||||
echo -n "$tpm_owner_password" > "$SECRET_DIR/tpm_owner_password"
|
||||
# Make sure the TPM is ready to be reset
|
||||
tpm physicalpresence -s
|
||||
tpm physicalenable
|
||||
tpm physicalsetdeactivated -c
|
||||
tpm forceclear
|
||||
tpm physicalenable
|
||||
tpm takeown -pwdo "$key_password"
|
||||
tpm takeown -pwdo "$tpm_owner_password"
|
||||
|
||||
# And now turn it all back on
|
||||
tpm physicalpresence -s
|
||||
|
@ -192,28 +192,28 @@ list_usb_storage() {
|
||||
# Prompt for an owner password if it is not already set in tpm_password. Sets
|
||||
# tpm_password. Tools should optionally accept a TPM password on the command
|
||||
# line, since some flows need it multiple times and only one prompt is ideal.
|
||||
prompt_tpm_password() {
|
||||
TRACE "Under /etc/functions:prompt_tpm_password"
|
||||
prompt_tpm_owner_password() {
|
||||
TRACE "Under /etc/functions:prompt_tpm_owner_password"
|
||||
#Caller might already have cached the password in tpm_password. If not, prompt for it and cache it externally
|
||||
if [ -n "$tpm_password" ]; then
|
||||
DEBUG "tpm_password variable already set by caller. Reusing"
|
||||
DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here."
|
||||
if [ -n "$tpm_owner_password" ]; then
|
||||
DEBUG "tpm_owner_password variable already set by caller. Reusing"
|
||||
DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here."
|
||||
return 0
|
||||
elif [ -s /tmp/secret/tpm_password ]; then
|
||||
DEBUG "/tmp/secret/tpm_password already cached in file. Reusing"
|
||||
tpm_password=$(cat /tmp/secret/tpm_password)
|
||||
DEBUG "TODO REMOVE THIS! tpm_password is $tpm_password here."
|
||||
elif [ -s /tmp/secret/tpm_owner_password ]; then
|
||||
DEBUG "/tmp/secret/tpm_owner_password already cached in file. Reusing"
|
||||
tpm_owner_password=$(cat /tmp/secret/tpm_owner_password)
|
||||
DEBUG "TODO REMOVE THIS! tpm_owner_password is $tpm_owner_password here."
|
||||
return 0
|
||||
fi
|
||||
|
||||
read -s -p "TPM Owner Password: " tpm_password
|
||||
read -s -p "TPM Owner Password: " tpm_owner_password
|
||||
#TODO: This function is called for both owner and TPM sealing calls. We should probably have a different prompt for each
|
||||
echo # new line after password prompt
|
||||
|
||||
# Cache the password externally to be reused by who needs it
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password"
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password"
|
||||
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
|
||||
echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret"
|
||||
echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM owner_password under /tmp/secret/tpm_owner_password"
|
||||
}
|
||||
|
||||
# Prompt for a new owner password when resetting the TPM. Returned in
|
||||
@ -221,26 +221,26 @@ prompt_tpm_password() {
|
||||
# the script will loop until this is met.
|
||||
prompt_new_owner_password() {
|
||||
TRACE "Under /etc/functions:prompt_new_owner_password"
|
||||
local key_password2
|
||||
key_password=1
|
||||
key_password2=2
|
||||
while [ "$key_password" != "$key_password2" ] || [ "${#key_password}" -gt 32 ] || [ -z "$key_password" ]; do
|
||||
read -s -p "New TPM Owner Password (2 words suggested, 1-32 characters max): " key_password
|
||||
local tpm_owner_password2
|
||||
tpm_owner_password=1
|
||||
tpm_owner_password2=2
|
||||
while [ "$tpm_owner_password" != "$tpm_owner_password2" ] || [ "${#tpm_owner_password}" -gt 32 ] || [ -z "$tpm_owner_password" ]; do
|
||||
read -s -p "New TPM Owner Password (2 words suggested, 1-32 characters max): " tpm_owner_password
|
||||
echo
|
||||
|
||||
read -s -p "Repeat chosen TPM Owner Password: " key_password2
|
||||
read -s -p "Repeat chosen TPM Owner Password: " tpm_owner_password2
|
||||
echo
|
||||
|
||||
if [ "$key_password" != "$key_password2" ]; then
|
||||
if [ "$tpm_owner_password" != "$tpm_owner_password2" ]; then
|
||||
echo "Passphrases entered do not match. Try again!"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
# Cache the password externally to be reused by who needs it
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_password"
|
||||
DEBUG "Caching TPM Owner Password to /tmp/secret/tpm_owner_password"
|
||||
mkdir -p /tmp/secret || die "Unable to create /tmp/secret"
|
||||
echo "$key_password" >/tmp/secret/tpm_password || die "Unable to cache TPM password under /tmp/secret"
|
||||
echo -n "$tpm_owner_password" >/tmp/secret/tpm_owner_password || die "Unable to cache TPM password under /tmp/secret"
|
||||
}
|
||||
|
||||
check_tpm_counter() {
|
||||
@ -253,7 +253,7 @@ check_tpm_counter() {
|
||||
TPM_COUNTER=$(grep counter- "$1" | cut -d- -f2)
|
||||
else
|
||||
warn "$1 does not exist; creating new TPM counter"
|
||||
prompt_tpm_password
|
||||
prompt_tpm_owner_password
|
||||
tpmr counter_create \
|
||||
-pwdo "$tpm_password" \
|
||||
-pwdc '' \
|
||||
|
Loading…
Reference in New Issue
Block a user