CLEVIS-ENCRYPT-TPM(1)
β¨ clevis-encrypt-tpm1 β¨
okay bestie, lemme put you on real quick π this is the manual page for clevis-encrypt-tpm1, and it's all about sealing your secrets to a TPM 1.2 chip. strap in, it's giving very secure, very demure π
π¦ NAME π¦
clevis-encrypt-tpm1 β encrypts using a TPM 1.2 chip binding policy πΈ
π SYNOPSIS π
clevis encrypt tpm1 CONFIG < PT > JWE
π OVERVIEW π
so basically, the clevis encrypt tpm1 command encrypts stuff using a Trusted Platform Module 1.2 (TPM 1.2) chip. it might work with TPM 1.1 too, but ngl nobody tested that, so who knows π. also important: the tpm1 pin does not support TPM 2.0 and higher β for those you gotta use the tpm2 pin instead, periodt.
the only argument is the JSON configuration object. that's it. that's the whole vibe check. β¨
when you're using the tpm1 pin, here's the tea: we create a brand new, cryptographically-strong, random key π₯. that key gets encrypted using the TPM 1.2 chip. then later, at decryption time, that key gets decrypted again using the TPM 1.2 chip. cute lil round trip, iconic behavior honestly.
$ clevis encrypt tpm1 '{}' < PT > JWE
to decrypt the data, you literally just hand it the ciphertext (JWE):
$ clevis decrypt < JWE > PT
and no cap, like the other pins, no configuration is used for decryption β this is because clevis stores the sealed encryption key inside the JWE itself, so clevis can just fetch that key outta there and unseal it using the TPM 1.2 chip. the JWE is carrying its own little key around, main character energy ππ
π sealing to PCR state π
the pin also supports sealing data to a Platform Configuration Registers (PCR) state π. what that means: the data can only be unsealed if the PCRs hash values match the values that were used when sealing. no match, no unseal, sorry babe π.
for example, to seal the data to the PCR with indexes 0, 4 and 7, you'd do:
$ clevis encrypt tpm1 '{"pcr_ids":"0,4,7"}' < PT > JWE
okay so here's why this is so cool: the BIOS, boot loader, Grub and the Linux kernel incrementally add hashes of the various system states to those registers π. the added hashes represent the state of different components, like:
- the BIOS (PCR 0 and PCR 1)
- option ROMs (PCR 2 and PCR 3)
- the boot loader (PCR 4)
- EFI Secure Boot state (PCR 0 and PCR 7)
- etc. β¨
and the requirement for exact matching of values is what guarantees the TPM 1.2 chip only unseals the data when the system state measured by the selected registers has not changed. it's like a fingerprint for your boot state, fr fr π«Ά
although the usage of Platform Configuration Registers is standardized, the BIOS implementation might differ slightly β so always test how the particular register value changes when the system is updated, most notably when the Grub boot loaded or the Linux kernel is updated β οΈ. you can check the PCR values with:
$ cat /sys/class/tpm/tpm0/pcrs
π CONFIG π
this command uses the following configuration properties:
pcr_ids(string) β comma separated list of PCR used for policy. if it's not present, no policy is used πΈ
π LIMITATIONS π
okay so this part matters, bestie, listen up π
to avoid prompting for a password during unlocking, the encryption and decryption processes require that the well-known Storage Root Key (SRK) be configured when taking ownership of the TPM 1.2 chip. so you must have either run the tpm_takeownership command
$ tpm_takeownership --srk-well-known
during setup, or executed the tpm_changeownerauth command
$ tpm_changeownerauth --srk --set-well-known
to configure it. and btw β a well-known key is not the same as an empty key. do not confuse them, i'm begging π
Important β οΈ if you have changed the SRK to a well-known key, remember to run theupdate-initramfscommand (on Debian-like systems)text $ update-initramfs -uor thedracutcommand (on Fedora-like systems)text $ dracut -fafterward, to recreate the initramfs image, because/var/lib/tpmis included in the image π§β¨. this applies toinitramfs-toolsand Dracut in host-only mode. in Dracut's default mode,/var/lib/tpmis already configured to allow access to the TPM 1.2 chip using a well-known SRK, so you're already slaying over there π
π UNLOCKING WITH A SEPARATELY-ENCRYPTED /var VOLUME WITH TPM1 PIN π
okay so real talk bestie, this part is the β¨advancedβ¨ level and it's giving "read it twice" energy π
Because TPM1 PIN relies on the tcsd daemon from the Trousers project to access the TPM 1.2 chip, that daemon has to start early in the boot process so your root filesystem can be unlocked automatically. And here's the kicker: the /var/lib/tpm directory holds runtime data for tcsd, so it has to already be available before the daemon starts. π«
Clevis bakes a minimal copy of the /var files it needs into the initramfs image it prepares, so if everything's configured right, tcsd should be able to start during the initrd bootup phase. πΈ But once you switch over to the real root (/) filesystem, the System Manager bootup phase kicks in and /var gets mounted from the actual target. And at that point, Clevis literally cannot unlock it β because tcsd would need /var to unlock /var. ππ So /var has to already be unlocked by then. The instructions for initramfs-tools and Dracut are below, keep scrolling.
Now, if your /var volume is part of the main LVM volume group (same one as the root / filesystem) and it's protected by the same LUKS volume β no special config, you're living your best life, nothing to do. π
But if /var is encrypted separately (i.e., it uses a different LUKS volume, regardless of whether it has the same password), follow the instructions below to get that automatic Clevis unlocking going. π
π initramfs-tools Initrd Bootup
initramfs-tools unlocks the root and swap filesystems by copying the corresponding option lines from /etc/crypttab into the initramfs. So to make sure your /var volume options also get included, add the initramfs option on Debian-like systems to the relevant line in /etc/crypttab, like this:
/etc/crypttab.
...
luks-aa0ce19c-cde9-44a2-adbd-4afb1845a959 UUID=aa0ce19c-cde9-44a2-adbd-4afb1845a959 none discard,initramfs
...
That line corresponds to the crypto_LUKS volume that your /var volume uses, and you can see that with the lsblk -fp command:
LVM on LUKS.
...
ββ/dev/vda3 crypto_LUKS 2 aa0ce19c-cde9-44a2-adbd-4afb1845a959
ββ/dev/mapper/luks-aa0ce19c-cde9-44a2-adbd-4afb1845a959 LVM2_member LVM2 001 lgk4ap-Fo39-PemI-eqKn-fxW2-e3Zt-CPGIv2
ββ/dev/mapper/separate-var xfs 767b750e-bba7-4ea7-b2b8-b1e6a2e22e43 753,3M 22% /var
The example above uses an LVM-on-LUKS encryption scheme, but the same thing applies to LUKS-on-LVM β just check the crypto_LUKS volume UUID. π¦
LUKS on LVM.
...
ββ/dev/vda3 LVM2_member LVM2 001 lgk4ap-Fo39-PemI-eqKn-fxW2-e3Zt-CPGIv2
ββ/dev/mapper/separate-var crypto_LUKS 2 aa0ce19c-cde9-44a2-adbd-4afb1845a959
ββ/dev/mapper/luks-aa0ce19c-cde9-44a2-adbd-4afb1845a959 xfs 767b750e-bba7-4ea7-b2b8-b1e6a2e22e43 781,5M 19% /var
Important π After modifying/etc/crypttab, you must runupdate-initramfs -u(on Debian-like systems).
π¦ Dracut Initrd Bootup
Dracut automatically unlocks the root and swap filesystems. Your operating system installer makes sure the kernel command line (in /etc/default/grub) contains the necessary parameters for Dracut and Systemd. And Dracut considers both the kernel command line and the lines copied from /etc/crypttab when unlocking. π
By default, the root and swap lines from /etc/crypttab get copied into the initramfs. To make sure the /var volume is also unlocked, you must make sure its options are included and referenced by the kernel command line (as described below).
Caution β οΈ Changing the following options can render the system unbootable, potentially requiring a rescue DVD and expert knowledge to recover. Make a full backup before proceeding!
For recovery, you may find these commands helpful: π«Ά
cryptsetup open /dev/<device> <mapped-device>mount /dev/mapper/<mapped-device> /<target>lvm vgscanlvm lvdisplay -o lv_full_name,lv_dm_path
To ensure that the /var options are included, add either the x-initrd.attach option to the corresponding line in /etc/crypttab (to unlock the /var volume) or the x-initrd.mount option to the corresponding line in /etc/fstab (to unlock and mount the /var volume). Using both is equivalent to x-initrd.mount. β¨
/etc/crypttab.
...
luks-aa0ce19c-cde9-44a2-adbd-4afb1845a959 UUID=aa0ce19c-cde9-44a2-adbd-4afb1845a959 none discard,x-initrd.attach
...
/etc/fstab.
...
UUID=767b750e-bba7-4ea7-b2b8-b1e6a2e22e43 /var xfs defaults,x-systemd.device-timeout=0,x-initrd.mount 0 0
...
Refer to the initramfs-tools section for instructions on finding the correct /etc/crypttab line with lsblk -fp. The /etc/fstab entry is matched by the UUID of the filesystem (see the line with /var in the lsblk -fp output). π
Important π After changing/etc/crypttaband/or/etc/fstab, rundracut -f.
Note πΈ If you usex-initrd.mount, the volume is mounted during the initrd bootup phase. However, this is not strictly necessary. Systemd's startup order ensures that/varis mounted beforetcsdstarts in the System Manager bootup phase, so usingx-initrd.attachalone is sufficient.
Next, make sure the volumes are found and unlocked. Two kernel command line parameters in /etc/default/grub affect this:
rd.luks.uuidβ Either remove all values or add the UUID of thecrypto_LUKSvolume (optionally prefixed byluks-). If this option is present (it can appear multiple times), only the specified volumes are initialized from/etc/crypttab. If it is missing, all lines from/etc/crypttabare considered.rd.lvm.lvβ Either remove all values or add the full LVM volume name for/var. If this option is present (it can appear multiple times), only the listed logical volumes are initialized. If it is missing, Dracut automatically detects LVM volumes during boot.
Note π Therd.lvm.lvoption matters only in the LUKS-on-LVM case, because thecrypto_LUKSvolume is accessible only after the LVM logical volume is activated. Ifrd.lvm.lvis missing, Dracut will detect LVM volumes automatically. If it is present, make sure to include the/varfull volume name.
For more information, see manual pages of dracut.cmdline and systemd-cryptsetup-generator. π
Note π Dracut internally uses the same Systemd options, so the same logic applies even if Systemd is not present in the Dracut initrd environment.
To find the correct rd.lvm.lv value, run:
$ lvs -o lv_full_name,lv_dm_path
This shows the logical volume's full name and Device Mapper path, which also appears in the lsblk -fp output. For example, if it shows separate/var (see example below), the rd.lvm.lv value would be rd.lvm.lv=separate/var: β
LV DMPath
...
separate/var /dev/mapper/separate-var
...
Example of a kernel command line in /etc/default/grub with all options present:
/etc/default/grub.
GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora/root rd.luks.uuid=luks-21a9c1b8-c202-4985-809a-aba2d6fdab01 rd.lvm.lv=separate/var rd.luks.uuid=luks-aa0ce19c-cde9-44a2-adbd-4afb1845a959 quiet"
Example of a kernel command line in /etc/default/grub when relying on the configuration copied from /etc/crypttab and Dracut's automatic LVM detection:
/etc/default/grub.
GRUB_CMDLINE_LINUX="quiet"
Important π₯ After changing the kernel command line, update the Grub configuration withupdate-grub2(on Debian-like systems) orgrub2-mkconfig -o /etc/grub2.cfg(on Fedora-like systems).
π΅οΈ THREAT MODEL π΅οΈ
The Clevis security model relies in the fact that an attacker will not be able to access both the encrypted data and the decryption key. That's the whole vibe check. π
For most Clevis pins, the decryption key is not locally stored, so the decryption policy is only satisfied if the decryption key can be remotely accessed. It could for example be stored in a remote server or in a hardware authentication device that has to be plugged into the machine. π
The tpm1 pin is different in this regard, since a key is wrapped by a TPM 1.2 chip that is always present in the machine. This does not mean that there are not use cases for this pin, but it is important to understand the fact that an attacker that has access to both the encrypted data and the local TPM 1.2 chip will be able to decrypt the data. π No cap β that's the tradeoff, know it going in.
The use of specific Platform Configuration Registers along with Secure Boot limits the attack surface because an attacker must reproduce the exact register values that are present during sealing before the TPM 1.2 chip will allow the encryption key to be unsealed. Careful selection of registers ensures that any change to the boot process will prevent the TPM 1.2 from unsealing the encryption key. π Iconic behaviour honestly.
π SEE ALSO π
aaand that's the whole page bestie, you made it to the end, I'm so proud of you ππ«Ά this was CLEVIS-ENCRYPT-TPM(1) β the source is the Clevis manual, dated 10/16/2026. go forth and encrypt responsibly, mwah πβ¨π
π¦ where this page comes from
- fedora 44: clevis-pin-tpm1 24-1.fc44 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms