Setting up LUKS to load encryption keys from the TPM2 device on the system is a pretty simple effort overall. We’re just going to be creating a new key for the disk, adding the key to the LUKS partition, adding the key to the TPM, and finally setting up crypttab to load the key from the TPM when the system starts up.

Install OS Dependencies

apt install tpm2-initramfs-tool xxd

Generate and Add Random LUKS Key

dd if=/dev/random bs=64 count=1 | xxd -p -c999 | tr -d '\n' > /root/luks_key
cryptsetup luksAddKey /dev/nvme0n1p3 /root/luks_key --pbkdf-force-iterations=4 --pbkdf-parallel=1 --pbkdf-memory=32

Register the Key in TPM

tpm2-initramfs-tool seal --data $(cat /root/luks_key) --pcrs 0,2,7

Add Fallback Method

Create the script that will read from the TPM during boot and ask for a passphrase if it fails at /etc/initramfs-tools/tpm2-cryptsetup:

#!/bin/sh

[ "$CRYPTTAB_TRIED" -lt "1" ] && exec tpm2-initramfs-tool unseal --pcrs 0,2,7

/usr/bin/askpass "Passphrase for $CRYPTTAB_SOURCE ($CRYPTTAB_NAME): "

Make the script executable:

chmod +x /etc/initramfs-tools/tpm2-cryptsetup

Next create the hook in the initramfs at /etc/initramfs-tools/hooks/tpm2-initramfs-tool:

#!/bin/sh

PREREQ=""
prereqs()
{
   echo "$PREREQ"
}

case $1 in
prereqs)
   prereqs
   exit 0
   ;;
esac

. /usr/share/initramfs-tools/hook-functions

copy_exec /usr/lib/x86_64-linux-gnu/libtss2-tcti-device.so.0
copy_exec /usr/bin/tpm2-initramfs-tool
copy_exec /usr/lib/cryptsetup/askpass /usr/bin

copy_exec /etc/initramfs-tools/tpm2-cryptsetup

The long beginning of this script is required according to the initramfs-tool manual.

Make this script executable as well:

chmod +x /etc/initramfs-tools/hooks/tpm2-initramfs-tool

Update the /etc/crypttab to include the keyscript option:

nvme0n1p3_crypt UUID=<<UUID>> none luks,discard,keyscript=/etc/initramfs-tools/tpm2-cryptsetup

Now rebuild all of the initrd images:

update-initramfs -u -k all