Following up on my email sent in November 2019: https://lists.trustedfirmware.org/pipermail/tf-a/2019-November/000124.html
and the proof-of-concept code and documentation shared at that time:  https://developer.trustedfirmware.org/w/tf_a/poc-multiple-signing-domains/  https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/2443
I've made a number of improvements and cleanups in the code. I am posting a new version that introduces this new chain of trust (called "dualroot", as it has 2 roots of trust) as an alternative to the default TBBR one. Right now, it is only enabled on some Arm platforms but it should be pretty straight-forward to extend this to other platforms.
The code is available there: https://review.trustedfirmware.org/q/topic:%22sb%252Fdualroot%22
and is comprised of the following patches: - Introduce a new "dualroot" chain of trust - cert_create: Define the dualroot CoT - Build system: Changes to drive cert_create for dualroot CoT - plat/arm: Provide some PROTK files for development - plat/arm: Add support for dualroot CoT - plat/arm: Pass cookie argument down to arm_get_rotpk_info() - plat/arm: Retrieve the right ROTPK when using the dualroot CoT
This patch stack is based on preparatory work (which has already been merged) to select a different CoT. This patch stack: - Did some build system refactoring. - Introduced a new 'COT' build option to select the chosen chain of trust. - Made no functional change. See http://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=dcd03c...
Note that I've not updated the TF-A documentation just yet to reflect these changes. I will do that once I've had some initial feedback from the community and feel that we're reaching a consensus (in the interest of saving time keeping documentation aligned with code going under rework).
Changes Compared to the Proof-of-Concept Patch  --------------------------------------------------
- Introduced a proper, separate chain of trust rather than hijacking the TBBR one. It also has its own header file for certificate extensions OIDs now.
- NS-ROTPK has been renamed into "Platform ROTPK", or PROTPK for short. Going forward, this key would sign both non-trusted images (such as BL33) and secure partitions. The NS- prefix did not fit well this use case. The "Platform" prefix instead refers to the owner of this key, i.e. the platform owner, as opposed to the Silicon Provider.
- Removed Non-Trusted World Bootloader Key Certificate. This didn't seem needed in this context and simplifies the CoT.
- Removed the Non-Trusted Key from the Trusted Key Certificate, as it's not used in this CoT (the PROTPK signs all non-trusted images instead).
- As a consequence, the corresponding option for feeding the PROTPK to the cert_create tool has been renamed into --prot-key (was --ns-rot-key).
- The hash of the PROTPK is now provided in a file rather than being hard-coded into the code. This is cleaner than polluting the code with a byte array.
- Proper integration in the build system. Using the dualroot chain of trust is achieved through the COT build option:
make <usual trusted boot build options> COT=dualroot
- plat_get_rotpk_info() is unchanged if using the TBBR CoT. The alternative implementation managing both ROTPK or PROTPK is selected only if the dualroot CoT has been chosen at build time.
Testing and Supported Platforms -------------------------------
Tested on AEMv8-A Base Platform (AArch32 and AArch64 execution states), rde1edge, rdn1edge, SGI-575 and SGM-775 FVPs (all available on https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual...).
Arm Juno is not supported right now because it has its own implementation of plat_get_arm_rotpk_info() instead of piggy-backing on the Arm common one.
Ran the standard set of tests available in the TF-A-Tests repository: http://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
Also ran the firmware update tests available in the same repository. See
https://trustedfirmware-a-tests.readthedocs.io/en/latest/user-guide.html#ns-... for more information.
Finally, performed some end-to-end boot tests to Linux.
And of course, ran our regression tests to make sure that existing configurations using the TBBR chain of trust are still working as expected.
The PROTPK hash is embedded into the firmware. It's unlikely that a real system would like to do that. The use case targeted here is to remove the need for the primary ROTPK owner to interact with the PROTPK owner. If BL2 embeds the hash, this defeats the purpose, as now the BL2 owner (which is expected to be the primary ROTPK owner) has to get the PROTPK from the other vendor.
In a real system, we would expect the PROTPK to be provisioned in such a way that BL2 is able to retrieve it. For example, the PROTPK owner might burn it (or a hash of it) in some OTP memory. As long as there is a defined contract between BL2 and the PROTK-rooted images as to how/where to securely get this key or hash, there should not be any need for the two vendors to do any cross-signing.
This caveat was already present in the proof-of-concept  and stays out of the scope for this work, as this ties into broader topics such as key provisioning. Right now, the onus is on the platform layer to handle this appropriately.
Future work -----------
We have plans to change the "dualroot" CoT further and extend the PROTPK signing domain with a secure partition. This would demonstrate the use of several secure partitions, some owned by the silicon provider, others owned by the platform owner.