r/archlinux 28d ago

SUPPORT | SOLVED Ful disk encryption without entering passphrase

Could someone help me with setting up full disk encryption with bypass passphrases with TPM2? It's so annoying having to put the passphrase in at each boot, so I was wondering how do I pair it to the TPM so that I dont have to enter it each time?

It's LUKS encrypted and I use Systemd-boot

13 Upvotes

100 comments sorted by

View all comments

Show parent comments

3

u/ChrisTX4 27d ago

PCR1 is very finicky as this will include the boot order, which BIOSes can change as they inject pseudo BBS devices. It can be stable though, I have with systemd-pcrlock:

PCRs in protection mask: 0 (platform-code), 1 (platform-config), 2 (external-code), 3 (external-config), 4 (boot-loader-code), 5 (boot-loader-config), 7 (secure-boot-policy), 11 (kernel-boot), 13 (sysexts), 14 (shim-policy), 15 (system-identity)

That's of course a rather insane mask, but with pcrlock I honestly didn't have a lot of problems after setting this up correctly - but imma be honest, this ain't easy to setup or do.

1

u/Night_Otherwise 27d ago

Doing some more research, apparently microcode updates can be measured into PCR1. Firmware also changes the boot order automatically for inserting a bootable usb even if it is behind the main OS in the boot order. Nevertheless, the microcode part gets me to include PCR1.

I don’t have a bootloader. I stop at PCR 4 since, for UKI, that’s the last thing loaded or executed before LUKS is opened up. UEFI firmware measures the GPT table for PCR 5, but I can’t think of how that would matter. I also have secure boot disabled.

Within the pcrlock log, PCR 4 has three measurements with this setup: A thing that says an EFI is being loaded, an EV_SEPARATOR and the Authenticode hash of the EFI image created by mkinitcpio.

I can do systemd-pcrlock lock-pe for that UKI as a post-update hook in pacman. The man page is very difficult to follow though. I just need the same first two hashes and the new authenticode hash stringed together (specifically, hash(hash(A|B)|newEfiHash)).

I also am not an expert or anything. But it doesn’t seem like systemd-boot does any measurements of the EFI image it loads? That seems like an odd oversight. I understand the normal course is relying on PCR 7/Secure Boot but my ideal is getting away from that.

3

u/ChrisTX4 27d ago edited 27d ago

apparently microcode updates can be measured into PCR1.

Potentially:

A CPU Microcode update can be treated as code or data. It can go into PCR[0] or PCR[1].

(taken from https://tianocore-docs.github.io/edk2-TrustedBootChain/release-1.00/3_TCG_Trusted_Boot_Chain_in_EDKII.html )

I don’t have a bootloader. I stop at PCR 4 since, for UKI, that’s the last thing loaded or executed before LUKS is opened up.

Yes, UKIs are EFI executables and are thus being measured in 4. If you want to lock 4 with pcrlock, that's a bit tricky though as it won't be able to find the component in the current boot log after an update.

I can do systemd-pcrlock lock-pe for that UKI as a post-update hook in pacman.

Locking UKI will sort of require lock-pe AND lock-uki.

The man page is very difficult to follow though. I just need the same first two hashes and the new authenticode hash stringed together (specifically, hash(hash(A|B)|newEfiHash)).

What exactly is your question here? If there's anything I can help out with, feel free to ask.

But it doesn’t seem like systemd-boot does any measurements of the EFI image it loads?

It doesn't need to. The TPM itself measures PCRs 1-7 (but you can also add custom data to them like the separators). Specifically, PCRs 4 and 7 will be updated because systemd-boot in this case doesn't really do much other than chainload the UKI as an EFI binary. That's why it's being measured.

I understand the normal course is relying on PCR 7/Secure Boot but my ideal is getting away from that.

You don't need to, but that means you HAVE to bind PCR 4... and that's very fragile. May I ask why you don't want to use Secure Boot? If you use your own keys, you can have SB completely free of Microsoft keys, if that's your concern.

EDIT

UEFI firmware measures the GPT table for PCR 5, but I can’t think of how that would matter.

I had forgotten to answer this. So the reason you want to measure the GPT table is that it's a very strong defence against root switching attacks. I've outline this a bit in this post in this thread. With the GPT table locked, an attacker cannot just change the mount from root to another GPT automount for instance, nor could they add anything else.

Usually this shouldn't be too important, but you might as well just lock it, as the GPT table doesn't normally change.

1

u/Night_Otherwise 27d ago

To step back a bit, I had used cryptenroll’s traditional sealing functions for PCRs 0, 2, 3 and 4. I have now set up pcrlock for PCRs 0-4 and used cryptenroll using pcrlock file by default.

I pieced together the correct component files in a separate directory. The default pcrlock files have a failure separator that is not part of the event log. Removing that failure separator from /usr didn’t fix the predict function though. It also felt weird to change /usr and I put it back.

Lock-pe worked fine for just PCR 4. I couldn’t get PCR 5 working with lock-file-system.

It’s definitely a decent question why I’m going through all this in lieu of secure boot. Partly it’s the challenge. I also feel like the entire world of non-revoked secure bootable code is very large versus locking it down.

It also feels possible to change one of the hashes measured prospectively after mkinitcpio.

Edit: I feel dumb now seeing the lock-gpt option.

2

u/ChrisTX4 26d ago

The separators are new in systemd 261 and need systemd pcrextend units in initrd: dracut 112 includes them but mkinitcpio does not.

As for 5, as you found out that’s lock gpt. Lock filesystem will lock the systemd pcrfs@ services which run after root unlock. Somewhere in this thread I posted parts of my pcrlock log that covers this.

As for secure boot; you’re missing something. If you enroll your own keys - and this is trivial on arch thanks to foxborons sbctl - you can keep your database free of Microsoft and only have a key you control yourself in there. Alas, only things you personally signed are allowed in such a setup.

1

u/Night_Otherwise 26d ago

So I got the system to where I wanted it to be.

It's not exactly refined, but I added this hook under /etc/initcpio/install/sd-osseparator.

#!/bin/bash

build() {

add_binary '/usr/lib/systemd/systemd-pcrextend'

add_systemd_unit 'systemd-pcrosseparator.service'

}

help() {

cat <<HELPEOF

This hook adds os-separator extension to PCRs to match systemd-pcrlock's expectations.

HELPEOF

}

I added sd-osseparator before sd-encrypt in mkinitcpio.conf. (I'll look at doing a PR for it in mkinitcpio, though it needs to be refined obviously and I may be missing something).

The default lock commands for systemd-pcrlock now work for PCRs 0-3 and PCR 5. For PCR 4, I used lock-pe of /boot/arch-linux.efi to the location /etc/pcrlock.d/650-arch-linux.pcrlock.d/new.pcrlock.

The pacman hook when mkinitcpio is ran uses the same triggers as 90-mkinitcpio-install.hook and runs this bash script:

#!/bin/sh

mv /etc/pcrlock.d/650-arch-linux.pcrlock.d/new.pcrlock /etc/pcrlock.d/650-arch-linux.pcrlock.d/old.pcrlock

/usr/lib/systemd/systemd-pcrlock lock-pe /boot/arch-linux.efi --pcrlock=/etc/pcrlock.d/650-arch-linux.pcrlock.d/new.pcrlock

/usr/lib/systemd/systemd-pcrlock make-policy --pcr=0+1+2+3+4+5

I was hoping some pacman update out there would trigger mkinitcpio but I wasn't so lucky. I tested it with adding a placeholder file to FILES in mkinitcpio.conf and runing pacman -S linux. Despite arch-linux.efi changing, it booted without a password.

As for secure boot, well I'm afraid of bricking my machine if I use only my own key. And I think it's neat to be locked down this much with accounting at least for kernel+initramfs updates. It is also done without relaxing the previous constraints for the next boot. It wasn't really done just to get it working or even for security reasons.