| ####################### |
| Adding Secure Partition |
| ####################### |
| |
| *********************** |
| Terms and abbreviations |
| *********************** |
| This document uses the following terms and abbreviations. |
| |
| .. table:: term table |
| :widths: auto |
| |
| ================== ================================== |
| **Term** **Meaning** |
| ================== ================================== |
| FF Firmware Framework |
| ID Identifier |
| IPC Interprocess communication |
| IPC model The secure IPC framework |
| irqs Interrupt requests |
| Library model The secure function call framework |
| MMIO Memory Mapped I/O |
| PSA Platform Security Architecture |
| RoT Root of Trust |
| SID RoT Service ID |
| SP Secure Partition |
| SPM Secure Partition Manager |
| TF-M Trusted firmware M |
| ================== ================================== |
| |
| ************ |
| Introduction |
| ************ |
| Secure Partition is an execution environment that provides the following |
| functions to Root of Trust (RoT) Services: |
| |
| - Access to resources, protection of its own code and data. |
| - Mechanisms to interact with other components in the system. |
| |
| Each Secure Partition is a single thread of execution and the smallest unit of |
| isolation. |
| |
| This document mainly describes how to add a secure partition in TF-M and |
| focuses on the configuration, manifest, implement rules. The actual |
| source-level implementation is not included in this document. |
| |
| .. Note:: |
| If not otherwise specified, the steps are identical for library and IPC |
| model. |
| |
| The IPC model conforms the *PSA Firmware Framework (FF) v 1.0.0*. Refer to |
| `PSA Firmware Framework specification`_ for details. |
| |
| ******* |
| Process |
| ******* |
| The main steps to add a secure partition are as follows: |
| |
| - `Add source folder`_ |
| - `Add manifest`_ |
| - `Add configuration`_ |
| - `Generate files`_ |
| - `Implement the RoT services`_ |
| |
| Add source folder |
| ================= |
| Add a source folder under ``<TF-M base folder>/secure_fw/partitions`` for the new |
| secure partition (Let's take EXAMPLE as the folder name): |
| |
| This folder should include those parts: |
| |
| - Manifest file: EXAMPLE.yaml |
| - CMake configuration files |
| - Source code files |
| |
| Add manifest |
| ============ |
| Each Secure Partition must have resource requirements declared in a manifest |
| file. The Secure Partition Manager (SPM) uses the manifest file to assemble and |
| allocate resources within the SPE. The manifest includes the following: |
| |
| - A Secure Partition name. |
| - A list of implemented RoT Services. |
| - Access to other RoT Services. |
| - Memory requirements. |
| - Scheduling hints. |
| - Peripheral memory-mapped I/O regions and interrupts. |
| |
| .. Note:: |
| The current manifest format in TF-M is "yaml" which is different from the |
| requirement of PSA FF. |
| |
| Here is a manifest reference example for the IPC model, please refer to |
| `Library model support`_ for the library extend: |
| |
| .. code-block:: yaml |
| |
| { |
| "psa_framework_version": 1.0, |
| "name": "TFM_SP_EXAMPLE", |
| "type": "PSA-ROT", |
| "priority": "HIGH", |
| "entry_point": "EXAMPLE_main", |
| "stack_size": "0x0200", |
| "services" : [ |
| { |
| "name": "ROT_A", |
| "sid": "0x0000F000", |
| "non_secure_clients": true, |
| "version": 1, |
| "version_policy": "STRICT" |
| } |
| ], |
| "mmio_regions": [ |
| { |
| "name": "TFM_PERIPHERAL_A", |
| "permission": "READ-WRITE" |
| } |
| ], |
| "irqs": [ |
| { |
| "source": "TFM_A_IRQ", |
| "signal": "SPM_CORE_A_IRQ", |
| "tfm_irq_priority": 64, |
| } |
| ], |
| "linker_pattern": { |
| "object_list": [ |
| "*EXAMPLE.*" |
| ] |
| } |
| } |
| |
| Secure Partition ID Distribution |
| -------------------------------- |
| Every Secure Partition has an identifier (ID). TF-M will generate a header file |
| that includes definitions of the Secure Partition IDs. The header file is |
| ``<TF-M base folder>/interface/include/psa_manifest/pid.h``. Each definition |
| uses the ``name`` attribute in the manifest as its name and the value is |
| allocated by SPM. |
| |
| .. code-block:: c |
| |
| #define name id-value |
| |
| Here is the Secure Partition ID table used in TF-M. |
| |
| .. table:: PID table |
| :widths: auto |
| |
| =============================== ================= |
| **Partition name** **Partition ID** |
| =============================== ================= |
| Reserved 0-255 |
| TFM_SP_PS 256 |
| TFM_SP_ITS 257 |
| TFM_SP_AUDIT_LOG 258 |
| TFM_SP_CRYPTO 259 |
| TFM_SP_PLATFORM 260 |
| TFM_SP_INITIAL_ATTESTATION 261 |
| TFM_SP_CORE_TEST 262 |
| TFM_SP_CORE_TEST_2 263 |
| TFM_SP_SECURE_TEST_PARTITION 264 |
| TFM_SP_IPC_SERVICE_TEST 265 |
| TFM_SP_IPC_CLIENT_TEST 266 |
| TFM_IRQ_TEST_1 267 |
| TFM_SP_PS_TEST 268 |
| =============================== ================= |
| |
| About where to add the definition, please refer to the chapter `Add |
| configuration`_. |
| |
| RoT Service ID (SID) Distribution |
| --------------------------------- |
| An RoT Service is identified by its RoT Service ID (SID). A SID is a 32-bit |
| number that is associated with a symbolic name in the Secure Partition |
| manifest. The bits [31:12] uniquely identify the vendor of the RoT Service. |
| The remaining bits [11:0] can be used at the discretion of the vendor. |
| |
| Here is the RoT Service ID table used in TF-M. |
| |
| .. table:: SID table |
| :widths: auto |
| |
| =========================== ====================== ======================== |
| **Services** **Vendor ID(20 bits)** **Function ID(12 bits)** |
| =========================== ====================== ======================== |
| audit_logging 0x00000 0x000-0x01F |
| initial_attestation 0x00000 0x020-0x03F |
| platform 0x00000 0x040-0x05F |
| protected_storage 0x00000 0x060-0x07F |
| crypto 0x00000 0x080-0x09F |
| internal_trusted_storage 0x00000 0x0A0-0x0BF |
| test_secure_service 0x0000F 0x000-0x01F |
| core_test 0x0000F 0x020-0x03F |
| core_test_2 0x0000F 0x040-0x05F |
| tfm_ipc_client 0x0000F 0x060-0x07F |
| tfm_ipc_service 0x0000F 0x080-0x09F |
| tfm_irq_test_service_1 0x0000F 0x0A0-0x0BF |
| tfm_ps_test_service 0x0000F 0x0C0-0x0DF |
| =========================== ====================== ======================== |
| |
| mmio_regions |
| ------------ |
| This attribute is a list of MMIO region objects which the Secure Partition |
| needs access to. TF-M only supports the ``named_region`` current. Please refer |
| to PSA FF for more details about it. The user needs to provide a name macro to |
| indicate the variable of the memory region. |
| |
| TF-M uses the below structure to indicate a peripheral memory. |
| |
| .. code-block:: c |
| |
| struct tfm_spm_partition_platform_data_t { |
| uint32_t periph_start; |
| uint32_t periph_limit; |
| int16_t periph_ppc_bank; |
| int16_t periph_ppc_loc; |
| }; |
| |
| .. Note:: |
| This structure is not expected by TF-M, it's only that the current |
| implementations are using. Other peripherals that need different information |
| to create isolation need to define a different structure with the same name. |
| |
| Here is a example for it: |
| |
| .. code-block:: c |
| |
| struct tfm_spm_partition_platform_data_t tfm_peripheral_A; |
| #define TFM_PERIPHERAL_A (&tfm_peripheral_A) |
| |
| linker_pattern |
| -------------- |
| ``linker_pattern`` is a legacy region which contains the minimum information |
| required to link a Secure Partition’s compiled static objects. Now, it is |
| required as 'IMPLEMENTATION DEFINED' in PSA FF 1.0.0. |
| |
| Library model support |
| --------------------- |
| For the library model, the user needs to add a ``secure_functions`` item. The |
| main difference between ``secure_function`` and ``services`` is the extra |
| ``signal`` key for secure function entry. |
| |
| The ``signal`` must be the upper case of the secure function name. |
| |
| .. code-block:: yaml |
| |
| "secure_functions": [ |
| { |
| "name": "TFM_EXAMPLE_A", |
| "signal": "EXAMPLE_A_FUNC", |
| "sid": "0x00000000", |
| "non_secure_clients": true, |
| "version": 1, |
| "version_policy": "STRICT" |
| }, |
| |
| Add configuration |
| ================= |
| The following configuration tasks are required for the newly added secure |
| partition: |
| |
| Add CMake configure files |
| ------------------------- |
| Two CMake configure files need to be added: |
| |
| - CMakeLists.inc, which is used to add the definition of what files are needed |
| to build. |
| - CMakeLists.txt, which is the compilation configuration for this module. |
| |
| .. Note:: |
| The CMakeLists.inc is not mandatory, the user can put everything in |
| CMakeLists.txt. |
| |
| Please refer to the source code of TF-M for more detail. |
| |
| Update manifest list |
| -------------------- |
| The ``<TF-M base folder>/tools/tfm_manifest_list.yaml`` is used to collect |
| necessary information of secure partition. |
| |
| - ``name``: The name string of the secure partition. |
| - ``short_name``: should be the same as the ``name`` in the secure partition |
| manifest file. |
| - ``manifest``: the relative path of the manifest file to TF-M root. |
| - ``tfm_partition_ipc``: indicate if this partition is compatible with the IPC |
| model. |
| - ``conditional``: Optional. Configure control macro for this partition. |
| - ``version_major``: major version the partition manifest. |
| - ``version_minor``: minor version the partition manifest. |
| - ``pid``: Secure Partition ID value distributed in chapter `Secure Partition |
| ID Distribution`_. |
| |
| Reference configuration example: |
| |
| .. code-block:: yaml |
| |
| { |
| "name": "Example Service", |
| "short_name": "TFM_SP_EXAMPLE", |
| "manifest": "secure_fw/partitions/EXAMPLE/tfm_example.yaml", |
| "tfm_extensions": true, |
| "tfm_partition_ipc": true, |
| "conditional": "TFM_PARTITION_EXAMPLE_ENABLE", |
| "version_major": 0, |
| "version_minor": 1, |
| "pid": 256 |
| } |
| |
| Generate files |
| ============== |
| After finishing the configuration works, the user needs to generate necessary |
| files from manifest by using TF-M tools. |
| |
| .. code-block:: bash |
| |
| cd <TF-M base folder> |
| cd trusted-firmware-m |
| python ./tools/tfm_parse_manifest_list.py |
| |
| Implement the RoT services |
| ========================== |
| The following not-binding rules, as currently implemented, can be used as |
| guidelines: |
| |
| - In the IPC model, Use PSA FF proposed memory accessing mechanism. SPM |
| provides APIs and checking between isolation boundaries, a free accessing |
| of memory can cause program panic. |
| - In the IPC model, the memory checking inside partition runtime is |
| unnecessary. SPM handles the checking while memory accessing APIs are |
| called. |
| - In the IPC model, the client ID had been included in the message structure |
| and secure partition can get it when calling psa_get() function. The secure |
| partition does not need to call ``tfm_core_get_caller_client_id()`` to get |
| the caller client ID anymore. |
| - In the IPC model, SPM will check the security policy and partition |
| dependence between client and service. So the service does not need to |
| validate the secure caller anymore. |
| |
| ********* |
| Reference |
| ********* |
| |
| | `PSA Firmware Framework specification`_ |
| |
| .. _PSA Firmware Framework specification: https://pages.arm.com/psa- |
| resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333 |
| |
| -------------- |
| |
| *Copyright (c) 2019-2020, Arm Limited. All rights reserved.* |