Automatic LUKS 2 disk decryption with TPM 2 and Clevis on Fedora 31

Photo courtesy of George Becker
Photo courtesy of George Becker

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 31.

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).

[[email protected] ~]$ 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:

[[email protected] ~]$ 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)


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
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.

[[email protected] ~]$  sudo cryptsetup luksDump /dev/nvme0n1p3
[sudo] password di kowalski7cc:
LUKS header information
Version:        2
Epoch:          7
  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