On Mo, 04.12.23 08:01, James Bottomley (James.Bottomley@xxxxxxxxxxxxxxxxxxxxx) wrote: > On Mon, 2023-12-04 at 10:20 +0100, Lennart Poettering wrote: > > On Fr, 01.12.23 17:23, James Bottomley > > (James.Bottomley@xxxxxxxxxxxxxxxxxxxxx) wrote: > [...] > > > > > I'm bringing this up for discussion now, in case anyone has a > > > > > better idea or wants to add nuances (like measuring the > > > > > creation to a real PCR and adding an event log to measured > > > > > boot) before I (or someone else) look into coding it up. > > > > > > > > Why would that be necessary though? The "name" of an nvindex pins > > > > the access policy of the nvindex. > > > > > > I assume you're talking about using TPM2_PolicyNameHash coupled > > > with TPM2_PolicyNV? That pins to NV index value and name, but the > > > problem is that still doesn't necessarily solve the deletion > > > problem (see below). > > > > I was thinking TPM2_PolicyAuthorizeNV and similar things too. They > > generally pin NVs by "name". > > Heh, well, you have to be careful with that one as I just discovered > with NV PINs. Most of the TPMs I have in my system actually comply > with rev 116. NV PIN was added in rev 124 and PolicyAuthorizeNV in rev > 132 which means they're not universally supported by TPM2 systems. Yeah, I am aware. In systemd we started to use TPM2_PolicyAuthorizeNV now (for implementing a PCR access policy for disk encryption that can relatively nicely handle PCR changes), but I have the luxury to simply say that this is not supported on old TPMs, and treat old TPMs like non-existing TPMs. > Yes, effectively a simple extension of the PCR system beyond 24 indexes > for anyone to use. > > > So a write policy like this should work, no: > > > > A TPM2_PolicyOR with three branches: > > 1. TPM2_PolicyCommandCode(TPM2_NV_Write) + > > TPM2_PolicyNvWritten(writtenSet=false) + > > TPM2_PolicySigned(…) > > 2. TPM2_PolicyCommandCode(TPM2_NV_Write) + > > TPM2_PolicyNvWritten(writtenSet=true) > > 3. TPM2_PolicyCommandCode(TPM2_NV_Read) > > > > (where "+" is suposed to mean AND...) > > Well, no, that would mean the entity doing the create (first write) has > to be able to sign the command. That requires a permanent secret (the > private key). The problem I have is that I want to do this in the > kernel. The kernel can generate ephemeral secrets but not permanent > ones that last across a boot and it certainly can't usefully (without > leaking) carry persistent private keys, so whatever scheme we come up > with for the kernel can't code a policy that contains a long lived > secret. These fake-PCR NVs are semi-persistent anyway (i.e. their definition is persistent, but their value is not). Hence if you allocate one NV index for this anyway, then maybe just allocated a second, and you might just store the key in it? And that other NV index uses TPM2_NV_ReadLock stuff so that it can be read during early boot, and then no more until a reset happens. I suggested this to Matthew for the hibernation stuff: store the encryption secret in an nvindex and make sure it is only accessible during kernel initialization, and not later via the read lock stuff. Lennart -- Lennart Poettering, Berlin