Prerequisites
Before we begin, the following conditions must be met:
| Requirement | Check command |
|---|---|
| LUKS2 (not LUKS1) | cryptsetup luksDump /dev/nvme1n1p2 | grep "Version:" |
| TPM2 chip present | systemd-cryptenroll --tpm2-device=list |
| Secure Boot active (User Mode) | bootctl status | grep "Secure Boot" |
| systemd-boot as bootloader | bootctl status |
| UKI-based boot | ls /boot/EFI/Linux/*.efi |
⚠️ Important: This guide is specifically for systems that use Unified Kernel Images (UKI) — i.e.
.efifiles under/boot/EFI/Linux/rather than classic loader entries under/boot/loader/entries/. The procedure differs for classic setups with loader entries.
Background: Why UKI + sd-encrypt?
A Unified Kernel Image bundles the kernel, initramfs, microcode and kernel cmdline into a single signed .efi file. Combined with Secure Boot, this creates a complete chain of trust: the firmware verifies the UKI signature before the kernel even starts.
The TPM2 chip uses PCR registers (Platform Configuration Registers) to measure the system state. By binding the LUKS key to PCR 0 (firmware integrity) and PCR 7 (Secure Boot state), the key is only released when the system boots in the expected state — i.e. with active Secure Boot and unchanged firmware.
The classic encrypt hook in mkinitcpio does not support TPM2. The sd-encrypt hook is required for this, which is based on systemd-cryptsetup and reads its configuration from /etc/crypttab.
Step 1: Enroll the TPM2 Key
systemd-cryptenroll writes a TPM2-bound key directly into the LUKS2 header. The existing passphrase is always retained as a fallback.
| |
Verify the enrollment:
| |
Expected output:
| |
Step 2: Populate /etc/crypttab
This is the most common mistake in failed setups: the sd-encrypt hook reads exclusively from /etc/crypttab — if this file is empty, it cannot find the LUKS partition and the boot will fail.
First, retrieve the UUID of the LUKS partition:
| |
Then add it to /etc/crypttab:
| |
| |
⚠️ Choose the
name(hereroot) to exactly match how the LUKS partition is currently mapped — verify withlsblk.
Step 3: Clean Up the Kernel Cmdline
Kernel parameters for UKIs are embedded from /etc/kernel/cmdline. The cryptdevice= parameter belongs to the old encrypt hook and must be removed — sd-encrypt does not recognise it.
| |
Before:
| |
After:
| |
⚠️ Everything must remain on a single line with no trailing newline.
Step 4: Adjust the mkinitcpio Hooks
| |
Before:
| |
After:
| |
Summary of changes:
| Old | New | Reason |
|---|---|---|
udev | systemd | Required base for all sd-* hooks |
keymap consolefont | sd-vconsole | systemd equivalent, reads from /etc/vconsole.conf |
encrypt | sd-encrypt | TPM2 support via systemd-cryptsetup |
Step 5: Rebuild Only the Main UKI
If an LTS kernel is installed, it is recommended to only rebuild the main UKI and keep the LTS UKI as a fallback. This allows booting with a password using the LTS kernel if something goes wrong.
| |
Step 6: Sign the New UKI with sbctl
Since Secure Boot is active, the newly built UKI must be signed before the firmware will accept it:
| |
Step 7: Reboot and Test
| |
On success: no password prompt, direct boot via TPM2 unlock.
If a password is still requested: that is the normal fallback — the TPM did not release the key. The most common cause is an unexpected PCR state (e.g. Secure Boot disabled or a firmware update that changed PCR 0).
Step 8 (After Successful Test): Update the LTS UKI as Well
| |
Troubleshooting
TPM does not release the key
| |
Common causes:
crypttabis empty or misconfiguredcryptdevice=is still present in the kernel cmdline- A firmware update changed PCR 0 → re-enrollment required
Reset enrollment and re-enroll
| |
That’s it. The system will now boot without a password prompt — as long as Secure Boot is active and the firmware remains unchanged. The LUKS passphrase is always available as a fallback.