[systemd-devel] systemd-cryptenroll with TPM2

Lennart Poettering lennart at poettering.net
Tue Aug 22 13:08:05 UTC 2023


On Mo, 21.08.23 17:40, Aleksandar Kostadinov (akostadi at redhat.com) wrote:

> Hello,
>
> This is more of a user question but I didn't find any other suitable forum
> to ask.
>
> I want to install a server that should have an encrypted root but be able
> to reboot unattended.
>
> systemd-cryptenroll with TPM2 looks like a viable option. I'm concerned
> about which PCRs to pin so that an average attacker  won't be able to
> decrypt the volume having physical possession of the server. This means I'm
> not concerned about cracking the TPM chip or reading out life memory.
>
> To me it is acceptable to pin a lot of them so that adding/changing devices
> would prevent automatic decryption. Also 5 looks good about changed GPT
> partitions.
>
> I'm concerned though about an attacker replacing the encrypted root volume
> with a non-encrypted one. Which may result in system booting an attacker
> controlled environment while PCRs may be in a state that allows decryption
> of the original root volume.
>
> Would anything prevent the system from booting with a replaced root
> volume?

Well, when you bind your disk to the TPM then this means you place a
TPM-encrypted key in the LUKS header. This key has to be passed to the
right TPM to be unlocked. This means that if an attacker just has the
disk it's hard for them to acquire the decrypted key if it lacks the
TPM. But it also means that if an attacker wants to replace the disk
its very hard to forge key that is locked against that specific TPM.

> If it can boot in such a way, which PCRs need to be pinned to remove the
> ability to decrypt the original root volume?

PCR pinning is a science of its own, due to the "brittleness" of
measurements, if you update firmware, boot loader, …

So you can bind things to a bunch of PCRs, but that means you simply
cannot make changes to things anymore from that point on, and never
allow the components to update. That's quite often not what you want
in a secure system though: software has bugs after all, and *must* be
regularly updated.

I am currently working on a mechanism to deal with this brittleness,
here in this git branch:

https://github.com/poettering/systemd/commits/pcrlock

It analyzes the UEFI TPM event log (which lists all measurements made
to PCRs), tries to recognize components in it safely. And then is
supposed to use that to generate signed PCR policies from that, based
on a keypair stored on the local TPM, that is itself protected by one
of its own signed PCR policies.

In the long run the way I envision this we'd have two signed PCR
policies in place:

1. A vendor supplied one that covers the UKI and its resources (this
   already pretty much exists), i.e. PCR 11. This one is pre-computed
   at build time of the OS and hence can only cover resources known at
   that time.

2. A locally maintained one on the individual system, based on a local
   key, that covers everything inherently local that is hard to
   predict from the outside (and for good measure also covers the
   vendor supplied stuff, because why not). This would then cover PCRs
   0-7, 9, 11-13, 15, i.e. everything that is reasonably stable
   locally.

Alas, as mentioned this is WIP, still.

Lennart

--
Lennart Poettering, Berlin


More information about the systemd-devel mailing list