Jump to content

Talk:Systemd-cryptenroll

From ArchWiki
Latest comment: 30 July by Benjarobin in topic PCR15 (and usage of PCR7 is discouraged)

TPM: implicit update of PCR7(+??) with fwupd

There is a warning under section 5.3 for TPM which suggests fwupd can be configured to update the PCR7 (and any related registers) implicitly when the firmware is scheduled for upgrade. The external link is to a systemd TODO list, and it's hard to tell if this is available in systemd-cryptenroll yet.

When I was installing this new laptop, I ran into an issue where the TPM2 module would not unlock my LUKS2 volume containing my root Btrfs subvolume because a PCR (I think it was PCR7) did not match the current hash of the firmware after I had run fwupdmgr update and rebooted. Like an idiot I didn't take a photo of the recovery key, and I couldn't unlock the system after the firmware update. Luckily reinstalling from scratch only took about 20 more minutes, but I'm loath to try to upgrade this laptop's firmware again until I have a solution (I see there are already new firmware updates to apply). Ectospasm (talk) 17:31, 6 January 2024 (UTC)Reply

Really sorry to hear this and I hope you had backups. Yes, the solution is to not bind disk encryption to PCR 7 and systemd plans to change this some time in the future in favor of binding to signatures of PCR values with either pcrlock policies or signed public key based policies. Currently, there's an open issue about this on fwupd for hooking firmware updates to systemd-pcrlock, which should prevent situations like yours from happening. Until that issue is resolved, I imagine binding pcrlock policies to disk encryption will be withheld so that leaves you with the latter--signed public key based policies based on measured boot states. For more detail about these policies please read the systemd-cryptenroll man page or watch Lennart's talk on Linux & TPMs. Nu4425 (talk) 01:44, 7 January 2024 (UTC)Reply
Thankfully, this was a new installation and I wasn't at the point of needing backups (I hadn't restored anything from my other systems yet). I actually found that fwupd RFE on my own, and at the top Lennart mentions what we can do now, though doesn't explicitly delineate all the steps. I'm thinking I can do this:
  • # fwupdmgr update (I must be sure not to reboot when prompted)
  • # sbctl sign --save /path/to/fwupd/file.efi
  • # systemd-pcrlock unlock-firmware-code
  • # systemd-pcrlock make-policy
Then reboot. Does that order of operations look correct? Should I unlock the firmware code before updating? Since pcrlock is so new, it's difficult to find any guides on this. Ectospasm (talk) 15:09, 7 January 2024 (UTC)Reply
The order of those operations look correct, as long as you do not make the policy before the firmware update. To quote a section of the man page: "If a firmware update is applied this data will be out-of-date and any access policy generated from it will no longer pass. It is thus recommended to invoke unlock-firmware-code before doing a firmware update, followed by make-policy to refresh the policy". Of course, this doesn't just apply to the unlock-firmware-code command. Therefore, if you want to follow it per the man page, I believe you'd first unlock the policy, update the firmware then make a new policy
Personally though, on my system, I haven't tried binding any secrets to a pcrlock policy and will wait until it's not experimental. Even if it wasn't, for some reason, systemd-pcrlock is unable to recognize a lot of the measurements in my TPM event log so I wouldn't be able to make a strong policy for anything Nu4425 (talk) 20:40, 7 January 2024 (UTC)Reply
So maybe the order of operations should be this:
# systemd-pcrlock unlock-firmware-code
# fwupdmgr update # be sure *NOT* to reboot when prompted
# sbctl sign --save /path/to/fwupd/file.efi
# systemd-pcrlock make-policy
I guess in order for this to work make-policy needs to anticipate what changes will be made when the computer is rebooted; I'll have to test this out and see how I fare.
Ectospasm (talk) 00:28, 13 January 2024 (UTC)Reply
And this worked! I didn't have previous pcrlock files in place, so unlock-firmware-code didn't really have anything to do. I updated the firmware, with --no-reboot-check. It looked like I only had one component of my laptop firmware updated, and fwupdmgr didn't appear to say I needed to reboot. I rebooted anyway, and my TPM unlocked my LUKS2 container no problem!

I'll go ahead and update this wiki article. It remains to be seen whether a more involved firmware update will have the same results, but I think this is promising! Ectospasm (talk) 02:54, 23 January 2024 (UTC)Reply
Oh, I see. I don't think I ran the sbctl step, I didn't see fwupdmgr install the fwupd.efi file, so that may have been why my TPM unlocked my LUKS2 container. Ectospasm (talk) 02:57, 23 January 2024 (UTC)Reply
I'm glad that you weren't locked out this time. To clarify though, you're binding the pcrlock policy to your system and not a storage device? Because you shouldn't be able decrypt your system as encryption for the root filesystem hasn't been merged yet unless you built systemd with that pull request? If you didn't, then this leaves me to believe that you were successful because you probably chose not to bind to PCR 7 anymore. Nu4425 (talk) 05:53, 23 January 2024 (UTC)Reply
Honestly I don't really understand much about this at all. The output of make-policy did appear to skip over PCR 7; the output (I wish I had saved it) did indeed look like it excluded that PCR.

I also noticed there are a bunch of pcrlock-related services, I haven't enabled or started any of those. Do I need to worry about those for now? Ectospasm (talk) 10:44, 23 January 2024 (UTC)Reply
If you had forgotten, you can review and verify the options you specified at enrollment by examining the dumped output of your LUKS2 header. If you do not see PCR 7, I believe that's probably why. Also, no, I believe you don't need to worry about those services until encryption for the root fs has been merged. Currently, only external storage devices should be supported, so if you have any to spare you can experimenting with systemd-pcrlock on them. Nu4425 (talk) 00:57, 24 January 2024 (UTC)Reply
Ahh, OK. So since this LUKS2 container is for my root subvolume (and subvolumes underneath), using systemd-pcrlock had no effect. I will check out the LUKS2 header, as when I ran into the problem back when I first installed this laptop the TPM balked since the firmware upgrade invalidated the digest in PCR7.

I'm not totally convinced the firmware update from yesterday actually did anything, since the only firmware update was for my webcam. Lenovo has been emailing me pretty regularly with firmware updates for Win10 and Win11, but my guess is they haven't gotten to LVFS yet. Ectospasm (talk) 03:41, 24 January 2024 (UTC)Reply
Just a heads up but in the upcoming release of systemd (258), systemd-cryptenroll will no longer bind to literal value of PCR 7. Same for systemd-creds. Instead, upstream’s recommendation is to use systemd-pcrlock to cover PCR 7 as well as others PCRs in combination with signed policies for PCR 11. For those that care and desire that system security, this will require manual intervention by wiping any relevant LUKS2 key slots and re-enrolling to the encrypted volume. Still, updating the firmware should still be handled with care by “unlocking” the relevant components before upgrade and enabling the relevant service units. See systemd-pcrlock(8) for more details.
- https://github.com/systemd/systemd/releases/tag/v258-rc2
S Nu4425 (talk) 01:32, 10 August 2025 (UTC)Reply
Quote:
“Note that this data only matches the current version of the firmware. If a firmware update is applied this data will be out-of-date and any access policy generated from it will no longer pass. It is thus recommended to invoke unlock-firmware-code before doing a firmware update, followed by make-policy to refresh the policy.”
So after unlocking, updating the firmware, making the policy, users will have to make the policy again in the next boot, if successful. Nu4425 (talk) 01:41, 10 August 2025 (UTC)Reply

Rewrite TPM section to use PCR policies by default, or merge with Trusted_Platform_Module#PCR_policies

PCR policies have been available for a while now, using them vs raw PCR values has been the recommendation upstream for a long time and is easy to do if using cryptenroll, and really avoids many ways to shoot your own foot. The main caveat I can think of is that there hasn't been a release of mkinitcpio containing this fix yet.. Hopefully should be soon. Once this lands, I think it would be a good idea to merge with the TPM Policies section. We also still don't have a pcrlock section. Cvlc (talk) 20:53, 7 August 2025 (UTC)Reply

PCR15 (and usage of PCR7 is discouraged)

https://wiki.archlinux.org/title/Systemd-cryptenroll#Trusted_Platform_Module

It is impossible to auto-unlock LUKS partition by enrolling PCR15 into TPM: https://en.opensuse.org/Portal:MicroOS/FDE#PCR_#15


... bind to an empty PCR 15 using --tpm2-pcrs=other_pcrs+15:sha256=0000000000000000000000000000000000000000000000000000000000000000.

Why should someone clear-out the PCR15 bank?

About PCR7:

https://github.com/systemd/systemd/blob/874fbb870cdcf40e502165bc0f688cf2ec3d70b1/NEWS#L1205 D.ALT (talk) 17:44, 7 April 2026 (UTC)Reply

PCR15 is initialized by the TPM to 00000... Note: it is impossible to clear or set a specific value inside a PCR register (otherwise there is not safety at all). In the initramfs nothing in measured (by default), and finally from the main partition, /etc/machine-id is measured into PCR15. So if you bind to 0000 as soon as the machine-id is measured into PCR15, the TPM will no longer unlock/provide the key to un-crypt the root partition. Benjarobin (talk) 18:13, 7 April 2026 (UTC)Reply
About PCR7, it is safer to use directly PCR7, but not as convenient. Also it is not clear how to use properly pcrlock. So we are waiting for proper documentation on systemd side to recommend using the "new stuff". Benjarobin (talk) 18:17, 7 April 2026 (UTC)Reply
This is not how this is supposed to work.
Binding PCR7 raw is entirely insecure as it's staying unlocked post boot. Replace the encrypted root fs with an attacker controlled dummy root fs (same GPT GUID) but booting with the same signed UKI. It will look look like a TPM mismatch and fallback to password. Attacker enters their dummy password, system happily boots. Attacker can unlock the disk post boot as the TPM only considered the UKI and bootloader and they've not been changed.
The PCR15 tip does not work with mkinitcpio, also: systemd has systemd-pcrphase and friends that measure various things. Most importantly, there's systemd-pcrfs@.service, which will measure crypt mounts with tpm2-measure-pcr=yes (also added to certain GPT automounts by systemd automatically). systemd-pcrfs@.service can only run inside initramfs and the idea is to bind to the volume key *BEFORE* unlocking. From my system:
15 system-identity volume-key 4e882ffdfceedd2f5ec9953fe3ec4d9c4a175f0e6119389da6b8bb31d6af226a U 825-cryptsetup-root cryptsetup:archmain:6abc8ffc-7419-4667-af8c-1ef04324f9f2
This event taking place prior to `leave-initrd` means that the PCR15 value is not zero by the time the FS root switch happens.
With mkinitcpio, this does not happen as these services do not exist in initrd and the only service measuring thus is systemd-pcrmachine.service. This runs *AFTER* the root switch on real-root and measures /etc/machine-id into PCR15. Importantly, volume-keys and machine id are the only thing measured into PCR15. Meaning, that if an attacker controlled root does simply mask systemd-pcrmachine.service the PCR15 thing is defeated.
As long as mkinitcpio does not ship systemd-pcrphase and co. it will be very challenging, to say the least, to create a secure TPM unlock setup, I'm afraid.
State of the art recommended by upstream is combining public key PCRs with systemd-pcrlock btw. This allows to lock to absolutely insane combinations, like my system is locked to PCRs 0+1+2+3+4+5+7+11+13+14+15, while still being rather reliable. But pcrlock of course requires pcrphase. ChrisTX (talk) 06:45, 30 July 2026 (UTC)Reply
I agree with you about the PCR15 stuff. The proper solution is to use Dm-crypt/System configuration#Pinning a LUKS volume. But the PCR15 trick can still be used if you enable a service in initramfs that measures something in it.
From my point of view, PCR7 raw + pinning the LUKS volume should be safe. Benjarobin (talk) 07:14, 30 July 2026 (UTC)Reply
That solution is exactly what I was talking about with PCR15, but using tpm2-measure-pcr=yes causes systemd-pcrfs@.service to perform the measurement. With mkinitcpio this is not in the initramfs, and thus this pinning does not work. You would need to use Dracut.
But if you do, that lock advice is badly outdated. systemd-pcrlock is what you want to be using - it uses the systemd-pcrphase mechanics to know the sort of progression of values that should be measured in each PCR. If you have GPT automounting configured, just doing systemd-pcrlock lock-machine-id and systemd-pcrlock make-policy will provide you a lock to PCR15. If you use systemd-cryptenroll, it will automatically locate the pcrlock.json and will just apply it, so you just need to run systemd-cryptenroll again (without --pcrs= or something like that of course).
Locking to the raw value like that is just very brittle and systemd-pcrlock can also handle this for automatically mounted disks: So for example if an attacker added a disk with GPT automount to /var, it will mount it but measure its volume key into PCR15 as well, and thus change the identity. If you just lock one volume key like this it doesn't work and such modifications to your system could be slipped in. systemd-pcrlock is immune against this on the other hand. ChrisTX (talk) 19:33, 30 July 2026 (UTC)Reply
If I am not mistaken, you can add very easily any service in initramfs using mkinitcpio. You just need to add the .service file, enabled it, and add any dependency needed.
Do you know where to find a proper documentation about systemd-pcrlock that explain in detail how this is working. If you know a lot of stuff about it, please document it in the Wiki, and please add details on how this is working.
And I don't see how systemd-pcrlock can make the stuff any safer, it is just more convenient (but I am not sure to fully understand everything about it...). I am also pretty confused, you can also use a PCR raw register to measure various stuff, this is possible to measure the volume key, or anything else. Benjarobin (talk) 21:32, 30 July 2026 (UTC)Reply