Re: [PATCH] efi: expose TPM event log to userspace via sysfs

Lennart Poettering
2024-04-25T11:13:14Z

On Do, 25.04.24 12:36, Ard Biesheuvel (ardb@kernel.org) wrote:

> > systemd these days makes use of the TPM — if available — for various
> > purposes, such as disk encryption, measuring boot phases and system
> > identity and various other things. Now, for the purpose of disk
> > encryption, we need to wait for two things: the hard drive, and the
> > TPM to be probed/driver loaded/accessible. /etc/fstab tells us pretty
> > explicitly what bloock device to wait for, hence it's easy. But
> > waiting for a TPM is harder: we might need it for disk encryption, but
> > we don't know right-away if there actually *is* a TPM device to show
> > up, and hence don't know whether to wait for it or not.
> >
>
> I take it this means that the LUKS metadata lacks a 'this key is
> sealed into the TPM' bit?

Well, it does carry that info. But this is of no relevance
really. typically luks has multiple keys enrolled, and which slot(s) to
use is really up to the moment of invocation, depending on what is available.

moreover, i used disk encryption as one example, but we have more
users of TPM. for example we measure early in the initrd that we are
now in the initd, and when we leave the initrd we measure that we are
now gone. we also have a tool that sets up the TPM SRK. All that stuff
is supposed to be run if a TPM is available, but delayed just enough
until the TPM actually shows up, but no more. So for all of that stuff
we must have a way to delay tings correctly.

> So exposing the physical address of the TPM event log is probably not
> what we want here.
>
> Note that the TPM event log table is a Linux/efistub construct,
> whereas the TPM final log table actually comes from the firmware
> directly. So the former only exists if the EFI stub executed first,
> and managed to invoke the TCG protocol etc. OTOH, the TPM final log is
> TPM2 only, so it doesn't exist on TPM 1.2

(side note: in systemd we do not care about tpm 1.2 anymore, we only
support tpm2, and treat systems with just tpm 1.2 like systems that
have no tpm).

> Another thing we need to consider is TDX, which exposes a pseudo-TPM
> which does not support sealing, along with a CC protocol similar to
> the TCG2 protocol. This code will use the event log infrastructure as
> well: there are discussions going on at the moment whether we can
> improve the way these protocols are combined.

The way the delay for a tpm device is actually implemented in systemd
is somewhat generic: there's a target unit called
"tpm2.target". Typically we just delay its activation until a
/dev/tpmrm0 device shows up, if the firmware check suggested that. But
you could also stuff all kinds of other stuff before that. For exampe,
we could also delay it until some userspace service is running that
turns the local security tech into a "fake" tpm device or similar. So
from our side it's entirely pluggable already, and supports other ways
to synchronize properly on a TPM being available, people can plug in
whatever they need there for the synchronization.

However, our primary focus is to cover nicely the typical/generic
systems that have a discrete TPM or ftpm that just needs some generic
driver probing/loading to be available.

Or in other words: i am fully aware that a tpm-like device can be
provided by various means. For now, with this firmware flag file thing
we primarily care about the simple case where it's just driver loading
that we need to do.

> So we should define a scope here:
> - do we need TPM1.2 support?

For our systemd usecase, that's a clear no.

> - do we need non-EFI boot support?

My own focus is EFI. systemd supports non-EFI of course. If people
care about non-EFI I am sure they'd be thankful if we could provide a
similar automatism

> - do we need to do anything in particular for FDE on TDX, which has a
> TPM event log but no TPM is likely to appear.

I'd ignore that for now. And if they provide a software tpm-like device
eventually they just have to plug in the service that provides it
before tpm2.target and be done with it. I think we have an acceptable
approach for that already.

> I am fine with adding a sysfs node under /sys/firmware/efi that
> exposes some of this information, e.g.,
> linux_efi_tpm_eventlog::version, but not the physical address of the
> table.

Yeah, the physical address is of no interest to us. We just need to
know the existance, and that independently of any actualy tpm device
having shown up. i.e. existance of
/sys/kernel/security/tpm0/binary_bios_measurements would be good
enough for is if it was available without "tpm0" actually being
around...

Lennart

--
Lennart Poettering, Berlin