Guía completa de /dev/tpm0, /dev/tpmrm0 y los comandos tpm2_pcrread y tpm2_pcr_extend en Linux

  • TPM 2.0 permite arranque medido y claves LUKS atadas a PCRs, ideal con PIN PBA.
  • Usa /dev/tpmrm0 y tpm2_pcrread/tpm2_pcrextend para gestionar PCRs.
  • UKI + política PCR firmada estabilizan actualizaciones sin perder seguridad.
  • Mitiga cold boot y sniffing con PBA y cifrado de parámetros; mantén recovery.

TPM y comandos tpm2 en Linux

En los últimos años, los módulos TPM 2.0 han pasado de ser un misterio de hardware a una pieza habitual en cualquier equipo moderno con UEFI y Secure Boot. Este artículo baja a tierra qué son /dev/tpm0 y /dev/tpmrm0 y cómo usar tpm2_pcrread y tpm2_pcrextend (así como su comando real en tpm2-tools), además de explicar cómo encajan en el arranque medido, el cifrado de disco y las políticas PCR firmadas en Linux.

La documentación útil existe, pero está dispersa entre man pages de systemd, entradas de wiki y posts muy densos; aquí reunimos todo lo clave (PCRs, ejemplos prácticos, riesgos y defensas) para que personas técnicas, aunque no sean expertas en TPM, puedan trabajar con estas herramientas sin perderse en detalles oscuros.

Qué es un TPM 2.0 y por qué te interesa

Un Trusted Platform Module es un chip de seguridad que vive en tu placa (o dentro de la CPU como fTPM/Intel PTT) y que actúa como almacén seguro, generador de números aleatorios y raíz de confianza del sistema. Es pasivo: si no lo usas, no hace nada, pero cuando lo integras en tu flujo de arranque y cifrado de disco, aporta verificación de integridad y claves protegidas por hardware.

En la práctica, un TPM 2.0 te permite dos grandes modos de uso en cifrado de disco: a) generar/guardar una clave robusta y proteger su uso con un PIN con bloqueo anti-fuerza bruta; b) activar el llamado measured boot, donde cada componente de arranque se mide en registros PCR, de modo que la clave solo se “desencapsula” si el sistema no ha sido alterado (y opcionalmente con un PIN de pre-boot).

/dev/tpm0 y /dev/tpmrm0: diferencias y cuándo usar cada uno

En Linux verás dos dispositivos de carácter cuando hay TPM 2.0 disponible. /dev/tpm0 es la interfaz “cruda” del TPM, mientras que /dev/tpmrm0 expone el acceso a través del Resource Manager (gestor que multiplica clientes, gestiona sesiones y recursos), siendo el recomendado por tpm2-tools en la mayoría de escenarios.

Si tienes dudas de si existe o no un TPM, puedes comprobarlo en caliente. Si /sys/class/tpm/ está vacío o el comando de la wiki no devuelve nada, no hay TPM visible: puede no existir físicamente o estar desactivado en firmware.

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

Cuando haya ambos nodos de dispositivo, lo normal es que tpm2-tools detecte /dev/tpmrm0 y lo utilice automáticamente. Si necesitas forzar un dispositivo, la mayoría de herramientas aceptan –tcti o usan variables de entorno TCTI, pero para tareas comunes no suele hacer falta.

PCRs del TPM: cómo funcionan y qué miden

Los Platform Configuration Registers son registros que almacenan hashes (normalmente SHA-256) del estado de componentes críticos en cada fase de arranque. Se inicializan a cero en el ciclo de encendido y solo se pueden “extender”: nunca reescribir o borrar (salvo casos de debug como el PCR 16).

La operación fundamento es la extensión: nuevo_valor = SHA256(valor_actual || SHA256(datos)). Así se encadenan mediciones sin permitir reseteos oportunistas. Este patrón se usa para medir firmware, configuración, Secure Boot, kernel, initrd y parámetros del kernel, entre otros.

En equipos modernos verás 24 PCRs (0–23). Los más relevantes en arranque UEFI con systemd son:
– PCR 0: código de firmware.
– PCR 1: configuración del firmware (UEFI settings).
– PCR 7: estado de Secure Boot y certificados en los que confía.
– PCR 9: initrd(s) medidos por el kernel.
– PCR 11: UKI (Unified Kernel Image) y marcas de fase vía systemd-stub/systemd-pcrphase.
– PCR 12: línea de comandos del kernel.

Leer y extender PCRs con tpm2-tools: tpm2_pcrread y tpm2_pcr_extend

En tpm2-tools la lectura se hace con tpm2_pcrread y la extensión con tpm2_pcrextend. Verás a veces citado “tpm2_pcr_extend” para referirse a la operación conceptual de extensión, pero el comando real de la suite es tpm2_pcrextend.

Para inspeccionar el estado actual de los PCRs SHA-256, es tan sencillo como:

# 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

Para extender un PCR con el hash de datos arbitrarios (como ejemplo pedagógico, el hash de /etc/passwd), calcula el SHA-256 y extiéndelo. Recuerda: el TPM no recibe datos gigantescos, sino su hash, por límites y diseño.

# 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

Si quieres reproducir la matemática de la extensión fuera del TPM, concatenas el valor actual del PCR (binario) con el hash nuevo y vuelves a aplicar SHA-256 para comprobar el resultado.

¿Se puede resetear un PCR?

En condiciones normales, no. La filosofía es que un PCR solo crece con extensiones. Existe una excepción: PCR 16 suele reservarse como “debug” y puede resetearse en ciertos flujos, pero no es útil como raíz de seguridad de tu política.

Measured Boot, LUKS y systemd-cryptenroll: unir las piezas

Cuando integras el TPM en tu cifrado de disco, puedes “atar” el desbloqueo de la clave a un conjunto de PCRs. Si en el arranque actual esos PCRs tienen los mismos valores que cuando matriculaste la clave, el TPM desencapsula (unseal) y el volumen LUKS se abre automáticamente (con o sin PIN de pre-arranque, según configures).

Esto se hace muy bien con systemd-cryptenroll y systemd-cryptsetup. La idea es crear tu volumen, matricular la clave TPM, y añadir clave de recuperación para no quedarte fuera si cambian mediciones (por ejemplo, tras actualizar firmware o 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

Si fuerzas una discrepancia (por ejemplo, extiendes PCR 4 a propósito), el TPM ya no liberará la clave y tendrás que usar la de recuperación. Posteriormente puedes volver a matricular el TPM con los nuevos valores actuales mediante –wipe-slot=tpm2 y otra ejecución de systemd-cryptenroll.

Qué PCRs elegir y por qué

Cuantos más PCRs relevantes vincules, más superficie reduces, pero más a menudo tendrás que re-matricular tras cambios legítimos. Algunos criterios prácticos:
– PCR 7 (Secure Boot): debería ser muy estable si tu set de claves no cambia.
– PCR 0/1 (firmware y configuración): rara vez cambian; obligan a re-matricular después de actualizar firmware o tocar la BIOS/UEFI.
– PCR 9/11/12 (kernel, initrd, UKI y cmdline): cambian con frecuencia si no usas UKI o firma/política estable.

En algunos entornos se ha visto enlazar solo PCR 7, apoyándose en que Secure Boot verifica kernel e initrd si se arrancan como UKI firmado y usando systemd-boot que no deja editar parámetros del kernel cuando SB está activo. Eso funciona, pero si tu Secure Boot confía en claves de terceros (como Microsoft 3rd Party) es más fácil orquestar un arranque alternativo que conserve PCR 7 y, por tanto, no es la opción más restrictiva.

UKI y políticas PCR firmadas: estabilidad sin perder seguridad

Una solución práctica para evitar re-matricular cada vez que actualizas kernel consiste en usar UKI (Unified Kernel Image) y una política PCR firmada. Generas un par de claves, atas la pública al TPM al matricular y firmas tu UKI tras cada actualización; el TPM confía en esa firma y permite el desbloqueo aun cuando el hash concreto del kernel cambie.

La herramienta systemd-measure y el helper systemd-ukify facilitan esto: ukify empaqueta kernel, initrd y cmdline en el UKI (medido habitualmente en PCR 11) y systemd-measure firma la política. Con mkinitcpio, ukify puede integrarse para que post-install la firma se ejecute sola.

# 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

De este modo, tu política queda estable frente a cambios del kernel/initrd mientras sigas firmando el UKI con tu clave. Si renuevas claves o cambias el set de PCRs, tocará re-matricular.

Ejemplos de cadenas de medición con systemd

Durante el arranque, systemd-stub y systemd-pcrphase extienden PCRs en momentos concretos. Por ejemplo, “enter-initrd” se registra en PCR 11, lo que permite que un desbloqueo solo sea válido dentro de la initrd (reduciendo vectores donde un atacante intente reutilizar la clave más tarde).

En sistemas con UKI, el contenido del UKI se mide en PCR 11; en sistemas sin UKI, el kernel mide initrds en PCR 9 y el gestor de arranque puede medir la cmdline en PCR 12. Asegúrate de cubrir initrd y cmdline en tu política, o alguien podría backdoorear la initrd o arrancar con una cmdline maliciosa como init=/bin/bash.

Riesgos reales: cold boot, sniffing TPM y más

¿Qué puede salir mal? Varias cosas que conviene conocer para modelar amenazas. Los ataques de cold boot siguen siendo viables: si el desbloqueo es totalmente automático, un atacante puede repetir intentos ilimitados. La mitigación clara es exigir un PIN de pre-boot (PBA), reduciendo intentos a uno por ciclo de alimentación.

Otra categoría son los sniffing attacks al bus TPM. La CPU solicita la clave, el TPM la envía; si el enlace se pincha, la clave puede filtrarse. Para esto, systemd implementa “parameter encryption” para que el intercambio viaje cifrado; como alternativa, usar fTPM/Intel PTT o memoria cifrada reduce la exposición. Hay demostraciones públicas relativamente asequibles (hasta con microcontroladores) que ilustran la viabilidad en portátiles de grandes marcas.

También han existido vulnerabilidades académicas y prácticas: TPM-Fail, faulTPM (con impacto notable en AMD) y el caso bitpixie (CVE-2023-21563). No significa que el TPM sea inútil, sino que debes mantener firmware al día, entender tu modelo de amenazas y no confiar ciegamente.

Estado de BitLocker frente a estas amenazas

En el mundo Windows, el cifrado de disco ampliamente desplegado es BitLocker. Actualmente se ha señalado que su configuración por defecto (desbloqueo automático solo con TPM) deja la puerta abierta tanto a cold boot como a sniffing del canal TPM, ya que no implementa cifrado de parámetros al estilo systemd. Esto hace que ciertos equipos corporativos sean atacables en minutos.

La recomendación allí es habilitar pre-boot authentication mediante políticas/registro o CLI, algo que no está lo bastante expuesto al usuario medio. Además, recuerda revisar dónde se almacena la clave de recuperación: a menudo reside en la cuenta de Microsoft del usuario, lo cual es otro ángulo de riesgo si no se controla.

Truco ofensivo/defensivo: sustituir la raíz LUKS para forzar tu clave

Existe un vector interesante cuando no hay pre-boot authentication. Un atacante puede clonar la partición LUKS real, sustituirla por otra LUKS con el mismo UUID y una contraseña que él conoce, y arrancar el equipo. Como las mediciones PCR cuadran, el TPM libera la clave, pero no coincide con la LUKS falsa, así que la initrd pedirá la clave “de recuperación”. Al introducir la contraseña conocida por el atacante, su sistema se ejecuta como root en initrd y ya puede orquestar robo de la clave original (por ejemplo, montando la copia verdadera a través de red y usando systemd-cryptsetup).

Mitigaciones claras: activar pre-boot authentication, aprovechar systemd-pcrphase para atar el desbloqueo estrictamente a la fase de initrd, y considerar medir/atar también el volumen LUKS objetivo (requiere un diseño cuidadoso para evitar círculos viciosos).

Elegir particionamiento y segunda clave: práctica recomendable

Mantener una clave de recuperación es obligatorio: si el TPM o la placa mueren, tu clave atada al TPM no te sirve. LUKS permite varios slots (TPM usa uno, la recuperación otro). Además, separar particiones / y /home tiene ventajas: puedes aplicar medición estricta con TPM a / y usar una clave fuerte o un dispositivo FIDO2/YubiKey para /home, reduciendo confianza total en un único mecanismo.

Qué pasa cuando actualizas firmware o kernel

Si cambias firmware o tocas opciones UEFI, PCRs como 0/1 variarán y el TPM no liberará la clave hasta que re-matricules. Para el kernel e initrd, los cambios son frecuentes: si no empleas UKI con política firmada, cada actualización puede obligarte a usar la recovery y re-matricular después. Con UKI firmado, firmas y listo.

Notas y observaciones de la comunidad

En algunas guías populares de ciertas distribuciones se ha recomendado atar solo PCR 7 siempre que se use UKI y systemd-boot, apoyándose en las garantías de Secure Boot y en la imposibilidad de editar cmdline. Funciona, pero hay riesgos si confías en terceros. También se ha documentado un bug en el pasado donde, al “martillear” Enter, aparecía una shell de recuperación tras el desbloqueo; conviene mantener versiones actualizadas para evitar sorpresas.

En 2025/06 se compartieron comentarios interesantes: faulTPM sigue afectando a AMD en cierta medida; wikis han añadido secciones específicas sobre políticas PCR firmadas; y se probó el instalador de una distribución que ofrece FDE con TPM como función experimental, con algunos tropiezos prácticos (pedir recovery al primer arranque, dependencia de snaps, doble disco cifrado), tema que merece una auditoría más profunda.

En 2025/07 se publicó un seguimiento centrado en cifrado de disco en Windows. La conclusión general refuerza la necesidad de PBA y de cifrar el canal TPM, además de limitar la confianza en claves de terceros en Secure Boot.

Consejos operativos con tpm2-tools y systemd

Para el día a día: instala tpm2-tools y tpm2-tss. Usa /dev/tpmrm0 por defecto, y tpm2_pcrread/tpm2_pcrextend para comprobar y experimentar con PCRs. Evita extender PCRs de producción con datos arbitrarios: hazlo en laboratorios o usa PCR 16 para pruebas.

Al matricular con systemd-cryptenroll: –tpm2-device=auto detecta el TPM; –tpm2-with-pin añade PBA; –tpm2-pcrs=… selecciona tus PCRs; –tpm2-public-key=… y –tpm2-public-key-pcrs=… activan una política PCR firmada (por ejemplo, atada a PCR 11 para UKI). No olvides –wipe-slot cuando quieras limpiar un slot previo.

Si no tienes TPM y systemd te hace esperar en el arranque

Ocasionalmente, tras una actualización, algún servicio intenta usar el TPM aunque tu máquina no lo tenga visible, causando esperas de timeout al arrancar. Comprueba primero que no aparezca ningún /dev/tpm* ni entradas en /sys/class/tpm.

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

Si no hay TPM, revisa que en tu /etc/crypttab no tengas opciones como tpm2-device=auto. Si existen, elimínalas y regenera tu initrd. También puedes desactivar la fase de medición en equipos sin 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

Con eso eliminas esperas innecesarias si tu equipo carece de TPM. Si más tarde activas el TPM en BIOS/UEFI, retira el blacklist y desmascara la unidad para recuperar mediciones.

Buenas prácticas y decisiones de confianza

Hay quien recela del TPM por ser una “caja negra”, igual que de discos autocifrados. Es una duda razonable. Valora tu modelo de amenazas y equilibra usabilidad, privacidad y mantenimiento. Para muchas personas, TPM+PBA+UKI firmado es un gran salto de seguridad sin fricción excesiva.

En hardware que lo permita, añade memoria cifrada y evita confiar en claves de terceros en Secure Boot; limita la cadena a tus propias claves cuando sea viable. Mantén firmware y kernel actualizados para incorporar mitigaciones de vulnerabilidades publicadas.

Dominar /dev/tpm0, /dev/tpmrm0 y las operaciones tpm2_pcrread/tpm2_pcr_extend te abre la puerta a un arranque medido y un cifrado de disco robusto en Linux; con UKI y política PCR firmada logras estabilidad operativa, y si añades PIN de pre-arranque, blindas los ataques más prácticos. La clave está en elegir bien los PCRs, firmar lo que cambia a menudo y conservar siempre una buena clave de recuperación.

Ubuntu 25.10 beta viene con el núcleo Linux 6.17
Artículo relacionado:
Ubuntu 25.10 beta llega con Linux 6.17 y cambios clave