Use TPM to decrypt Linux LUKS Encryption

Using TPM 2.0 (Trusted Platform Module) to unlock a LUKS-encrypted drive provides a secure and seamless method for disk decryption without requiring user input at boot. This is particularly useful for headless systems or enhancing security by tying decryption keys to system integrity.

Use TPM to decrypt Linux LUKS Encryption

Using TPM 2.0 (Trusted Platform Module) to unlock a LUKS-encrypted drive provides a secure and seamless method for disk decryption without requiring user input at boot. This is particularly useful for headless systems or enhancing security by tying decryption keys to system integrity.

With tools like Clevis, you can bind a LUKS keyslot to the TPM, allowing the system to automatically decrypt the disk only if the TPM and system state (e.g. boot configuration, kernel, Secure Boot) match trusted conditions.

Assumptions

You have already installed rocky linux with full disk encryption.

Instructions

Install the following software:

sudo dnf install clevis clevis-luks clevis-systemd clevis-udisks2 clevis-dracut tpm2-tools tpm2-tss

We need to figure out what volume is encrypted to do this run lsblk and look for luks- in my case this was my output.

NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
nvme0n1                                       259:0    0 953.9G  0 disk
├─nvme0n1p1                                   259:1    0   600M  0 part  /boot/efi
├─nvme0n1p2                                   259:2    0     1G  0 part  /boot
└─nvme0n1p3                                   259:3    0 952.3G  0 part
  └─luks-0a6a8879-0145-468e-ab7e-a7fec4ca08d6 253:0    0 952.3G  0 crypt
    ├─rl_vt000464570-root                     253:1    0   921G  0 lvm   /
    └─rl_vt000464570-swap                     253:2    0  31.3G  0 lvm   [SWAP]

In this case my luks partition is nvme0n1p3 this will be the device that we pass to a lot of the commands in this process. The full path to the device is /dev/nvme0n1p3.

Verify that you have a TPM Chip by running tpm2_getcap properties-fixed
Output should look like this:

TPM2_PT_FAMILY_INDICATOR:
  raw: 0x322E3000
  value: "2.0"
TPM2_PT_LEVEL:
  raw: 0
TPM2_PT_REVISION:
  raw: 0x8A
  value: 1.38
TPM2_PT_DAY_OF_YEAR:
  raw: 0x160
TPM2_PT_YEAR:
  raw: 0x7E3
TPM2_PT_MANUFACTURER:
  raw: 0x494E5443
  value: "INTC"
TPM2_PT_VENDOR_STRING_1:
  raw: 0x41444C00
  value: "ADL"
TPM2_PT_VENDOR_STRING_2:
  raw: 0x0
  value: ""
TPM2_PT_VENDOR_STRING_3:
  raw: 0x0
  value: ""
TPM2_PT_VENDOR_STRING_4:
  raw: 0x0
  value: ""
TPM2_PT_VENDOR_TPM_TYPE:
  raw: 0x0
TPM2_PT_FIRMWARE_VERSION_1:
  raw: 0x2580012
TPM2_PT_FIRMWARE_VERSION_2:
  raw: 0x2309FD
TPM2_PT_INPUT_BUFFER:
  raw: 0x400
TPM2_PT_HR_TRANSIENT_MIN:
  raw: 0x3
TPM2_PT_HR_PERSISTENT_MIN:
  raw: 0x7
TPM2_PT_HR_LOADED_MIN:
  raw: 0x3
TPM2_PT_ACTIVE_SESSIONS_MAX:
  raw: 0x40
TPM2_PT_PCR_COUNT:
  raw: 0x18
TPM2_PT_PCR_SELECT_MIN:
  raw: 0x3
TPM2_PT_CONTEXT_GAP_MAX:
  raw: 0xFFFF
TPM2_PT_NV_COUNTERS_MAX:
  raw: 0x80
TPM2_PT_NV_INDEX_MAX:
  raw: 0x800
TPM2_PT_MEMORY:
  raw: 0x6
TPM2_PT_CLOCK_UPDATE:
  raw: 0x400000
TPM2_PT_CONTEXT_HASH:
  raw: 0xC
TPM2_PT_CONTEXT_SYM:
  raw: 0x6
TPM2_PT_CONTEXT_SYM_SIZE:
  raw: 0x100
TPM2_PT_ORDERLY_COUNT:
  raw: 0xFF
TPM2_PT_MAX_COMMAND_SIZE:
  raw: 0xF80
TPM2_PT_MAX_RESPONSE_SIZE:
  raw: 0xF80
TPM2_PT_MAX_DIGEST:
  raw: 0x30
TPM2_PT_MAX_OBJECT_CONTEXT:
  raw: 0x6CC
TPM2_PT_MAX_SESSION_CONTEXT:
  raw: 0x148
TPM2_PT_PS_FAMILY_INDICATOR:
  raw: 0x1
TPM2_PT_PS_LEVEL:
  raw: 0x0
TPM2_PT_PS_REVISION:
  raw: 0x104
TPM2_PT_PS_DAY_OF_YEAR:
  raw: 0x0
TPM2_PT_PS_YEAR:
  raw: 0x0
TPM2_PT_SPLIT_MAX:
  raw: 0x80
TPM2_PT_TOTAL_COMMANDS:
  raw: 0x65
TPM2_PT_LIBRARY_COMMANDS:
  raw: 0x65
TPM2_PT_VENDOR_COMMANDS:
  raw: 0x0
TPM2_PT_NV_BUFFER_MAX:
  raw: 0x800
TPM2_PT_MODES:
  raw: 0x0

Now run sudo clevis luks bind -d /dev/nvme0n1p3 tpm2 '{}' you should get prompted for your existing LUKS password. Enter that and then hit enter. Note: You will not see anything when you type your password in.

Now we need to update the boot process to ensure the TPM is accessible by the os during the boot process. Run this command sudo dracut -fv --regenerate-all it will take some time for this to run.

Verification

Run sudo clevis luks list -d /dev/nvme0n1p3 you should see something like this:

4: tpm2 '{"hash":"sha256","key":"ecc"}'

Now for the real test, reboot and see what happens. If everything worked right the system should reboot and you should be on the login screen. With no prompt for the decryption key.