Complete guide to /dev/tpm0, /dev/tpmrm0, and the tpm2_pcrread and tpm2_pcr_extend commands in Linux

  • TPM 2.0 allows measured boot and LUKS keys tied to PCRs, ideal with PBA PIN.
  • Use /dev/tpmrm0 and tpm2_pcrread/tpm2_pcrextend to manage PCRs.
  • UKI + PCR policy signed stabilizes updates without losing security.
  • Mitigate cold boot and sniffing with PBA and parameter encryption; maintain recovery.

TPM and tpm2 commands in Linux

In recent years, TPM 2.0 modules have gone from being a hardware mystery to a common part of any modern computer with UEFI and Secure Boot. This article explains what /dev/tpm0 and /dev/tpmrm0 are and how to use tpm2_pcrread and tpm2_pcrextend. (as well as its actual command in tpm2-tools), as well as explaining how they fit into measured boot, disk encryption, and signed PCR policies in Linux.

Useful documentation exists, but it is scattered among systemd man pages, wiki entries, and very dense posts; Here we gather all the key information (PCRs, practical examples, risks and defenses) so that technical people, even if they are not TPM experts, can work with these tools without getting lost in obscure details.

What is a TPM 2.0 and why you might care

A Trusted Platform Module is a security chip that lives on your motherboard (or inside the CPU like fTPM/Intel PTT) and acts as a secure store, random number generator, and root of trust for the system. It's passive: if you don't use it, it does nothing., but when you integrate it into your boot flow and disk encryption, it provides integrity verification and hardware-protected keys.

In practice, a TPM 2.0 allows you two main modes of use in disk encryption: a) generate/save a strong key and protect its use with a PIN with anti-brute force lock; b) activate the so-called measured boot, where Each boot component is measured in PCR records, so the key is only “unwrapped” if the system has not been tampered with (and optionally with a pre-boot PIN).

/dev/tpm0 and /dev/tpmrm0: differences and when to use each one

On Linux you will see two character devices when TPM 2.0 is available. /dev/tpm0 is the “raw” interface of the TPMWhile /dev/tpmrm0 exposes access through the Resource Manager (a manager that multiplies clients, manages sessions and resources), being the one recommended by tpm2-tools in most scenarios.

If you are unsure whether a TPM exists or not, you can hot-test it. If /sys/class/tpm/ is empty or the wiki command returns nothing, no TPM visible: It may not exist physically or may be disabled in firmware.

# ¿Hay TPM 2.0?
ls /sys/class/tpm/
cat /sys/class/tpm/tpm*/tpm_version_major
# Dispositivos
ls -l /dev/tpm*

When both device nodes are present, tpm2-tools will normally detect /dev/tpmrm0 and use it automatically. If you need to force a device, most tools accept –tcti or use TCTI environment variables, but for common tasks it is not usually necessary.

TPM PCRs: How they work and what they measure

Platform Configuration Registers are records that store hashes (usually SHA-256) of the state of critical components at each boot phase. They are initialized to zero at power-up cycle and can only be “extended”: never rewrite or erase (except in debug cases like PCR 16).

The fundamental operation is the extension: new_value = SHA256(current_value || SHA256(data))This is how measurements are chained together without allowing opportunistic resets. This pattern is used to measure firmware, configuration, Secure Boot, kernel, initrd, and kernel parameters, among others.

On modern equipment you will see 24 PCRs (0–23). The most relevant ones in UEFI boot with systemd are:
– PCR 0: firmware code.
– PCR 1: firmware configuration (UEFI settings).
– PCR 7: Secure Boot status and certificates it trusts.
– PCR 9: initrd(s) measured by the kernel.
– PCR 11: UKI (Unified Kernel Image) and phase marks via systemd-stub/systemd-pcrphase.
– PCR 12: kernel command line.

Read and extend PCRs with tpm2-tools: tpm2_pcrread and tpm2_pcr_extend

In tpm2-tools the reading is done with tpm2_pcrread and the extension with tpm2_pcrextend. You will sometimes see “tpm2_pcr_extend” referred to as the conceptual operation of extending, but The actual suite command is tpm2_pcrextend.

To inspect the current status of the PCRs SHA-256, it is as simple as:

# Leer PCRs en SHA-256 (ejemplos de índices habituales)
sudo tpm2_pcrread sha256:0,1,7,9,11,12

# O todos los PCRs SHA-256 disponibles
tpm2_pcrread sha256:all

To extend a PCR with the hash of arbitrary data (as a pedagogical example, the hash of /etc/passwd), calculate the SHA-256 and extend it. Remember: the TPM does not receive gigantic data, but its hash, by limits and design.

# 1) Guardar el hash de /etc/passwd
echo -n $(sha256sum /etc/passwd | cut -d' ' -f1) > passwd.sha

# 2) Extender PCR 7 (ejemplo) con el hash previo
sudo tpm2_pcrextend 7:sha256=$(cat passwd.sha)

# 3) Ver el nuevo valor del PCR 7
tpm2_pcrread sha256:7

If you want to reproduce the extension mathematics outside of the TPM, You concatenate the current PCR value (binary) with the new hash and you apply SHA-256 again to check the result.

Can a PCR be reset?

Under normal conditions, no. The philosophy is that a PCR only grows with extensionsThere is one exception: PCR 16 is typically reserved for “debug” and can be reset in certain flows, but it isn’t useful as the security root of your policy.

Measured Boot, LUKS, and systemd-cryptenroll: Putting the Pieces Together

When you integrate the TPM into your disk encryption, you can “bind” the key unlock to a set of PCRs. If in the current boot those PCRs have the same values ​​as when you registered the key, the TPM is unsealed and the LUKS volume is automatically opened (with or without a pre-boot PIN, depending on your configuration).

This is done very nicely with systemd-cryptenroll and systemd-cryptsetup. The idea is to create your volume, enroll the TPM key, and add a recovery key. so you don't get left out if measurements change (for example, after updating firmware or kernel).

# Ejemplo: crear LUKS, matricular TPM y añadir recuperación (pseudoflujo)
# 1) Crear el volumen con contraseña temporal
sudo cryptsetup luksFormat /dev/nvme0n1p2

# 2) Matricular TPM en LUKS usando PCRs concretos y PIN
sudo systemd-cryptenroll \
  --tpm2-device=auto \
  --tpm2-with-pin=yes \
  --tpm2-pcrs=1+2+3+4 \
  --wipe-slot=empty \
  /dev/nvme0n1p2

# 3) Añadir clave de recuperación aleatoria
sudo systemd-cryptenroll --recovery-key /dev/nvme0n1p2

# 4) Abrir con TPM o con recovery cuando proceda
systemd-cryptsetup attach root /dev/nvme0n1p2 - tpm2-device=auto

If you force a discrepancy (for example, you extend PCR 4 on purpose), the TPM will no longer release the key and you will need to use the recovery key. You can later re-enroll the TPM with the new current values ​​using –wipe-slot=tpm2 and another execution of systemd-cryptenroll.

Which PCRs to choose and why

The more relevant PCRs you link, the more surface area you reduce, but the more often you'll have to re-register after legitimate changes. Some practical criteria:
– PCR 7 (Secure Boot): Should be very stable if your keyset doesn’t change.
– PCR 0/1 (firmware and configuration): These rarely change; they require re-registration after updating firmware or changing the BIOS/UEFI.
– PCR 9/11/12 (kernel, initrd, UKI and cmdline): These change frequently if you don’t use UKI or stable signature/policy.

In some environments it has been seen to link only PCR 7, relying on Secure Boot verifying kernel and initrd if they are started as signed UKI and using systemd-boot which does not allow editing kernel parameters when SB is active. That works, but if your Secure Boot relies on third-party keys (such as Microsoft 3rd Party) it is easier to orchestrate an alternate boot that preserves PCR 7 and therefore It is not the most restrictive option.

UKI and PCR policies signed: stability without losing security

A practical solution to avoid re-registering every time you update the kernel is to use UKI (Unified Kernel Image) and a signed PCR policyYou generate a key pair, bind the public key to the TPM upon registration, and sign your UKI after each update. The TPM trusts that signature and allows unlocking even if the specific kernel hash changes.

The systemd-measure tool and the systemd-ukify helper make this easy: ukify packages kernel, initrd and cmdline into UKI (usually measured in PCR 11) and systemd-measure signs the policy. With mkinitcpio, ukify can be integrated so that post-install the signature executes itself.

# Esquema típico (pseudocomandos)
# 1) Crear claves para política PCR firmada
openssl genpkey -algorithm RSA -out /etc/kernel/pcr-initrd.key.pem -pkeyopt rsa_keygen_bits:3072
openssl req -new -x509 -key /etc/kernel/pcr-initrd.key.pem -out /etc/kernel/pcr-initrd.pub.pem -subj "/CN=UKI PCR Policy"

# 2) Configurar ukify/mkinitcpio para generar UKI y firmar política
# (consultar man ukify y systemd-measure para parámetros)

# 3) Matricular en LUKS atando PCRs y clave pública de la política
sudo systemd-cryptenroll \
  --tpm2-device=auto \
  --wipe-slot=tpm2 \
  --tpm2-with-pin=yes \
  --tpm2-pcrs=0+1+2+7 \
  --tpm2-public-key=/etc/kernel/pcr-initrd.pub.pem \
  --tpm2-public-key-pcrs=11 \
  /dev/nvme0n1p2

Thus, Your policy remains stable against kernel/initrd changes as long as you continue signing the UKI with your key.If you renew your passwords or change your PCR set, you'll need to re-enroll.

Examples of measurement chains with systemd

During boot, systemd-stub and systemd-pcrphase extend PCRs at specific times. For example, “enter-initrd” is recorded in PCR 11, allowing an unlock to only be valid within the initrd (reducing vectors where an attacker tries to reuse the key later).

In systems with UKI, the UKI content is measured in PCR 11; in systems without UKI, the kernel measures initrds in PCR 9 and the bootloader can measure the cmdline in PCR 12. Make sure you cover initrd and cmdline in your policy, or someone could backdoorear the initrd or boot with a malicious cmdline like init = / bin / bash.

Real risks: cold boot, TPM sniffing, and more

What can go wrong? Several things to know when modeling threats. Cold boot attacks are still viable: if the unlock is fully automatic, an attacker can repeat unlimited attempts. The clear mitigation is to require a pre-boot PIN (PBA), reducing attempts to one per power cycle.

Another category is the sniffing attacks on the TPM busThe CPU requests the key, the TPM sends it; if the link is tapped, the key can be leaked. To this end, systemd implements "parameter encryption" so that the exchange is encrypted; alternatively, using fTPM/Intel PTT or encrypted memory reduces exposure. There are relatively affordable public demonstrations (even with microcontrollers) that illustrate the feasibility on major brand laptops.

There have also been academic and practical vulnerabilities: TPM-Fail, faultTPM (with notable impact on AMD) and the case bitpixie (CVE-2023-21563)This doesn't mean the TPM is useless, but you should keep your firmware up to date, understand your threat model, and not blindly trust it.

BitLocker status against these threats

In the Windows world, the most widely deployed disk encryption is BitLocker. It has now been noted that its default configuration (auto unlock only with TPM) It leaves the door open to both cold boot and TPM channel sniffing, as it doesn't implement systemd-style parameter encryption. This makes certain corporate computers vulnerable to attack within minutes.

The recommendation there is to enable pre-boot authentication via policies/registry or CLI, something that isn't sufficiently exposed to the average user. Also, remember to check where the recovery key is stored: it often resides in the user's Microsoft account, which It is another angle of risk if not controlled.

Offensive/Defensive Trick: Replace the LUKS root to force your password

There is an interesting vector when there is no pre-boot authentication. An attacker can clone the real LUKS partition, replace it with another LUKS with the same UUID and a password that he knows, and boot the computer. Since the PCR measurements match, the TPM releases the key, but it doesn't match the fake LUKS, so the initrd will prompt for the "recovery" key. By entering the password known to the attacker, your system runs as root in the initrd, and you can then orchestrate the theft of the original key (for example, by mounting the real copy over the network and using systemd-cryptsetup).

Clear mitigations: activate pre-boot authentication, leverage systemd-pcrphase to bind unlocking strictly to the initrd phase, and consider measuring/binding the target LUKS volume as well (requires careful design to avoid vicious circles).

Choosing partitioning and second key: best practice

Keep a recovery key It's mandatory: if the TPM or the motherboard dies, your key tied to the TPM is useless. LUKS allows multiple slots (TPM uses one, recovery uses another). Additionally, separating the / and /home partitions has advantages: you can apply strict measurement with TPM a/ and use a strong key or FIDO2/YubiKey device for /home, reducing overall trust in a single mechanism.

What happens when you update firmware or kernel?

If you change firmware or touch UEFI options, PCRs like 0/1 will change and the TPM will not release the key until you re-enroll. For kernel and initrd, changes are frequentIf you don't use a UKI with a signed policy, each update could force you to use the recovery option and re-register later. With a signed UKI, you just sign it and that's it.

Community Notes and Observations

In some popular guides of certain distributions it has been recommended bind only PCR 7 whenever using UKI and systemd-boot, relying on Secure Boot's safeguards and the inability to edit the cmdline. It works, but there are risks if you rely on third parties. A bug has also been documented in the past where hitting Enter would bring up a recovery shell after unlocking; it's a good idea to keep your versions up to date to avoid surprises.

Interesting comments were shared in 2025/06: TPM fault continues to affect AMD to some extent; wikis have added specific sections on signed PCR policies; and the installer for a distribution that offers FDE with TPM as an experimental feature was tested, with some practical hiccups (requiring recovery on first boot, dependency on snaps, double disk encryption), an issue that deserves a more in-depth audit.

A follow-up focused on disk encryption in Windows was published in 2025/07. The overall conclusion reinforces the need for PBA and encrypting the TPM channel., as well as limiting reliance on third-party keys in Secure Boot.

Operational tips with tpm2-tools and systemd

For everyday use: Install tpm2-tools and tpm2-tss. Uses /dev/tpmrm0 by default, and tpm2_pcrread/tpm2_pcrextend for testing and experimenting with PCRs. Avoid extending production PCRs with arbitrary data: do this in labs or use PCR 16 for testing.

When enrolling with systemd-cryptenroll: –tpm2-device=auto detects TPM; –tpm2-with-pin adds PBA; –tpm2-pcrs=… select your PCRs; –tpm2-public-key=… and –tpm2-public-key-pcrs=… activate a signed PCR policy (e.g., tied to PCR 11 for UKI). Don't forget –wipe-slot when you want to clean a previous slot.

If you don't have TPM and systemd makes you wait on boot

Occasionally, after an update, a service attempts to use the TPM even though your machine doesn't have it visible, causing timeouts on boot. First check that no /dev/tpm* appears nor entries in /sys/class/tpm.

# Verificación rápida
ls /dev/tpm*
ls /sys/class/tpm/

If there is no TPM, check your /etc/crypttab don't have options like tpm2-device=autoIf they exist, delete them and rebuild your initrd. You can also disable the measurement phase on computers without a TPM:

# 1) Eliminar referencias TPM en /etc/crypttab y regenerar initrd
sudo mkinitcpio -P    # (o dracut/rebuildinitrd según distro)

# 2) Evitar carga de módulos TPM si el firmware publica algo extraño
echo -e "blacklist tpm\nblacklist tpm_tis\nblacklist tpm_crb" | sudo tee /etc/modprobe.d/no-tpm.conf

# 3) Opcional: evitar pcrphase si te da problemas
sudo systemctl mask systemd-pcrphase.service

This eliminates unnecessary waiting if your equipment lacks TPM. If you later enable the TPM in BIOS/UEFI, remove the blacklist and unmask the unit to recover measurements.

Good practices and trust decisions

Some people are wary of TPM because it's a "black box," just like self-encrypting disks. This is a reasonable doubt. Assess your threat model and balances usability, privacy, and maintenance. For many people, TPM+PBA+signed UKI is a huge security leap without excessive friction.

On hardware that allows it, add encrypted memory and avoid relying on third-party keys in Secure Boot; limit the chain to your own keys whenever possible. Keep firmware and kernel updated to incorporate mitigations for published vulnerabilities.

Mastering /dev/tpm0, /dev/tpmrm0, and the tpm2_pcrread/tpm2_pcr_extend operations opens the door to measured boot and robust disk encryption in Linux; with UKI and a signed PCR policy, you achieve operational stability, and adding a pre-boot PIN also shields you from more practical attacks. The key is to choose PCRs well, sign what changes often and always keep a good recovery key..

Ubuntu 25.10 beta comes with the Linux 6.17 kernel
Related article:
Ubuntu 25.10 beta arrives with Linux 6.17 and key changes