# Limine + LUKS2 + TPM2 Auto-Unlock Guide (CachyOS/Arch Linux)

> Source: <https://gist.github.com/zerofltexx/d75168b7d2a0b146a5a6e13a397acf07>
> Published: 2025-11-19 13:53:25+00:00

Working configuration for:
- Limine bootloader
- LUKS2 encrypted root partition
- btrfs with Snapper snapshots
- dracut (required for btrfs snapshot boot)
- systemd-based initramfs
- Secure Boot enabled
- TPM2 auto-unlock using PCR 0+7
Verify your current setup:
Verify LUKS2 (not LUKS1):
sudo cryptsetup luksDump /dev/nvme1n1p2 | grep Version
Expected output:
Version: 2
Verify btrfs:
df -Th /
Expected output (look for "btrfs"):
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad btrfs 1.9T 606G 1.3T 33% /
Verify snapper is configured:
snapper list-configs
Expected output:
Config │ Subvolume
───────┼──────────
root │ /
Verify TPM2 is available:
systemd-cryptenroll --tpm2-device=list
Expected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
# Install from official repos
sudo pacman -S dracut tpm2-tss tpm2-tools
# Install from AUR
paru -S limine-dracut-support
sudo pacman -R limine-mkinitcpio-hook
Note: limine-dracut-support
and limine-mkinitcpio-hook
conflict and cannot coexist.
Create /etc/dracut.conf.d/tpm.conf
:
sudo nano /etc/dracut.conf.d/tpm.conf
Add this line:
add_dracutmodules+=" tpm2-tss "
Create /etc/dracut.conf.d/cryptsetup.conf
:
sudo nano /etc/dracut.conf.d/cryptsetup.conf
Add this line (fixes missing TPM2 token library):
install_items+=" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so "
Verify the files:
cat /etc/dracut.conf.d/tpm.conf
cat /etc/dracut.conf.d/cryptsetup.conf
Expected output:
add_dracutmodules+=" tpm2-tss "
install_items+=" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so "
Edit /etc/crypttab
:
sudo nano /etc/crypttab
Change from:
luks-<UUID> UUID=<UUID> none
To:
luks-<UUID> UUID=<UUID> - tpm2-device=auto
Example:
luks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto
Verify:
cat /etc/crypttab
Expected output (look for -
and tpm2-device=auto
):
luks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto
Edit /etc/default/limine
:
sudo nano /etc/default/limine
Change from (mkinitcpio syntax):
KERNEL_CMDLINE[default]+="... cryptdevice=UUID=<UUID>:<mapper-name> ..."
To (dracut syntax):
KERNEL_CMDLINE[default]+="... rd.luks.name=<UUID>=<mapper-name> ..."
Example:
KERNEL_CMDLINE[default]+="quiet nowatchdog splash rw rootflags=subvol=/@ rd.luks.name=3d2966af-234b-424e-a81d-570f9d2299ad=luks-3d2966af-234b-424e-a81d-570f9d2299ad root=/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad"
Verify:
cat /etc/default/limine
Expected output (look for rd.luks.name=
instead of cryptdevice=
):
ESP_PATH="/boot"
KERNEL_CMDLINE[default]+="quiet nowatchdog splash rw rootflags=subvol=/@ rd.luks.name=3d2966af-234b-424e-a81d-570f9d2299ad=luks-3d2966af-234b-424e-a81d-570f9d2299ad root=/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad"
BOOT_ORDER="*, *lts, *fallback, Snapshots"
sudo limine-dracut
This will:
- Generate new initramfs with dracut
- Update Limine boot entries
- Apply new kernel parameters
Expected output:
dracut: Executing: /usr/bin/dracut --force --hostonly ...
dracut: *** Including module: systemd ***
dracut: *** Including module: tpm2-tss ***
dracut: *** Including module: crypt ***
...
dracut: *** Creating initramfs image file done ***
sudo reboot
IMPORTANT: You should still be prompted for your LUKS password. Verify:
- System boots correctly
- Password unlock works
- System fully boots to desktop
If this fails, DO NOT PROCEED. Fix boot issues before enrolling TPM.
After confirming password boot works:
Verify TPM is detected:
systemd-cryptenroll --tpm2-device=list
Expected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
Enroll TPM key (replace /dev/nvme1n1p2
with your LUKS partition):
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2
Expected output:
🔐 Please enter current passphrase for disk /dev/nvme1n1p2: ****
New TPM2 token enrolled as key slot 1.
PCR Explanation:
- PCR 0: UEFI firmware code
- PCR 7: Secure Boot state
Verify enrollment:
sudo systemd-cryptenroll /dev/nvme1n1p2
Expected output:
SLOT TYPE
0 password
1 tpm2
Also verify token:
sudo cryptsetup luksDump /dev/nvme1n1p2 | grep -A 5 "Tokens:"
Expected output:
Tokens:
0: systemd-tpm2
tpm2-hash-pcrs: 0+7
tpm2-pcr-bank: sha256
tpm2-pubkey:
(null)
sudo limine-dracut
Expected output:
dracut: Executing: /usr/bin/dracut --force --hostonly ...
dracut: *** Including module: tpm2-tss ***
...
dracut: *** Creating initramfs image file done ***
sudo reboot
Expected behavior:
- System boots to Limine
- LUKS partition automatically unlocks (no password prompt)
- System boots normally
If TPM unlock fails:
- You'll be prompted for password (fallback still works)
- System is NOT bricked
Check TPM enrollment:
sudo systemd-cryptenroll /dev/nvme1n1p2
Expected output:
SLOT TYPE
0 password
1 tpm2
Check LUKS keyslots:
sudo cryptsetup luksDump /dev/nvme1n1p2
Expected output (look for Token 0: systemd-tpm2 and Keyslot 1):
LUKS header information
Version: 2
...
Tokens:
0: systemd-tpm2
tpm2-hash-pcrs: 0+7
tpm2-pcr-bank: sha256
...
Keyslots:
0: luks2
Key: 512 bits
...
1: luks2
Key: 512 bits
...
Verify dracut includes TPM modules:
lsinitrd | grep tpm2
Expected output (should show TPM-related files):
-rw-r--r-- 1 root root 123456 Nov 19 18:53 usr/lib/systemd/system-generators/systemd-tpm2-generator
drwxr-xr-x 3 root root 0 Nov 19 18:53 usr/lib/cryptsetup
-rwxr-xr-x 1 root root 98765 Nov 19 18:53 usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so
Check journal for errors:
sudo journalctl -b | grep -i tpm
sudo journalctl -b | grep -i crypt
Look for errors like:
libcryptsetup-token-systemd-tpm2.so: cannot open shared object file
- Missing cryptsetup libraryFailed to unseal
- PCR values changedTPM2 token not found
- Enrollment failed
Common causes:
- Missing cryptsetup library - verify
/etc/dracut.conf.d/cryptsetup.conf
- PCR values changed (firmware update) - re-enroll TPM key
- Secure Boot state changed - re-enroll TPM key
PCR values change when:
- Firmware/BIOS updated
- Secure Boot keys changed
- Boot configuration modified
Solution - Re-enroll TPM:
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2
sudo limine-dracut
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2
sudo limine-dracut
Password unlock continues to work.
List TPM devices:
systemd-cryptenroll --tpm2-device=list
Expected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
Check TPM in sysfs:
cat /sys/class/tpm/tpm0/device/description
Expected output:
TPM 2.0 Device
Check dmesg for TPM:
sudo dmesg | grep -i tpm
Expected output (should show TPM initialization):
[ 0.614715] tpm_crb MSFT0101:00: Disabling hwrng
- Password always works - TPM is convenience, not a replacement for your password
- Snapshots remain bootable - With
limine-snapper-sync
, btrfs snapshots work with TPM - PCR selection trade-offs:
- PCR 0+7 (recommended): Survives most updates, secure
- PCR 0+2+7: More secure, may break on boot config changes
- PCR 7 only: Most flexible, least secure
- Secure Boot required - PCR 7 measures Secure Boot state
- Recovery is safe - Password fallback always available
For systems with btrfs snapshots (using Snapper/Timeshift), dracut is required because:
- mkinitcpio's systemd hook is incompatible with btrfs-overlayfs
- dracut properly supports bootable snapshot entries via
limine-snapper-sync
If you don't use btrfs snapshots, you can use the simpler mkinitcpio path.
Tested on:
- CachyOS (Arch-based)
- Limine 10.3.0-1
- dracut 109-1
- systemd 258.2-2
- Kernel: linux-cachyos 6.17.8-2
- Hardware: ASUS ROG with Intel PTT (TPM 2.0)
