Trusted Platform Module

From ArchWiki

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

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.

Versions

There are two very different TPM specifications: 1.2 and 2.0, which also use different software stacks.

  • TPM 1.2 uses the "TrouSerS" TSS (TCG software stack) by IBM, which is packaged as trousersAUR (tcsd) and tpm-toolsAUR (userspace). All software access the TPM through the tcsd daemon.
  • TPM 2.0 allows direct access via /dev/tpm0 (one client at a time), managed access through the tpm2-abrmd resource manager daemon, or kernel-managed access via /dev/tpmrm0. 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 1.2 and 2.0 through a firmware upgrade (which can be done only a limited number of times).

Using TPM 1.2

Drivers

TPM drivers are natively supported in modern kernels, but might need to be loaded:

# modprobe tpm

Depending on your chipset, you might also need to load one of the following:

# modprobe -a tpm_{atmel,infineon,nsc,tis,crb}

Usage

TPM 1.2 is managed by tcsd, a userspace daemon that manages Trusted Computing resources and should be (according to the TSS spec) the only portal to the TPM device driver. tcsd is part of the trousersAUR package, which was created and released by IBM, and can be configured via /etc/tcsd.conf.

To start tcsd and watch the output, run:

# tcsd -f

or simply start and enable tcsd.service.

Once tcsd is running you might also want to install tpm-toolsAUR which provides many of the command line tools for managing the TPM.

Some other tools of interest:

  • tpmmanager — A Qt front-end to tpm-tools
https://github.com/Rohde-Schwarz/TPMManager || tpmmanagerAUR
  • opencryptoki — A PKCS#11 implementation for Linux. It includes drivers and libraries to enable IBM cryptographic hardware as well as a software token for testing.
https://sourceforge.net/projects/opencryptoki || opencryptokiAUR

Basics

Start off by getting basic version info:

$ tpm_version

and running a selftest:

$ tpm_selftest -l info
TPM Test Results: 00000000 ...
tpm_selftest succeeded

Securing SSH keys

There are several methods to use TPM to secure keys, but here we show a simple method based on simple-tpm-pk11-gitAUR.

First, create a new directory and generate the key:

$ mkdir ~/.simple-tpm-pk11
$ stpm-keygen -o ~/.simple-tpm-pk11/my.key

Point the configuration to the key:

~/.simple-tpm-pk11/config
key my.key

Now configure SSH to use the right PKCS11 provider:

~/.ssh/config
Host *
    PKCS11Provider /usr/lib/libsimple-tpm-pk11.so

It is now possible to generate keys with the PKCS11 provider:

$ ssh-keygen -D /usr/lib/libsimple-tpm-pk11.so
Note: This method currently does not allow for multiple keys to be generated and used.

Accessing PCR registers

Platform Configuration Registers (PCR) contain hashes that can be read at any time but can only be written via the extend operation, which depends on the previous hash value, thus making a sort of blockchain. They are intended to be used for platform hardware and software integrity checking between boots (e.g. protection against Evil Maid attack). They can be used to unlock encryption keys and proving that the correct OS was booted.

The TCG PC Client Specific Platform Firmware Profile Specification defines the registers in use:

PCR Use Notes
PCR0 Core System Firmware executable code (aka Firmware) May change if you upgrade your UEFI
PCR1 Core System Firmware data (aka UEFI settings)
PCR2 Extended or pluggable executable code
PCR3 Extended or pluggable firmware data Set during Boot Device Select UEFI boot phase
PCR4 Boot Manager Code and Boot Attempts Measures the boot manager and the devices that the firmware tried to boot from
PCR5 Boot Manager Configuration and Data Can measure configuration of boot loaders; includes the GPT Partition Table
PCR6 Resume from S4 and S5 Power State Events
PCR7 Secure Boot State Contains the full contents of PK/KEK/db, as well as the specific certificates used to validate each boot application[1]
PCR8 Hash of the kernel command line Supported by grub and systemd-boot
PCR 9 Hash of the initrd Scheduled for linux v5.17
PCR10 Reserved for Future Use
PCR11 BitLocker Access Control
PCR12 Data events and highly volatile events
PCR13 Boot Module Details
PCR14 Boot Authorities
PCR 15 to 23 Reserved for Future Use

Documentation from tianocore[2].

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

# cat /sys/kernel/security/tpm0/ascii_bios_measurements

Using TPM 2.0

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: This section is a stub. You can help by expanding it with information on how to set up and use a TPM 2.0 device. (Discuss in Talk:Trusted Platform Module)

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.

Checking support

A TPM 2.0 chip has been a requirement for computers certified to run Windows 10 since 2016-07-28.[3] Linux has support for TPM 2.0 since version 3.20[4] and should not require any other steps to be enabled on a default Arch install.

Two ways to verify whether TPM 2.0 is setup without specific software:

  • checking the logs, e.g., by running journalctl -k --grep=tpm as root
  • read the value of /sys/class/tpm/tpm0/device/description[5] or /sys/class/tpm/tpm0/tpm_version_major

Data-at-rest encryption with LUKS

There are two methods for unlocking a LUKS volume using a TPM. An older method using clevis, and a newer method using systemd-cryptenroll. The newer method will be detailed first.

Using either method, an encrypted volume or volumes may be unlocked using keys stored in a TPM, either automatically at boot or manually at a later time. Using a TPM for this purpose ensures that your drives will not unlock unless certain conditions are met, such as your firmware not having been modified and Secure Boot not having been disabled (see #Accessing PCR registers).

Warning: If you use this method on your root volume, this means that, as long as the previously mentioned certain conditions are met, your computer will unlock automatically at boot without needing to enter an encryption password.
  • This means that access to data is not protected in case the hardware gets stolen.
  • Be aware that this method makes you more vulnerable to cold boot attacks, because even if your computer has been powered off for a long time (ensuring the memory is completely cleared), an attacker could simply turn it on and wait for the TPM to load the key automatically. This may be a concern for high-value targets.

systemd-cryptenroll

systemd-cryptenroll(1) has native support for enrolling LUKS keys in TPMs. It requires the following:

To begin, run the following command to list your installed TPMs and the driver in use:

$ systemd-cryptenroll --tpm2-device=list

A key may be enrolled in both the TPM and the LUKS volume using only one command. The following example binds the key to PCRs 0 and 7 (the system firmware and Secure Boot state):

# systemd-cryptenroll --tpm2-device=/path/to/tpm2_device --tpm2-pcrs=0+7 /dev/sdX

where /dev/sdX is the full path to the encrypted LUKS volume and /path/to/tpm2_device is the full path to the TPM as given in the output of the first command.

Note: As of systemd 251 it is now possible to require a PIN to be entered in addition to the TPM state being correct. Simply add the option --tpm2-with-pin=yes to the command above and enter the PIN when prompted.
Tip: If your computer has only one TPM installed, which is usually the case, you may instead specify --tpm2-device=auto to automatically select the only available TPM.

To test that the key works, run the following command while the LUKS volume is closed:

# /usr/lib/systemd/systemd-cryptsetup attach mapping_name /dev/sdX - tpm2-device=/path/to/tpm2_device

where mapping_name is your chosen name for the volume once opened. If the volume successfully unlocks, you are ready to add the required information to the crypttab so that systemd-cryptsetup-generator(8) can automatically unlock the device at boot.

Merge-arrows-2.pngThis article or section is a candidate for merging with dm-crypt/System configuration.Merge-arrows-2.png

Notes: Early and late userspace unlocking have a dedicated article. This section should focus on the systemd-cryptenroll commands. (Discuss in Talk:Trusted Platform Module)
/etc/crypttab
# Example crypttab file. Fields are: name, underlying device, passphrase, cryptsetup options.

# Unlock /dev/sdX using the only available TPM, naming it myvolume
 myvolume	/dev/sdX	-	tpm2-device=auto # also add tpm2-pin=yes if PIN is used
Note: While you may specify the UUID of your LUKS volume in place of the pathname /etc/crypttab, the systemd-cryptenroll command itself currently only supports pathnames.

If the volume you wish to unlock contains your root file system, you must take the following additional steps:

  • Ensure you are using systemd and sd-encrypt in the HOOKS array of /etc/mkinitcpio.conf
  • Configure your initramfs to unlock the root volume with one of the following methods:
    • Specifying the root volume using the configuration outlined above in /etc/crypttab.initramfs (see tip at the top of Using sd-encrypt hook)
    • Setting rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=tpm2-device=auto in addition to rd.luks.uuid or rd.luks.name in the kernel command line

To remove a key enrolled using this method, run:

# systemd-cryptenroll /dev/sdX --wipe-slot=slot_number

where slot_number is the numeric LUKS slot number in which your TPM key is stored.

Alternatively, run:

# systemd-cryptenroll /dev/sdX --wipe-slot=tpm2

to remove all TPM-associated keys from your LUKS volume.

See systemd-cryptenroll(1) and crypttab(5) for more information and examples.

Clevis

Merge-arrows-2.pngThis article or section is a candidate for merging with Booster#Clevis_encryption.Merge-arrows-2.png

Notes: The general info on clevis and specification (linked below) benefit from merging into a new clevis. The luks example can be deduplicated based on an example working for both in a subsection to be linked from here. (Discuss in Merge with booster#clevis)

clevis allows binding a LUKS volume to a system by creating a key and encrypting it using the TPM, and sealing the key using PCR values which represent the system state at the time of the Clevis pin creation.

Warning: Set a strong backup password in case the TPM unsealing fails, using:
# cryptsetup luksAddKey /dev/sdX

To bind a LUKS volume to the TPM, use:

# clevis luks bind -d /dev/sdX tpm2 '{}'

where '{}' contains the configuration. Even with no parameters, the drive cannot be decrypted from another computer (unless the attacker knows the backup password).

To seal the LUKS key against, for example, the UEFI settings and the Secure Boot policy, use:

'{"pcr_ids":"1,7"}'

If the UEFI or Secure Boot settings are modified, the TPM will compute different PCR values and decryption will fail. This gives protection against evil maid attacks.

For a list of parameters, see clevis-encrypt-tpm2(1) § CONFIG.

For a full explanation of the meanings of PCRs, see the TCG specification (§ 2.3.4).

To generate a new Clevis pin after changes in system configuration that result in different PCR values, for example updating the UEFI when PCR 0 is used, run

# cryptsetup luksDump /dev/sdX
Tokens:
  token slot: clevis
        Keyslot:  keyslot

to find the slot used for the Clevis pin, then

# clevis luks regen -d /dev/sdX -s keyslot

To remove the Clevis binding, run:

# clevis luks unbind -d /dev/sdX -s keyslot 
Warning: Double check you have chosen the right slot, or you might lose access to your volume.

You can unlock a TPM-bound volume using:

# clevis luks unlock -d /dev/sdX

For automated decryption of volumes in /etc/crypttab, enable clevis-luks-askpass.path.

For automated decryption of the root volume, use Booster, Dracut or mkinitcpio-clevis-hook. Booster automatically decrypts LUKS volumes bound using Clevis out of the box. Dracut and mkinitcpio-clevis-hook needs the following extra packages:

followed by an initramfs regeneration:

Dracut:

# dracut -f

mkinitcpio-clevis-hook:

# mkinitcpio -P

Other good examples of TPM 2.0 usage

Troubleshooting

tcsd.service failed to start

After installing trousersAUR, the tcsd.service service may not start correctly due to permission issues.[6] It is possible to fix this either by rebooting or by triggering the udev rule that is included in the trousersAUR package:

# udevadm control --reload-rules
# udevadm trigger

See also