Note: This document is outdated and is only kept here for reference. It described some proof of concept work that has now been productized and merged upstream. The final implementation diverges from the PoC on a number of areas, please refer to this email for a detailed list of changes.
The Trusted Board Boot (TBB) feature prevents malicious firmware from running on the platform by authenticating all firmware images up to and including the normal world bootloader. It does this by establishing a Chain of Trust (CoT) using public key cryptography standards.
The TBBR CoT is explained in details in the TF-A documentation (TBB design guide, Authentication Framework design guide) but the following diagram summarizes it (SCP and debug certificates are not shown here for conciseness):
As can be seen, all firmware binaries and certificates are (directly or indirectly) linked to the Root of Trust Public Key (ROTPK). Typically, the same vendor owns the ROTPK, the Trusted key and the Non-Trusted Key. This means that they need to get involved and sign every BL3x Key Certificate. Depending on the foreseen key provisioning and key ownership model, this may be impractical and too restrictive in some cases.
The TBBR implementation in TF-A provides some flexibility for other CoTs. The one depicted above is only one example. The platform layer is free to define and use an alternate CoT.
In this document, we are exploring how the existing TBBR CoT may be modified such that the BL33 image is made independent from the rest of the CoT. In this proof of concept, the BL33 image (and associated certificates) has its own CoT linked to a new key, NS-ROTPK, owned by the BL33 vendor. The following diagram shows the new CoT:
We will refer to the existing ROTPK as the S-ROTPK to make the distinction clear between the 2 keys throughout the rest of this document.
Note that the BL33 CoT could be further simplified, for example to remove the BL33 Key Certificate. Also, the Non-Trusted Key is still present in the Trusted Key Certificate here but is not used. Such modifications are out of scope for this proof of concept, which focuses on the minimal changes needed to meet the use case described above.
The patch is available for download here:
(Apply on top of commit 1d2b41614c5675b144ae1f4517c1f8bf249a12d2)
It modifies 3 areas in the code base:
- The chain of trust definition.
- The platform layer.
- The cert_create tool.
The CoT is defined in the drivers/auth/tbbr/tbbr_cot.c file.
The BL33 key certificate is turned into a root certificate. This means it no longer has any parent certificate and the public key used to authenticate it should be retrieved from the platform (rather than from the parent certificate).
We also specify that the authentication should use the NS-ROTPK.
Today, the platform layer must implement the plat_get_rotpk_info() API. This is used by the generic code to retrieve the ROTPK (or a hash of it) for verifying images in the CoT. See the function documentation.
Where the Arm platforms implementation always returned the hash of the S-ROTPK previously, we now want it to return either the S-ROTPK or the NS-ROTPK information depending on the cookie argument:
- If the cookie is NULL then we continue to return the S-ROTPK, as before.
- Otherwise, we interpret the cookie as the Object ID (OID) of the X.509 certificate extension to retrieve the public key from.
In line with the way it is implemented for the S-ROTPK, we embed the hash of the NS-ROTPK in the BL2 image itself and return it.
The definition of the TBBR CoT in the cert_create tool is located in tools/cert_create/include/tbbr/ and tools/cert_create/src/tbbr/ directories.
The cert_create tool needs to have the same view of the CoT as the firmware itself. Therefore, the same kind of changes need to be done for the Non-Trusted Firmware Key Certificate. Its definition is changed to embed the NS-ROTPK in the certificate. The key is added as an X.509 extension in the certificate so a new OID for this extension is added.
As the tool currently requires each key to be specified on the command line, we introduce a new option --ns-rot-key to pass the filename of the NS-ROT private key. This will be used by the tool to sign the Non-Trusted Firmware Key Certificate.
Most of the changes are on data structures to describe the new CoT. The only code changes are in the platform layer. This shows that the TBBR implementation as it stands today mainly supports this use case out of the box.
There are a number of workarounds and shortcuts taken in this proof of concept that means it's only useful as a prototype and cannot be integrated in the code base right now.
First of all, the TBBR specification defines a specific CoT (see page 21) and any deviation from that is not compliant. Therefore, it's not appropriate to modify the TBBR CoT like that. The specification also defines reserved OIDs for each of the X.509 certificate extensions involved in the CoT (see appendix C) and we should not take the liberty to add one like the NS-ROTPK OID. A cleaner solution would be to define a new CoT instead of piggy-backing on the TBBR one.
Also, embedding the NS-ROTPK hash into the firmware is not realistic. The use case targeted here is to remove the need for the S-ROTPK owner to sign any of the non-secure world images. If BL2 embeds the hash, this defeats the purpose, as now the BL2 owner (which is typically also the S-ROTPK owner) has to get the NS-ROTPK from the non-secure world software vendor.
In a real world situation, we would expect the NS-ROTPK to be provisioned in such a way that BL2 is able to retrieve it. For example, the BL33 vendor might burn the NS-ROTPK (or a hash of it) in some OTP memory. As long as there is a defined contract between BL2 and BL33 as to how/where to get this key or hash, there should not be any need for the two vendors to do any cross-signing.
Finally, the patch is missing proper integration of the tools invocation in the build system. A script is provided instead to directly invoke the tools with the right options.