A Modern and Secure Desktop Setup

Eh I don’t entirely agree. Like I said, it can be done correctly. And when it’s done correctly, it is as secure as the TPM2 itself is. So yes, if a thief is able to compromise the TPM2, then the purpose is defeated. But the point is that this is a significantly difficult barrier. You need to have an active exploit against the TPM2, or something like an electron microscope to extract its secrets. These things are indeed possible (there have been many TPM2 exploits in the past), but again the point is that it is a strong barrier, not a perfect one.

Regardless, even if you don’t want to risk auto-unlocking, the TPM2 is still quite valuable. Binding your LUKS volume to the TPM2 with a pin provides at least the same security as a regular passphrase while also informing you if the secure boot state isn’t as it should be since the pin will fail in that case. Not to mention strengthening the passphrase with the TPM2’s dictionary attack lockout mode, which helps to prevent brute forcing.

1 Like

The trouble is that it depends on the setup. In your case, where there’s just an encrypted partition with a btrfs file system on it, it’s as simple as binding the volume to 15:sha256=00000..., adding the tpm2-measure-pcr=yes crypttab option, and making sure to specify the root device as /dev/mapper/<name> instead of any other path for the device.

In the case of one of my systems that uses ZFS on LUKS, I had to make changes to the ZFS import service to make it depend on /dev/mapper/<name> correctly.

Not sure what was going on there but it seems after upgrading to 24.11 the tpm cryptenroll works again without any extra fuss.

Updated my setup and the guide based on the PCR 15 suggestions.

This is too much. PCR 12 will all change with every generation, and PCRs 4, 9, and 11 will change on certain system updates, so this will break and need re-enrolling when you do a nixos-rebuild. I just wouldn’t bind to PCRs that you don’t need. I recommend 0+2+7+15:sha256=0000000000000000000000000000000000000000000000000000000000000000, and maybe 1+3 if you want changes to bios settings to require re-enrolling. The systemd-cryptenroll manpage even suggests not including 0+2 because they’re (effectively) covered by secure boot / PCR 7, but I personally still bind against them because I don’t want to be vulnerable to firmware downgrade attacks.

It’s also worth noting that the tpm2-measure-pcr=yes thing will only work if you use only one disk. You’d have to get more clever to support multiple.

3 Likes

Thank you for the info, it’s really hard for me to understand what actually goes into which PCR even with this info. For example based on that wiki I wouldn’t assume that 9 and 11 necessarily change from a rebuild. Would be nice to have a better overview of what goes into which and what’s the reason to include or not include it.

The manpage for systemd-cryptenroll has a pretty good table about what goes into each PCR. systemd-cryptenroll

3 Likes

Seems PCR 1 changes when the PC hibernates so I removed that. I’m still testing the rest to see which ones are not stable enough.

This isn’t a testing problem. They’re documented. Like I said, the manpage for systemd-cryptenroll, also the uapi-group. You don’t want to just apply a blanket binding to all PCRs and hope for the best. Use the ones where the documentation indicates it makes sense for you.

That approach doesn’t work for me because based on the short descriptions I don’t understand what the implications are. For example based on the description using PCR1 makes sense for me but it doesn’t work with hibernation.

I think most people don’t have your level of understanding what each of them does.

Description for PCR1:
Core system firmware data/host platform configuration; typically contains serial and model numbers

How does that implicate hibernation?

1 Like

The reason hibernation affects PCR 1 is probably because systemctl hibernate writes some state to EFI variables so that it knows which device / offset to resume from.

1 Like

How would I use tpm2-measure-pcr=yes with Disko? I don’t see an option for crypttab anywhere.

Disko accepts a settings attribute for controlling the NixOS option luks option.

content = {
    type = "luks";
    ...
    settings.crypttabExtraOpts = [ "tpm2-measure-pcr=yes" ];
};
1 Like

Thanks for the clarification! Sadly, this option breaks --tpm2-with-pin=yes.

That’s quite surprising. How does it fail?

Thankfully these extra measurements are less important if you’re using a pin, because an attacker still needs to know the pin to decrypt the disk.

1 Like

Idk, the PIN prompt doesn’t appear, it goes straight to the LUKS password. When removed this from crypttab, it worked without doing anything (no systemd-cryptenroll again). I’m not sure but I think Plymouth didn’t work too.

Try adding "tpm2-device=auto" to crypttabExtraOpts. It seems to be required if systemd-cryptsetup’s external plugin support is disabled (a side-effect of tpm2-measure-pcr=yes).

2 Likes

It worked, thanks! @balint could you add a warning for people that might try to use tpm2-pin?