Future of Encryption in Fedora desktop variants

There needs to be a bunch more detail regarding how the TPM sealing is handled. For instance, sealing against PCR 7 on its own is insufficient - if a user boots from a Fedora live CD, PCR 7 will be the same, and the TPM will happily release the secret even though there’s no user authentication performed. This is the reason for Bitlocker sealing against PCR 11 as well - once the Bitlocker key has been unsealed, PCR 11 is extended and the TPM will no longer release it again. The equivalent on Linux would be for the live CD to extend PCR 11 before any user interaction is performed in order to prevent this (which obviously makes the live CD useless as a recovery mechanism, but that’s kind of the point here).

And remember that this has to be done for everything that is signed using these signing keys! UKI may have a restricted initramfs, but if I have an old kernel and unsigned initramfs signed with the same signing keys, I can just boot those and have the same measurements and then bypass the encryption that way. Doing this properly implies rolling to a new set of signing keys for the kernel, which implies a new shim or support for shipping certs independently of shim.

And, of course, this has to be accompanied by restricting the kernel command line. If I can just pass rdinit=/bin/sh I’m going to have interactive control without a password, and the TPM is going to have a valid set of measurements for decrypting the drive, and our assumptions are broken. This is in-kernel, so can’t just be handled at the dracut layer.

We should also remember that PCR 7 will change if secure boot is disabled, or if an additional MOK is enrolled. If a user does either to install (for instance) the nvidia drivers, the measurements will change and their filesystem will no longer decrypt. There probably needs to be a robust mechanism for handling that.

I don’t mean to be negative here. I think this is, if done properly, a significant improvement in usable security. But there’s several subtle cases (and I don’t want to claim the above is necessarily comprehensive in any way!) that can result in either insecure outcomes or unexpected breakage, and I think those need to be more clearly documented before committing to implementation.

3 Likes

I’m not sure there’s really a huge difference between TPM1.2 and TPM2 in this respect? The quality of the TPM1.2 tooling is, well, pretty bad, but for the specific case being described here I think the appropriate security properties exist.

I think disk encryption should be widely used, but the draft plan is not quite nailed down, and some directions it could go give me pause. Particularly, storage of entire keys in TPM2, and fscrypt.

Storing an entire key(file) in the TPM is no doubt required for systems that (re)boot unattended, and is the best way I know to do that. However, if user data is protected by such a key, security depends on the TPM firmware being free of bugs and backdoors (that might deniably look like bugs). This secureboot fakery was not a TPM bug, but it does show that the space of possible problems may include, “let’s not do the cryptography and pretend we did”.

I tried to convince the UAPI group to avoid the TPM being a single point of failure by hashing a TPM-sealed secret salt with the user password on the host CPU, but I failed to communicate sufficiently well.

The problem with fscrypt (at least from what I remember of how it works on ext4) is that only file names and data are encrypted, but not file sizes or directory layouts. That makes it vulnerable to a kind of known-plaintext attack when the plaintext is a few large files or multiple files, such as an archived Youtube channel, a source code repository, a wikileaks dump, etc. If secret data ever leaves the device, an adversary can prove that the user is in possession of it.

Fscrypt is enough to protect browser session cookies, and saved passwords or credit card numbers, which satisfies Googles desires for Android. But I am dismayed to see it expanding elsewhere while that problem remains.

Honestly, I like systemd-homed. It solves the multi-user problem, LUKS prevents metadata leakage, and TRIM support keeps its volumes from consuming more disk space that the data within.

Whatever ends up implemented should be no less secure against any threat model than the status-quo with LUKS+password. That is, block-level encryption of /, but not /boot, with a key derived from a password stored nowhere else but inside the user’s brain, unless they explicitly write it down. The reason is that if some threats require changing the standard configuration in a visible way, users who face those threats will be marked as suspicious. As a particular example if something weaker replaces the status quo:

Prompting for decryption is a major driver of needing framebuffer support in the initrd.

“What do you need a custom initrd for, citizen?”

This is a bit of a problem with the status quo too, but a lot of people are using strong FDE who otherwise wouldn’t, to cover the lost laptop threat model.

Aside, on the subject of evil-maid attacks and their prevention:

An evil maid is allowed to hide cameras or microphones in the space around your computer, without tampering with it at all. This can even be done in advance before you check into the hotel. Such attacks are probably easier and more general than preparing evil initrds that imitate the correct bootsplashe for every common OS, and then guaranteeing enough time alone with victims’ computers to install them. There is no substitute for physical security.

For this reason, I don’t think schemes that provide resistance to evil-maid attacks should be chosen if they are less secure in other respects than less evil-maid-resistant schemes.

1 Like

The systemd measurement logic actually already measures the boot “phase” into the PCR we also measure the kernel into. Thus you can bind secrets to a specific phase of the boot, for example you can say that the root fs can only be unlocked via TPM while in the initrd, but not later. This should deliver exactly what you are asking for, already.

There’s a plan somewhere to implement rollback protection via a TPM nvindex in systemd, so that you can bind the unlocking of TPM keys to “nvindex counter must be at X or higher”, and through policy we restrict that the counter can only go up. And then at boot we always bump the counter to whatever is declared for the current OS. But all this is a plan, and not implemented at this point.

1 Like

Yeah you should. But of course, I might be biased :wink:

Regarding the doc you linked. I doubt systemd-homed is “complicated”? With newest fedora use authselect to enabled homed and then do “homectl create” and you have your homedir… if you want you can pick a backend, i.e. chose between fscrypt and luks or unencrypted.

homed does fscrypt too btw. (though this hasn’t been update to use the newer kernel apis).

I personally am not a fan of fscrypt for home dirs, because it doesn’t protect metadata and UNIX home dirs have too much of those, with lots of small files. I think it makes a ton of sense to use for per-app encrypted data dirs though, but that’s a story for another time I guess.

Your doc claims a minus point of homed was that it doesn’t do NFS. But neither does fscrypt, hence this seems a bit unfair? For NFS/LDAP/SSSD users you want neither fscrypt nor homed or anything, it’s from a different era, and should just manage their own home dirs.

homed supports locking the home dirs to fido2 and pkcs11 btw, which you list as desirable

you mention homed doesn’t support ssh logins? That’s not really the case. Currently, to allow ssh logins you have to log in locally first. Once you do that the homedir is unlocked and mounted and then ssh just works, until you log out locally. What is missing is that you can log in via ssh without logging in locally first.

I have a branch somewhere that removes that limitation, but I haven’t finished it. The idea of that branch is that we provide a temporary pseudo-shell (i.e. instead of /bin/bash) while the user hasn’t unlocked their homedir, and it asks for the password for unlocking the homedir and does so, and we then update the user record and show the real shell. This would then mean if you ssh into an account that has not been unlocked yet you’d first do regular ssh auth (i.e. ssh key pairs and stuff) and then get a another prompt asking for the password, and then you are in. If you then login a second time in parallel the password would not be queried again. Untill you fully log out with all your sessions and the home dir gets locked again and we start from the beginning.

oh, and pure fscrypt will have the same problem btw, because if you want the login password to be the decryption password then you need to provide it somehow and ssh does not allow that. You can do then what homed does, and write new infra for that, or you can just use homed right-away, and we’ll fix this for you eventually.

There’s also plan to support talking to a client’s ssh-agent when logging in via ssh and then unlocking the disk via that. This should work if users use RSA or ed21559 keys, but won’t work for some other key types (because we would rely on signatures being fixed, and they aren’t for some of the other key types).

4 Likes

Nvindexes prevent rollback, but anything can roll them forward as far as they want - if a live image drops a user into a root prompt they can increment any existing nvindexes to an arbitrary value.

subject to policy, no?

There are a million ways to brick your system, bumping an nvindex “too early” is not a particularly frightening way to brick it…

I mean, the worst thing that happens is that you have to type in your recovery key again, like on windows.

Good thread and very relevant. I don’t believe it’s a good idea to make encryption the default. At most just put a parameter in that you must reply that asks whether or not you want encryption. Installation would not continue until you answer.

When I said “I don’t think there’s any way to provide a useful amount of tamper resistance on pre-TPM2 devices”, it wasn’t actually meant to be a comment on TPM1.2 - what I had my head was:

  • If we don’t capabilities like what we get with TPM2+secure boot, we shouldn’t worry about tamper resistance.
  • We should initially concentrate on getting things right for TPM2, since that’s widely available and well supported.

Extending support to TPM1.2 seems like an add-on step. From looking around quickly, it also seems that TPM1.2 only supports SHA1, which we’re trying to squeeze out of Fedora. (security-wise it’s probably a big step up from nothing anyways…)

1 Like

Do I understand correctly, that this would be used with PCR signatures, something like:

  • Fedora advertises a RSA public key used to sign initrd-phase PCR11 values for Fedora Unified Kernel Images
  • Each UKI we ship has the signature for that UKI’s expected PCR11 value embedded in it, and available to the initrd.
  • The encryption key is bound to the combination of the specific PCR7 value for that machine + any PCR11 value signed with the Fedora RSA key

(I had only seen “But quite frankly I don’t really see the point” about PCR signatures in your old blog, and just read through the systemd-measure docs now.)

Thanks for the detailed reply, Matthew! I’ll try to capture the concerns you mention in the document. We’ll definitely need to engage domain experts for further review both at the planning level and of actual implementation details.

Does not rsa is insecure now as qc is can break it in next 3years or so.?

RSA’s demise from quantum attacks is very much exaggerated, expert says | Ars Technica is a good read. If cryptological advances threaten the foundations of TPM2, then there will be a TPM3, and we’ll have to adapt like everyone else.

I am a big fan of PCR signatures these days. Changed my mind 180° on that.

PCR 7-based policies are not that easy to deploy, if you at the same time let fwupd update dbx as part of its firmware upgrade routines (and thus the secureboot policy). I probably should add a note to our docs about that. Because that means fwupd would change PCR 7 values regularly (and you cannot sign the expected values because laptops have keys enrolled specific to the vendor). So for now I’d step away from PCR7 based policies. This needs more preparation in systemd first.

I think what you can do is PCR 11 based policies for now. I’d envision it like this: fedora would create a signing keypair. Each time fedora builds a kernel it would include a “.pcrsig” PE section that contains a signature for the expected PCR 11 value in the boot phase where the rootfs shall be unlocked (i.e. in the initrd), generated with that key. Then, fedora would enroll the rootfs to that public key and thus have a rootfs that can only be unlocked on fedora, from the initrd.

(it might make sense to generate a second keypair at the same time, and sign with it the PCR 11 values expected on that kernel for the boot phases expected during regular runtime too. This should be used for auxiliary encrypted volumes, i.e. not the rootfs but anything else that is activated from later boot or on demand, instead of from the initrd like the rootfs).

PCR 4-based policies are probably out of scope for now too, we also need more infrastructure to make that happen. We probably have to predict changes like Windows does, and then hook into that from fwupd and from boot loader updater (bootctl) or so. It’s a mess, and nothing has been done.

So, under the assumption you stick to PCR 11 based policies for now, there are two attack vectors I see, that we need to address sooner or later.

  1. the rollback thing matthew mentioned: we need to cut off old versions of the OS regularly so that people cannot attack the disk encryption by booting old versions of the OS. See above for our ideas on that. No code exists.

  2. right now the systemd efi stub that measure the kernel it is about to boot to PCR 11 does so knowing that it is the only user of that PCR. Which is great. But it also means that if you boot through shim, then anything else booted through shim will see an all zero PCR 11, and then can manually measure whatever it wants into PCR 11 and fake the values we expect only to see if a valid fedora UKI kernel is booted. (This vulnerability is not specific to sd-stub btw, IMA has the same weakness, afaics). A fix to this is technically easy, but I didn’t want to deal with the politics of this: shim should probably just measure a string derived from the payload it is about to boot into all PCRs that are not used by itself or by the firmware, including PCR11.That way, shim payloads cannot easily fake each other’s PCR values.

I’d ignore TPM1.2. It’s legacy hw, and pretty useless, given that SHA1 is icky. It’s also different enough from TPM2 that it’s not worth it I think (e.g. you cannot do signed PCR policies with TPM 1.2).

There needs to be graceful fallback for systems lacking TPM anyway, and I’d really treat TPM1.2 systems like TPM-less systems.

(I mean, the TPM2 situation i missing so much infra already, by throwing TPM1.2 in the mix you just add more work on top that’s not going to make anything easier)

Oh and there’s one more problem I see. Unless I am mistaken Fedora uses Grub to boot. And I think it doesn’t boot through the kernel’s EFI stub, does it, but loads the kernel via its own loader? If so, sd-stub won’t run, and hence the PCR 11 measurement and all that magic doesn’t happen.

I think grub can be told to invoke the kernel as EFI program though. Dunno. You’d have to do some research. Grub of course is a icky if you ask me, if I was you I’d address that issue by dropping it too. As I understand RH is working on some new boot loader that is the linux kernel. I think it’s totally nuts, but it might get you into similar problems.

Grub when invoking a kernel as EFI program won’t implement fs interfaces on the EFI image btw, which is another problem, as we try to load various sidecard files from the file system backing the kernel. initrd sysext, systemd credentials, random seed, and so on. We degrade gracefully there, but I think this will sooner or later become a problem for you: if you want modern graphics drivers in the initrd (for plymouth) then you might have to embedd 100M+ into the UKI. We suggest using sysext images for such extensions, so that you basically install one UKI plus a bunch of sysext for the major drivers you need in the ESP, but of course, if you can’t pass the sysext to the UKI safely then this is not going to work.

Yeah, this all is a lot of work to get ready for general purpose distros.


(I cannot participate in this discussion further btw, this stupid discussion webforum doesn’t allow me to post anything anymore. Some limits apply, suggests I edit existing posts instead? This is so stupid.)


Entirely unrelated to the above, here’s what I wanted to post earlier, but the webforum didn’t allow me to.

RSA is the only asymmetric encryption scheme all current TPM2 implementations support. Thus you have few options there.

That said, Fedora could additionally generate UKI PCR sigs with an ECC key, and then provide both in the .pcrsig PE section. Then, local systems can chose against which of the two they lock their disk to, using ECC if supported and RSA otherwise. But not sure this is worth the effort given the SecureBoot signing is RSA only anyway.

1 Like

16 posts were split to a new topic: Getting systemd-homed working properly on Fedora Workstation

Interesting thread :slight_smile:

Just from my rather niche perspective (and I saw it was touched on in the document) - but please consider what would happen with Fedora preloads on the Lenovo platforms - and if this is something that can be enabled on a Fedora preloaded system, so that the user can login on first boot.

I imagine a lot of people will appreciate an encrypted and guaranteed non-tampered with preload image (I can see why that’s important) - but I suspect it’s not easy to do.

As a note - we do currently add our documentation to the Fedora preload after getting the image from the Fedora site - and I suspect that would break a lot of this. I’m sure we can find an alternative to that but figured I would flag it so it’s at least a consideration.

Mark

1 Like

As making full disk encryption a default option seems imminent: I would like to remind everyone (a quote from the previous post) that not all Fedora distros are ready to offer FDE by default to users with custom keyboard layouts (= not with the “US English” one), which is not that rare as it might seem. I have seen that Fedora Workstation 37 works fine (respects the custom keyboard layout during boot), while Fedora Silverblue all versions (including F39 Rawhide) for some reason always uses US English during boot even if it was deleted during the setup phase (and does not even show the layout) - which makes unlocking the disk practically impossible after first reboot. And it better be fresh install, as the newly encrypted data will be lost.
A new user would reinstall the system several times trying to guess why the system won’t accept the (apparent) correct passphrase on the first boot… And each time it will refuse to unlock during boot because of the poor keyboard layout handling.

There’s a related Bugzilla report: Bug 1890085 - English keyboard layout is erroneously used during initramfs phase (e.g. decrypting encrypted storage devices) instead of native layout, on Silverblue / ostree installs which has survived several generations of Fedora already; is completely stagnant, and does not seem to have any priority whatsoever :frowning:

I have also noticed that during the install phase there’s a great option to test the keyboard layout, but not always the symbols appeared as expected (for example, instead of “ñ” a different symbol appeared), which is unacceptable if you need to define a passkey for FDE.

Unfortunately, this bug appears to be completely abandoned. If “FDE by default” is near, these bugs must be fixed soon as it affects lots of people with national and non-standard keyboard layouts. On behalf of such users, I’d like to remind about it and suggest prioritizing the bug.