TPM2 + LUKS - Auto Unlock on Boot [systemd only]

Hi all, I was trying to for some time automatically unencrypt my LUKS partition on boot so I wasn´t stopped by the password prompt on boot. Usually I turn on my PC and go do something else while it boots (it takes less than 10 seconds, but still old habits die hard). It was a bit frustrating when I cam back and the LUKS password prompt was there instead my display manager.

I use encryption o my drive just as as safeguard when discarding it or if it fails and I have to RMA. This grantees if someone has access to my drives but not my whole PC, they can´t acess my data. I don´t recommend this if you are using a Laptop or your concern is having the whole PC stolen!

My goal was to have something similar to Bitlocker but still mantain control over my system. The main source for this tutorial is the Arch Wiki but focused on CachyOS.

ATTENTION: BACKUP YOUR DATA
The process is easy but any misstep potentially brick your bootloader.
I had a hard time making my crypttab.initramfs correct and had to use a rescue boot to save my PC.

The TLDR:

  • Make sure you have Secure Boot enable and working
  • Make sure you have TPM2 support running :

systemd-analyze has-tpm2

  • Make a copy of your /etc/crypttab to /etc/crypttab.initramfs:

sudo cp /etc/crypttab /etc/cryptab.initramfs

  • Enroll the PCR keys on the TPM2 slot of systemd-crypt

sudo systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs “1+3+5+7+11+12+14+15” /dev/nvmeXnXpX

Where /dev/nvmeXnXpX is your encypted device with system

  • Change your HOOKS on /etc/mkinitcpio.conf:

sudo micro /etc/mkinitcpio.conf

Edit the line

HOOKS=(base udev autodetect microcode kms modconf block keyboard keymap consolefont plymouth encrypt filesystems)

to

HOOKS=(base systemd plymouth autodetect microcode modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)

  • Rebuild your initramfs with:

sudo mkinitcpio -P

  • Reboot the PC and pray

The full Guide:

  1. Eneable Secure Boot

Cachy Wiki has an excellent guide on how to enable Secure Boot post installation.
Also make sure you have a TPM2 device available running:

systemd-analyze has-tpm2

Double check on Octopi if the package tpm2-tss is installed.

  1. Create the /etc/crypttab.initramfs file

As we are unlocking the device on boot time, we must identify it on /etc/crypttab.initramfs. This indicates the boot loader the device name (map), its UUID and how to unlock it (in our case, tpm2-auto). If you have only one encrypted drive, the easiest way to create the file is to copy the userspace version /etc/crypttab to /etc/crypttab.initramfs using the command:

sudo cp /etc/crypttab /etc/cryptab.initramfs

If you have more encrypted devices and they are on the userspace /etc/crypttab, you can do the same but edit out to leave only the root partition on the file. To check your your root partition name and UUID you can use gParted or other partitioning tool. use the ENCRYPTION section data, not the File System section!

Crypttab file has the format:

<name> <device> <password> <options>

  • Name must be your mapper name. In this case luks-XXXXXXXXXXXX6c9f
  • Device is UUID. In this case, XXXXXXXXXXXX6c9f or the name without “luks-”
  • Password must be none to force use the TPM2 key

Once done you are ready ton enroll the TPM2 keys

  1. Enrolling the TPM2 keys and PCRs:
    Arch Wiki has a great article about this step.

For this tutorial we will use the PCRs: “1+3+5+7+11+12+14+15”.
Bitlocker uses “0+2+4+8+9+10+11” for comparison. It is up to you judge your needs, but my rational is:

Here are the reasons for my config:

  • I omitted 9 (Linux Kernel and grub), which requires rebuild every time there is a kernel update. As Fedora updates the Kernel quite often, I omitted this integrity check.
  • I omitted 4 because I observed a change in its signature after a kernel update. I am assuming it will sometimes be changed by an regular update.
  • I omitted 0 (firmware) and 2 (pluggable hardware), because it is explicitly recommended against bysystemd-cryptenroll man page
  • I added 11 (ELF kernel image, embedded initrd and other payload of the PE image ) and 14 (shim) because 7, 11, 14 is recommended by systemd-cryptenroll man page
  • I added 12 (kernel-config) because I don’t typically change kernel parameters
  • I added 15 (volume key of activated LUKS volumes), because I don’t imagine I would change the LUKS volumes.

PCRs 12 and 15 are the most "personal"and should be considered case by case.

After deciding the PCRs, check the name of your root partition (based on gparted example, mine is /dev/nvme0n1p2. The comand to enroll the TPM keys is:

sudo systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs “1+3+5+7+11+12+14+15” /dev/nvmeXnXpX

If any of the PCRs changes you just neede to rerun the previous command to update your TPM2 key.

Once done, you are ready to modify the initramfs with the new information.

  1. Updating the initramfs
    The boot hooks must be changed to include the necessary systemd hooks to auto unlock your LUKS partition. To do so, firt we have to change the /etc/mkinitcpio.conf file.

Make a backup copy of the original file as I bricked my system multiple times here.

sudo cp /etc/mkinitcpio.conf /etc/mkinitcpio.conf.old

When ready, open the original file with a text editor and find the line:

HOOKS=(base udev autodetect microcode kms modconf block keyboard keymap consolefont plymouth encrypt filesystems)

change to

HOOKS=(base systemd plymouth autodetect microcode modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)

fsck is optional, plymouth must be changed to run just after systemd

Once done, rebuid your initramfs and rebboot the system.

sudo mkinitcpio -P

On the next boot, everything should be exactly the same, but you won´t be prompted to type your LUKS password.
I recommend you also make a recovery key for your LUKS partition.
Follow this Arch Wiki link (section 4) systemd-cryptenroll - ArchWiki.

Please let me know if the tutotrial works for you or if something neede to be adjusted.
Currently I can only add 2 links to the post. When this restrictions is lifted I will format with more sources.

2 Likes

This kinda defeats the purpose of disk encryption… Maybe I’m missing something, but it will unlock for any OS with a correctly configured initramfs? This is only good if they only steal your disk?

I just don’t think that relying on some chip to handle your security is 100% safe. I saw so many articles where they exploit a few years old secure boot and tpm implementations.

You are actually correct, that’s why I do not recommend the setup for notebooks. This only protects you with someone steels your drive but not your pc. I described my use case but I should be more clear.

If someone steels your drive, they need an exact hardware match to Auto Unlock it. Otherwise your password will be prompted. My main concern is only when I have to dispose my drive / RMA it. This year I RMAed 4 Segate drives. Some of them I was unable to erase before sending to RMA (the controller died), so having data encrypted this way was suitable for my use case.

Regarding TPM spoofing, I’ve read some articles but it seems to be a somewhat sophisticated atack. For my gaming rig I’m not concerned, but for my NAS I would never use this Auto Unlock. Depends on your threat model.

Guys there is a typo when on the command to copy crypttab. It should be:

sudo cp /etc/crypttab /etc/crypttab.initramfs

It is missing a t on the second crypttab.
Can any mod help me edit it?

It will render the system with the typo, however it is an easy fix. Just boot to the live usb environment, use cachy-chroot tool to mount your root and fix the typo.

Rebuild the initramfs and reboot

Hi @Nuk3,
thank you for gathering this information and sharing your choices with us!

I have set it up exactly as shared by you except using the –tpm2-with-pin=yes flag when enrolling the PCR keys.
However I would expect that tpm fails and prompts to unencrypt with the LUKS password if any of the PCR States fail. Such as a change of the Secure Boot or newly added kernels. However, having tested with those two modifications, I can unencrypt the system with the TPM PIN as normal. Do you happen to have any idea what I am missing here?

I found a Note on Arch Wiki about that:

Note:

  • It is possible to require a PIN to be entered in addition to the TPM state being correct. Simply add the option --tpm2-with-pin=yes to the command above and enter the PIN when prompted.
  • systemd-cryptenroll does not check the TPM measurement before asking for the PIN, therefore consider using a unique PIN since the environment may be untrustworthy.

As per my understand, it will ignore the PCRs and ask for PIN. If you have the correct PIN it would automatically unencrypt your drive, so what you are describing is the expected behavior.
Take a look Systemd-cryptenroll see if your understanding is the same as mine.

1 Like

Thanks for checking! The quote led me to the cause of the issue.

During my tests, I had used the same password for both PIN and LUKS password. If you enter the wrong PIN, it will ask for the LUKS password. However, if the PCRs do not validate and you enter the PIN, it seems that the system will attempt to use the PIN as the LUKS password, which is why the second password prompt is skipped. With different PIN and LUKS passwords, the behavior is as expected: with an invalid PCR status, even with the correct PIN, the LUKS password is still requested.

The second point in the quote, therefore, should not only be understood as someone trying to grab the password and therefore the PIN should be unique to protect the LUKS password. Instead it means the system would accidentally boot in an untrustworthy environment.

However, this made me notice a second hidden problem. I’m mounting a second LUKS drive via crypttab (crypttab.initramfs only contains root). Apparently, this leads to one of the PCRs being invalid. TPM boot doesn’t work.

edit: it was caused by the decryption order, the second luks device was attempted to be decrypted first. But TPM was set up for the first, the root device. I got around it by adding keyfile for the second device to crypttab.

So I set this up yesterday and it worked, however today I installed some updates and after a reboot I was prompted for the LUKS password again. At first I panicked because I thought it was going to be asking for a TPM key I didn’t have but it seems my password still worked.

Ended up getting this working again by just following the above steps from the beginning.

This is expected behavior, Cachy had a recent kernel update, so the TPM SHA wont match the new system, so it asks to retype password.
Whenever that hapens you only have to re run:


sudo systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs “1+3+5+7+11+12+14+15” /dev/nvmeXnXpX

changing /dev/nvmeXnXpX to your corresponding device.

This will update the TPM SHA to match the new kernel.

1 Like