Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Thu, May 30, 2024 at 11:22:56PM +0200, Lennart Poettering wrote: > On Do, 30.05.24 22:43, Lennart Poettering (lenn...@poettering.net) wrote: > > > > What about combining two different secrets, such that _both_ must be > > > accessible? At a minimum, something like HASH(SECRET1||SECRET2) is > > > guaranteed to be available if and only if both SECRET1 and SECRET2 are > > > available. This won't work with TPM-bound keys that are not accessible > > > outside the TPM, but my understanding is that the most common cases > > > (LUKS and fscrypt keys and systemd credentials) must be accessible in > > > cleartext on the host _anyway_. If the secret to be sealed is provided > > > externally, then one can use symmetric encryption with a randomly > > > generated key to have the same effect. > > > > Hmm, this is an interesting idea, I kinda like it. But I am not sure > > how far this will get us, because I think even for FDE we eventually > > want to store asymmetric keys, not symmetric ones (i.e. I think we > > should start supporting things like TPM2+FIDO or TPM2+PKCS11 or > > TPM2+ssh-agent where both devices operate in tandem, in a challenge > > response model, not sure how far you get with that if we can only > > protect symmetric keys) > > Eh, I might have figured out a way how I can do this, somewhat > inspired by this: > > TPMs implement hierarchies of keys after all where each key is wrapped > by its parent, and you can apparently nest things pretty liberally, to > as many levels as one likes. > > So here's what systemd's TPM2-based FDE does right now: > > When enrolling: it ensures that a "storage root key" (SRK) exists on > the TPM. It then loads the plaintext FDE encryption key as a symmetric > key into the TPM, so that it is "wrapped" by the SRK. It then reads > back the wrapped (i.e. encrypted) key (this is called "sealing") and > writes that to the LUKS superblock. When unlocking we take that > wrapped key, load it back into the TPM and then read back the > plaintext key (this is called "unsealing"). Since the SRK is specific > to the TPM only the TPM can give us access to our FDE key. This model > is then enriched with TPM2 "extended policies" which we set while > sealing and which tell the TPM to insist that during unsealing the > PCRs are in a specific state. > > So much so good. This allows us to define *one* extended policy for the > FDE key. And as mentioned that's a problem for us, because we'd like > to define *two* extended policies (i.e. the pcrlock one, and the > signed PCR one). But if we take benefit of the fact we can wrap keys > arbitrarily we can do it like this: > > when enrolling: as before, take care of the SRK. But now generate > another key, wrapped by the SRK and with our first policy built into > it. And then seal the FDE key against that "intermediate" key, and > build our 2nd policy into that sealing. > > To unlock we then first have to load the intermediate key (which will > just work) and then load the FDE key below it (which will require us > to fulfill policy 1) and then the unseal the FDE key (which will > require us to fulfill policy 2). > > Unless I am missing something this should work and do exactly what I > want: I can combine policies arbitrarily. Does this require policies 1 and 2 to be fulfilled _at the same time_? -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab signature.asc Description: PGP signature
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Do, 30.05.24 17:08, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > Hmm, this is an interesting idea, I kinda like it. But I am not sure > > how far this will get us, because I think even for FDE we eventually > > want to store asymmetric keys, not symmetric ones (i.e. I think we > > should start supporting things like TPM2+FIDO or TPM2+PKCS11 or > > TPM2+ssh-agent where both devices operate in tandem, in a challenge > > response model, not sure how far you get with that if we can only > > protect symmetric keys) > > How would TPM2+FIDO work? chromeos is passing a nonce from the tpm to the fido device, which then signs it, which the tpm then can verify. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Do, 30.05.24 22:43, Lennart Poettering (lenn...@poettering.net) wrote: > > What about combining two different secrets, such that _both_ must be > > accessible? At a minimum, something like HASH(SECRET1||SECRET2) is > > guaranteed to be available if and only if both SECRET1 and SECRET2 are > > available. This won't work with TPM-bound keys that are not accessible > > outside the TPM, but my understanding is that the most common cases > > (LUKS and fscrypt keys and systemd credentials) must be accessible in > > cleartext on the host _anyway_. If the secret to be sealed is provided > > externally, then one can use symmetric encryption with a randomly > > generated key to have the same effect. > > Hmm, this is an interesting idea, I kinda like it. But I am not sure > how far this will get us, because I think even for FDE we eventually > want to store asymmetric keys, not symmetric ones (i.e. I think we > should start supporting things like TPM2+FIDO or TPM2+PKCS11 or > TPM2+ssh-agent where both devices operate in tandem, in a challenge > response model, not sure how far you get with that if we can only > protect symmetric keys) Eh, I might have figured out a way how I can do this, somewhat inspired by this: TPMs implement hierarchies of keys after all where each key is wrapped by its parent, and you can apparently nest things pretty liberally, to as many levels as one likes. So here's what systemd's TPM2-based FDE does right now: When enrolling: it ensures that a "storage root key" (SRK) exists on the TPM. It then loads the plaintext FDE encryption key as a symmetric key into the TPM, so that it is "wrapped" by the SRK. It then reads back the wrapped (i.e. encrypted) key (this is called "sealing") and writes that to the LUKS superblock. When unlocking we take that wrapped key, load it back into the TPM and then read back the plaintext key (this is called "unsealing"). Since the SRK is specific to the TPM only the TPM can give us access to our FDE key. This model is then enriched with TPM2 "extended policies" which we set while sealing and which tell the TPM to insist that during unsealing the PCRs are in a specific state. So much so good. This allows us to define *one* extended policy for the FDE key. And as mentioned that's a problem for us, because we'd like to define *two* extended policies (i.e. the pcrlock one, and the signed PCR one). But if we take benefit of the fact we can wrap keys arbitrarily we can do it like this: when enrolling: as before, take care of the SRK. But now generate another key, wrapped by the SRK and with our first policy built into it. And then seal the FDE key against that "intermediate" key, and build our 2nd policy into that sealing. To unlock we then first have to load the intermediate key (which will just work) and then load the FDE key below it (which will require us to fulfill policy 1) and then the unseal the FDE key (which will require us to fulfill policy 2). Unless I am missing something this should work and do exactly what I want: I can combine policies arbitrarily. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Thu, May 30, 2024 at 10:43:48PM +0200, Lennart Poettering wrote: > On Mi, 29.05.24 14:48, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > > > > > (you can of course include PolicyAuthorizeNV in the policy you sign > > > > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > > > > local nvindex really, and allocate it localy, and the signer (i.e. the > > > > > OS vendor) cannot possibly do that. Or you could include the > > > > > PolicyAuthorize in the policy you store in the nvindex for > > > > > PolicyAuthorizeNV use, but that feels much less interesting since it > > > > > means the enforcement of the combination is subject to local, > > > > > delegated policy choices instead of mandated by the policy of the > > > > > actual object we want to protect) > > > > > > this here is where i discuss what you are saying ^^^ > > > > > > so technically this works, but this means objects are effectively > > > protected by local policy only. And whether to also protect by OS vendor > > > policy is then a choice of the local policy, but not a choice of the > > > original object's policy anymore. Or in other words: that shifts > > > around who owns which part of the policy. Ideally we want that when I > > > create a protected object in the TPM I can say: "to unlock this you > > > *must* validate OS vendor policy *and* local pcrlock policy". But you > > > cannot do that. You can only say "to unlick this you *must* validate > > > local pcrlock policy", and then hope that that local policy also > > > enforces validation via OS vendor policy. > > > > What about combining two different secrets, such that _both_ must be > > accessible? At a minimum, something like HASH(SECRET1||SECRET2) is > > guaranteed to be available if and only if both SECRET1 and SECRET2 are > > available. This won't work with TPM-bound keys that are not accessible > > outside the TPM, but my understanding is that the most common cases > > (LUKS and fscrypt keys and systemd credentials) must be accessible in > > cleartext on the host _anyway_. If the secret to be sealed is provided > > externally, then one can use symmetric encryption with a randomly > > generated key to have the same effect. > > Hmm, this is an interesting idea, I kinda like it. But I am not sure > how far this will get us, because I think even for FDE we eventually > want to store asymmetric keys, not symmetric ones (i.e. I think we > should start supporting things like TPM2+FIDO or TPM2+PKCS11 or > TPM2+ssh-agent where both devices operate in tandem, in a challenge > response model, not sure how far you get with that if we can only > protect symmetric keys) How would TPM2+FIDO work? -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab signature.asc Description: PGP signature
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mi, 29.05.24 14:48, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > > > (you can of course include PolicyAuthorizeNV in the policy you sign > > > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > > > local nvindex really, and allocate it localy, and the signer (i.e. the > > > > OS vendor) cannot possibly do that. Or you could include the > > > > PolicyAuthorize in the policy you store in the nvindex for > > > > PolicyAuthorizeNV use, but that feels much less interesting since it > > > > means the enforcement of the combination is subject to local, > > > > delegated policy choices instead of mandated by the policy of the > > > > actual object we want to protect) > > > > this here is where i discuss what you are saying ^^^ > > > > so technically this works, but this means objects are effectively > > protected by local policy only. And whether to also protect by OS vendor > > policy is then a choice of the local policy, but not a choice of the > > original object's policy anymore. Or in other words: that shifts > > around who owns which part of the policy. Ideally we want that when I > > create a protected object in the TPM I can say: "to unlock this you > > *must* validate OS vendor policy *and* local pcrlock policy". But you > > cannot do that. You can only say "to unlick this you *must* validate > > local pcrlock policy", and then hope that that local policy also > > enforces validation via OS vendor policy. > > What about combining two different secrets, such that _both_ must be > accessible? At a minimum, something like HASH(SECRET1||SECRET2) is > guaranteed to be available if and only if both SECRET1 and SECRET2 are > available. This won't work with TPM-bound keys that are not accessible > outside the TPM, but my understanding is that the most common cases > (LUKS and fscrypt keys and systemd credentials) must be accessible in > cleartext on the host _anyway_. If the secret to be sealed is provided > externally, then one can use symmetric encryption with a randomly > generated key to have the same effect. Hmm, this is an interesting idea, I kinda like it. But I am not sure how far this will get us, because I think even for FDE we eventually want to store asymmetric keys, not symmetric ones (i.e. I think we should start supporting things like TPM2+FIDO or TPM2+PKCS11 or TPM2+ssh-agent where both devices operate in tandem, in a challenge response model, not sure how far you get with that if we can only protect symmetric keys) Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mi, 29.05.24 14:42, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > Hence, maybe tickets aren't the way to go, they bring complexity, they > > would make a pretty relevant feature of our policies go down the drain > > – even though they would combine the two relevant policies correctly. > > What about inserting an explicit delay into the boot process until the > ticket expires? Sorry, but no. That would be racy (since the TPM clocks are relatively inaccurate afaics, unlike system clocks). Also it's one hell of an ugly hack and given that TPMs are slow as fuck anyway and already slow down boots measurably (heh, pun!) I am sure we shouldn't try to make it even slower by inserting artificial sleeps... Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Wed, May 29, 2024 at 04:54:13PM +0200, Lennart Poettering wrote: > On Mi, 29.05.24 17:00, Andrei Borzenkov (arvidj...@gmail.com) wrote: > > > If you use pcrlock for more flexibility it will change into > > > > PolicyPCR(PCR1, PCR2, ...) > > PolicyAuthorize > > PolicyPCR(PCR3, PCR4, ...) > > PolicyOR(digest1, digest2, ...) > > PolicyAuthorizeNV > > Unseal > > When you do this then the policy made up of the three expressions in > the middle would have to be stored in the nvindex. Which you > definitely can do, and this is exactly what I discussed below, see > below: > > > > (you can of course include PolicyAuthorizeNV in the policy you sign > > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > > local nvindex really, and allocate it localy, and the signer (i.e. the > > > OS vendor) cannot possibly do that. Or you could include the > > > PolicyAuthorize in the policy you store in the nvindex for > > > PolicyAuthorizeNV use, but that feels much less interesting since it > > > means the enforcement of the combination is subject to local, > > > delegated policy choices instead of mandated by the policy of the > > > actual object we want to protect) > > this here is where i discuss what you are saying ^^^ > > so technically this works, but this means objects are effectively > protected by local policy only. And whether to also protect by OS vendor > policy is then a choice of the local policy, but not a choice of the > original object's policy anymore. Or in other words: that shifts > around who owns which part of the policy. Ideally we want that when I > create a protected object in the TPM I can say: "to unlock this you > *must* validate OS vendor policy *and* local pcrlock policy". But you > cannot do that. You can only say "to unlick this you *must* validate > local pcrlock policy", and then hope that that local policy also > enforces validation via OS vendor policy. What about combining two different secrets, such that _both_ must be accessible? At a minimum, something like HASH(SECRET1||SECRET2) is guaranteed to be available if and only if both SECRET1 and SECRET2 are available. This won't work with TPM-bound keys that are not accessible outside the TPM, but my understanding is that the most common cases (LUKS and fscrypt keys and systemd credentials) must be accessible in cleartext on the host _anyway_. If the secret to be sealed is provided externally, then one can use symmetric encryption with a randomly generated key to have the same effect. -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab signature.asc Description: PGP signature
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Wed, May 29, 2024 at 10:36:28AM +0200, Lennart Poettering wrote: > On Di, 28.05.24 17:36, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > > > (you can of course include PolicyAuthorizeNV in the policy you sign > > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > > local nvindex really, and allocate it localy, and the signer (i.e. the > > > OS vendor) cannot possibly do that. Or you could include the > > > PolicyAuthorize in the policy you store in the nvindex for > > > PolicyAuthorizeNV use, but that feels much less interesting since it > > > means the enforcement of the combination is subject to local, > > > delegated policy choices instead of mandated by the policy of the > > > actual object we want to protect) > > > > Does this work in practice? I agree that this is ugly, but "ugly" might > > be better than "not working". > > Well, it should work. I am still not ready to give up on finding a > better solution to this. For example, I have some vague hopes that we > can make TPM "tickets" work for this. > > As I understand tickets would allow us to validate policies once, > which would give us a "ticket" back for that that is valid for a > specific time. Then we can bind the policies of other objects to the > availibility of such valid tickets, and then combine two ticket > validations that way. > > Superficially that would do what we need. i.e. if I get one ticket for > the signed PCR policy (i.e. for the PolicyAuthorize thing) and another > ticket for the pcrlock policy (i.e. the PolcyAuhtorizeNV thing) then I > can build a policy checking both tickets and be fine. > > Except that things aren't that easy (well, the above isn't precisely > "easy" either), because suddenly a time-out comes into play, and we > lose this nice "fuse blowing" feature of PCRs: i.e. while we boot we > measure the boot phase into PCR 11 after all, to ensure that secrets > that shall only be possible to be unlocked in — let's say – the initrd > cannot possibly be unlocked any later, because the PCR is "destroyed" > via the later phase measurement. If we use tickets we could still > unlock things till the end of the timeout, which we probably have to > pick large because of differences of boot speeds, hence this > compromises security quite a bit I'd say. > > Hence, maybe tickets aren't the way to go, they bring complexity, they > would make a pretty relevant feature of our policies go down the drain > – even though they would combine the two relevant policies correctly. What about inserting an explicit delay into the boot process until the ticket expires? -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab signature.asc Description: PGP signature
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mi, 29.05.24 17:00, Andrei Borzenkov (arvidj...@gmail.com) wrote: > If you use pcrlock for more flexibility it will change into > > PolicyPCR(PCR1, PCR2, ...) > PolicyAuthorize > PolicyPCR(PCR3, PCR4, ...) > PolicyOR(digest1, digest2, ...) > PolicyAuthorizeNV > Unseal When you do this then the policy made up of the three expressions in the middle would have to be stored in the nvindex. Which you definitely can do, and this is exactly what I discussed below, see below: > > (you can of course include PolicyAuthorizeNV in the policy you sign > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > local nvindex really, and allocate it localy, and the signer (i.e. the > > OS vendor) cannot possibly do that. Or you could include the > > PolicyAuthorize in the policy you store in the nvindex for > > PolicyAuthorizeNV use, but that feels much less interesting since it > > means the enforcement of the combination is subject to local, > > delegated policy choices instead of mandated by the policy of the > > actual object we want to protect) this here is where i discuss what you are saying ^^^ so technically this works, but this means objects are effectively protected by local policy only. And whether to also protect by OS vendor policy is then a choice of the local policy, but not a choice of the original object's policy anymore. Or in other words: that shifts around who owns which part of the policy. Ideally we want that when I create a protected object in the TPM I can say: "to unlock this you *must* validate OS vendor policy *and* local pcrlock policy". But you cannot do that. You can only say "to unlick this you *must* validate local pcrlock policy", and then hope that that local policy also enforces validation via OS vendor policy. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Tue, May 28, 2024 at 10:55 PM Lennart Poettering wrote: > > On Di, 28.05.24 21:21, Andrei Borzenkov (arvidj...@gmail.com) wrote: > > > On 28.05.2024 17:49, Lennart Poettering wrote: > > > > > > systemd-cryptenroll supports pin, literal PCR, signed PCR — in any > > > combination. (plus pcrlock, but that's currently cannot be combined > > > with signed PCR, because afaics not expressible in the TPM policy > > > language). > > > > > > > Why not? You can AND pcrlock with other policies just like currently literal > > PCR is ANDed with signed PCR. You can even use signed PCR in pcrlock policy > > - PolicyOR does not care what policies are combined, literal PCR (like is > > done currently) or signed PCR. Or what semantic do you have in mind that > > cannot be expressed? > > pcrlock is ultimately a PolicyAuthorizeNV policy, and signed policies > use PolicyAuthorize. Both of these policy items do not *extend* the > policy so far enqueued, but *replace* it instead. (This is different > from policies such as PolicyPCR or PolicyAuthValue and so on, which > result in extension, i.e. "AND") Thus, there's not directly obvious > way how you could combine them. > And? You *already* combine PolicyAuthorize with subsequent PolicyPCR, that is exactly how you build a policy if both tpm2-pcrs and tpm2-public-key-pcrs are provided. You already use PolicyOR (which *replaces* the policy as well) in pcrlock. Why is it not a problem? What you have now is PolicyPCR(PCR1, PCR2, ...) PolicyAuthorize PolicyPCR(PCR3, PCR4, ...) Unseal If you use pcrlock for more flexibility it will change into PolicyPCR(PCR1, PCR2, ...) PolicyAuthorize PolicyPCR(PCR3, PCR4, ...) PolicyOR(digest1, digest2, ...) PolicyAuthorizeNV Unseal I am sorry, I still miss the problem. Why is the former acceptable but the latter is not? Where is the difference? The reverse order is indeed more challenging. In this case we would need to effectively sign a digest that indirectly includes pcrlock PCRs which rather defeats the idea of separating the local registers from remotely controlled ones. > (you can of course include PolicyAuthorizeNV in the policy you sign > for PolicyAuthorize, but that doesn#t work, since we want to pin the > local nvindex really, and allocate it localy, and the signer (i.e. the > OS vendor) cannot possibly do that. Or you could include the > PolicyAuthorize in the policy you store in the nvindex for > PolicyAuthorizeNV use, but that feels much less interesting since it > means the enforcement of the combination is subject to local, > delegated policy choices instead of mandated by the policy of the > actual object we want to protect) > > I have so far not found a nice way out of this problem. Seems to be a > limitation of the TPM policy language. > > Lennart > > -- > Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mi, 29.05.24 10:36, Lennart Poettering (lenn...@poettering.net) wrote: > But still, I am not ready to give up, there must be some other way I > think, that I have missed so far. I posted this on the tpm2-tss ML now: https://lore.kernel.org/tpm2/ZlbtJ0jcy8rrUbUg@gardel-login/T/#u Maybe they have an idea what we can do. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Di, 28.05.24 17:36, Demi Marie Obenour (d...@invisiblethingslab.com) wrote: > > (you can of course include PolicyAuthorizeNV in the policy you sign > > for PolicyAuthorize, but that doesn#t work, since we want to pin the > > local nvindex really, and allocate it localy, and the signer (i.e. the > > OS vendor) cannot possibly do that. Or you could include the > > PolicyAuthorize in the policy you store in the nvindex for > > PolicyAuthorizeNV use, but that feels much less interesting since it > > means the enforcement of the combination is subject to local, > > delegated policy choices instead of mandated by the policy of the > > actual object we want to protect) > > Does this work in practice? I agree that this is ugly, but "ugly" might > be better than "not working". Well, it should work. I am still not ready to give up on finding a better solution to this. For example, I have some vague hopes that we can make TPM "tickets" work for this. As I understand tickets would allow us to validate policies once, which would give us a "ticket" back for that that is valid for a specific time. Then we can bind the policies of other objects to the availibility of such valid tickets, and then combine two ticket validations that way. Superficially that would do what we need. i.e. if I get one ticket for the signed PCR policy (i.e. for the PolicyAuthorize thing) and another ticket for the pcrlock policy (i.e. the PolcyAuhtorizeNV thing) then I can build a policy checking both tickets and be fine. Except that things aren't that easy (well, the above isn't precisely "easy" either), because suddenly a time-out comes into play, and we lose this nice "fuse blowing" feature of PCRs: i.e. while we boot we measure the boot phase into PCR 11 after all, to ensure that secrets that shall only be possible to be unlocked in — let's say – the initrd cannot possibly be unlocked any later, because the PCR is "destroyed" via the later phase measurement. If we use tickets we could still unlock things till the end of the timeout, which we probably have to pick large because of differences of boot speeds, hence this compromises security quite a bit I'd say. Hence, maybe tickets aren't the way to go, they bring complexity, they would make a pretty relevant feature of our policies go down the drain – even though they would combine the two relevant policies correctly. But still, I am not ready to give up, there must be some other way I think, that I have missed so far. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Tue, May 28, 2024 at 09:55:36PM +0200, Lennart Poettering wrote: > On Di, 28.05.24 21:21, Andrei Borzenkov (arvidj...@gmail.com) wrote: > > > On 28.05.2024 17:49, Lennart Poettering wrote: > > > > > > systemd-cryptenroll supports pin, literal PCR, signed PCR — in any > > > combination. (plus pcrlock, but that's currently cannot be combined > > > with signed PCR, because afaics not expressible in the TPM policy > > > language). > > > > > > > Why not? You can AND pcrlock with other policies just like currently literal > > PCR is ANDed with signed PCR. You can even use signed PCR in pcrlock policy > > - PolicyOR does not care what policies are combined, literal PCR (like is > > done currently) or signed PCR. Or what semantic do you have in mind that > > cannot be expressed? > > pcrlock is ultimately a PolicyAuthorizeNV policy, and signed policies > use PolicyAuthorize. Both of these policy items do not *extend* the > policy so far enqueued, but *replace* it instead. (This is different > from policies such as PolicyPCR or PolicyAuthValue and so on, which > result in extension, i.e. "AND") Thus, there's not directly obvious > way how you could combine them. > > (you can of course include PolicyAuthorizeNV in the policy you sign > for PolicyAuthorize, but that doesn#t work, since we want to pin the > local nvindex really, and allocate it localy, and the signer (i.e. the > OS vendor) cannot possibly do that. Or you could include the > PolicyAuthorize in the policy you store in the nvindex for > PolicyAuthorizeNV use, but that feels much less interesting since it > means the enforcement of the combination is subject to local, > delegated policy choices instead of mandated by the policy of the > actual object we want to protect) Does this work in practice? I agree that this is ugly, but "ugly" might be better than "not working". > I have so far not found a nice way out of this problem. Seems to be a > limitation of the TPM policy language. > > Lennart -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab signature.asc Description: PGP signature
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Di, 28.05.24 21:21, Andrei Borzenkov (arvidj...@gmail.com) wrote: > On 28.05.2024 17:49, Lennart Poettering wrote: > > > > systemd-cryptenroll supports pin, literal PCR, signed PCR — in any > > combination. (plus pcrlock, but that's currently cannot be combined > > with signed PCR, because afaics not expressible in the TPM policy language). > > > > Why not? You can AND pcrlock with other policies just like currently literal > PCR is ANDed with signed PCR. You can even use signed PCR in pcrlock policy > - PolicyOR does not care what policies are combined, literal PCR (like is > done currently) or signed PCR. Or what semantic do you have in mind that > cannot be expressed? pcrlock is ultimately a PolicyAuthorizeNV policy, and signed policies use PolicyAuthorize. Both of these policy items do not *extend* the policy so far enqueued, but *replace* it instead. (This is different from policies such as PolicyPCR or PolicyAuthValue and so on, which result in extension, i.e. "AND") Thus, there's not directly obvious way how you could combine them. (you can of course include PolicyAuthorizeNV in the policy you sign for PolicyAuthorize, but that doesn#t work, since we want to pin the local nvindex really, and allocate it localy, and the signer (i.e. the OS vendor) cannot possibly do that. Or you could include the PolicyAuthorize in the policy you store in the nvindex for PolicyAuthorizeNV use, but that feels much less interesting since it means the enforcement of the combination is subject to local, delegated policy choices instead of mandated by the policy of the actual object we want to protect) I have so far not found a nice way out of this problem. Seems to be a limitation of the TPM policy language. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On 28.05.2024 17:49, Lennart Poettering wrote: systemd-cryptenroll supports pin, literal PCR, signed PCR — in any combination. (plus pcrlock, but that's currently cannot be combined with signed PCR, because afaics not expressible in the TPM policy language). Why not? You can AND pcrlock with other policies just like currently literal PCR is ANDed with signed PCR. You can even use signed PCR in pcrlock policy - PolicyOR does not care what policies are combined, literal PCR (like is done currently) or signed PCR. Or what semantic do you have in mind that cannot be expressed?
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mo, 27.05.24 22:42, Aleksandar Kostadinov (akost...@redhat.com) wrote: > > if you want to use literal PCR policies like clevis does it, systemd > > can do that for you just fine? > > clevis combines multiple methods and combinations. Like pin, PCRs (not > signing), tang servers, but can be combined in different ways. systemd-cryptenroll supports pin, literal PCR, signed PCR — in any combination. (plus pcrlock, but that's currently cannot be combined with signed PCR, because afaics not expressible in the TPM policy language). > > > P.S. also would be great if systemd also supported tang so that both - > > > signed PCRs and tang to be required for automatic unlock. > > > > I am not convinced networked unlock with really is something > > relevant for anyone but a select few folks who run major data centers > > and are willing to pay the price for doing the work. It's also just a > > bunch of shell scripts last time I looked, or did that change? If so, > > doubly uninterested. > > Actually my use case is to keep a remote private server where I was > concerned about somebody taking the hardware away. So the network > policy based encryption pretty much covered my main concerns. + TPM to > make local data access more difficult but I don't really see this as a > likely threat. And you can build the tang server with a raspberry or > install it on an openrwt router. So definitely something close to > trivial for anybody building a home server. > > I didn't go in depth into how tang and clevis worked. `tang` (the > server https://github.com/latchset/tang) seems to be using a lot of c > but also a lot of shell. If it is good for big datacenters, then it > should be fine for me also. The relevant pieces are all glued-together shell scripts: https://github.com/latchset/clevis/blob/master/src/pins/tpm2/clevis-decrypt-tpm2 Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mon, May 27, 2024 at 5:02 PM Lennart Poettering wrote: > > On Mo, 27.05.24 14:47, Aleksandar Kostadinov (akost...@redhat.com) wrote: > > > Excuse me for top-posting but I can second that. Earlier I had a long > > thread about not being able to get the signed PCRs work, I never > > figured out that a signature was only created for 11. > > > > It would really help people not to lose their time if documentation > > stated - there be dragons, go only if you want to become a TPM > > low-level details and linux boot expert. > > > > Eventually I went with clevis and tang. Although if systemd allowed > > signing with more PCRs, that would definitely be very useful. > > clevis/tang does not allow signing PCRs, last time I looked. > > It's really not comparable. I know > if you want to use literal PCR policies like clevis does it, systemd > can do that for you just fine? clevis combines multiple methods and combinations. Like pin, PCRs (not signing), tang servers, but can be combined in different ways. > systemd-cryptenroll --tpm2-pcrs= is for literal PCR enrollments. > > You can combine that with --tpm2-public-key= stuff for PCR 11. This could be a reasonable option. Because they are not supposed to change. For now I'm good though. I'll rather wait for TPM support to mature. > > If somebody from systemd team managed to use signed PCRs to unlock > > together with the new systemd-pcrlock for non-11 PCRs, please write a > > short how to install and what to do by kernel upgrade. Presently it is > > not usable for regular or advanced users. Which is fine as long the > > documentation doesn't suggest it is (and it presently does). > > Yeah, I want a pony too, and I keep demanding one, but noone gives one > to me for free. Weird. It's not the problem that there was no pony. It appears that multiple people didn't understand there were dragons over there. > Honestly, maybe dial down your expectations a bit, both of you. All > this TPM support in systemd is fairly new, and it's definitely not > user facing stuff anyway (hence super-friendly docs are *not* my > priority, sorry, got enough on my plate), it's something distros > should integrate and we are only at the beginning of that path. I understand very well how oss works. The tone of some emails was a little bit over the top, I wouldn't use it. On the other hand I can very well understand the frustration. Just stating the facts. Of course you owe nothing to anybody and you can give a sh*t or not give a sh*t about user's perception. That's your choice. I thought there was a value in stating user perception. I mean value for the project and project maintainers. If you don't find value in this, feel free to ignore. > And complaining that things aren't just polished yet is certainly not > helping anyone to get the tiniest step ahead on that path. It just > annoys the people who you apparently believe work for you for free. I don't think I thought anybody worked for me. Many projects are interested in feedback especially for new features. I think specific points were raised that can help polish the feature. If you don't have time for this feature now and/or you don't find the feedback valuable, then feel free to ignore. I hold no offence. Again, I only stated my perception as a user. (namely that it might be documented more clearly that this feature is under limited and not for the faint hearted) Eventually my other thread was ignored and I didn't start blaming anybody. I understood nobody was willing to help me with these and decided on the most sensible way to proceed according to my needs. So please don't take offence. Nobody or at least I don't blame you. > > P.S. also would be great if systemd also supported tang so that both - > > signed PCRs and tang to be required for automatic unlock. > > I am not convinced networked unlock with really is something > relevant for anyone but a select few folks who run major data centers > and are willing to pay the price for doing the work. It's also just a > bunch of shell scripts last time I looked, or did that change? If so, > doubly uninterested. Actually my use case is to keep a remote private server where I was concerned about somebody taking the hardware away. So the network policy based encryption pretty much covered my main concerns. + TPM to make local data access more difficult but I don't really see this as a likely threat. And you can build the tang server with a raspberry or install it on an openrwt router. So definitely something close to trivial for anybody building a home server. I didn't go in depth into how tang and clevis worked. `tang` (the server https://github.com/latchset/tang) seems to be using a lot of c but also a lot of shell. If it is good for big datacenters, then it should be fine for me also. > Lennart > > -- > Lennart Poettering, Berlin >
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mo, 27.05.24 14:47, Aleksandar Kostadinov (akost...@redhat.com) wrote: > Excuse me for top-posting but I can second that. Earlier I had a long > thread about not being able to get the signed PCRs work, I never > figured out that a signature was only created for 11. > > It would really help people not to lose their time if documentation > stated - there be dragons, go only if you want to become a TPM > low-level details and linux boot expert. > > Eventually I went with clevis and tang. Although if systemd allowed > signing with more PCRs, that would definitely be very useful. clevis/tang does not allow signing PCRs, last time I looked. It's really not comparable. if you want to use literal PCR policies like clevis does it, systemd can do that for you just fine? systemd-cryptenroll --tpm2-pcrs= is for literal PCR enrollments. You can combine that with --tpm2-public-key= stuff for PCR 11. > If somebody from systemd team managed to use signed PCRs to unlock > together with the new systemd-pcrlock for non-11 PCRs, please write a > short how to install and what to do by kernel upgrade. Presently it is > not usable for regular or advanced users. Which is fine as long the > documentation doesn't suggest it is (and it presently does). Yeah, I want a pony too, and I keep demanding one, but noone gives one to me for free. Weird. Honestly, maybe dial down your expectations a bit, both of you. All this TPM support in systemd is fairly new, and it's definitely not user facing stuff anyway (hence super-friendly docs are *not* my priority, sorry, got enough on my plate), it's something distros should integrate and we are only at the beginning of that path. And complaining that things aren't just polished yet is certainly not helping anyone to get the tiniest step ahead on that path. It just annoys the people who you apparently believe work for you for free. > P.S. also would be great if systemd also supported tang so that both - > signed PCRs and tang to be required for automatic unlock. I am not convinced networked unlock with really is something relevant for anyone but a select few folks who run major data centers and are willing to pay the price for doing the work. It's also just a bunch of shell scripts last time I looked, or did that change? If so, doubly uninterested. Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
Excuse me for top-posting but I can second that. Earlier I had a long thread about not being able to get the signed PCRs work, I never figured out that a signature was only created for 11. It would really help people not to lose their time if documentation stated - there be dragons, go only if you want to become a TPM low-level details and linux boot expert. Eventually I went with clevis and tang. Although if systemd allowed signing with more PCRs, that would definitely be very useful. If somebody from systemd team managed to use signed PCRs to unlock together with the new systemd-pcrlock for non-11 PCRs, please write a short how to install and what to do by kernel upgrade. Presently it is not usable for regular or advanced users. Which is fine as long the documentation doesn't suggest it is (and it presently does). P.S. also would be great if systemd also supported tang so that both - signed PCRs and tang to be required for automatic unlock. On Mon, May 27, 2024 at 11:44 AM Andrei Borzenkov wrote: > > On Mon, May 27, 2024 at 11:17 AM Lennart Poettering > wrote: > > > > On Sa, 25.05.24 13:23, Andrei Borzenkov (arvidj...@gmail.com) wrote: > > > > > These are PCRs for which you intend to provide signed policy. These PCRs > > > must be listed in JSON file that is given to systemd-cryptsetup as > > > tpm2-signature= parameter. The only PCR for which there is systemd tool to > > > compute it is PCR 11. You should be able to add other PCRs to this JSON > > > file > > > and it should work, but you will need to compute the values yourself. > > > > > > Unfortunately, this is yet another case where systemd pretends to be > > > generic > > > while in reality it is not. > > > > Hmm, where do we pretend anything? > > > > By allowing users to specify different PCRs than PCR 11 without > providing any way to actually provide necessary information in the > format that is expected. Or documenting this format if the answer is > "you need to do it yourself". > > If the only PCR that can be practically used is PCR 11 anyway, then > --tpm2-public-key-pcrs= is simply redundant and confusing. > > > We give you a tool to predict/sign the measurements for PCR 11 because > > we can just do that from the UKI. For other PCRs it's a very different > > story however. > > > > That is exactly what I mean. The whole implementation of signed policy > was done for UKI only but the documentation looks like it is generic. > > Nobody demands a tool to predict PCR values. But if I do have PCR > values, there is no tool to pack them into tpm2-pcr-signature.json. > > > (And we do provide a tool for that too nowadays btw, i.e. systemd-pcrlock). > > > > That is a different story altogether. It is much better than raw PCR > policy for local use, but signed policy allows centrally managing > trusted values. If there is a way to tell systemd-pcrlock to only > accept PCR values coming from the trusted source I missed it. >
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Mon, May 27, 2024 at 11:17 AM Lennart Poettering wrote: > > On Sa, 25.05.24 13:23, Andrei Borzenkov (arvidj...@gmail.com) wrote: > > > These are PCRs for which you intend to provide signed policy. These PCRs > > must be listed in JSON file that is given to systemd-cryptsetup as > > tpm2-signature= parameter. The only PCR for which there is systemd tool to > > compute it is PCR 11. You should be able to add other PCRs to this JSON file > > and it should work, but you will need to compute the values yourself. > > > > Unfortunately, this is yet another case where systemd pretends to be generic > > while in reality it is not. > > Hmm, where do we pretend anything? > By allowing users to specify different PCRs than PCR 11 without providing any way to actually provide necessary information in the format that is expected. Or documenting this format if the answer is "you need to do it yourself". If the only PCR that can be practically used is PCR 11 anyway, then --tpm2-public-key-pcrs= is simply redundant and confusing. > We give you a tool to predict/sign the measurements for PCR 11 because > we can just do that from the UKI. For other PCRs it's a very different > story however. > That is exactly what I mean. The whole implementation of signed policy was done for UKI only but the documentation looks like it is generic. Nobody demands a tool to predict PCR values. But if I do have PCR values, there is no tool to pack them into tpm2-pcr-signature.json. > (And we do provide a tool for that too nowadays btw, i.e. systemd-pcrlock). > That is a different story altogether. It is much better than raw PCR policy for local use, but signed policy allows centrally managing trusted values. If there is a way to tell systemd-pcrlock to only accept PCR values coming from the trusted source I missed it.
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Sa, 25.05.24 13:23, Andrei Borzenkov (arvidj...@gmail.com) wrote: > These are PCRs for which you intend to provide signed policy. These PCRs > must be listed in JSON file that is given to systemd-cryptsetup as > tpm2-signature= parameter. The only PCR for which there is systemd tool to > compute it is PCR 11. You should be able to add other PCRs to this JSON file > and it should work, but you will need to compute the values yourself. > > Unfortunately, this is yet another case where systemd pretends to be generic > while in reality it is not. Hmm, where do we pretend anything? We give you a tool to predict/sign the measurements for PCR 11 because we can just do that from the UKI. For other PCRs it's a very different story however. (And we do provide a tool for that too nowadays btw, i.e. systemd-pcrlock). Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On Sa, 25.05.24 09:00, Felix Rubio (fe...@kngnt.org) wrote: > Hi everybody, > > For some time now I have been using UKIs, with SB enabled and tying FDE > decryption on PCRs 7+11+14, with the PCR 11 being measured during UKI > creation. Then, I use systemd-cryptenroll to update the secret: > > > PCR11=$(/usr/lib/systemd/ukify -c /etc/kernel/uki.conf --measure > --output=/tmp/arch-linux.efi build | grep 11:sha256) > systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt > --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7+11:sha256=d05ee4...+14 > /dev/nvme0n1p5 > > > This works, flawlessly. Now, I am exploring the possibility to not bind to > the value of those PCRS but to their signature, given that I am also > embedding that in the UKI (the correspondent .pcrsig section is in place). > However, I am a bit lost: > * in .pcrsig there is only the signature for pcr11, and there seems to be no > way to embed the signatures for other PCR values. systemd-measure/ukify doesn't support embedding anything else, since those measurements do not depend on the UKI but on external factors, hence it makes little sense to include them in the UKI pcrsig section, except for specialist cases where you know your hardware/systemd very well and never update it separately from the kernel. > * when used in cryptenroll, how should I use this? So far, seems should be a > call like > > systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt > --wipe-slot=tpm2 --tpm2-device=auto > --tpm2-public-key=/root/creds/tpm2-pcr-public.pem > --tpm2-public-key-pcrs= > > > ... but then I do not see what should be provided in tpm2-public-key-pcrs. > The same values I am currently giving to --tpm2-pcrs? the signatures that I > get from the .pcrsig for 11 + the calculated signatures for the current > values of the PCRs 7 and 14? You can specify whatever you like there, as long as you then can provide the right signature files. Thing though is that systemd-measure/ukify won't prep those signatures for you, you'd have to use a different tool for that. (Or prep a patch teaching literal PCR specifications in systemd-measure, we would be open to merging this I guess). Or in other words: there are three parts to signed PCR policies: 1. enrollment 2. unlocking 3. signing Of these steps 1 + 2 as implemented in systemd should just work for PCRs other than 11. But step 3 is simply not. That all said, With recent systemd versions we added "systemd-pcrlock" that is supposed to cover other PCRs than 11 nicely, maintaining a local policy (which I think is much preferable for the other PCRs, since they are dependent on local configuration, hardware and so on, not OS constructs). Lennart -- Lennart Poettering, Berlin
Re: [systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
On 25.05.2024 10:00, Felix Rubio wrote: Hi everybody, For some time now I have been using UKIs, with SB enabled and tying FDE decryption on PCRs 7+11+14, with the PCR 11 being measured during UKI creation. Then, I use systemd-cryptenroll to update the secret: PCR11=$(/usr/lib/systemd/ukify -c /etc/kernel/uki.conf --measure --output=/tmp/arch-linux.efi build | grep 11:sha256) systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7+11:sha256=d05ee4...+14 /dev/nvme0n1p5 This works, flawlessly. Now, I am exploring the possibility to not bind to the value of those PCRS but to their signature, given that I am also embedding that in the UKI (the correspondent .pcrsig section is in place). However, I am a bit lost: * in .pcrsig there is only the signature for pcr11, and there seems to be no way to embed the signatures for other PCR values. systemd-measure/ukify is only intended for measuring UKI in PCR 11. * when used in cryptenroll, how should I use this? So far, seems should be a call like systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt --wipe-slot=tpm2 --tpm2-device=auto --tpm2-public-key=/root/creds/tpm2-pcr-public.pem --tpm2-public-key-pcrs= ... but then I do not see what should be provided in tpm2-public-key-pcrs. These are PCRs for which you intend to provide signed policy. These PCRs must be listed in JSON file that is given to systemd-cryptsetup as tpm2-signature= parameter. The only PCR for which there is systemd tool to compute it is PCR 11. You should be able to add other PCRs to this JSON file and it should work, but you will need to compute the values yourself. Unfortunately, this is yet another case where systemd pretends to be generic while in reality it is not. Another problem is that systemd will silently add the literal PCR policy for PCR 7 *in addition* to the signed policy you specify. See https://github.com/systemd/systemd/issues/32946. The same values I am currently giving to --tpm2-pcrs? Only PCR11 will work as it is the only PCR for which systemd-measure will create the signature file. Other PCRs can additionally be used in --tpm2-pcrs, but that sort of invalidates the whole point of the signed policy. You may consider using systemd-pcrlock instead. the signatures that I get from the .pcrsig for 11 + the calculated signatures for the current values of the PCRs 7 and 14? Thank you very much for your time, -- Felix Rubio
[systemd-devel] PCR signing / enrolling on UKI and validation by systemd-cryptenroll
Hi everybody, For some time now I have been using UKIs, with SB enabled and tying FDE decryption on PCRs 7+11+14, with the PCR 11 being measured during UKI creation. Then, I use systemd-cryptenroll to update the secret: PCR11=$(/usr/lib/systemd/ukify -c /etc/kernel/uki.conf --measure --output=/tmp/arch-linux.efi build | grep 11:sha256) systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7+11:sha256=d05ee4...+14 /dev/nvme0n1p5 This works, flawlessly. Now, I am exploring the possibility to not bind to the value of those PCRS but to their signature, given that I am also embedding that in the UKI (the correspondent .pcrsig section is in place). However, I am a bit lost: * in .pcrsig there is only the signature for pcr11, and there seems to be no way to embed the signatures for other PCR values. * when used in cryptenroll, how should I use this? So far, seems should be a call like systemd-cryptenroll --unlock-key-file=/root/creds/fdepassword.txt --wipe-slot=tpm2 --tpm2-device=auto --tpm2-public-key=/root/creds/tpm2-pcr-public.pem --tpm2-public-key-pcrs= ... but then I do not see what should be provided in tpm2-public-key-pcrs. The same values I am currently giving to --tpm2-pcrs? the signatures that I get from the .pcrsig for 11 + the calculated signatures for the current values of the PCRs 7 and 14? Thank you very much for your time, -- Felix Rubio