{"slug": "limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux", "title": "Limine + LUKS2 + TPM2 Auto-Unlock Guide (CachyOS/Arch Linux)", "summary": "This article provides a step-by-step guide for configuring automatic LUKS2 root partition decryption using a TPM2 chip on Arch Linux or CachyOS systems using the Limine bootloader and dracut. The process involves installing necessary packages, configuring dracut modules and crypttab, switching kernel parameters from mkinitcpio to dracut syntax, and then enrolling a TPM2 key bound to PCRs 0 and 7 after verifying that password-based boot still works. The guide emphasizes verifying each configuration step and warns against proceeding with TPM enrollment if the system does not boot correctly with a password first.", "body_md": "Working configuration for:\n- Limine bootloader\n- LUKS2 encrypted root partition\n- btrfs with Snapper snapshots\n- dracut (required for btrfs snapshot boot)\n- systemd-based initramfs\n- Secure Boot enabled\n- TPM2 auto-unlock using PCR 0+7\nVerify your current setup:\nVerify LUKS2 (not LUKS1):\nsudo cryptsetup luksDump /dev/nvme1n1p2 | grep Version\nExpected output:\nVersion: 2\nVerify btrfs:\ndf -Th /\nExpected output (look for \"btrfs\"):\nFilesystem Type Size Used Avail Use% Mounted on\n/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad btrfs 1.9T 606G 1.3T 33% /\nVerify snapper is configured:\nsnapper list-configs\nExpected output:\nConfig │ Subvolume\n───────┼──────────\nroot │ /\nVerify TPM2 is available:\nsystemd-cryptenroll --tpm2-device=list\nExpected output:\nPATH DEVICE DRIVER\n/dev/tpmrm0 MSFT0101:00 tpm_crb\n# Install from official repos\nsudo pacman -S dracut tpm2-tss tpm2-tools\n# Install from AUR\nparu -S limine-dracut-support\nsudo pacman -R limine-mkinitcpio-hook\nNote: limine-dracut-support\nand limine-mkinitcpio-hook\nconflict and cannot coexist.\nCreate /etc/dracut.conf.d/tpm.conf\n:\nsudo nano /etc/dracut.conf.d/tpm.conf\nAdd this line:\nadd_dracutmodules+=\" tpm2-tss \"\nCreate /etc/dracut.conf.d/cryptsetup.conf\n:\nsudo nano /etc/dracut.conf.d/cryptsetup.conf\nAdd this line (fixes missing TPM2 token library):\ninstall_items+=\" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so \"\nVerify the files:\ncat /etc/dracut.conf.d/tpm.conf\ncat /etc/dracut.conf.d/cryptsetup.conf\nExpected output:\nadd_dracutmodules+=\" tpm2-tss \"\ninstall_items+=\" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so \"\nEdit /etc/crypttab\n:\nsudo nano /etc/crypttab\nChange from:\nluks-<UUID> UUID=<UUID> none\nTo:\nluks-<UUID> UUID=<UUID> - tpm2-device=auto\nExample:\nluks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto\nVerify:\ncat /etc/crypttab\nExpected output (look for -\nand tpm2-device=auto\n):\nluks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto\nEdit /etc/default/limine\n:\nsudo nano /etc/default/limine\nChange from (mkinitcpio syntax):\nKERNEL_CMDLINE[default]+=\"... cryptdevice=UUID=<UUID>:<mapper-name> ...\"\nTo (dracut syntax):\nKERNEL_CMDLINE[default]+=\"... rd.luks.name=<UUID>=<mapper-name> ...\"\nExample:\nKERNEL_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\"\nVerify:\ncat /etc/default/limine\nExpected output (look for rd.luks.name=\ninstead of cryptdevice=\n):\nESP_PATH=\"/boot\"\nKERNEL_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\"\nBOOT_ORDER=\"*, *lts, *fallback, Snapshots\"\nsudo limine-dracut\nThis will:\n- Generate new initramfs with dracut\n- Update Limine boot entries\n- Apply new kernel parameters\nExpected output:\ndracut: Executing: /usr/bin/dracut --force --hostonly ...\ndracut: *** Including module: systemd ***\ndracut: *** Including module: tpm2-tss ***\ndracut: *** Including module: crypt ***\n...\ndracut: *** Creating initramfs image file done ***\nsudo reboot\nIMPORTANT: You should still be prompted for your LUKS password. Verify:\n- System boots correctly\n- Password unlock works\n- System fully boots to desktop\nIf this fails, DO NOT PROCEED. Fix boot issues before enrolling TPM.\nAfter confirming password boot works:\nVerify TPM is detected:\nsystemd-cryptenroll --tpm2-device=list\nExpected output:\nPATH DEVICE DRIVER\n/dev/tpmrm0 MSFT0101:00 tpm_crb\nEnroll TPM key (replace /dev/nvme1n1p2\nwith your LUKS partition):\nsudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2\nExpected output:\n🔐 Please enter current passphrase for disk /dev/nvme1n1p2: ****\nNew TPM2 token enrolled as key slot 1.\nPCR Explanation:\n- PCR 0: UEFI firmware code\n- PCR 7: Secure Boot state\nVerify enrollment:\nsudo systemd-cryptenroll /dev/nvme1n1p2\nExpected output:\nSLOT TYPE\n0 password\n1 tpm2\nAlso verify token:\nsudo cryptsetup luksDump /dev/nvme1n1p2 | grep -A 5 \"Tokens:\"\nExpected output:\nTokens:\n0: systemd-tpm2\ntpm2-hash-pcrs: 0+7\ntpm2-pcr-bank: sha256\ntpm2-pubkey:\n(null)\nsudo limine-dracut\nExpected output:\ndracut: Executing: /usr/bin/dracut --force --hostonly ...\ndracut: *** Including module: tpm2-tss ***\n...\ndracut: *** Creating initramfs image file done ***\nsudo reboot\nExpected behavior:\n- System boots to Limine\n- LUKS partition automatically unlocks (no password prompt)\n- System boots normally\nIf TPM unlock fails:\n- You'll be prompted for password (fallback still works)\n- System is NOT bricked\nCheck TPM enrollment:\nsudo systemd-cryptenroll /dev/nvme1n1p2\nExpected output:\nSLOT TYPE\n0 password\n1 tpm2\nCheck LUKS keyslots:\nsudo cryptsetup luksDump /dev/nvme1n1p2\nExpected output (look for Token 0: systemd-tpm2 and Keyslot 1):\nLUKS header information\nVersion: 2\n...\nTokens:\n0: systemd-tpm2\ntpm2-hash-pcrs: 0+7\ntpm2-pcr-bank: sha256\n...\nKeyslots:\n0: luks2\nKey: 512 bits\n...\n1: luks2\nKey: 512 bits\n...\nVerify dracut includes TPM modules:\nlsinitrd | grep tpm2\nExpected output (should show TPM-related files):\n-rw-r--r-- 1 root root 123456 Nov 19 18:53 usr/lib/systemd/system-generators/systemd-tpm2-generator\ndrwxr-xr-x 3 root root 0 Nov 19 18:53 usr/lib/cryptsetup\n-rwxr-xr-x 1 root root 98765 Nov 19 18:53 usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so\nCheck journal for errors:\nsudo journalctl -b | grep -i tpm\nsudo journalctl -b | grep -i crypt\nLook for errors like:\nlibcryptsetup-token-systemd-tpm2.so: cannot open shared object file\n- Missing cryptsetup libraryFailed to unseal\n- PCR values changedTPM2 token not found\n- Enrollment failed\nCommon causes:\n- Missing cryptsetup library - verify\n/etc/dracut.conf.d/cryptsetup.conf\n- PCR values changed (firmware update) - re-enroll TPM key\n- Secure Boot state changed - re-enroll TPM key\nPCR values change when:\n- Firmware/BIOS updated\n- Secure Boot keys changed\n- Boot configuration modified\nSolution - Re-enroll TPM:\nsudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2\nsudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2\nsudo limine-dracut\nsudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2\nsudo limine-dracut\nPassword unlock continues to work.\nList TPM devices:\nsystemd-cryptenroll --tpm2-device=list\nExpected output:\nPATH DEVICE DRIVER\n/dev/tpmrm0 MSFT0101:00 tpm_crb\nCheck TPM in sysfs:\ncat /sys/class/tpm/tpm0/device/description\nExpected output:\nTPM 2.0 Device\nCheck dmesg for TPM:\nsudo dmesg | grep -i tpm\nExpected output (should show TPM initialization):\n[ 0.614715] tpm_crb MSFT0101:00: Disabling hwrng\n- Password always works - TPM is convenience, not a replacement for your password\n- Snapshots remain bootable - With\nlimine-snapper-sync\n, btrfs snapshots work with TPM - PCR selection trade-offs:\n- PCR 0+7 (recommended): Survives most updates, secure\n- PCR 0+2+7: More secure, may break on boot config changes\n- PCR 7 only: Most flexible, least secure\n- Secure Boot required - PCR 7 measures Secure Boot state\n- Recovery is safe - Password fallback always available\nFor systems with btrfs snapshots (using Snapper/Timeshift), dracut is required because:\n- mkinitcpio's systemd hook is incompatible with btrfs-overlayfs\n- dracut properly supports bootable snapshot entries via\nlimine-snapper-sync\nIf you don't use btrfs snapshots, you can use the simpler mkinitcpio path.\nTested on:\n- CachyOS (Arch-based)\n- Limine 10.3.0-1\n- dracut 109-1\n- systemd 258.2-2\n- Kernel: linux-cachyos 6.17.8-2\n- Hardware: ASUS ROG with Intel PTT (TPM 2.0)", "url": "https://wpnews.pro/news/limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux", "canonical_source": "https://gist.github.com/zerofltexx/d75168b7d2a0b146a5a6e13a397acf07", "published_at": "2025-11-19 13:53:25+00:00", "updated_at": "2026-05-23 10:35:27.626843+00:00", "lang": "en", "topics": ["open-source", "cybersecurity", "developer-tools"], "entities": ["Limine", "LUKS2", "TPM2", "CachyOS", "Arch Linux", "btrfs", "Snapper", "dracut"], "alternates": {"html": "https://wpnews.pro/news/limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux", "markdown": "https://wpnews.pro/news/limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux.md", "text": "https://wpnews.pro/news/limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux.txt", "jsonld": "https://wpnews.pro/news/limine-luks2-tpm2-auto-unlock-guide-cachyos-arch-linux.jsonld"}}