Use TBOOT to boot Linux with DRTM (part 1)

Posted by Łukasz Hawryłko on October 15, 2021 · 9 mins read

In this article I will describe what is DRTM and how it compares to UEFI Secure Boot. In second part, I will show how to install and configure TBOOT to use DRTM in Linux.

DRTM vs SRTM

At the beginning let’s expand these acronyms:

  • DRTM - Dynamic Root for Trusted Measurement
  • SRTM - Static Root for Trusted Measurement

The common part for both terms is “Root for Trusted Measurement”, so let’s start from this.

Root for Trusted Measurement

The easiest way to explain what is measurement is to treat it as a fancy name for SHA256 (or any other algorithm) hash. To get a measurement of some component we have to calculate its hash with any hashing algorithm.

Trusted means what it means. We can trust that indeed the measurement is calculated over the component that we want to measure. As we are focused on a boot components the easiest example of non-trusted measurement is when attacker can modify bootloader to measure original Linux kernel binary, but load and executed another one with some exploit.

Root means that this is a starting point for measurements chain. To have trusted measurements of Linux kernel, we have to trust bootloader that it will measure the binary that is going to be executed. How we can trust the bootloader? Measure it! If we calculate measurement of the bootloader and compare it to the expected value of non-malformed binary we can be sure that bootloader does what we want and nobody is trying to attack us.

But hey, who will measure the bootloader? Before bootloader there is UEFI. So we have to trust UEFI that it will measure and execute the same bootloader binary. Are we sure that UEFI is always trusted and cannot be replaced by attacked? Of course not - to trust UEFI we have to measure it. Who will do that? Without digging into too many details - CPU microcode - a piece of code that is embedded into CPU.

All in all there is a chain (called chain of trust), where starting point is in CPU microcode (that’s Root for Trusted Measurement) and every component in that chain needs to be measured to be sure that measurements of last component - Linux kernel in this example - are trusted.

Dynamic vs Static

The example from previous section where CPU measures UEFI, UEFI measures bootloader and bootloader measures Linux kernel is a model of Static Root for Trusted Measurement. Root of trust is established when user pushes power button and chain of trust has to be maintained over all boot components. That means - we have to trust every line of code that is executed during whole boot process, we can assume that this over a million lines.

Trusted chain in SRTM

It is not difficult to imagine that where there is over a million lines of code, there can be some potential vulnerabilities. There is a simple connection:

bigger code base = higher chance of a bug

That’s why we should limit software that we need to trust to make system secure.

Dynamic Root for Trusted Measurement can limit that. It allows to establish root of trust at some point during boot process, not necessary at the beginning. If our goal is to make sure that loaded OS is trusted, we can enter trusted environment just before loading OS. In this scenario, we don’t have to check any boot component before that point. That means - even if UEFI or bootloader have some vulnerabilities, it does not change anything, we can still verify OS in secure way.

Trusted chain in DRTM

DLME is a small application that prepares system for entering DRTM environment and (in our example) verifies Linux kernel binary.

TPM - Trusted Platform Module

There is one more thing that need to be explained to make everything clear - TPM. TPM is a sophisticated device that can be either embedded in motherboard, or as an external module inserted into dedicated header. Recently, there is also a possibility to have firmware TPM that is a kind of TPM emulation inside a chipset.

There are two major versions of TPMs: 2.0 and 1.2. The older one is no longer used, all recent PCs have 2.0 version. The differences between these versions from our point of view are not very important, both of them can be used in DRTM.

TPM is a very clever and feature-rich device. I will explain just one functionality - PCR. Platform Configuration Registers (PCRs) are registers that are dedicated to store values of cryptographic hashes. In TPM 1.2 only SHA1 is supported, in TPM 2.0 more algorithms can be supported, but at least there should be SHA1 and SHA256. There are 23 PCRs, if TPM supports more than one algorithm these registers are mirrored to each of hashing algorithm bank.

The special property of PCR is that you can’t write its value directly. To put new measurement into PCR you have to do an extend operation. It is defined as:

PCR_new = hash(PCR_old * new_value)

Multiplication is just a symbol of some math operation, in real world this function is a little more complicated.

What does it change? A lot! Cryptographic hashing function by design is an one-way function. This attribute does not allow to find a set of data that after hashing will produce given result. The only way is to use brutal force and try with different combinations of input data waiting for a bit of luck. With modern SHA256 and stronger algorithms, this method is useless.

Measured Launch

Extend operation, combined with one-way hashing function, does not allow to set PCR for a specific value, because it is impossible to find input that will produce given hash. Let’s imagine the following situation: system administrator boots fresh PC, with OS installed from trusted source. PC has never been connected to the Internet, there is not way that anybody can modify it, so we can assume that everything is intact and trusted. During boot process, measurements of each component are calculated and extended to TPM PCR. When system is booted, value of the PCR is read and saved as good one.

There is also a special mechanism that allow to do a remote attestation - TPM PCRs values can be transferred over the network in secure way, even if whole system, including UEFI and OS is compromised. We can imagine the following rule: Only after successful attestation (checking if PCRs have correct values), PC will get an access to the confidential data on some remote server.

Let’s assume that attacker knows proper values of PCRs, he can modify anything he wants, will system defend this?

If attacker modify any boot component, its measurements will be different than expected. Even if attacker knows the proper values, it can’t just write it to the TPM, overwriting the bad ones. The only way to achieve good values of PCRs is to do all extend operation with exactly the same data as during the golden run. Remote attestation that does not requires to trust OS is also a feature of TPM.

At the end of the day - attacker can boot PC with malformed UEFI and OS, but if he does that, remote attestator does not give this system access to any valuable data. This is called Measured Launch, in opposite to Verified Launch, system does not check if components are intact, it only collects measurement. The decision is made by attestator.

In next article I will show how to configure Linux OS to collect measurements of boot components using Intel TXT (DRTM solution for Intel PCs) and TBOOT.

"Binary code" by Christiaan Colen is licensed under CC BY-SA 2.0