Jump to content

# Trusted Platform Module

3 languages

- 日本語
- Polski
- 中文（简体）

From ArchWiki

Related articles

- Self-encrypting drives
- Smartcards
- Trusted Platform Module/1.2

This article or section needs expansion.

Reason: Needs clarification about usage difference between TPM 1.2 and 2.0, Evil Maid attack defense and Trusted boot. PCR registers sealing and using in combination with LUKS. (Discuss in Talk:Trusted Platform Module)

Trusted Platform Module (TPM) is an international standard for a secure cryptoprocessor, which is a dedicated microprocessor designed to secure hardware by integrating cryptographic keys into devices.

In practice a TPM can be used for various different security applications such as secure boot, key storage and random number generation.

TPM is naturally supported only on devices that have TPM hardware support. If your hardware has TPM support but it is not showing up, it might need to be enabled in the BIOS settings.

Note: There are two very different TPM specifications: 2.0 and 1.2, which also use different software stacks. This article only describes TPM 2.0, for the older TPM 1.2 see /1.2.

## Checking TPM support

Most modern computers support TPM 2.0, as it has been required for Windows 10 certification since 2016. To check support on your system, use any of the following methods:

- check the logs, e.g., by running `journalctl -k --grep=tpm` as root
- read the value of `/sys/class/tpm/tpm0/device/description`[1], `/sys/class/tpm/tpm0/device/firmware_node/description`, or `/sys/class/tpm/tpm0/tpm_version_major`:

    $ cat /sys/class/tpm/tpm0/device/description
    TPM 2.0 Device

- use systemd-analyze(1) to check for TPM 2.0 and the necessary software dependencies:

      $ systemd-analyze has-tpm2

TPM 2.0 allows direct access via `/dev/tpm0` (one client at a time), kernel-managed access via `/dev/tpmrm0`, or managed access through the tpm2-abrmd resource manager daemon. According to a systemd project member, using tpm2-abrmd is no longer recommended. There are two choices of userspace tools, tpm2-tools by Intel and ibm-tssAUR by IBM.

TPM 2.0 requires UEFI boot; BIOS or Legacy boot systems can only use TPM 1.2.

Some TPM chips can be switched between 2.0 and 1.2 through a firmware upgrade (which can be done only a limited number of times).

## Usage

Many informative resources to learn how to configure and make use of TPM 2.0 services in daily applications are available from the tpm2-software community.

### LUKS encryption

It is possible to encrypt volumes using keys securely stored in the TPM. This approach ensures that your drives remain locked unless the TPM is present and specific conditions are met, such as the integrity of the firmware or Secure Boot state (see #Accessing PCR registers).

This mechanism can be used to automatically decrypt the root volume during the boot process, similarly to how BitLocker works on Windows or FileVault on macOS. While this provides strong protection if the drive is removed from the computer with the TPM, data protection will only rely on basic measures like user passwords and system settings if the entire PC is stolen. To mitigate this, you can:

- Consider encrypting user data, such as individual home folders, with a different mechanism, such as fscrypt or systemd-homed.
- Use a TPM pin to benefit from the security properties of the TPM, while avoiding completely unattended unlocking.

Warning: Be aware that this method makes you more vulnerable to cold boot attacks.

systemd-cryptenroll and Clevis allow locking LUKS volumes with a key stored in the TPM. Additionally, systemd-cryptenroll enables tying the encryption to signed policies instead of static PCR values (See systemd-cryptenroll(1)).

### SSH

For TPM sealed SSH keys, there are two options:

- ssh-tpm-agent — ssh-agent compatible agent using TPM backed keys.

  https://github.com/Foxboron/ssh-tpm-agent || ssh-tpm-agent
  See Store ssh keys inside the TPM: ssh-tpm-agent.

- tpm2-pkcs11 — PKCS#11 interface for Trusted Platform Module 2.0 hardware.

  https://github.com/tpm2-software/tpm2-pkcs11 || tpm2-pkcs11
  See SSH configuration and Using a TPM for SSH authentication (2020-01).

### systemd-creds

systemd-creds uses TPM to securely store and retrieve credentials used by systemd units.

### GnuPG

This article or section needs expansion.

Reason: Add instructions for probing the TPM to find out which keys it supports. (Discuss in Talk:Trusted Platform Module)

GnuPG, since version 2.3, supports moving compatible keys into the TPM. See Using a TPM with GnuPG 2.3 for the instructions.

### OpenSSL

There are OpenSSL providers and OpenSSL engines that implement storing keys in the TPM.

- tpm2-openssl — OpenSSL Provider for TPM2 integration.

  https://github.com/tpm2-software/tpm2-openssl || tpm2-openssl

- tpm2-tss-engine — OpenSSL Engine for TPM2 devices.

  https://github.com/tpm2-software/tpm2-tss-engine || tpm2-tss-engine
  See Using the TPM - It's Not Rocket Science (Anymore) - Johannes Holland & Peter Huewe (2020-11, Youtube)

### Other good examples of TPM 2.0 usage

- Configuring Secure Boot + TPM 2 (2018-06, Debian)

## Accessing PCR registers

This article or section needs expansion.

Reason: It's probably wiser to list only useful PCRs and give real life examples of when to use them, rather than listing all existing PCRs. (Discuss in Talk:Trusted Platform Module#PCR register table)

Platform Configuration Registers (PCR) allow binding of the encryption of secrets to specific software versions and system state via hashes, so that the enrolled key is only accessible (may be "unsealed") if specific trusted software and/or configuration is used.

PCRs are intended to be used for platform hardware and software integrity verification between boots (e.g. protection against Evil Maid attack).

The TCG PC Client Specific Platform Firmware Profile Specification defines the registers in use, and The Linux TPM PCR Registry assigns Linux system components using them.

The registers are:

PCR | Description | Extended by
--- | --- | ---
PCR0 | Core System Firmware executable code (aka Firmware). May change if you upgrade your UEFI. | Firmware
PCR1 | Core System Firmware data (aka UEFI settings; configured boot order, for example) | Firmware
PCR2 | Extended or pluggable executable code (aka OpROMs) | Firmware
PCR3 | Extended or pluggable firmware data. Set during Boot Device Select UEFI boot phase. | Firmware
PCR4 | Boot Manager Code and Boot Attempts. Measures the boot manager and the devices that the firmware tried to boot from. | Firmware
PCR5 | Boot Manager Configuration and Data. Can measure configuration of boot loaders; includes the GPT Partition Table. | Firmware
PCR6 | Resume from S4 and S5 Power State Events | Firmware
PCR7 | Secure Boot State. Contains the full contents of PK/KEK/db, as well as the specific certificates used to validate each boot application[2] | Firmware, shim (adds MokList, MokListX, and MokSBState)
PCR81 | Hash of the kernel command line | GRUB
PCR91 | Hash of the initrd and EFI Load Options | Linux (measures the initrd and EFI Load Options, essentially the kernel cmdline options)
PCR101 | Reserved for Future Use |
PCR111 | Hash of the Unified kernel image | systemd-stub(7)
PCR121 | Overridden kernel command line, Credentials | systemd-stub(7)
PCR131 | System Extensions | systemd-stub(7)
PCR141 | shim's MokList, MokListX, and MokSBState.[3] | shim
PCR151 | Hash of the LUKS volume key | systemd-cryptsetup
PCR161 | Debug. May be used and reset at any time. May be absent from an official firmware release. |
PCR23 | Application Support. The OS can set and reset this PCR. |

1. Use case defined by the OS and might change between various Linux distros and Windows devices.

On Windows, BitLocker uses PCR8-11 (Legacy) or PCR11-14 (UEFI) for its own purposes. Documentation from tianocore[4].

tpm2-totp facilitates this check with a human observer and dedicated trusted device.

The current PCR values can be listed with systemd-analyze(1):

    $ systemd-analyze pcrs

Or, alternatively with tpm2_pcrread(1) from tpm2-tools:

    # tpm2_pcrread

## PCR policies

PCR policies are mechanisms in TPM2 that enable the binding of secrets, like the LUKS root decryption key, to a signed policy rather than raw PCR values. These policies add flexibility by allowing PCR values to vary, provided their content matches a known "expected" value. For instance, rather than simply tying the encryption key to the PCR7 value—which ensures that Secure Boot hasn't been disabled or tampered with—you can bind it to a PCR policy that verifies the booting of a known Unified kernel image (UKI), with all its components measured during the boot process. See systemd-cryptenroll(1) § TPM2_PCRs_and_policies.

Different PCR policies can be established for various purposes. For example, one policy can be used for the root volume key, making it accessible only from the initrd, while another policy can be set for the swap encryption key, which needs to be available later in the boot process when the swap is mounted. This design ensures that neither of these keys is accessible once the system has fully booted, thereby enhancing overall security.

First generate the necessary keys:

    # ukify genkey --pcr-private-key=/etc/systemd/tpm2-pcr-private-key.pem --pcr-public-key=/etc/systemd/tpm2-pcr-public-key.pem
    Writing private key for PCR signing to /etc/systemd/tpm2-pcr-private-key.pem
    Writing public key for PCR signing to /etc/systemd/tpm2-pcr-public-key.pem

Note: `/etc/systemd/tpm2-pcr-private-key.pem` is the default path and the file is automatically picked up by systemd-cryptenroll if it exists.

Create `/etc/kernel/uki.conf` or copy the template from `/usr/lib/kernel/uki.conf`. Although PCR policies can be used without Secure Boot, it makes sense to also sign your UKI, so update the following as needed with your keys:

    /etc/kernel/uki.conf/

    [UKI]
    SecureBootSigningTool=systemd-sbsign
    SignKernel=true
    SecureBootPrivateKey=/etc/kernel/secure-boot-private-key.pem
    SecureBootCertificate=/etc/kernel/secure-boot-certificate.pem
    Splash=/usr/share/systemd/bootctl/splash-arch.bmp

    [PCRSignature:initrd]
    Phases=enter-initrd
    PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key.pem
    PCRPublicKey=/etc/systemd/tpm2-pcr-public-key.pem

    [PCRSignature:swap]
    Phases=enter-initrd:leave-initrd
    PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key.pem
    PCRPublicKey=/etc/systemd/tpm2-pcr-public-key.pem

To generate the UKI, use a tool which reads `/etc/kernel/uki.conf` by default, such as kernel-install or mkinitcpio.

Finally, enroll the TPM2 policy in your LUKS volumes.

    # systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs="" /dev/disk/by-label/root
    # systemd-cryptenroll --wipe-slot tpm2 --tpm2-device auto --tpm2-pcrs="" /dev/disk/by-label/swap

Note: `--tpm2-pcrs=""` currently needs to be forced to avoid binding to raw PCR7 values until systemd v258.

Check the UKI with `# ukify inspect /path/to/uki` to make sure it contains the `.pcrsig` section.

Also check that the LUKs volume registered the public key:

    # cryptsetup luksDump /dev/disk/by-label/root | grep pubkey

            tpm2-pubkey:
                        .....
            tpm2-pubkey-pcrs: 11

Warning: Booting this UKI requires the mkinitcpio systemd hook. However, initrds created by mkinitcpio currently do not copy over the required files. See https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/merge_requests/414 for an updated systemd hook which you can put in `/etc/initcpio/install/systemd`.

## Troubleshooting

### TPM2 LUKS2 unlocking still asking for password

If you followed the instruction described above for automatically unlocking luks2 devices with enrolled keys in a TPM2 hardware module, but still receive a prompt to input a password during the initramfs boot stage. You may need to early load the kernel module (you can obtain its name with `systemd-cryptenroll --tpm2-device=list`) that is responsible for handling your specific TPM2 module.

### A TPM error (714) occurred attempting to create NULL primary

Starting from Linux Kernel 6.10 `CONFIG_TCG_TPM2_HMAC` was enabled by default and now TPM must support AES-128-CFB for session encryption. TPMs that do not support this mode, such as older Intel PTT, will fail to initialize the driver, resulting in `A TPM error (714) occurred attempting to create NULL primary`. Replacing hardware is the only complete solution. systemd-cryptenroll also requires AES-128-CFB support, so disabling kernel option isn't enough and it will fails producing this error: `TPM device not usable as it does not support the required functionality (AES-128-CFB missing?).`

## See also

- Gentoo:Trusted Platform Module
- TPM-JS testing tool: source - live web version.

Categories:

- Security
- Hardware

Hidden category:

- Pages or sections flagged with Template:Expansion