Skip to main content

Trusted Platform Module

The 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, for example in conjunction with Secure Boot, encryption key storage and random number generation.

To start using a TPM, it has to be present on your hardware (an fTPM or a dedicated device connected to a header on your mainboard) and enabled in the device's firmware settings.

List of Platform Configuration Registers

Platform Configuration Registers (PCRs) hold cryptographic hashes that record the precise state of the system. While these registers can be read at any time, they can only be modified via an "extend" operation, blending new data with the preceding hashes to create an unalterable, cumulative cryptographic chain.

By verifying these measurements between boots, the system can detect unauthorized hardware or software tampering, for example in the scenario of an Evil Maid attack. If any component has been tampered with(i.e. the hash chain deviates from a previously known good configuration), the TPM will not release its secrets. Once the PCRs prove that the correct, untampered operating system has booted, they can be safely trusted to automatically unlock your disk encryption keys.

The UAPI Group describes the TPM PCRs as follows:

PCR Measured Component Notes
PCR0 Core System Firmware BIOS/UEFI executable code; changes on firmware update.
PCR1 System Firmware Config Firmware settings, hardware config, and boot order.
PCR2 Extended Executable Code Option ROMs of PCIe cards, GPUs, RAID controllers, etc.
PCR3 Extended Configuration Device data from the UEFI Boot Device Select (BDS) phase.
PCR4 Boot Manager Code Bootloader binary (e.g. GRUB, systemd-boot) and boot attempts.
PCR5 Boot Manager Config Bootloader configuration and the GPT partition table.
PCR6 State Transitions ACPI power states and S4/S5 suspend/resume events.
PCR7 Secure Boot State Secure Boot status and database keys (PK, KEK, db, dbx).
PCR8 Kernel Command Line Literal kernel parameters passed by the bootloader.
PCR9 Initramfs / Initrd External initramfs/initrd image passed by the bootloader.
PCR10 IMA Linux Integrity Measurement Architecture (IMA) log.
PCR11 Unified Kernel Image (UKI) UKI components (kernel, initrd, cmdline) via systemd-stub.
PCR12 Boot Credentials / Overrides Systemd boot credentials and UKI command-line extensions.
PCR13 System Extensions System extension (sysext) and config (confext) overlays.
PCR14 Shim / MOK Shim bootloader binary and Machine Owner Key (MOK) certificates.
PCR15 System Identity Operating system state (machine ID, LUKS keys, root UUID).

For further details on how PCR 11-13 are used, see systemd-stub(7).

Usage

TPM2-based LUKS key

You can use the TPM in your computer as a key store to unlock LUKS encrypted volumes with them.

Arch Linux comes with systemd which itself comes with systemd-cryptenroll allowing you to specify a TPM2 device for key storage.

Using a TPM for this purpose automates the process of unlocking your LUKS volumes, given that certain conditions are met, e.g. the firmare of the machine and the Secure Boot state.

WARNING: When using this method on your root volume, there are a few caveats to be aware of.

Provided the PCR slots you chose to seal against are considered valid by the system, the TPM will automatically unlock the LUKS volume at boot without the need to enter a passphrase.

However, this also means that in case of theft, it's as if you didn't encrypt the system to begin with. Since the computer just has to be booted up to gain access to the decrypted data, all benefits of data-at-rest encryption are nullified.

It is therefore strongly recommended to at least pass the --tpm2-with-pin=yes option to systemd-cryptenroll to still have a mechanism for user authentication. Despite the name of the option, alphanumeric values can be supplied during interactive enrollment.

Also, make sure the system is in the exact state it should be for normal booting, i.e. the entire system is exactly set up the way you want it and there will be no further changes to core components, especially Secure Boot keys.

Enrolling a new key

Certain preconditions are necessary to use TPM2 in conjunction with a LUKS encrypted volume:

  • tpm2-tss must be installed
  • the volume uses LUKS2 encryption (default when using cryptsetup)
  • the initramfs must be systemd-based (mkinitcpio hooks: systemd and sd-encrypt)

Install the tpm2-tss package from the repositories to provice necessary TPM software stack tooling:

pacman -S tpm2-tss

List the TPM2 devices available on your machine:

TIP: If there are no devices listed, make sure the TPM is enabled in your device's firmware. Devices from 2016 onwards usually have a TPM 2.0, as it is a requirement from Microsoft for Windows 10 certification for hardware manufacturers.

systemd-cryptenroll --tpm2-device=list

To enroll a new TPM-based key into a LUKS slot, specify the TPM device and the PCRs to seal against, followed by the LUKS volume to save a new slot to:

ATTENTION: The more PCRs you bind to, the more hardened your setup becomes. But at the same time you can also end up with a less flexible setup. Binding your TPM LUKS key to PCRs 8, 9 and/or 11 harden your system against attempts to boot a kernel image which's hashes aren't measured into these PCRs but the moment your kernel changes (i.e. you update your kernel, change initramfs or UKI generation, etc.) the PCRs stop validating and trigger a passphrase or recovery key prompt!

TIP: If your device only has one TPM (which is usually the case) you can supply --tpm2-device=auto to use the only device available.

systemd-cryptenroll --tpm2-device=/path/to/tpm2_device --tpm2-pcrs=7 --tpm2-with-pin=yes /dev/disk/by-label/cryptroot

It will ask you for a PIN to enter, which you will be asked to put in every time you boot the system.

Recovery key

It is also generally advisable to let systemd-cryptenroll generate a recovery key, in case the key stored in the TPM doesn't validate anymore for whatever reason.

A recovery key is generated automatically with a character set that's easy to type in while still having high entropy (brute force mitigation).

To generate a recovery key and have it saved to a slot in the LUKS device:

systemd-cryptenroll --recovery-key /dev/disk/by-label/cryptroot

Unlocking at boot

Making systemd use the TPM to unlock the volume can be done in one of two ways:

  1. add kernel parameters, telling systemd which device to unlock with the TPM
  2. use a /etc/crypttab.initramfs file to be included in the initramfs to point systemd to the correct volume

For the kernel command line, add the following:

TIP: Again, if your device only has one TPM you can supply tpm2-device=auto to use the only device available.

rd.luks.options=tpm2-device=/path/to/tpm2_device

If you'd rather use a crypttab.initramfs file, the syntax is as follows:

# <name>	<device>									<passphrase>	<options>
root		UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX	none			tpm2-device=auto