- The LUKS auto-unlock with TPM It is based on adding an extra sealed key to the PCR and releasing it only if the Boot It matches the expected state.
- Modern tools like systemd-cryptenroll and Clevis allow TPM2 to be integrated with LUKS and initramfs without resorting to handcrafted scripts.
- The choice of PCR and the correct support in initramfs determine the balance between security, upgrade tolerance, and convenience.
- This model primarily protects against disk theft and unauthorized booting, although it involves sacrificing some security against highly advanced physical attacks.
Setting up automatic LUKS unlocking using TPM has become very appealing to those who want full disk encryption without having to type the password at every boot. The problem is that there are countless different guides; some mix concepts, others depend on the distribution... and in the end, it's easy to get quite lost.
In this article, you'll find a step-by-step, in-depth explanation of the various ways to integrate LUKS with TPM (TPM2 and even TPM 1.2), using modern tools like systemd-cryptenroll and Clevis , as well as more manual methods with initramfs scripts. You'll see advantages, real-world drawbacks people encounter, how to choose PCR, and the security implications of all this.
What exactly is LUKS auto-unlock with TPM?
When we talk about auto-unlock via TPM, we mean that the computer can decrypt the LUKS volume during startup without you entering the password, provided the machine's state matches the expected one. Instead of using your passphrase, an additional key stored and sealed within the TPM is used.
In LUKS, data isn't protected directly with your password, but with an internal master key . Your passphrase (or a random key) is only used to encrypt that master key using a derivation algorithm. This allows for multiple key slots on the same volume: one or more human passwords, and another random key associated with the TPM for automatic unlocking.
The TPM, for its part, is a cryptographic chip that can store secrets and release them only if certain conditions are met, including that specific platform configuration registers, the PCRs (Platform Configuration Registers) , have particular values. These PCRs store hashes of different parts of the boot process (firmware, bootloader, kernel, Secure Boot state, etc.), so if anything is modified, the TPM refuses to release the key.
General requirements before starting
Before attempting any auto-unlock method with TPM, it's advisable to ensure that the system meets a series of basic requirements to avoid wasting time or, worse, leaving the machine unable to boot.
- You need a chip TPM2 (or TPM 1.2 in some scenarios) enabled in the BIOS/UEFI. hardware Modern systems usually include it by default, but it can be disabled. On systems using systemd, you can check if the system detects a TPM2 with a command like systemd-analyze has-tpm2.
- The volume must be encrypted with LUKSideally in format LUKS2 If you want to use systemd-cryptenroll or the modern systemd integration, you can check it with cryptsetup luksDump /dev/your_deviceIf you see LUKS1 and want to convert to LUKS2, it's a delicate operation in which it is It is essential to have a backup.
- You need to have the appropriate packages installed depending on the method: for systemd-cryptenroll they are usually systemd-cryptenroll y tpm2-tss; for Clevis they will be clevis, clevis-luks, clevis-tpm2 and, depending on the distro, modules like clevis-systemd, clevis-dracut or clevis-initramfs.
- El initramfs It must include everything necessary for early unlocking: LUKS support, drivers from the TPM and the binaries or hooks that make the request to the chip. In Debian/Ubuntu, this is managed with mkinitramfs or update-initramfs, in Fedora with dracut and in Arch with mkinitcpio.
Furthermore, it is advisable to have Secure Boot enabled if you want a model similar to BitLocker, since Secure Boot and TPM complement each other : the former validates that the boot code is signed and has not been altered, and the latter seals the key against the measurement of that boot.
Choosing the right PCR testers: a balance between safety and comfort
One of the most confusing aspects of configuring LUKS with TPM2 is deciding which PCR to use to seal the key . This isn't trivial, because the more PCRs included in the seal, the more likely it is that auto-unlock will be broken after an upgrade or hardware change. However, it will also be more difficult for an attacker to manipulate the boot process without compromising the security measures.
PCRs are numbered, and each one reflects a different part of the system. Tools like systemd-cryptenroll document the meaning of each one very well. To summarize the most relevant ones for these cases, we have firmware PCRs , boot code PCRs , partition configuration PCRs , Secure Boot status PCRs , kernel PCRs, initrd and command line PCRs , shim and MOK certificate PCRs, and even PCRs that can measure enabled LUKS volumes and machine-id.
Many people seek a compromise between security and avoiding the hassle of every update. For example, some guides recommend using only PCRs related to basic configuration and Secure Boot status , such as 1 and 7, which allows updating signed firmware and bootloaders without breaking the unlock. Other, more stringent configurations combine PCRs like 1+3+5+7+11+12+14+15 , adding partition table integrity, kernel, shim, kernel parameters, LUKS volumes, etc., at the cost of requiring any significant changes to re-enroll the key in the TPM.
There are also combinations focused on what systemd considers reasonable, such as binding the key to PCRs 0, 4, 7, and 11 to cover firmware, bootloader, Secure Boot state, and kernel packaged in a unified image. Others choose to avoid PCRs that change relatively frequently, such as those related to firmware or kernels that are updated almost daily, to avoid having to re-roll the key every few minutes.
Method 1: auto-unlock with systemd-cryptenroll and TPM2
In modern systems with LUKS2 and systemd , the cleanest way to integrate the TPM is through systemd-cryptenroll . This tool adds a sealed random key slot to LUKS using TPM2 and coordinates unlocking during boot using sd-encrypt in initramfs.
Registering the key in the TPM2
The first step is to identify the encrypted volume, usually the partition containing the root or the set of volumes you want to unlock without intervention. Once the device is located, run a command like ` systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=PCR_LIST /dev/your_device` as root.
This command generates a new random key and places it in an extra LUKS slot, sealing it to the specified PCRs. During the process, the tool will ask for a valid password for that volume to authorize the operation. The TPM is then associated with that volume: if the PCRs match, the key will be released and used transparently at boot time.
systemd-cryptenroll can also optionally combine TPM sealing with an additional PIN , using an option that forces the user to enter a short code in addition to completing the measurements. This mitigates "hotel creature" attacks where someone with physical access manipulates the environment, although in practice it complicates use and not everyone needs it.
Integration with crypttab and the kernel command line
Once the TPM slot is created in LUKS, the boot system needs to be told to try to use it. On systemd systems, the most common way is to edit /etc/crypttab and add the option tpm2-device=auto to the options field of the corresponding entry. The line format is usually something like name UUID=… none luks,tpm2-device=auto.
When the encrypted volume contains the root filesystem , many distributions also require passing an option on the kernel command line, something like `rd.luks.options=tpm2-device=auto` or a variant with the volume's UUID, depending on how the initramfs generator interprets such options. This is done by editing `/etc/default/grub` and adding the parameter to the appropriate variable (`GRUB_CMDLINE_LINUX` or `GRUB_CMDLINE_LINUX_DEFAULT`).
After modifying the GRUB configuration, you must regenerate the main configuration file using tools such as `update-grub` on Debian/Ubuntu or `grub2-mkconfig -o /boot/grub/grub.cfg` on Fedora and other derivatives. This step is crucial to ensure that the kernel receives the correct unlock parameters on the next reboot.
Regenerate initramfs with TPM and sd-encrypt support
For all of this to work in the early boot phase, the initramfs must contain sd-encrypt and the TPM2 libraries . In Fedora, this is done using dracut; in Debian/Ubuntu, update-initramfs is typically used; and in Arch, mkinitcpio comes into play with the appropriate hooks. Many guides emphasize the need to use tpm2-tss and ensure that the sd-encrypt and sd-vconsole modules are present.
On distributions like CachyOS or Arch, it's recommended to change the mkinitcpio hook list, replacing the classic encrypt- based approach with the variant using systemd, sd-encrypt, and sd-vconsole . This involves modifying the HOOKS line so that the following appear in the correct order: base, systemd, plymouth (if used), autodetect, microcode, modconf, kms, keyboard, sd-vconsole, sd-encrypt, block, filesystems, and optionally, fsck.
Once the hooks are configured, the initramfs is regenerated with ` mkinitcpio -P` or equivalent command, and on the next boot, if everything goes well, the root volume is unlocked using the TPM without requiring a password. In real user guides, it's mentioned that any misconfiguration of crypttab or hooks can prevent the system from booting, so it's recommended to back up `/etc/mkinitcpio.conf` and crypttab before making any changes.
Method 2: Auto-unlock using Clevis and TPM2
Another very popular approach, especially in RHEL, Fedora, Debian, and derivative environments , is to leverage Clevis , a policy-based decryption framework that integrates with LUKS, TPM2, and various boot systems. Clevis adds a layer of flexibility, even allowing you to combine TPM with other factors or implement more advanced configurations.
Clevis installation and TPM preparation
To work with Clevis on Debian/Ubuntu, it's common to install clevis, clevis-tpm2, clevis-luks, clevis-udisks2, clevis-systemd, and clevis-initramfs , and then refresh permissions with something like `udevadm trigger` . On systems using dracut, you can also install clevis-dracut , which injects Clevis modules into the initramfs generated by dracut.
It's advisable to check which PCR banks the TPM supports using ` tpm2_pcrread` . This command will list various hash functions (e.g., SHA1, SHA256) and show which PCRs are active. Most guides recommend using SHA256 as the measurement bank, as it's the current robust standard and is supported by almost everything.
Linking LUKS with TPM using Clevis
Once the environment is ready, locate the LUKS device (for example, with `cryptsetup luksDump /dev/sdaX` ) and execute a command like ` clevis luks bind -d /dev/sda3 tpm2 '{"pcr_bank":"sha256","pcr_ids":"0,1,7"}'` . This command adds a key associated with the TPM to LUKS and seals it to the chosen PCRs. The choice of PCR here, as with `systemd-cryptenroll`, is a compromise between security and ensuring that auto-unlocking isn't broken by every minor change.
There are practical examples where it's recommended to include at least PCR 7 (Secure Boot status) and another platform-related PCR, such as PCR 1, to mitigate some attacks while maintaining flexibility when updating the firmware or bootloader, as long as they are properly signed. Others opt for more conservative combinations, which slightly reduces security but avoids headaches on servers that are frequently updated.
Integrating Clevis with initramfs and systemd
After binding Clevis with LUKS, you need to ensure that the initramfs contains the Clevis modules and TPM libraries . On Debian/Ubuntu, this usually involves running `update-initramfs -u -k all` to regenerate the image, while on Fedora, you use `dracut -f` and verify that the Clevis module is included.
Clevis integrates with systemd's password agent framework . At startup, systemd launches various agents that respond to passphrase requests: the traditional agents that display prompts in tty or plymouth, and Clevis as an additional agent that attempts to automatically unlock the volume. This means you may still see a prompt even while Clevis is running; on some systems, even if the volume has been automatically unlocked, the previously displayed visual prompt is not cleared, leading to confusion.
For this to work as root, in addition to Clevis and the TPM binaries, packages like clevis-systemd are needed , and for the early stages of booting, either clevis-dracut or clevis-initramfs, depending on the distribution. Various practical examples show that when any of these components are missing, the system simply crashes to a password prompt or even the dracut shell, indicating that the cryptsetup could not be completed.
Method 3: Manual integration with TPM2 and scripts in initramfs
Before integrated solutions like systemd-cryptenroll or Clevis existed, many people relied—and some still do—on custom scripts within the initramfs that use low-level TPM tools (like tpm2_unseal ) to obtain a key and give it to cryptsetup.
This approach begins by installing tpm2-tools and often involves cleaning or resetting the TPM through the system or BIOS , depending on the manufacturer. Next, a long random key (e.g., 512 bits) is generated, added as a valid key in LUKS using cryptsetup, and then sealed in the TPM using the tpm2-tools utilities. This creates a key hierarchy (root key, sealing key) that holds the secret associated with certain PCRs.
For the key to be usable at boot, the initramfs must include the tpm2_unseal binary , its library dependencies, and the scripts that call that command. On systems based on initramfs-tools, hook scripts in /etc/initramfs-tools/hooks are used to include the binaries in the image, and additional scripts in /usr/local/bin or similar locations run early to obtain the key and pass it to cryptsetup.
Finally, `/etc/crypttab` is adjusted to indicate that the key is obtained using a custom keyscript that executes `tpm2_unseal`. Since keyscript options don't always integrate well with systemd in the early stages, some guides add options like `initramfs` to force the unlock attempt to occur in `initramfs` and not later. The `initramfs` is then rebuilt, and the boot process is tested.
This method is much more manual and prone to errors , but it illustrates well what is happening underneath: the only essential thing is that, during startup, there is something that is able to ask the TPM for the sealed key and pass it to cryptsetup without user intervention.
TPM 1.2 and specific methods with Dracut
Although almost everyone is talking about TPM2 these days, there are still environments where only TPM 1.2 is used . In those cases, the general pattern remains the same: a LUKS key is stored in the TPM, and the initramfs is prepared to read it automatically. There are solutions based on tpm-tools/trousers and specific dracut modules that read an NV index from the TPM at boot time.
A typical example involves installing trousers and tpm-tools , initializing the TPM, saving the key previously added to LUKS to a specific index, and then using a custom Dracut module that executes tpm_nvread on initramfs to retrieve that key and pass it to cryptsetup. If Dracut doesn't include cryptsetup by default at this stage, the module scripts need to be modified to include it, which is sometimes not straightforward because Dracut doesn't always include everything we expect.
These methods have been documented in environments like RHEL8, but they are generally considered somewhat fragile compared to modern integrations based on TPM2 and standard tools. Even so, they demonstrate that, with appropriate precautions, it is possible to achieve auto-unlock-like behavior even with TPM 1.2.
Practical differences between BitLocker and LUKS+TPM
For years , BitLocker on Windows has offered a virtually seamless experience : the system disk is encrypted, a key is sealed in the TPM, and the computer boots without prompting for anything as long as the platform doesn't undergo any suspicious changes. It's so simple to use that many organizations activate it en masse with minimal user intervention.
LUKS, conceptually, works very similarly to BitLocker : an internal master key protects the data, and various unlock keys (passwords, key files, TPM) allow access to that master key. The major difference has historically been the lack of seamless integration between different Linux distributions and boot systems, which forced administrators to build custom solutions in initramfs.
With the arrival of tools like systemd-cryptenroll and Clevis , and initramfs generated by dracut or mkinitcpio with native TPM2 support, the situation has become much closer to the BitLocker experience. Today, it's relatively easy to set up a Linux server with full disk encryption that automatically unlocks with TPM without human intervention, maintaining a level of security very similar to Windows, provided the PCRs are chosen correctly and Secure Boot is maintained.
Passionate writer about the world of bytes and technology in general. I love sharing my knowledge through writing, and that's what I'll do on this blog, show you all the most interesting things about gadgets, software, hardware, tech trends, and more. My goal is to help you navigate the digital world in a simple and entertaining way.