Trusted Platform Module
The Trusted Platform Module, or TPM for short, is a secure, isolated, cryptographic processor that is typically built into most modern computers. The TPM can be used to hash files and store the hash in PCRs, using a blockchain for measurement. Additionally, a TPM can be used to securely store cryptographic keys, preventing unauthorized access, or access once the boot environment has changed.
The two most common versions of the TPM are 1.2 and 2.0. Both versions are supported on Linux, but this article covers TPM 2.0. There are a few ways to use TPM under Linux: storing SSH, GPG, and LUKS keys in the TPM, measuring the integrity of files and boot components, and generating random data.
- SRTM - Static Root of Trust for Measurements
- DRTM - Dynamic Root of Trust for Measurements
- CRTM - Core Root of Trust for Measurements
- SRK - Storage Root Key
- EK - Endorsement Key
- PK - Platform Key
- UEFI - Unified Extensible Firmware Interface
- PCR - Platform Configuration Registers
TPMs typically have 3 builtin seeds, each associated with a hierarchy. These seeds are used to generate private keys, and each is typically used for different purposes.
- Platform - This hierarchy is typically associated with early boot code and firmware, typically used for boot integrity verification.
- Storage (Owner) - This hierarchy is meant to be used by the device owner, and is often used to wrap and seal data.
- Endorsement - This hierarchy is associated with the TPM itself, and can be used to generate keys that are associated with the particular device.
Each seed type has an associated key, which is generated and used in a different manner.
- Platform Key - Deterministically generated using the Platform Seed, used for attestation and verifying boot integrity.
- Storage Root Key - Randomly generated with the TPM is initialized, primarily used to wrap other keys.
- Endorsement Key - Derived from the endorsement Seed. Used to verify the authenticity of the TPM itself, keys derived from this correlate to that specific TPM.
In order to protect data, the TPM wraps or binds the data. Data, often private keys, is wrapped using the TPM's SRK. Wrapping involves encrypting the data using the internal key, so it can later only be decrypted using this key. Because the TPM has full control of this key, conditions can be set deciding when data can be decrypted.
Once data has been encrypted or wrapped using the TPM, conditions can be defined controlling when the TPM will allow decryption of this data, sealing the data. If a decryption attempt has been made, and the appropriate PCR values are measured, the TPM will decrypt or unseal the data.
Platform Configuration Registers
PCRs typically contain hashes which can only be written by extension. The extension operation uses the value of the currently stored value along with the new data, forming a cryptographic blockchain.
Records of each TPM event should be stored in the TPM's event log.
A detailed explanation of the TPM implementation is available at Trusted Computing Group's website
|0||SRTM, BIOS, Host Platform Extensions, Embedded Option, ROMs and PI Drivers||Stores firmware, may change if the UEFI/BIOS is updated. Acts as the root for the chain of trust. Some implementations record CPU microcode measurements here.|
|1||Host Platform Configuration||The UEFI configuration itself, such as settings. This typically contains the entire contents of the CMOS/NVRAM, minus any dynamic or security-sensitive data.|
|2||UEFI driver and application Code||Option ROMs|
|3||UEFI driver and application Configuration and Data||Option ROM configuration|
|4||UEFI Boot Manager Code (usually the MBR) and Boot Attempts||Measures manager code itself, and that a use was attempted|
|5||Boot Manager Code Configuration and Data (for use by the Boot Manager Code) and GPT/Partition Table||Measures the configuration of the boot device, including the GPT partition table of the device|
|6||Host Platform Manufacturer Specific||May be used for S4 and S5 Power State Events|
|7||Secure Boot Policy||Measures contents of Secure Boot keys and certificates used to verify boot applications|
|8 - 15||Defined for use by the Static OS|
|16||Debug||Optional, and sometimes unused PCR|
|23||Application Support||Can be set and reset by the OS|
The first seven PCRs are mainly used by the Pre-Boot environment, while the rest are typically used by the Operating System.
Every time a PCR is extended, a TPM event log entry is made.
Device Drivers ---> Character devices ---> [*] TPM Hardware Support ---> <*> TPM HW Random Number Generator support <*> TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface <*> TPM 2.0 CRB Interface
USE flags for app-crypt/tpm2-tss TCG Trusted Platform Module 2.0 Software Stack
||Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally|
||Enable feature API (requires openssl as crypto backend)|
||Use net-libs/mbedtls as crypto engine|
||Use dev-libs/openssl as crypto engine|
||Enable policy library (requires openssl as crypto backend)|
||Build static versions of dynamic libraries as well|
||Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)|
emerge --ask app-crypt/tpm2-tools
emerge --ask app-crypt/tpm2-tss
Checking the TPM version
/sys/class/tpm/ can be used to view TPM details such as the version:
Reading public keys
To view the public keys stored on the TPM, first a list of persistent handles must be obtained with:
- 0x81000001 - 0x81000002 - 0x81000009 - 0x81010001
Handles starting in 8100 are assicated with the Endorsement Key, while keys starting with 8101 are associated with the Storage Root Key.
With the handle, the public key contents can be viewed with:
tpm2_readpublic -c 0x81000001
Viewing TPM register values
tpm2_pcrread lists ALL PCR values of the TPM. If the system's configuration changes (for instance, if Secure Boot is disabled, the CMOS is reset, or if any UEFI settings are changed), then these values will change.
sha1: sha256: 0 : 0xB3BDD700D0E3BE5248B0B37395F8C07CCD3D12C9BEBFEFD2717E63A74C16171F 1 : 0xF540343BED5BFD8D8902C874F2ADB907A6FA8213FA7942389D3AE4DD1D4B7570 2 : 0xEF674CD26AD78DD8240A4723B1A527DE84218773ADEAAABF68A9A71B64E1DBA8 3 : 0x3D458CFE55CC03EA1F443F1562BEEC8DF51C75E14A9FCF9A7234A13F198E7969 4 : 0xB1F4D1EB09E1786C2FE17A2D7A0235D25981D3D42967551E75C4E6E02D774864 5 : 0x1F94EED8C1BB1BB3D3782D0D2F75216F6EC4D67F435D872F139DDE8126D99BC8 6 : 0x3D458CFE55CC03EA1F443F1562BEEC8DF51C75E14A9FCF9A7234A13F198E7969 7 : 0x6438D21F9AB1B83FD3E7341F7C4C379DBE7003A2D4CC9BFB0C1856694BDA5492 8 : 0x0000000000000000000000000000000000000000000000000000000000000000 9 : 0x0000000000000000000000000000000000000000000000000000000000000000 10: 0x4F27447C738A6F4CADD90E05B40888A72F448C57607C60B3A2B8F81FB7D8934B 11: 0x0000000000000000000000000000000000000000000000000000000000000000 12: 0x0000000000000000000000000000000000000000000000000000000000000000 13: 0x0000000000000000000000000000000000000000000000000000000000000000 14: 0x0000000000000000000000000000000000000000000000000000000000000000 15: 0x0000000000000000000000000000000000000000000000000000000000000000 16: 0x0000000000000000000000000000000000000000000000000000000000000000 17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 23: 0x0000000000000000000000000000000000000000000000000000000000000000 sha384: 0 : 0x417D61CA58074DE5CFD625F0D85B870F9A5CB47B5B91B8B4A61B16C368A6B5B1C26F7EB1F3DD2F1423BE80CA6E70A96D 1 : 0xB5D743284345EAAFCD479CECA26E4A2534F1AA96C247D48B5A20556F040F07CE90B3B6ACAA8FBB5D16B842300D7C1886 2 : 0xAB9EC365C4A0929685BF9FFE968B5A4815267AE3B01B81A03829E6CF36D03AA3CB0C8CB82B8272BE23C7C7E453E097E7 3 : 0x518923B0F955D08DA077C96AABA522B9DECEDE61C599CEA6C41889CFBEA4AE4D50529D96FE4D1AFDAFB65E7F95BF23C4 4 : 0x21031F9A56551177B82CCEB6A498188C674906E6F67588EC2B5DDF3EE50A01B60C8FAA323BE2F70F249A548315F6929C 5 : 0xC0E688F4FBFF3F7F28D57A64C2439D8536855373BE4EE329C5A98F77FE239E89ADC6A4FFAA9BCB31D8ACC91FC798AA60 6 : 0x518923B0F955D08DA077C96AABA522B9DECEDE61C599CEA6C41889CFBEA4AE4D50529D96FE4D1AFDAFB65E7F95BF23C4 7 : 0x0B3BE1E49223C893F4C2006235E501DFA5EDC7B6CA743EAC123F2E73F19BE36CD5303E130BFFDA2EF2EB7273800C6063 8 : 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 9 : 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 10: 0x9701564F204AB8CBF8E3F08B1690212168A23B3C7D62CB4B4A75F6CCFCC70966AED8455DE56B211CE5C2DB51493B53D5 11: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 12: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 13: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 14: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 15: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 16: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 23: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
To read a single value, such as the sha384 hash of the Secure Boot Policy:
sha384: 7 : 0x0B3BE1E49223C893F4C2006235E501DFA5EDC7B6CA743EAC123F2E73F19BE36CD5303E130BFFDA2EF2EB7273800C6063
Reading the TPM event log
tpm2_eventlog <(cat /sys/kernel/security/tpm0/binary_bios_measurements)
The output of this command will contain detailed information about all TPM events.
Each event should contain the following attributes:
- EventNum - The event number, starts at 0.
- PCRIndex - The PCR index this event recorded to.
- EventType The type of event.
- Digest - The resulting digest of the event.
- DigestCount - How many digests are associated with this event.
- Event - Details about the event, such as the variable name and UUID if reading an EFI variable.
Creating a new Primary Key
To create a new primary key using the Storage key:
tpm2_createprimary --key-context primary.ctx
Save PCR data for key sealing
Once a trusted state has been established, PCR data can be logged to a file for key sealing:
tpm2_pcrread --output safestate.pcrread sha256:0,7
Any PCRs can be used, but 0 and 7 are good choices since they measure the UEFI code and Secure Boot states.
Create a TPM PCR policy for data sealing
A PCR policy can be created with:
tpm2_createpolicy --policy-pcr --pcr-list sha256:0,7 --pcr safestate.pcrread --policy trusted_policy.pol
To store data in NVRAM wrapped using keys in the TPM:
echo "key data" | tpm2_create --parent-context primary.ctx --policy trusted_policy.pol --key-context data.ctx --sealing-input -
If PCR register data matches context, data can be usealed with:
tpm2_unseal --object-context data.ctx --auth pcr:sha256:0,7
Random Number Generation
Using a hardware random number generator gives more entropy to the system and can therefore give faster random numbers. When the TPM drivers compiled in the kernel, there will be a new device named /dev/hwrng. This is the TPM random number generator.
To use it, first, emerge the package sys-apps/rng-tools which will be used to redirect /dev/hwrng into /dev/random.
emerge --ask sys-apps/rng-tools
Then, simply start the service. By default, rng-tools looks for /dev/hwrng so it does not need any configuration to work.
rc-service rngd start
rngd | * Caching service dependencies ... [ ok ] rngd | * Starting rngd ... [ ok ]
rc-update add rngd default
Some TPMs have NVRAM which can be used to store data persistently. Most commands default to using the Storage or Owner hierarchy. This can be changed by using --hierarchy p to use the Platform hierarchy.
All tpm2_nvram commands have well written man pages.
Viewing the NVRAM
To list populated public sections of the NVRAM, the following command can be used:
The output of this command contains several attributes such as the handle (index), in hexadecimal format, name, and:
- hash algorithm - Has the friendly name, such as sha256 and the raw value, such as 0xbB.
- attributes - The friendly list of attributes, and the corresponding bitfield mask value.
- size - The size of this memory region.
Attribute information, according to man tpm2_nvreadpublic, is present in Table 204.
Defining a Public NVRAM Region
tpm2_nvdefine can be used to define memory regions, the size is in bytes, the command returns the handle of the defined region:
tpm2_nvdefine --size 32
Although a memory handle can be defined manually, the TPM will automatically use the first, lowest, free memory region.
Writing to a Public NVRAM Region
Using a handle, the NVRAM can be written to with tpm2_nvwrite:
echo "test content" | tpm2_nvwrite 0x1000000 --input -
The --input argument is required and typically takes a file, but stdin can be used with -i- or --input -.
Reading a public NVRAM Region
Reading will fail if the region has not been written to.
To read a defined region, the tpm2_nvread command can be used:
WARN: Reading full size of the NV index test content
Removing a NVRAM Region Definition
Memory regions can be undefined with:
On success, there will be no output, results can be confirmed with tpm2_nvreadpublic.
The TPM event log cannot be read
For reasons currently unknown, sometimes the TPM event log will not be readable in Linux, a method to resolve this is to clear the TPM from Windows. This can be done by running Clear-TPM in an admin powershell session or selecting "Cear TPM" under the Device Security -> Security Processor Settings menu.
- Secure Boot — an enhancement the security of the pre-boot process of a UEFI system.
- Nokia TPM Course
- Arch Wiki: TPM