[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Linux DRTM on UEFI platforms

From: Matthew Garrett
Subject: Linux DRTM on UEFI platforms
Date: Tue, 29 Mar 2022 18:40:57 +0100
User-agent: Mutt/1.10.1 (2018-07-13)

We're still trying to come to a conclusion about the most maintainable 
approach to getting DRTM implementations like Intel TXT working on UEFI 
platforms under Linux. I'm going to try to summarise the situation here 
- I'm not an expert, so details may be inaccurate, but I think this is 
the rough shape of things.

Under normal circumstances on UEFI platforms, the bootloader (or system 
firmware directly) load the kernel and execute code in the boot stub. 
This boot stub code interacts with the firmware in various ways, 
including working around some platform-specific issues and doing things 
like copying the TPM event log into memory that can be used by the 
kernel proper. While it remains technically possible to boot the kernel 
on x86 UEFI platforms by jumping directly to the kernel entry point and 
skipping the boot stub, this risks disabling certain functionality and 
leaving the kernel in a slightly unexpected state. The contract that 
exists between the UEFI stub and the kernel is not meaningfully 
documented - portions are carried out by updating the contents of the 
bootparams struct on x86 or devicetree on ARM, but other information is 
conveyed via UEFI configuration tables, the boot stub may modify the 
contents of certain UEFI variables, and some of this is implicit in 
the form of hardware state.

The Trenchboot project is attempting to implement DRTM under Linux. 
Traditional measured boot takes the form of a static root of trust - 
each component in the boot chain is measured by the previous component 
before being executed, and each measures what it considers to be 
security relevant configuration and behavioural state. Modifying any 
component will change the measurements, even if the end result is 
equivalent. Dynamic Root of Trust Measurement aims to provide more 
useful measurements by performing a measurement at a specific point in 
time - as a result, DRTM cares only about what the state *is*, not what 
happened before then.

There's a bunch of complexity involved in this that's vendor specific, 
but the short version is that a launch environment is set up and a 
specific CPU instruction executed that triggers a secure launch event. 
The Trenchboot code consists of patches to bootloaders to support 
setting up this environment, and patches to the kernel to provide 
support for the "Secure Launch" kernel that handles DRTM before handing 
control off to the kernel proper, skipping the UEFI boot stub.

Since this skips the UEFI boot stub, it's then the responsibility of the 
bootloader to implement the functionality of the boot stub. This is made 
difficult due to the absence of an express contract between the boot 
stub and the rest of the kernel - our assumption has been that the code 
is the contract, and this is free to change arbitrarily since both the 
producer and the consumer of the information can be updated 
simultaneously and can't get out of sync. That seems to leave us with 
two options:

1) Formalise the contract between the boot stub and the kernel, making 
it easier for other boot loaders to implement the contract. This has the 
downside that even within the scope of the contract we may end up with 
divergent behaviour, and also new functionality in the kernel may not be 
available without the bootloader also being updated.

2) Modify the boot stub such that it can be provided with a callback, 
and instead of jumping to the kernel it can jump to the callback. The 
boot flow would then involve the boot loader setting up the launch 
environment, calling the boot stub code, and then performing the DRTM 
event. This avoids requiring an explicit contract (the boot stub would 
remain part of the kernel image and would be updated in lockstep).

One complexity for both approaches is that the secure launch environment 
needs to be aware of all security-critical state in the system. The 
firmware nominally exposes that information for everything it's aware 
of that's security-critical, but the boot stub may have performed 
security-critical actions or exposed security-critical state that the 
firmware is unaware of. The secure launch code from Trenchboot has to be 
aware of this in order to ensure it's measured.

If there's a contract, then in theory this would be embodied in the 
contract and when the contract is updated the secure launch code could 
also be updated. If there's no contract, every change to the boot stub 
would need to be examined and the secure launch code updated if 

While the secure launch code is currently out of tree, the goal is for 
it to be integrated into the kernel tree. My feeling is that it's 
going to be easier to manage this if everything is in tree - ie, all the 
EFI setup code that does anything security-critical is either in the 
firmware (and so the firmware takes responsibility for exposing it) or 
is in the Linux tree (and so we take responsibility for updating the 
secure launch code whenever something relevant changes in the boot 
stub). But this requires support from the EFI maintainers in terms of 
not merging things until we've established whether updates are required 
to the secure launch code. The alternative is effectively the same, 
except it would require updating the contract instead.

But, as mentioned, that's just my feeling - I know that Daniel feels 
that the contract approach is preferable. So:

1) From an EFI maintainer perspective, is making the contract between 
the boot stub and the kernel explicit viable?

2) If so, is it desirable?

3) If either (1) or (2) is "no", is it reasonable to ensure that all 
potentially security-critical state or configuration changes to the 
boot stub are reviewed by DRTM people to verify whether the secure 
launch code needs to be updated to match?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]