You just switched to Linux after years of Windows, and after setting up full disk encryption with LUKS2, you already miss one handy Windows feature: BitLocker and its automatic disk unlock.
Today we will learn how to approximate its behavior under the popular Linux distribution Fedora
If you are using an old version of Fedora, you must use clevis to bind the TPM2 (TPM 1.0 is not supported and never will be) key to the LUKS volume, but if you are using Fedora 35 or later, you can use the new systemd-cryptenroll
command.
First chech for available TPM2 devices:
systemd-cryptenroll --tpm2-device=list
And check for Secure Boot status, you need to enable it in order to prevent tampering with the boot process:
mokutil --sb-state
If you have a TPM2 device, you can use the following command to bind the TPM2 key to the LUKS volume:
sudo systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs "0+1+2+3+4+5+7+9" /dev/nvme0n1p3
where --tpm2-pcrs
is the list of PCRs to use for the binding, you can find more information about PCRs later in this article.
You need to update the /etc/crypttab
file to unlock the volume at boot:
luks-7a02e564-b7fa-4837-a3ec-3b83752c3a20 UUID=1f7f5ba4-01f8-419e-ae48-5daaa69bd1e6 none discard,tpm2-device=auto
On earlier versions of Fedora (before 36), you may update dracut to include libtss2 in the initramfs:
Create a file /etc/dracut.conf.d/tss2.conf
with the following content:
install_optional_items+=" /usr/lib64/libtss2* "
and then regenerate the initramfs:
dracut -f
You can also add a recovery key to the LUKS volume. It's the same as the normal key, but it's generated with higher entropy.
systemd-cryptenroll --recovery-key /dev/nvme0n1p3
Clevis installation and configuration
The things we need (besides the LUKS2 installation we already did) to accomplish this task are the Trusted Platform Module
First things first, we need to install the Clevis framework and the needed plugins with Fedora's DNF package manager with this simple command:
sudo dnf install clevis clevis-luks clevis-dracut clevis-udisks2 clevis-systemd
Then we need to find the LUKS volume to bind, we can use the tool lsblk
to find the volume (In my case it was nvme0n1p3
).
[kowalski7cc@Kaos ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 477G 0 disk
├─nvme0n1p1 259:1 0 600M 0 part /boot/efi
├─nvme0n1p2 259:2 0 1G 0 part /boot
└─nvme0n1p3 259:3 0 475,4G 0 part
└─luks-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 253:0 0 475,3G 0 crypt
├─fedora_localhost--live-root 253:1 0 70G 0 lvm /
├─fedora_localhost--live-swap 253:2 0 7,8G 0 lvm [SWAP]
└─fedora_localhost--live-home 253:3 0 397,6G 0 lvm /home
If we are right we should have an output like this using the tool cryptsetup
:
[kowalski7cc@Kaos ~]$ sudo cryptsetup luksDump /dev/nvme0n1p3
[sudo] password di kowalski7cc:
LUKS header information
Version: 2
Epoch: 3
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
PCR IDS
To make sure our boot has not tampered, we must choose some PCRs to validate against the boot.
Here is a table with the IDs and a small description of its usage:
PCR ID | Description |
---|---|
0 | Firmware |
1 | Firmware configuration |
2 | Option ROMs |
3 | Option ROMs configuration |
4 | MBR |
5 | MBR Configuration |
6 | State transition |
7 | Platform-specific |
8 - 15 | Operating System reserved |
16 | Debug |
23 | Applications |
Finally we can use the following command to set up the decryption key usin the TPM PCRs:
sudo clevis luks bind -d /dev/nvme0n1p3 tpm2 '{"pcr_ids":"0,1,2,3,4,5,6,7"}'
If it's correct, it will ask for your LUKS encryption password and add the Clevis key to the LUKS header.
Key upgrade procedure
When we do a kernel upgrade, probably our saved key will be invalidated. At this point, we need first to locate the Clevis key slot in the LUKS header.
We can use the command cryptsetup luksDump
like before to locate it.
[kowalski7cc@Kaos ~]$ sudo cryptsetup luksDump /dev/nvme0n1p3
[sudo] password di kowalski7cc:
LUKS header information
Version: 2
Epoch: 7
...
Tokens:
0: clevis
Keyslot: 1
...
We can see that clevis is using Keyslot 1, so we can proceed with
sudo clevis luks unbind -d /dev/nvme0n1p3 -s 1
Then we can use sudo clevis luks bind...
again to set up the new key.
Some notes and small thoughts about security
- At the moment I've tested successfully Clevis only with GRUB
- GRUB doesn't support measured boot, so it could be possible to tamper
- You need a full trusted chain of boot, e.g. using secureboot
- You need to allow only your keys
- Oops! Microsoft Accidentally Leaks Backdoor Keys to Bypass UEFI Secure Boot
- Exploiting signed bootloaders to circumvent UEFI Secure Boot
- TPM 2 has been proved to be unsafe when used alone
- More things about secureboot, trustedboot, measuredboot