summaryrefslogtreecommitdiffstats
path: root/docs/design_documents
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/design_documents/cmake_framework.rst165
-rw-r--r--docs/design_documents/context_mgmt_rework.rst197
-rw-r--r--docs/design_documents/drtm_poc.rst132
-rw-r--r--docs/design_documents/index.rst15
-rw-r--r--docs/design_documents/measured_boot_poc.rst507
5 files changed, 1016 insertions, 0 deletions
diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst
new file mode 100644
index 0000000..d88942e
--- /dev/null
+++ b/docs/design_documents/cmake_framework.rst
@@ -0,0 +1,165 @@
+TF-A CMake buildsystem
+======================
+
+:Author: Balint Dobszay
+:Organization: Arm Limited
+:Contact: Balint Dobszay <balint.dobszay@arm.com>
+:Status: Accepted
+
+.. contents:: Table of Contents
+
+Abstract
+--------
+This document presents a proposal for a new buildsystem for TF-A using CMake,
+and as part of this a reusable CMake framework for embedded projects. For a
+summary about the proposal, please see the `Phabricator wiki page
+<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
+mentioned there, the proposal consists of two phases. The subject of this
+document is the first phase only.
+
+Introduction
+------------
+The current Makefile based buildsystem of TF-A has become complicated and hard
+to maintain, there is a need for a new, more flexible solution. The proposal is
+to use CMake language for the new buildsystem. The main reasons of this decision
+are the following:
+
+* It is a well-established, mature tool, widely accepted by open-source
+ projects.
+* TF-M is already using CMake, reducing fragmentation for tf.org projects can be
+ beneficial.
+* CMake has various advantages over Make, e.g.:
+
+ * Host and target system agnostic project.
+ * CMake project is scalable, supports project modularization.
+ * Supports software integration.
+ * Out-of-the-box support for integration with several tools (e.g. project
+ generation for various IDEs, integration with cppcheck, etc).
+
+Of course there are drawbacks too:
+
+* Language is problematic (e.g. variable scope).
+* Not embedded approach.
+
+To overcome these and other problems, we need to create workarounds for some
+tasks, wrap CMake functions, etc. Since this functionality can be useful in
+other embedded projects too, it is beneficial to collect the new code into a
+reusable framework and store this in a separate repository. The following
+diagram provides an overview of the framework structure:
+
+|Framework structure|
+
+Main features
+-------------
+
+Structured configuration description
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In the current Makefile system the build configuration description, validation,
+processing, and the target creation, source file description are mixed and
+spread across several files. One of the goals of the framework is to organize
+this.
+
+The framework provides a solution to describe the input build parameters, flags,
+macros, etc. in a structured way. It contains two utilities for this purpose:
+
+* Map: simple key-value pair implementation.
+* Group: collection of related maps.
+
+The related parameters shall be packed into a group (or "setting group"). The
+setting groups shall be defined and filled with content in config files.
+Currently the config files are created and edited manually, but later a
+configuration management tool (e.g. Kconfig) shall be used to generate these
+files. Therefore, the framework does not contain parameter validation and
+conflict checking, these shall be handled by the configuration tool.
+
+Target description
+^^^^^^^^^^^^^^^^^^
+The framework provides an API called STGT ('simple target') to describe the
+targets, i.e. what is the build output, what source files are used, what
+libraries are linked, etc. The API wraps the CMake target functions, and also
+extends the built-in functionality, it can use the setting groups described in
+the previous section. A group can be applied onto a target, i.e. a collection of
+macros, flags, etc. can be applied onto the given output executable/library.
+This provides a more granular way than the current Makefile system where most of
+these are global and applied onto each target.
+
+Compiler abstraction
+^^^^^^^^^^^^^^^^^^^^
+Apart from the built-in CMake usage of the compiler, there are some common tasks
+that CMake does not solve (e.g. preprocessing a file). For these tasks the
+framework uses wrapper functions instead of direct calls to the compiler. This
+way it is not tied to one specific compiler.
+
+External tools
+^^^^^^^^^^^^^^
+In the TF-A buildsystem some external tools are used, e.g. fiptool for image
+generation or dtc for device tree compilation. These tools have to be found
+and/or built by the framework. For this, the CMake find_package functionality is
+used, any other necessary tools can be added later.
+
+Workflow
+--------
+The following diagram demonstrates the development workflow using the framework:
+
+|Framework workflow|
+
+The process can be split into two main phases:
+
+In the provisioning phase, first we have to obtain the necessary resources, i.e.
+clone the code repository and other dependencies. Next we have to do the
+configuration, preferably using a config tool like KConfig.
+
+In the development phase first we run CMake, which will generate the buildsystem
+using the selected generator backend (currently only the Makefile generator is
+supported). After this we run the selected build tool which in turn calls the
+compiler, linker, packaging tool, etc. Finally we can run and debug the output
+executables.
+
+Usually during development only the steps in this second phase have to be
+repeated, while the provisioning phase needs to be done only once (or rarely).
+
+Example
+-------
+This is a short example for the basic framework usage.
+
+First, we create a setting group called *mem_conf* and fill it with several
+parameters. It is worth noting the difference between *CONFIG* and *DEFINE*
+types: the former is only a CMake domain option, the latter is only a C language
+macro.
+
+Next, we create a target called *fw1* and add the *mem_conf* setting group to
+it. This means that all source and header files used by the target will have all
+the parameters declared in the setting group. Then we set the target type to
+executable, and add some source files. Since the target has the parameters from
+the settings group, we can use it for conditionally adding source files. E.g.
+*dram_controller.c* will only be added if MEM_TYPE equals dram.
+
+.. code-block:: cmake
+
+ group_new(NAME mem_conf)
+ group_add(NAME mem_conf TYPE DEFINE KEY MEM_SIZE VAL 1024)
+ group_add(NAME mem_conf TYPE CONFIG DEFINE KEY MEM_TYPE VAL dram)
+ group_add(NAME mem_conf TYPE CFLAG KEY -Os)
+
+ stgt_create(NAME fw1)
+ stgt_add_setting(NAME fw1 GROUPS mem_conf)
+ stgt_set_target(NAME fw1 TYPE exe)
+
+ stgt_add_src(NAME fw1 SRC
+ ${CMAKE_SOURCE_DIR}/main.c
+ )
+
+ stgt_add_src_cond(NAME fw1 KEY MEM_TYPE VAL dram SRC
+ ${CMAKE_SOURCE_DIR}/dram_controller.c
+ )
+
+.. |Framework structure| image::
+ ../resources/diagrams/cmake_framework_structure.png
+ :width: 75 %
+
+.. |Framework workflow| image::
+ ../resources/diagrams/cmake_framework_workflow.png
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/context_mgmt_rework.rst b/docs/design_documents/context_mgmt_rework.rst
new file mode 100644
index 0000000..59f9d4e
--- /dev/null
+++ b/docs/design_documents/context_mgmt_rework.rst
@@ -0,0 +1,197 @@
+Enhance Context Management library for EL3 firmware
+===================================================
+
+:Authors: Soby Mathew & Zelalem Aweke
+:Organization: Arm Limited
+:Contact: Soby Mathew <soby.mathew@arm.com> & Zelalem Aweke <zelalem.aweke@arm.com>
+:Status: RFC
+
+.. contents:: Table of Contents
+
+Introduction
+------------
+The context management library in TF-A provides the basic CPU context
+initialization and management routines for use by different components
+in EL3 firmware. The original design of the library was done keeping in
+mind the 2 world switch and hence this design pattern has been extended to
+keep up with growing requirements of EL3 firmware. With the introduction
+of a new Realm world and a separate Root world for EL3 firmware, it is clear
+that this library needs to be refactored to cater for future enhancements and
+reduce chances of introducing error in code. This also aligns with the overall
+goal of reducing EL3 firmware complexity and footprint.
+
+It is expected that the suggestions below could have legacy implications and
+hence we are mainly targeting SPM/RMM based systems. It is expected that these
+legacy issues will need to be sorted out as part of implementation on a case
+by case basis.
+
+Design Principles
+-----------------
+The below section lays down the design principles for re-factoring the context
+management library :
+
+(1) **Decentralized model for context mgmt**
+
+ Both the Secure and Realm worlds have associated dispatcher component in
+ EL3 firmware to allow management of their respective worlds. Allowing the
+ dispatcher to own the context for their respective world and moving away
+ from a centralized policy management by context management library will
+ remove the world differentiation code in the library. This also means that
+ the library will not be responsible for CPU feature enablement for
+ Secure and Realm worlds. See point 3 and 4 for more details.
+
+ The Non Secure world does not have a dispatcher component and hence EL3
+ firmware (BL31)/context management library needs to have routines to help
+ initialize the Non Secure world context.
+
+(2) **EL3 should only initialize immediate used lower EL**
+
+ Due to the way TF-A evolved, from EL3 interacting with an S-EL1 payload to
+ SPM in S-EL2, there is some code initializing S-EL1 registers which is
+ probably redundant when SPM is present in S-EL2. As a principle, EL3
+ firmware should only initialize the next immediate lower EL in use.
+ If EL2 needs to be skipped and is not to be used at runtime, then
+ EL3 can do the bare minimal EL2 init and init EL1 to prepare for EL3 exit.
+ It is expected that this skip EL2 configuration is only needed for NS
+ world to support legacy Android deployments. It is worth removing this
+ `skip EL2 for Non Secure` config support if this is no longer used.
+
+(3) **Maintain EL3 sysregs which affect lower EL within CPU context**
+
+ The CPU context contains some EL3 sysregs and gets applied on a per-world
+ basis (eg: cptr_el3, scr_el3, zcr_el3 is part of the context
+ because different settings need to be applied between each world).
+ But this design pattern is not enforced in TF-A. It is possible to directly
+ modify EL3 sysreg dynamically during the transition between NS and Secure
+ worlds. Having multiple ways of manipulating EL3 sysregs for different
+ values between the worlds is flaky and error prone. The proposal is to
+ enforce the rule that any EL3 sysreg which can be different between worlds
+ is maintained in the CPU Context. Once the context is initialized the
+ EL3 sysreg values corresponding to the world being entered will be restored.
+
+(4) **Allow more flexibility for Dispatchers to select feature set to save and restore**
+
+ The current functions for EL2 CPU context save and restore is a single
+ function which takes care of saving and restoring all the registers for
+ EL2. This method is inflexible and it does not allow to dynamically detect
+ CPU features to select registers to save and restore. It also assumes that
+ both Realm and Secure world will have the same feature set enabled from
+ EL3 at runtime and makes it hard to enable different features for each
+ world. The framework should cater for selective save and restore of CPU
+ registers which can be controlled by the dispatcher.
+
+ For the implementation, this could mean that there is a separate assembly
+ save and restore routine corresponding to Arch feature. The memory allocation
+ within the CPU Context for each set of registers will be controlled by a
+ FEAT_xxx build option. It is a valid configuration to have
+ context memory allocated but not used at runtime based on feature detection
+ at runtime or the platform owner has decided not to enable the feature
+ for the particular world.
+
+Context Allocation and Initialization
+-------------------------------------
+
+|context_mgmt_abs|
+
+.. |context_mgmt_abs| image::
+ ../resources/diagrams/context_management_abs.png
+
+The above figure shows how the CPU context is allocated within TF-A. The
+allocation for Secure and Realm world is by the respective dispatcher. In the case
+of NS world, the context is allocated by the PSCI lib. This scheme allows TF-A
+to be built in various configurations (with or without Secure/Realm worlds) and
+will result in optimal memory footprint. The Secure and Realm world contexts are
+initialized by invoking context management library APIs which then initialize
+each world based on conditional evaluation of the security state of the
+context. The proposal here is to move the conditional initialization
+of context for Secure and Realm worlds to their respective dispatchers and
+have the library do only the common init needed. The library can export
+helpers to initialize registers corresponding to certain features but
+should not try to do different initialization between the worlds. The library
+can also export helpers for initialization of NS CPU Context since there is no
+dispatcher for that world.
+
+This implies that any world specific code in context mgmt lib should now be
+migrated to the respective "owners". To maintain compatibility with legacy, the
+current functions can be retained in the lib and perhaps define new ones for
+use by SPMD and RMMD. The details of this can be worked out during
+implementation.
+
+Introducing Root Context
+------------------------
+Till now, we have been ignoring the fact that Root world (or EL3) itself could
+have some settings which are distinct from NS/S/Realm worlds. In this case,
+Root world itself would need to maintain some sysregs settings for its own
+execution and would need to use sysregs of lower EL (eg: PAuth, pmcr) to enable
+some functionalities in EL3. The current sequence for context save and restore
+in TF-A is as given below:
+
+|context_mgmt_existing|
+
+.. |context_mgmt_existing| image::
+ ../resources/diagrams/context_mgmt_existing.png
+
+Note1: The EL3 CPU context is not a homogenous collection of EL3 sysregs but
+a collection of EL3 and some other lower EL registers. The save and restore
+is also not done homogenously but based on the objective of using the
+particular register.
+
+Note2: The EL1 context save and restore can possibly be removed when switching
+to S-EL2 as SPM can take care of saving the incoming NS EL1 context.
+
+It can be seen that the EL3 sysreg values applied while the execution is in Root
+world corresponds to the world it came from (eg: if entering EL3 from NS world,
+the sysregs correspond to the values in NS context). There is a case that EL3
+itself may have some settings to apply for various reasons. A good example for
+this is the cptr_el3 regsiter. Although FPU traps need to be disabled for
+Non Secure, Secure and Realm worlds, the EL3 execution itself may keep the trap
+enabled for the sake of robustness. Another example is, if the MTE feature
+is enabled for a particular world, this feature will be enabled for Root world
+as well when entering EL3 from that world. The firmware at EL3 may not
+be expecting this feature to be enabled and may cause unwanted side-effects
+which could be problematic. Thus it would be more robust if Root world is not
+subject to EL3 sysreg values from other worlds but maintains its own values
+which is stable and predictable throughout root world execution.
+
+There is also the case that when EL3 would like to make use of some
+Architectural feature(s) or do some security hardening, it might need
+programming of some lower EL sysregs. For example, if EL3 needs to make
+use of Pointer Authentication (PAuth) feature, it needs to program
+its own PAuth Keys during execution at EL3. Hence EL3 needs its
+own copy of PAuth registers which needs to be restored on every
+entry to EL3. A similar case can be made for DIT bit in PSTATE,
+or use of SP_EL0 for C Runtime Stack at EL3.
+
+The proposal here is to maintain a separate root world CPU context
+which gets applied for Root world execution. This is not the full
+CPU_Context, but subset of EL3 sysregs (`el3_sysreg`) and lower EL
+sysregs (`root_exc_context`) used by EL3. The save and restore
+sequence for this Root context would need to be done in
+an optimal way. The `el3_sysreg` does not need to be saved
+on EL3 Exit and possibly only some registers in `root_exc_context`
+of Root world context would need to be saved on EL3 exit (eg: SP_EL0).
+
+The new sequence for world switch including Root world context would
+be as given below :
+
+|context_mgmt_proposed|
+
+.. |context_mgmt_proposed| image::
+ ../resources/diagrams/context_mgmt_proposed.png
+
+Having this framework in place will allow Root world to make use of lower EL
+registers easily for its own purposes and also have a fixed EL3 sysreg setting
+which is not affected by the settings of other worlds. This will unify the
+Root world register usage pattern for its own execution and remove some
+of the adhoc usages in code.
+
+Conclusion
+----------
+Of all the proposals, the introduction of Root world context would likely need
+further prototyping to confirm the design and we will need to measure the
+performance and memory impact of this change. Other changes are incremental
+improvements which are thought to have negligible impact on EL3 performance.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/drtm_poc.rst b/docs/design_documents/drtm_poc.rst
new file mode 100644
index 0000000..79e1142
--- /dev/null
+++ b/docs/design_documents/drtm_poc.rst
@@ -0,0 +1,132 @@
+DRTM Proof of Concept
+=====================
+
+Dynamic Root of Trust for Measurement (DRTM) begins a new trust environment
+by measuring and executing a protected payload.
+
+Static Root of Trust for Measurement (SRTM)/Measured Boot implementation,
+currently used by TF-A covers all firmwares, from the boot ROM to the normal
+world bootloader. As a whole, they make up the system's TCB. These boot
+measurements allow attesting to what software is running on the system and
+enable enforcing security policies.
+
+As the boot chain grows or firmware becomes dynamically extensible,
+establishing an attestable TCB becomes more challenging. DRTM provides a
+solution to this problem by allowing measurement chains to be started at
+any time. As these measurements are stored separately from the boot-time
+measurements, they reduce the size of the TCB, which helps reduce the attack
+surface and the risk of untrusted code executing, which could compromise
+the security of the system.
+
+Components
+~~~~~~~~~~
+
+ - **DCE-Preamble**: The DCE Preamble prepares the platform for DRTM by
+ doing any needed configuration, loading the target payload image(DLME),
+ and preparing input parameters needed by DRTM. Finally, it invokes the
+ DL Event to start the dynamic launch.
+
+ - **D-CRTM**: The D-CRTM is the trust anchor (or root of trust) for the
+ DRTM boot sequence and is where the dynamic launch starts. The D-CRTM
+ must be implemented as a trusted agent in the system. The D-CRTM
+ initializes the TPM for DRTM and prepares the environment for the next
+ stage of DRTM, the DCE. The D-CRTM measures the DCE, verifies its
+ signature, and transfers control to it.
+
+ - **DCE**: The DCE executes on an application core. The DCE verifies the
+ system’s state, measures security-critical attributes of the system,
+ prepares the memory region for the target payload, measures the payload,
+ and finally transfers control to the payload.
+
+ - **DLME**: The protected payload is referred to as the Dynamically Launched
+ Measured Environment, or DLME. The DLME begins execution in a safe state,
+ with a single thread of execution, DMA protections, and interrupts
+ disabled. The DCE provides data to the DLME that it can use to verify the
+ configuration of the system.
+
+In this proof of concept, DCE and D-CRTM are implemented in BL31 and
+DCE-Preamble and DLME are implemented in UEFI application. A DL Event is
+triggered as a SMC by DCE-Preamble and handled by D-CRTM, which launches the
+DLME via DCE.
+
+This manual provides instructions to build TF-A code with pre-buit EDK2
+and DRTM UEFI application.
+
+Building the PoC for the Arm FVP platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(1) Use the below command to clone TF-A source code -
+
+.. code:: shell
+
+ $ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+
+(2) There are prebuilt binaries required to execute the DRTM implementation
+ in the `prebuilts-drtm-bins`_.
+ Download EDK2 *FVP_AARCH64_EFI.fd* and UEFI DRTM application *test-disk.img*
+ binary from `prebuilts-drtm-bins`_.
+
+(3) Build the TF-A code using below command
+
+.. code:: shell
+
+ $ make CROSS_COMPILE=aarch64-none-elf- ARM_ROTPK_LOCATION=devel_rsa
+ DEBUG=1 V=1 BL33=</path/to/FVP_AARCH64_EFI.fd> DRTM_SUPPORT=1
+ MBEDTLS_DIR=</path/to/mbedTLS-source> USE_ROMLIB=1 all fip
+
+Running DRTM UEFI application on the Armv8-A AEM FVP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+To run the DRTM test application along with DRTM implementation in BL31,
+you need an FVP model. Please use the version of FVP_Base_RevC-2xAEMvA model
+advertised in the TF-A documentation.
+
+.. code:: shell
+
+ FVP_Base_RevC-2xAEMvA \
+ --data cluster0.cpu0=</path/to/romlib.bin>@0x03ff2000 \
+ --stat \
+ -C bp.flashloader0.fname=<path/to/fip.bin> \
+ -C bp.secureflashloader.fname=<path/to/bl1.bin> \
+ -C bp.ve_sysregs.exit_on_shutdown=1 \
+ -C bp.virtioblockdevice.image_path=<path/to/test-disk.img> \
+ -C cache_state_modelled=1 \
+ -C cluster0.check_memory_attributes=0 \
+ -C cluster0.cpu0.etm-present=0 \
+ -C cluster0.cpu1.etm-present=0 \
+ -C cluster0.cpu2.etm-present=0 \
+ -C cluster0.cpu3.etm-present=0 \
+ -C cluster0.stage12_tlb_size=1024 \
+ -C cluster1.check_memory_attributes=0 \
+ -C cluster1.cpu0.etm-present=0 \
+ -C cluster1.cpu1.etm-present=0 \
+ -C cluster1.cpu2.etm-present=0 \
+ -C cluster1.cpu3.etm-present=0 \
+ -C cluster1.stage12_tlb_size=1024 \
+ -C pctl.startup=0.0.0.0 \
+ -Q 1000 \
+ "$@"
+
+The bottom of the output from *uart1* should look something like the
+following to indicate that the last SMC to unprotect memory has been fired
+successfully.
+
+.. code-block:: shell
+
+ ...
+
+ INFO: DRTM service handler: version
+ INFO: ++ DRTM service handler: TPM features
+ INFO: ++ DRTM service handler: Min. mem. requirement features
+ INFO: ++ DRTM service handler: DMA protection features
+ INFO: ++ DRTM service handler: Boot PE ID features
+ INFO: ++ DRTM service handler: TCB-hashes features
+ INFO: DRTM service handler: dynamic launch
+ WARNING: DRTM service handler: close locality is not supported
+ INFO: DRTM service handler: unprotect mem
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
+
+.. _prebuilts-drtm-bins: https://downloads.trustedfirmware.org/tf-a/drtm
+.. _DRTM-specification: https://developer.arm.com/documentation/den0113/a
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
new file mode 100644
index 0000000..3e20c07
--- /dev/null
+++ b/docs/design_documents/index.rst
@@ -0,0 +1,15 @@
+Design Documents
+================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+
+ cmake_framework
+ context_mgmt_rework
+ measured_boot_poc
+ drtm_poc
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
new file mode 100644
index 0000000..3ae539b
--- /dev/null
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -0,0 +1,507 @@
+Interaction between Measured Boot and an fTPM (PoC)
+===================================================
+
+Measured Boot is the process of cryptographically measuring the code and
+critical data used at boot time, for example using a TPM, so that the
+security state can be attested later.
+
+The current implementation of the driver included in Trusted Firmware-A
+(TF-A) stores the measurements into a `TGC event log`_ in secure
+memory. No other means of recording measurements (such as a discrete TPM) is
+supported right now.
+
+The driver also provides mechanisms to pass the Event Log to normal world if
+needed.
+
+This manual provides instructions to build a proof of concept (PoC) with the
+sole intention of showing how Measured Boot can be used in conjunction with
+a firmware TPM (fTPM) service implemented on top of OP-TEE.
+
+.. note::
+ The instructions given in this document are meant to be used to build
+ a PoC to show how Measured Boot on TF-A can interact with a third
+ party (f)TPM service and they try to be as general as possible. Different
+ platforms might have different needs and configurations (e.g. different
+ SHA algorithms) and they might also use different types of TPM services
+ (or even a different type of service to provide the attestation)
+ and therefore the instuctions given here might not apply in such scenarios.
+
+Components
+~~~~~~~~~~
+
+The PoC is built on top of the `OP-TEE Toolkit`_, which has support to build
+TF-A with support for Measured Boot enabled (and run it on a Foundation Model)
+since commit cf56848.
+
+The aforementioned toolkit builds a set of images that contain all the components
+needed to test that the Event Log was properly created. One of these images will
+contain a third party fTPM service which in turn will be used to process the
+Event Log.
+
+The reason to choose OP-TEE Toolkit to build our PoC around it is mostly
+for convenience. As the fTPM service used is an OP-TEE TA, it was easy to add
+build support for it to the toolkit and then build the PoC around it.
+
+The most relevant components installed in the image that are closely related to
+Measured Boot/fTPM functionality are:
+
+ - **OP-TEE**: As stated earlier, the fTPM service used in this PoC is built as an
+ OP-TEE TA and therefore we need to include the OP-TEE OS image.
+ Support to interfacing with Measured Boot was added to version 3.9.0 of
+ OP-TEE by implementing the ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` syscall, which
+ allows the former to pass a copy of the Event Log to any TA requesting it.
+ OP-TEE knows the location of the Event Log by reading the DTB bindings
+ received from TF-A. Visit :ref:`DTB binding for Event Log properties`
+ for more details on this.
+
+ - **fTPM Service**: We use a third party fTPM service in order to validate
+ the Measured Boot functionality. The chosen fTPM service is a sample
+ implementation for Aarch32 architecture included on the `ms-tpm-20-ref`_
+ reference implementation from Microsoft. The service was updated in order
+ to extend the Measured Boot Event Log at boot up and it uses the
+ aforementioned ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` call to retrieve a copy
+ of the former.
+
+ .. note::
+ Arm does not provide an fTPM implementation. The fTPM service used here
+ is a third party one which has been updated to support Measured Boot
+ service as provided by TF-A. As such, it is beyond the scope of this
+ manual to test and verify the correctness of the output generated by the
+ fTPM service.
+
+ - **TPM Kernel module**: In order to interact with the fTPM service, we need
+ a kernel module to forward the request from user space to the secure world.
+
+ - `tpm2-tools`_: This is a set of tools that allow to interact with the
+ fTPM service. We use this in order to read the PCRs with the measurements.
+
+Building the PoC for the Arm FVP platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned before, this PoC is based on the OP-TEE Toolkit with some
+extensions to enable Measured Boot and an fTPM service. Therefore, we can rely
+on the instructions to build the original OP-TEE Toolkit. As a general rule,
+the following steps should suffice:
+
+(1) Start by following the `Get and build the solution`_ instructions to build
+ the OP-TEE toolkit. On step 3, you need to get the manifest for FVP
+ platform from the main branch:
+
+ .. code:: shell
+
+ $ repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml
+
+ Then proceed synching the repos as stated in step 3. Continue following
+ the instructions and stop before step 5.
+
+(2) Next you should obtain the `Armv8-A Foundation Platform (For Linux Hosts Only)`_.
+ The binary should be untar'ed to the root of the repo tree, i.e., like
+ this: ``<fvp-project>/Foundation_Platformpkg``. In the end, after cloning
+ all source code, getting the toolchains and "installing"
+ Foundation_Platformpkg, you should have a folder structure that looks like
+ this:
+
+ .. code:: shell
+
+ $ ls -la
+ total 80
+ drwxrwxr-x 20 tf-a_user tf-a_user 4096 Jul 1 12:16 .
+ drwxr-xr-x 23 tf-a_user tf-a_user 4096 Jul 1 10:40 ..
+ drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 10:45 build
+ drwxrwxr-x 16 tf-a_user tf-a_user 4096 Jul 1 12:16 buildroot
+ drwxrwxr-x 51 tf-a_user tf-a_user 4096 Jul 1 10:45 edk2
+ drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 12:14 edk2-platforms
+ drwxr-xr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:52 Foundation_Platformpkg
+ drwxrwxr-x 17 tf-a_user tf-a_user 4096 Jul 2 10:40 grub
+ drwxrwxr-x 25 tf-a_user tf-a_user 4096 Jul 2 10:39 linux
+ drwxrwxr-x 15 tf-a_user tf-a_user 4096 Jul 1 10:45 mbedtls
+ drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 10:45 ms-tpm-20-ref
+ drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_client
+ drwxrwxr-x 10 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_examples
+ drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 12:13 optee_os
+ drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_test
+ drwxrwxr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:45 .repo
+ drwxrwxr-x 4 tf-a_user tf-a_user 4096 Jul 1 12:12 toolchains
+ drwxrwxr-x 21 tf-a_user tf-a_user 4096 Jul 1 12:15 trusted-firmware-a
+
+(3) Now enter into ``ms-tpm-20-ref`` and get its dependencies:
+
+ .. code:: shell
+
+ $ cd ms-tpm-20-ref
+ $ git submodule init
+ $ git submodule update
+ Submodule path 'external/wolfssl': checked out '9c87f979a7f1d3a6d786b260653d566c1d31a1c4'
+
+(4) Now, you should be able to continue with step 5 in "`Get and build the solution`_"
+ instructions. In order to enable support for Measured Boot, you need to
+ set the ``MEASURED_BOOT`` build option:
+
+ .. code:: shell
+
+ $ MEASURED_BOOT=y make -j `nproc`
+
+ .. note::
+ The build process will likely take a long time. It is strongly recommended to
+ pass the ``-j`` option to make to run the process faster.
+
+ After this step, you should be ready to run the image.
+
+Running and using the PoC on the Armv8-A Foundation AEM FVP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With everything built, you can now run the image:
+
+.. code:: shell
+
+ $ make run-only
+
+.. note::
+ Using ``make run`` will build and run the image and it can be used instead
+ of simply ``make``. However, once the image is built, it is recommended to
+ use ``make run-only`` to avoid re-running all the building rules, which
+ would take time.
+
+When FVP is launched, two terminal windows will appear. ``FVP terminal_0``
+is the userspace terminal whereas ``FVP terminal_1`` is the counterpart for
+the secure world (where TAs will print their logs, for instance).
+
+Log into the image shell with user ``root``, no password will be required.
+Then we can issue the ``ftpm`` command, which is an alias that
+
+(1) loads the ftpm kernel module and
+
+(2) calls ``tpm2_pcrread``, which will access the fTPM service to read the
+ PCRs.
+
+When loading the ftpm kernel module, the fTPM TA is loaded into the secure
+world. This TA then requests a copy of the Event Log generated during the
+booting process so it can retrieve all the entries on the log and record them
+first thing.
+
+.. note::
+ For this PoC, nothing loaded after BL33 and NT_FW_CONFIG is recorded
+ in the Event Log.
+
+The secure world terminal should show the debug logs for the fTPM service,
+including all the measurements available in the Event Log as they are being
+processed:
+
+.. code:: shell
+
+ M/TA: Preparing to extend the following TPM Event Log:
+ M/TA: TCG_EfiSpecIDEvent:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 3
+ M/TA: Digest : 00
+ M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ M/TA: : 00 00 00
+ M/TA: EventSize : 33
+ M/TA: Signature : Spec ID Event03
+ M/TA: PlatformClass : 0
+ M/TA: SpecVersion : 2.0.2
+ M/TA: UintnSize : 1
+ M/TA: NumberOfAlgorithms : 1
+ M/TA: DigestSizes :
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: DigestSize : 32
+ M/TA: VendorInfoSize : 0
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 3
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ M/TA: EventSize : 17
+ M/TA: Signature : StartupLocality
+ M/TA: StartupLocality : 0
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
+ M/TA: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
+ M/TA: EventSize : 5
+ M/TA: Event : BL_2
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
+ M/TA: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
+ M/TA: EventSize : 6
+ M/TA: Event : BL_31
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
+ M/TA: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
+ M/TA: EventSize : 10
+ M/TA: Event : HW_CONFIG
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
+ M/TA: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
+ M/TA: EventSize : 14
+ M/TA: Event : SOC_FW_CONFIG
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
+ M/TA: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
+ M/TA: EventSize : 6
+ M/TA: Event : BL_32
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
+ M/TA: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
+ M/TA: EventSize : 18
+ M/TA: Event : BL32_EXTRA1_IMAGE
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
+ M/TA: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
+ M/TA: EventSize : 6
+ M/TA: Event : BL_33
+ M/TA: PCR_Event2:
+ M/TA: PCRIndex : 0
+ M/TA: EventType : 1
+ M/TA: Digests Count : 1
+ M/TA: #0 AlgorithmId : SHA256
+ M/TA: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
+ M/TA: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
+ M/TA: EventSize : 13
+ M/TA: Event : NT_FW_CONFIG
+
+These logs correspond to the measurements stored by TF-A during the measured
+boot process and therefore, they should match the logs dumped by the former
+during the boot up process. These can be seen on the terminal_0:
+
+.. code:: shell
+
+ NOTICE: Booting Trusted Firmware
+ NOTICE: BL1: v2.5(release):v2.5
+ NOTICE: BL1: Built : 10:41:20, Jul 2 2021
+ NOTICE: BL1: Booting BL2
+ NOTICE: BL2: v2.5(release):v2.5
+ NOTICE: BL2: Built : 10:41:20, Jul 2 2021
+ NOTICE: TCG_EfiSpecIDEvent:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 3
+ NOTICE: Digest : 00
+ NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ NOTICE: : 00 00 00
+ NOTICE: EventSize : 33
+ NOTICE: Signature : Spec ID Event03
+ NOTICE: PlatformClass : 0
+ NOTICE: SpecVersion : 2.0.2
+ NOTICE: UintnSize : 1
+ NOTICE: NumberOfAlgorithms : 1
+ NOTICE: DigestSizes :
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: DigestSize : 32
+ NOTICE: VendorInfoSize : 0
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 3
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ NOTICE: EventSize : 17
+ NOTICE: Signature : StartupLocality
+ NOTICE: StartupLocality : 0
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63
+ NOTICE: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5
+ NOTICE: EventSize : 5
+ NOTICE: Event : BL_2
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5
+ NOTICE: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c
+ NOTICE: EventSize : 6
+ NOTICE: Event : BL_31
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2
+ NOTICE: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0
+ NOTICE: EventSize : 10
+ NOTICE: Event : HW_CONFIG
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a
+ NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0
+ NOTICE: EventSize : 14
+ NOTICE: Event : SOC_FW_CONFIG
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22
+ NOTICE: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75
+ NOTICE: EventSize : 6
+ NOTICE: Event : BL_32
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e
+ NOTICE: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63
+ NOTICE: EventSize : 18
+ NOTICE: Event : BL32_EXTRA1_IMAGE
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25
+ NOTICE: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2
+ NOTICE: EventSize : 6
+ NOTICE: Event : BL_33
+ NOTICE: PCR_Event2:
+ NOTICE: PCRIndex : 0
+ NOTICE: EventType : 1
+ NOTICE: Digests Count : 1
+ NOTICE: #0 AlgorithmId : SHA256
+ NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6
+ NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a
+ NOTICE: EventSize : 13
+ NOTICE: Event : NT_FW_CONFIG
+ NOTICE: BL1: Booting BL31
+ NOTICE: BL31: v2.5(release):v2.5
+ NOTICE: BL31: Built : 10:41:20, Jul 2 2021
+
+Following up with the fTPM startup process, we can see that all the
+measurements in the Event Log are extended and recorded in the appropriate PCR:
+
+.. code:: shell
+
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: TPM2_PCR_EXTEND_COMMAND returned value:
+ M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000
+ M/TA: 9 Event logs processed
+
+After the fTPM TA is loaded, the call to ``insmod`` issued by the ``ftpm``
+alias to load the ftpm kernel module returns, and then the TPM PCRs are read
+by means of ``tpm_pcrread`` command. Note that we are only interested in the
+SHA256 logs here, as this is the algorithm we used on TF-A for the measurements
+(see the field ``AlgorithmId`` on the logs above):
+
+.. code:: shell
+
+ sha256:
+ 0 : 0xA6EB3A7417B8CFA9EBA2E7C22AD5A4C03CDB8F3FBDD7667F9C3EF2EA285A8C9F
+ 1 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 2 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 3 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 4 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 5 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 6 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 7 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 8 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 9 : 0x0000000000000000000000000000000000000000000000000000000000000000
+ 10: 0x0000000000000000000000000000000000000000000000000000000000000000
+ 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
+
+In this PoC we are only interested in PCR0, which must be non-null. This is
+because the boot process records all the images in this PCR (see field ``PCRIndex``
+on the Event Log above). The rest of the records must be 0 at this point.
+
+.. note::
+ The fTPM service used has support only for 16 PCRs, therefore the content
+ of PCRs above 15 can be ignored.
+
+.. note::
+ As stated earlier, Arm does not provide an fTPM implementation and therefore
+ we do not validate here if the content of PCR0 is correct or not. For this
+ PoC, we are only focused on the fact that the event log could be passed to a third
+ party fTPM and its records were properly extended.
+
+Fine-tuning the fTPM TA
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As stated earlier, the OP-TEE Toolkit includes support to build a third party fTPM
+service. The build options for this service are tailored for the PoC and defined in
+the build environment variable ``FTPM_FLAGS`` (see ``<toolkit_home>/build/common.mk``)
+but they can be modified if needed to better adapt it to a specific scenario.
+
+The most relevant options for Measured Boot support are:
+
+ - **CFG_TA_DEBUG**: Enables debug logs in the Terminal_1 console.
+ - **CFG_TEE_TA_LOG_LEVEL**: Defines the log level used for the debug messages.
+ - **CFG_TA_MEASURED_BOOT**: Enables support for measured boot on the fTPM.
+ - **CFG_TA_EVENT_LOG_SIZE**: Defines the size, in bytes, of the larger event log that
+ the fTPM is able to store, as this buffer is allocated at build time. This must be at
+ least the same as the size of the event log generated by TF-A. If this build option
+ is not defined, the fTPM falls back to a default value of 1024 bytes, which is enough
+ for this PoC, so this variable is not defined in FTPM_FLAGS.
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
+
+.. _OP-TEE Toolkit: https://github.com/OP-TEE/build
+.. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref
+.. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution
+.. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
+.. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools
+.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/