FDE in MicroOS and Tumbleweed: pcrlock update
Hi, after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism! In December we described[3] how we implemented in MicroOS (and later in Tumbleweed) a solution for FDE that uses the TPM2 or the FIDO2 key to unlock the LUKS2 root device, using only the systemd user space tools. To generate the predictions of the PCRs values, we used the in-house pcr-oracle application, that we extended to support the generation of signed policies in JSON format, that systemd-cryptenroll and systemd-cryptsetup use to seal and unseal the key that will open the encrypted LUK2 device in our system. Two weekends ago something changed: openSUSE released systemd v255, that now support the generation of policies using the new experimental tool systemd-pcrlock[4]. pcrlock proposes a different approach to the generation of TPM2 policies. Instead of signed policies (which requires the generation of a RSA key pair that is used to sign the PCR policy to make it independent of the sealed key), pcrlock uses NVIndex policies. Those are basically policies that are stored inside the non-volatile RAM that the TPM2 provides. The policy is now stored inside the TPM2, and the index can only be changed if the policy itself is meet. The new pcrlock tool is also quite handy. It can generate the predictions (some small .pcrlock files stored in /var) of each component (firmware, bootloader, kernel, raw files, etc), and also present all the extensions of the PCR registered in the event log in a very nice way! The architecture is sound, but there is a systemd-pcrlock bug[5] that fails when measuring large initrd files. This has an implication only on the first boot, as the initial initrd is for now ignored, discarding initially PCR9. This is automatically fixed in the next update, but can also be manually fixed if the user reboot using the new smaller initrd, and later call `sdbootutil update-predictions`. Anyway, we extended the tools to support the pcrlock mechanism now. For new installations, if pcrlock is supported it will be preferred instead of the signed policies. The team is still working on more interesting stuff for later: we are making good progress in turning the distribution independent of the boot loader. We can use exactly this same FDE mechanism (signed policies or NVIndex policies) using systemd-boot or GRUB2 (with BLS patches). More on that in the next announcement! [1] https://lists.opensuse.org/archives/list/factory@lists.opensuse.org/message/... [2] https://lists.opensuse.org/archives/list/factory@lists.opensuse.org/thread/W... [3] https://news.opensuse.org/2023/12/20/systemd-fde [4] https://www.freedesktop.org/software/systemd/man/latest/systemd-pcrlock.html [5] https://github.com/systemd/systemd/issues/31883
On 2024-03-27 15:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
[...] I should mention that the images are in the usual place for MicroOS[1] and Tumbleweed[2] [1] https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-... [2] https://download.opensuse.org/tumbleweed/appliances/openSUSE-Tumbleweed-Mini...
On 27.03.2024 18:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
Can existing images be updated?
On 2024-03-27 17:19, Andrei Borzenkov wrote:
On 27.03.2024 18:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
Can existing images be updated?
The new images support both models (pcr-oracle and systemd-pcrlock), but there is not automatic migration path. The reason is that ideally we will support only the pcrlock model after we settle all (grub2, systemd 256, yast, and other components) I can prepare an update to sdbootutil that will do the migration from pcr-oracle to pcrlock, or at least I will document how it can be done manually (is as simple as removing the tpm2-* files from the ESP and /var and calling `sdbootutil update-predictions`)
On 27.03.2024 20:26, aplanas wrote:
On 2024-03-27 17:19, Andrei Borzenkov wrote:
On 27.03.2024 18:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
Can existing images be updated?
The new images support both models (pcr-oracle and systemd-pcrlock), but there is not automatic migration path. The reason is that ideally we will support only the pcrlock model after we settle all (grub2, systemd 256, yast, and other components)
I can prepare an update to sdbootutil that will do the migration from pcr-oracle to pcrlock, or at least I will document how it can be done manually (is as simple as removing the tpm2-* files from the ESP and /var and calling `sdbootutil update-predictions`)
You mean - after sdbootutil has been updated? Is systemd-pcrlock affected by https://bugzilla.suse.com/show_bug.cgi?id=1219807?
On 2024-03-27 17:38, Andrei Borzenkov wrote:
On 27.03.2024 20:26, aplanas wrote:
I can prepare an update to sdbootutil that will do the migration from pcr-oracle to pcrlock, or at least I will document how it can be done manually (is as simple as removing the tpm2-* files from the ESP and /var and calling `sdbootutil update-predictions`)
You mean - after sdbootutil has been updated?
Yes. The new sdbootutil contains now a set of calls to pcrlock, that will generate the predictions. For that will check before that is not already a signed policy systemd (pcr-oracle). So removing the files will now generate the .pcrlock files and insert in the TPM2 the policy.
Is systemd-pcrlock affected by https://bugzilla.suse.com/show_bug.cgi?id=1219807?
The one about secure boot was fixed (workaround really) in an already release of pcr-oracle, so the current user should not experience the original bug. Do you still experience this one? But about your question: no, pcrlock uses a different mechanism to guess the meaning of an extension in the event log. With pcr-oracle we use the tags and the data of the event to guess what that means (so the error is that shim removes part of this data), but pcrlock use the components and variants that contain the hash. If pcrlock find the hash in the event log in one of those components or variants, the bijection is done. You can validate this mapping with systemd-pcrlock itself as it will indicate what .pcrlock file has this hash (or at least one of the variants)
On 27.03.2024 21:19, aplanas wrote:
On 2024-03-27 17:38, Andrei Borzenkov wrote:
On 27.03.2024 20:26, aplanas wrote:
I can prepare an update to sdbootutil that will do the migration from pcr-oracle to pcrlock, or at least I will document how it can be done manually (is as simple as removing the tpm2-* files from the ESP and /var and calling `sdbootutil update-predictions`)
You mean - after sdbootutil has been updated?
Yes.
There are no tpm2-* files in /var, they were in /etc/systemd. And one needs to install systemd-experimental which provides systemd-pcrlock. And even after that I cannot make it work. I run "sdbootutil update-predictions", I run "transactional-update initrd", I see pcrlock hashes in /var/lib/pcrlock.d (multiple e.g. for initrd), but I am asked for passphrase on boot.
On 2024-03-27 17:26, aplanas wrote:
On 2024-03-27 17:19, Andrei Borzenkov wrote:
On 27.03.2024 18:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
Can existing images be updated?
I can prepare an update to sdbootutil that will do the migration from pcr-oracle to pcrlock, or at least I will document how it can be done manually (is as simple as removing the tpm2-* files from the ESP and /var and calling `sdbootutil update-predictions`)
Ok. This is how the transition from pcr-oracle to systemd-pcrlock can be done: == From pcr-oracle to systemd-pcrlock # Install systemd-experimental (reboot, as sdbootutil should find # systemd-pcrlock) transactional-update pkg in systemd-experimental # Remove public and private keys fron /etc and public from ESP rm /etc/systemd/tpm2-pcr-private-key.pem rm /etc/systemd/tpm2-pcr-public-key.pem rm /boot/efi/EFI/systemd/tpm2-pcr-public-key.pem # Remove signed policy from /etc and ESP rm /etc/systemd/tpm2-pcr-signature.json rm /boot/efi/EFI/systemd/tpm2-pcr-signature.json # Drop the "tpm2" keyslot from the LUKS2 device systemd-cryptenroll --wipe-slot=tpm2 $DEV # Generate predictions and policy, and register it in the TPM2's NVRAM sdbootutil update-predictions # Enroll the keyslot in the LUKS2 device. Will ask for the recovery # password systemd-cryptenroll \ --tpm2-device=auto \ --tpm2-pcrlock=/var/lib/systemd/pcrlock.json \ /dev/vda3 For completion, this is how we can go back to pcr-oracle: == From systemd-pcrlock to pcr-oracle # Remove systemd-experimental package (reboot, as sdbootutil should # not find systemd-pcrlock) transactional-update pkg rm systemd-experimental # Remove .pcrlock files with components and variants rm -fr /var/lib/pcrlock.d # Remove pcrlock.json in /var and ESP rm /var/lib/systemd/pcrlock.json rm /boot/efi/EFI/systemd/pcrlock.json # Clean the TPM2, to remove the NVIndex policy tpm2_clear # Generate a RSA key pair pcr-oracle \ --rsa-generate-key \ --private-key /etc/systemd/tpm2-pcr-private-key.pem \ --public-key /etc/systemd/tpm2-pcr-public-key.pem \ store-public-key # Drop the "tpm2" keyslot from the LUKS2 device systemd-cryptenroll --wipe-slot=tpm2 $DEV # Enroll the private key systemd-cryptenroll \ --tpm2-device=auto \ --tpm2-public-key=/etc/systemd/tpm2-pcr-public-key.pem \ --tpm2-public-key-pcrs=0,2,4,9 \ $DEV # Generate new predictions with pcr-oracle sdbootutil update-predictions
On 3/27/24 11:41, aplanas wrote:
Hi,
after the announcement of sdbootutil[1] and the support of full disk encryption (FDE)[2] using systemd-cryptenroll via pcr-oracle, we are releasing images for MicroOS and Tumbleweed that support the new systemd-pcrlock mechanism!
Will we continue to be able to use systemd-boot WITHOUT FDE ? I am testing systemd-boot on a test machine but do NOT want to use FDE. I assume that will continue to be true ? Are there plans to switch TW to systemd-boot ? If so what is the timeframe ? -- Regards, Joe
On 2024-03-29 21:49, Joe Salmeri wrote:
Will we continue to be able to use systemd-boot WITHOUT FDE ?
They are independent. You can use sd-boot without FDE. The dependency is in reverse: as today you need to use sd-boot to use the systemd based FDE.
I am testing systemd-boot on a test machine but do NOT want to use FDE.
OK
I assume that will continue to be true ?
Sure.
Are there plans to switch TW to systemd-boot ?
There is work in YaST that allows you to install systemd-boot instead of GRUB2. But the kernel command line is not properly transferred yet.
If so what is the timeframe ?
I do no have a time frame from the sd-boot support from YaST.
On 27.03.2024 18:41, aplanas wrote:
pcrlock proposes a different approach to the generation of TPM2 policies. Instead of signed policies (which requires the generation of a RSA key pair that is used to sign the PCR policy to make it independent of the sealed key), pcrlock uses NVIndex policies. Those are basically policies that are stored inside the non-volatile RAM that the TPM2 provides. The policy is now stored inside the TPM2, and the index can only be changed if the policy itself is meet.
I added one more disk to this VM after initial setup and apparently it invalidated measurements. Now I cannot also update predictions (or, better, I cannot update policy), it fails at the make-policy step. systemd-pcrlock by defaults generates recovery pin that is itself protected by the same NVIndex policy, so to update policy it has to match first. Catch 22. Any pointers how I can reinitialize whatever is needed to be reinitialized so automatic unlocking works again?
Andrei Borzenkov wrote:
On 27.03.2024 18:41, aplanas wrote:
pcrlock proposes a different approach to the generation of TPM2 policies. Instead of signed policies (which requires the generation of a RSA key pair that is used to sign the PCR policy to make it independent of the sealed key), pcrlock uses NVIndex policies. Those are basically policies that are stored inside the non-volatile RAM that the TPM2 provides. The policy is now stored inside the TPM2, and the index can only be changed if the policy itself is meet.
I added one more disk to this VM after initial setup and apparently it invalidated measurements. Now I cannot also update predictions (or, better, I cannot update policy), it fails at the make-policy step. systemd-pcrlock by defaults generates recovery pin that is itself protected by the same NVIndex policy, so to update policy it has to match first. Catch 22.
Yes. That turns out to be pretty annoying in practice.
Any pointers how I can reinitialize whatever is needed to be reinitialized so automatic unlocking works again?
# pcrlock remove-policy # systemd-cryptenroll --wipe=tpm2 /dev/yourdev # sdbootutil update-predictions # systemd-cryptenroll --tpm2-device=auto /dev/yourdev cu Ludwig -- (o_ Ludwig Nussel //\ V_/_ http://www.suse.com/ SUSE Software Solutions Germany GmbH; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; HRB 36809 (AG Nürnberg)
On 08.04.2024 09:16, Ludwig Nussel wrote:
Andrei Borzenkov wrote:
On 27.03.2024 18:41, aplanas wrote:
pcrlock proposes a different approach to the generation of TPM2 policies. Instead of signed policies (which requires the generation of a RSA key pair that is used to sign the PCR policy to make it independent of the sealed key), pcrlock uses NVIndex policies. Those are basically policies that are stored inside the non-volatile RAM that the TPM2 provides. The policy is now stored inside the TPM2, and the index can only be changed if the policy itself is meet.
I added one more disk to this VM after initial setup and apparently it invalidated measurements. Now I cannot also update predictions (or, better, I cannot update policy), it fails at the make-policy step. systemd-pcrlock by defaults generates recovery pin that is itself protected by the same NVIndex policy, so to update policy it has to match first. Catch 22.
Yes. That turns out to be pretty annoying in practice.
Well, conceptually it is not much different to locking LUKS password to the raw PCR values. After all, you *do* lock to the raw PCR values, just several possible values. But it will be fun when system fails to reboot unattended several months after disk has been added online ...
Any pointers how I can reinitialize whatever is needed to be reinitialized so automatic unlocking works again?
# pcrlock remove-policy # systemd-cryptenroll --wipe=tpm2 /dev/yourdev # sdbootutil update-predictions # systemd-cryptenroll --tpm2-device=auto /dev/yourdev
Yes, that works. Thank you!
On 2024-04-08 17:30, Andrei Borzenkov wrote:
On 08.04.2024 09:16, Ludwig Nussel wrote:
Andrei Borzenkov wrote:
Any pointers how I can reinitialize whatever is needed to be reinitialized so automatic unlocking works again?
# pcrlock remove-policy # systemd-cryptenroll --wipe=tpm2 /dev/yourdev # sdbootutil update-predictions # systemd-cryptenroll --tpm2-device=auto /dev/yourdev
Yes, that works. Thank you!
That lock one NVIndex slot in the TPM2. After the wipe I would do a `tpm2_clear` to free it.
aplanas wrote:
On 2024-04-08 17:30, Andrei Borzenkov wrote:
On 08.04.2024 09:16, Ludwig Nussel wrote:
Andrei Borzenkov wrote:
Any pointers how I can reinitialize whatever is needed to be reinitialized so automatic unlocking works again?
# pcrlock remove-policy # systemd-cryptenroll --wipe=tpm2 /dev/yourdev # sdbootutil update-predictions # systemd-cryptenroll --tpm2-device=auto /dev/yourdev
Yes, that works. Thank you!
That lock one NVIndex slot in the TPM2. After the wipe I would do a `tpm2_clear` to free it.
systemd-pcrlock remove-policy clears the nvindex cu Ludwig -- (o_ Ludwig Nussel //\ V_/_ http://www.suse.com/ SUSE Software Solutions Germany GmbH; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; HRB 36809 (AG Nürnberg)
On 2024-04-09 09:26, Ludwig Nussel wrote:
aplanas wrote:
That lock one NVIndex slot in the TPM2. After the wipe I would do a `tpm2_clear` to free it.
systemd-pcrlock remove-policy clears the nvindex
Not always succeed (TSS lib complain). But indeed, I just tested some manual invalidation and seems more reliable today.
On Mon, 2024-04-08 at 20:30 +0300, Andrei Borzenkov wrote:
Well, conceptually it is not much different to locking LUKS password to the raw PCR values. After all, you *do* lock to the raw PCR values, just several possible values.
I missed this part in Alberto's initial announcement of the new approach. If this is true, it looks like a step back wrt the previous signed policy approach, or am I missing something? Martin
On 2024-04-09 15:11, Martin Wilck via openSUSE Factory wrote:
On Mon, 2024-04-08 at 20:30 +0300, Andrei Borzenkov wrote:
Well, conceptually it is not much different to locking LUKS password to the raw PCR values. After all, you *do* lock to the raw PCR values, just several possible values.
I missed this part in Alberto's initial announcement of the new approach. If this is true, it looks like a step back wrt the previous signed policy approach, or am I missing something?
I do not understand Andrei's analogy, but IMO it is a step forward. In any case (signed policy nor nvindex policy) there is not a lock in raw PCR values. There is a calculation of a policy hash (that this time was extended to support PolicyOR), and instead of signing them, now it is stored inside the TPM2 NVRAM. In both cases the LUKS2 password in encrypted using the SRK from the TPM2.
Martin
On 09.04.2024 18:20, aplanas wrote:
On 2024-04-09 15:11, Martin Wilck via openSUSE Factory wrote:
On Mon, 2024-04-08 at 20:30 +0300, Andrei Borzenkov wrote:
Well, conceptually it is not much different to locking LUKS password to the raw PCR values. After all, you *do* lock to the raw PCR values, just several possible values.
I missed this part in Alberto's initial announcement of the new approach. If this is true, it looks like a step back wrt the previous signed policy approach, or am I missing something?
I do not understand Andrei's analogy, but IMO it is a step forward.
The most basic form of TPM2 protection binds decryption of the secret to the raw PCR values. If PCR values changed, it is impossible to access the secret anymore and one needs to re-enroll it. This is what systemd-cryptenroll --tmp2-pcrs does. The signed policy binds decryption of the secret to *any* PCR values as long as these PCR values are signed by the known good key. This means secret needs to be enrolled just once and if PCR values changed, one can simply sign them and continue to use the same bound secret. This is what systemd-cryptenroll --tpm2-public-key does and is what sdbootutil + pcr-oracle used. systemd-cryptenroll --tpm2-pcrlock binds decryption of the secret to the set of the alternative PCR values stored in NVIndex. The read access to these values is not restricted. But - the systemd-pcrlock binds writing of the NVIndex to the pin which is encrypted by TPM2 and its decryption is bound to the same set of the alternative PCR values. Which means - if PCR values changed, you can neither decrypt LUKS password *NOR* decrypt pin and hence cannot update the set of PCR values stored in the NVIndex. Either you need to know pin to update NVIndex or you need to re-enroll everything. And by default systemd-pcrlock generates random pin and does not show it, so we are left with "re-enroll everything". Looking at it this way, yes, it is step backward.
In any case (signed policy nor nvindex policy) there is not a lock in raw PCR values.
OK, what I meant - TPM2 will be using PCR values to decide whether to decrypt LUKS password. Policy will match if PCR will be equal to one of possible values. Here nothing changed really. Both pcr-oracle and systemd-pcrlock work this way. They differ only in what is accepted by TPM as valid values.
There is a calculation of a policy hash (that this time was extended to support PolicyOR), and instead of signing them, now it is stored inside the TPM2 NVRAM.
Yes. And the practical problem I hit - access to the policy itself is locked to the same set of (alternative) PCR values, so if something changed, it is no more possible to update the policy. From usability PoV the challenge is to automatically discover all objects protected by this same policy and "relock" them. Because most likely there will be just one NVIndex protecting multiple LUKS secrets and what not. You cannot just wipe everything. Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it. This would allow updating NVIndex even if PCRs changed "under the hood". This is functionally equivalent to LUKS recovery key. This would solve the problem of updating *the single copy* of the policy in NVIndex for all users bound to it without need to re-enroll each and every user.
In both cases the LUKS2 password in encrypted using the SRK from the TPM2.
How it is encrypted is irrelevant for this problem. What is relevant - how TPM2 decides whether LUKS2 password can be decrypted and how we can update the conditions it is using to decide it.
On 2024-04-10 04:39, Andrei Borzenkov wrote:
Either you need to know pin to update NVIndex or you need to re-enroll everything. And by default systemd-pcrlock generates random pin and does not show it, so we are left with "re-enroll everything".
I was thinking to change the default and manually add the users PIN, so the re-enrollment case is simplified.
Looking at it this way, yes, it is step backward.
For the usability this can be the case, but I am sure that can be improved. But security is increased one bit. The unseal of the LUKS2 key now depends on the SRK and the NVIndex, two components that are in the local TPM2.
In any case (signed policy nor nvindex policy) there is not a lock in raw PCR values.
OK, what I meant - TPM2 will be using PCR values to decide whether to decrypt LUKS password. Policy will match if PCR will be equal to one of possible values. Here nothing changed really. Both pcr-oracle and systemd-pcrlock work this way. They differ only in what is accepted by TPM as valid values.
Right. Should be noted that the more complex policy that pcrlock generates can also be a signed policy.
From usability PoV the challenge is to automatically discover all objects protected by this same policy and "relock" them. Because most likely there will be just one NVIndex protecting multiple LUKS secrets and what not. You cannot just wipe everything.
The key slot in the LUKS2 header stores this relationship.
Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it.
Yes, we can make it explicit during the first enrollment.
On Wed, Apr 10, 2024 at 8:15 AM aplanas <aplanas@suse.de> wrote:
On 2024-04-10 04:39, Andrei Borzenkov wrote:
Either you need to know pin to update NVIndex or you need to re-enroll everything. And by default systemd-pcrlock generates random pin and does not show it, so we are left with "re-enroll everything".
I was thinking to change the default and manually add the users PIN, so the re-enrollment case is simplified.
Looking at it this way, yes, it is step backward.
For the usability this can be the case, but I am sure that can be improved.
But security is increased one bit. The unseal of the LUKS2 key now depends on the SRK and the NVIndex, two components that are in the local TPM2.
In any case (signed policy nor nvindex policy) there is not a lock in raw PCR values.
OK, what I meant - TPM2 will be using PCR values to decide whether to decrypt LUKS password. Policy will match if PCR will be equal to one of possible values. Here nothing changed really. Both pcr-oracle and systemd-pcrlock work this way. They differ only in what is accepted by TPM as valid values.
Right. Should be noted that the more complex policy that pcrlock generates can also be a signed policy.
Could you elaborate? I do not see any options to do it.
From usability PoV the challenge is to automatically discover all objects protected by this same policy and "relock" them. Because most likely there will be just one NVIndex protecting multiple LUKS secrets and what not. You cannot just wipe everything.
The key slot in the LUKS2 header stores this relationship.
Probably I was not clear. The challenge is not to find NVIndex. The challenge is to find all LUKS2 containers bound to it. As some of them may not even be present when you do it (consider removable encrypted drive that auto unlocks only when you connect it to your laptop booted into a trusted operating system instance). And am sure the usage will be extended beyond LUKS2 in the future (systemd-pcrlock itself is not specific to LUKS in any way). The only reason to have multiple NVIndex is different PCR values, which effectively means different boot stages (or run-time stages). Of course, grub2 using the same technique to unlock /boot would need a different policy and different NVIndex. But all LUKS2 containers can normally be bound to the same NVIndex representing a fully booted state.
Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it.
Yes, we can make it explicit during the first enrollment.
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now. Oh, and while we are on topic - currently we by default have a plain text user specified password and a plain text recovery key. Isn't it one too many?
On 2024-04-10 07:17, Andrei Borzenkov wrote:
On Wed, Apr 10, 2024 at 8:15 AM aplanas <aplanas@suse.de> wrote:
Right. Should be noted that the more complex policy that pcrlock generates can also be a signed policy.
Could you elaborate? I do not see any options to do it.
Yes sorry, it was just a technical remark. With pcrlock we can do more rich policies as they include the PolicyOR to make disjunctions, but at the end we still generate a policy hash that can be signed. That makes me think that updating pcrlock to generate nvindex policies and/or signed policies should be a nice contribution. The UI of pcrlock makes very easy (at least for me) to find why the policy refused to comply, and what variations do I care for.
From usability PoV the challenge is to automatically discover all objects protected by this same policy and "relock" them. Because most likely there will be just one NVIndex protecting multiple LUKS secrets and what not. You cannot just wipe everything.
The key slot in the LUKS2 header stores this relationship.
Probably I was not clear. The challenge is not to find NVIndex. The challenge is to find all LUKS2 containers bound to it.
Yes, that is what I was talking about. The header contains the srk handle in base64, that should be possible to link with the pcrlock.json that contains srk information in hex. This json contains the nvindex that also links with the TPM2. So should be possible to build this relation from the devices to the associated broken policy.
As some of them may not even be present when you do it (consider removable encrypted drive that auto unlocks only when you connect it to your laptop booted into a trusted operating system instance).
Right, if the device is not there on the time where the re-enroll is done, it will be lost.
The only reason to have multiple NVIndex is different PCR values, which effectively means different boot stages (or run-time stages).
Uhmm not exactly. TPM2 can do very rich policies, but until now we only used a subset of the possible expressions that can be integrated in a policy (basically a list of PCR in conjunction, i.e AND operation). pcr-oracle can do this kind of policy, and pcrlock now itegrated the disjunction (OR operation). The policy can be of the form (PCRx == vx1 && PCRy == vy1) || (PCRx == vx2 && PCRy == vy2), for example. The run-time stages are included there as variant (see 750-enter-initrd.pcrlock and family from /usr/lib/pcrlock.d/)
Of course, grub2 using the same technique to unlock /boot would need a different policy and different NVIndex.
From one side grub2 does not have this kind of unlock mechanism (but I have a grub2-bls image that is using this kind of user space encryption for sysroot, exactly as we are doing with systemd-boot). For the other, an hypothetical boot loader can still use the same NVIndex if there is an expression that can capture the PCR status at this stage (and with AND and OR I do not see why not)
Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it.
Yes, we can make it explicit during the first enrollment.
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
Oh, and while we are on topic - currently we by default have a plain text user specified password and a plain text recovery key. Isn't it one too many?
Yes. There is discussion to drop it. My plan was to remove it some time ago. Initially makes sense to have a weaker password for debugging, but in the general release it should not be there.
On 10.04.2024 11:45, aplanas wrote:
Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it.
Yes, we can make it explicit during the first enrollment.
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
I looked if there is a reasonably simple way to extract the generated pin using tmp2-tools, but whatever I did policy session always failed at tpm2_policyauthorizenv step. I am not sure what is missing, but systemd-pcrlock first starts encryption session and the references it when starting policy session and this mode is not supported by tpm2_startauthsession. So it looks like either pin needs to be supplied externally or systemd-pcrlock modified to (optionally) print generated pin.
On 13.04.2024 14:54, Andrei Borzenkov wrote:
On 10.04.2024 11:45, aplanas wrote:
Now, systemd-pcrlock also supports the user-supplied PIN instead of auto-generating it.
Yes, we can make it explicit during the first enrollment.
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
I looked if there is a reasonably simple way to extract the generated pin using tmp2-tools, but whatever I did policy session always failed at tpm2_policyauthorizenv step. I am not sure what is missing, but systemd-pcrlock first starts encryption session and the references it when starting policy session and this mode is not supported by tpm2_startauthsession. So it looks like either pin needs to be supplied externally or systemd-pcrlock modified to (optionally) print generated pin.
OK, I was able to recover stored pin only to realize that it is not pin itself, but rather the final authorization hash derived from it. Which means, while it can be used to manually write (recomputed) policy into NVIndex, it cannot be used as input to systemd-pcrlock.
On Wed, Apr 10, 2024 at 11:45 AM aplanas <aplanas@suse.de> wrote:
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
Next systemd version should add an option to systemd-pcrlock to print the generated pin. As we will need to re-enroll anyway (due to changed authorization policy), it will be a good occasion to store the pin safely :)
On 2024-04-18 11:40, Andrei Borzenkov wrote:
On Wed, Apr 10, 2024 at 11:45 AM aplanas <aplanas@suse.de> wrote:
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
Next systemd version should add an option to systemd-pcrlock to print the generated pin.
I do not see the code in github, is this a new issue or there is a pending PR? I would like to monitor this.
As we will need to re-enroll anyway (due to changed authorization policy), it will be a good occasion to store the pin safely :)
I will be sure to update the scripts with this.
On Thu, Apr 18, 2024 at 3:03 PM aplanas <aplanas@suse.de> wrote:
On 2024-04-18 11:40, Andrei Borzenkov wrote:
On Wed, Apr 10, 2024 at 11:45 AM aplanas <aplanas@suse.de> wrote:
I think it should really be the default. The cryptographically strong recovery PIN should be auto-generated (not entered manually) and shown to the user like is the case with LUKS recovery key now.
That makes sense for me.
Next systemd version should add an option to systemd-pcrlock to print the generated pin.
I do not see the code in github, is this a new issue or there is a pending PR? I would like to monitor this.
On 2024-04-18 12:10, Andrei Borzenkov wrote:
On Thu, Apr 18, 2024 at 3:03 PM aplanas <aplanas@suse.de> wrote:
On 2024-04-18 11:40, Andrei Borzenkov wrote:
Next systemd version should add an option to systemd-pcrlock to print the generated pin.
I do not see the code in github, is this a new issue or there is a pending PR? I would like to monitor this.
The change is a bit more deep that printing the PIN. Now it becomes a signature that protect the nvindex. Also seems that pcrlock will be stable in v257. Thanks a lot for the pointer, this change is more than welcome.
participants (5)
-
Andrei Borzenkov
-
aplanas
-
Joe Salmeri
-
Ludwig Nussel
-
Martin Wilck