# Trusted Firmware-M Isolation level 2
This document analyzes the requirements of isolation level 2 in IPC mode and describes the design proposal.
### Terms and abbreviations
This document uses the following terms and abbreviations.
|Term|Meaning|
|---|---|
|Application Root of Trust | This is the security domain in which additional security services are implemented. See *PSA Security Model* for details.|
|Application RoT Service | This is a RoT Service within the Application Root of Trust domain. |
|IPC | Inter-process communication. The PSA Firmware Framework specifies an IPC mechanism to provide a communication channel for requests between isolated firmware partitions.|
|MPU | Memory protection unit. |
|Non-secure Processing Environment (NSPE)| This is the security domain outside of the Secure Processing Environment. It is the Application domain, typically containing the application firmware and hardware.|
|PSA | Platform Security Architecture. |
|PSA Root of Trust | This defines the most trusted security domain within a PSA system. See *PSA Security Model* for details.|
|PSA RoT Service | This is a RoT Service within the PSA Root of Trust domain.|
|RO | Refers to read-only data. The code is regarded as read-only on some occasions.|
|RW | Refers to read-able and write-able data.|
|Root of Trust (RoT) | This is the minimal set of software, hardware and data that is implicitly trusted in the platform -- there is no software or hardware at a deeper level that can verify that the Root of Trust is authentic and unmodified. See [*Root of Trust Definitions and Requirements*](https://globalplatform.org/wp-content/uploads/2018/07/GP_RoT_Definitions_and_Requirements_v1.1_PublicRelease-2018-06-28.pdf).|
|RoT Service | A set of related security operations that are implemented in a Secure Partition. The server endpoint of a PSA IPC channel. Multiple RoT Services can coexist in a single Secure Partition.|
|Secure Partition (SP) | A thread of execution with protected runtime state within the Secure Processing Environment. Container for the implementation of one or more RoT Services. Multiple Secure Partitions are allowed in a platform.|
|Secure Processing Environment (SPE) | This is the security domain that includes the PSA Root of Trust and the Application Root of Trust domains. |
|Service ID (SID) |Service Identification. The identifier used for a PSA or an Application RoT Service.|
|SPM | Secure Partition Manager. Part of the PSA Firmware Framework that is responsible for isolating software in Partitions, managing the execution of software within Partitions, and providing IPC between Partitions.|
|TF-M | Trusted Firmware-M, an open source PSA Firmware Framework compatible firmware implementation.|
|ZI | Refers to zero-initialized data.|
## Introduction
PSA Firmware Framework defines three levels of isolation. The following table provides a summary of the three supported isolation levels:
|Isolation level|Purpose|Security domains|Description|
|---|---|---|---|
|Level 1|SPE isolation.|Two|SPE is protected from access by Non-secure application firmware and hardware.|
|Level 2|PSA Root of Trust isolation.|Three|In addition to Level 1, the PSA Root of Trust is also protected from access by the Application Root of Trust.|
|Level 3|Maximum firmware isolation.|Three or more|In addition to Level 2, each Secure Partition is sandboxed and only permitted to access its own resources. This protects each Secure Partition from access by other Secure Partitions and protects the SPM from access by any Secure Partition.|
The IPC model is implemented to follow PSA Firmware Framework v1.0. The interaction between clients and services happens via the IPC
mechanism. The IPC model supports isolation level 1. To get align with PSA Firmware Framework, the other two isolation levels need to be supported. This document describes the design of isolation level 2.
## Requirements
The requirements of isolation level 2 in PSA Firmware Framework specification is:
* The SPM must ensure that no runtime state, data or devices that are part of the PSA Root of Trust can be read or written by firmware or hardware in the Application Root of Trust.
* The SPM can allow the firmware and hardware in the PSA RoT Services to read/write runtime state, data or hardware in other Secure Partitions. However, enforcing isolation is recommended because it mitigates the risk of defects in secure firmware that could disclose secrets or accept untrusted inputs.
## Design Details
This chapter describes the design details of isolation level 2. Includes background, proposal and implementation.
### Background
The existing TF-M implementation with isolation is:
* IPC mode is implemented with isolation level 1.
* Library mode is implemented with isolation level 1 and a prototype isolation level 3.
### Isolation level 1
IPC mode isolation level 1 uses the same isolation settings of library mode. There are no MPU region activated in isolation level 1, default memory map is applied in this case. The following table describes the memory layout of isolation level 1 TF-M:
|Section |MPU Region |Comments|
|-----------------|-------------|-----------------------|
|CODE + RO |NA |Code and read-only data|
|BL2 Shared Area |NA |Bootloader shared data|
|MSP Stack |NA |Default MSP stack|
|PSP Stack |NA |Initial PSP stack|
|Secure Stack |NA |SP shared stack|
|Scratch |NA |Secure shared memory|
|DATA + ZI |NA |Read/write and zero-initialized data|
|Veneer |NA |Secure function entry|
NOTE: The all upper case words 'DATA' and 'CODE' are the alias of definition for 'data' and 'code' in sections.
NOTE: Default memory map accessing is **privileged** by setting **MPU_CONTROL.PRIVDEFENA.**
### Isolation level 3
Isolation level 3 is a prototype and showcases the isolation between
partitions. There are 8 MPU regions are enabled for the following purposes:
|Region Index |Description |Attribute|
|-------------- |--------------------------------------- |----------------------------|
|0 |Veneer region |Read-only, Executable|
|1 |Un-privileged code and RO data |Read-only, Executable|
|2 |Privileged RW, Un-privileged RO data |Read-only, Non-executable|
|3 |Non-Secure data region |Read-write, Non-executable|
|4 |SP code and RO data |Read-only, Executable|
|5 |SP RW, ZI, stack |Read-write, Non-executable|
|6 |Peripheral |Read-write, Non-executable|
|7 |Shared region |Read-write, Non-executable|
The region 0,1,2 and 3 are enabled while booting with a fixed setting. The accessible memory regions of running partition are set into region 4,5,6 and 7 while running partition to be switched into. The following table describes the secure firmware memory layout in isolation level 3 and related to MPU regions:
|Section |MPU Region |Comments|
|-----------------------------------|-------------|--------|
|Vector |NA |Initial vector|
|Un-privileged CODE + RO |1 |Un-privileged code and read-only data|
|(Secure Partitions CODE + RO) x N |4 |Multiple Secure Partition code and read-only data|
|BL2 Shared |NA |Bootloader shared data|
|MSP Stack |NA |Default MSP stack|
|PSP Stack |NA |Initial PSP stack|
|Scratch |7 |Secure shared memory|
|Un-privileged DATA + ZI |2 |Un-privileged read/write data and zero value data|
|(Secure Partition DATA + ZI) x N |5 |Multiple Secure Partition read/write data and zero value data|
|Veneer |0 |Secure function entry|
NOTE: The missing region index **3** and **6** range is out of secure firmware memory layout. 3 is for NSPE which enables secure firmware accessing NS memory. 6 is for secure peripheral which is dynamically set if the running Secure Partition needs to access hardware peripheral.
NOTE: The MPU region number involved in this table comes from TF-M reference design. **The minimal MPU regions needed** for isolation depends on the number of security domains. Check the table in the 'introduction' chapter to get security domains for each isolation level.
Sections not listed in the table (privileged code and data like SPM and Core) follow default memory map setting. The default memory map is set as privileged accessing as default. Library mode uses direct call between caller and callee, so there are areas for the partition shared code and data (Region1,2,3 and 7). These areas are unnecessary for IPC mode because IPC mode applies SVCalls instead of putting shared code and
data in region 1,2,3 and 7.
### Configuration switches and scheduler
One configuration switch for isolation is available with two values: 'TFM_LVL=1' and 'TFM_LVL=3'. 'TFM_LVL=1' works under IPC mode and
library mode. While 'TFM_LVL=3' works for library mode only.
The IPC scheduler works in isolation level 1. The scheduler does not update partition related status since Secure Partitions in isolation level 1 could access all TF-M memory, no extra setting needs to be changed during the running partition switching.
## Proposal
### Linker script sections re-arrangement
As isolation level 2 requires, the App RoT partitions and PSA RoT partitions have different accessing levels. The PSA RoT partitions are put under a privileged level, which is the same privileged level as SPM. MPU is necessary in this case since the default memory map put all memory in the same privileged level. MPU has a limited number of regions, App RoT partition data need to be put together to avoid different memory sections get interleaved. Interleaving costs more regions to be enabled, which is a waste of MPU regions. There are suggestions of isolating RO data and RW data in the PSA Firmware Framework specification, these two parts of App RoT partitions can be put in two different locations.
Summarized points of isolation level 2 are:
* The RO data of all App RoT partitions need to be put together.
* The RW data of all App RoT partitions need to be put together.
RW data area here contains read-write data and zero-initialized data. The stack for each partition is covered in RW data area.
The following table describes the changed section arrangement of isolation level 2:
|Section |MPU Region |Comments|Change|
|-------|-------------|--------|------|
|Vector |NA |Initial vector| |
|Un-privileged CODE + RO |1 |Un-privileged code and read-only data | |
|App RoT (Secure Partitions CODE + RO) x N |4 |Multiple APP RoT Secure Partition|**Modified**|
|PSA RoT (Secure Partitions CODE + RO) x N |NA |Multiple PSA RoT Secure Partition |**Modified**|
|BL2 Shared |NA |Bootloader shared data| |
|MSP Stack |NA |Default MSP stack| |
|PSP Stack |NA |NSPE partition usage| |
|Scratch |7 |Secure shared memory|**Removed**|
|Un-privileged DATA + ZI |2 |Un-privileged read/write data and zero value data| |
|APP RoT (Secure Partition DATA + ZI) x N |5 |Multiple APP RoT Secure Partition read/write data and zero value data |**Modified**|
|PSA RoT (Secure Partition DATA + ZI) x N |NA |Multiple PSA RoT Secure Partition read/write data and zero value data |**Modified**|
|Veneer |0 |Secure function entry| |
PSA Firmware Framework APIs are implemented as SVCalls in IPC mode. All the service providing APIs are packaged into calling of PSA Firmware Framework APIs. Besides PSA FF APIs, there are shared code and its related read-only data for Secure Partition calling, for example, thread exiting interface. A dedicated MPU region needs to be prepared for these codes. The requirement for this region are:
- This code must be thread-safe and reentrant.
- This code must be read-only.
The updated MPU regions with status are listed in the following table:
|Region Index |Description |Attribute |Status |
|------------- |------------------------------- |---------------------------- |----------|
|0 |Veneer region |Read-only, Executable | |
|1 |Un-privileged code and RO data |Read-only, Executable | |
|2 |Privileged RW, Un-privileged RO data |Read-only, Non-executable|**Not used**|
|3 |Non-Secure data region |Read-write, Non-executable |**Not used**|
|4 |SP code and RO data |Read-only, Executable | |
|5 |SP RW, ZI, Stack |Read-write, Non-executable | |
|6 |Peripheral |Read-write, Non-executable | |
|7 |Shared region |Read-write, Non-executable |**Not used**|
After the combination of the two updated tables, the following tables describe the arrangement for isolation level 2:
|Section |MPU Region |Comments|Change|
|------------------------------------------ |------------|--------|------|
|Vector |NA |Initial vector| |
|App RoT (Secure Partitions CODE + RO) x N |4 |Multiple APP RoT Secure Partition |Modified|
|PSA RoT (Secure Partitions CODE + RO) x N |NA |Multiple PSA RoT Secure Partition |Modified|
|BL2 Shared |NA |Bootloader shared data| |
|MSP Stack |NA |Default MSP stack| |
|PSP Stack |NA |NSPE partition usage| |
|APP RoT (Secure Partition DATA + ZI) x N |5 |Multiple APP RoT Secure Partition|Modified|
|PSA RoT (Secure Partition DATA + ZI) x N |NA |Multiple PSA RoT Secure Partition|Modified|
|Veneer |0 |Secure function entry| |
And updated MPU regions:
|Region Index |Description |Attribute|
|------------- |------------------- |-----------------------------------------|
|0 |Veneer region |Read-only, Executable |
|1 |Un-privileged code and RO data |Read-only, Executable |
|4 |SP code and RO data |Read-only, Executable |
|5 |SP RW, ZI, Stack |Read-write, Non-executable |
|6 |Peripheral |Read-write, Non-executable |
//NOTE://
- In the first implementation, one MPU region for peripheral is supported as default. Typically there should be more MPU regions are available for peripheral usage if a Secure Partition needs more un-continuous peripheral registers. The un-continuous peripheral number larger than available free region number needs an advanced implementation which needs further design.
### Configuration switch and scheduler
A new value of TFM_LVL is going to be added for isolation level 2. And the scheduler needs to set related settings based on Secure Partition information.
## Implementation
This chapter describes the implementation of the proposed points.
### Section relocation
The linker script for GNUARM and the scatter file for ARMCLANG need to be changed to put AppRoT partition components together. Since PSA RoT partitions have the same privileged level with SPM, PSA RoT partitions could be placed freely.
#### GNUARM
The linker script for GNUARM is put at:
**TFM_ROOT/platform/ext/target/<platform_name>/gcc/<platform_name>.ld**
This linker script is generated from a template, and the template is put
at:
**TFM_ROOT/platform/ext/target/<platform_name>/gcc/<platform_name>.ld.template**
The related sections in GNUARM are:
|Name |Description|
|-------- |----------|
|.text |Executable code, Read-only and Executable|
|.rodata |Read-only data, Non-executable|
|.data |Read-write data with initial values, Non-executable|
|.bss |Read-write data without initial values, initialized as ZERO at the start, Non-executable|
PSA Firmware Framework specification also suggests isolating Read-only part with other parts of a Secure Partition if possible. The section
'.text' plus '.rodata' are regarded as 'Read-only' part in GNUARM case.
#### ARMCLANG
For ARMCLANG, the scatter file is put at:
**TFM_ROOT/platform/ext/target/<platform_name>/armclang/<platform_name>.sct**
TF-M does not use a template for ARMCLANG scatter file.
The related sections in ARMCLANG are:
|Name |Description|
|----- |-----|
|RO |Read-only data includes Executable code and Non-executable data|
|RW |Read-write Non-executable data|
|ZI |Zero initialized (Read-write data without initial values)|
The RO part is regarded as 'Read-only' in PSA Firmware Framework specification. The RO sections of App RoT partitions are put together. RW sections of App RoT partitions are put together, too. No requirements tell that these two groups (RO and RW) can be neighboured.
#### Conclusion
Summarized items list below:
- Change template for GNUARM to support grouping App RoT partitions in
the linker script.
- Change scatter file for ARMCLANG to support grouping App RoT
partitions.
- Template tool support for ARMCLANG (optional).
### MPU configuration
The MPU needs to be default initialized for isolation level 2. To re-use the design of isolation level 3, set the region 4,5 and 6 with the App
Rot partitions group information.
The memory type needs to be set correctly to provide better memory performance.
Summarized items:
- Apply MPU configuration.
- Correct set memory type in MPU configuration.
### Configuration switches
There is a configuration switch for isolation: 'TFM_LVL=1' and 'TFM_LVL=3'. A new configuration switch needs to be added for isolation level 2: 'TFM_LVL=2'. The dependency checking rules need to be available to permit isolation level 2 in IPC mode only.
### Scheduler
#### Partition status
The scheduler in isolation level 1 is put freely because scheduler does not need to change Secure Partition information. This behavior is not
aligned with PSA Firmware Framework. The scheduler should get Secure Partition type by calling Secure Partition Manager APIs and do necessary environment setup before switches into the running partition.
Secure Partition has three types of status (From Firmware Framework specification):
- Running
- Blocked
- Ready
While scheduler supports 4 exiting status:
- Creating
- Running
- Blocked
- Detach
There must be an alignment between these statuses. The status value is not defined as a detailed code in PSA Firmware Framework, SPM could take the values defined in thread sources directly:
|Partition status|Thread status in scheduler|Comment|
|------ |------|------|
|Running |THRD_STAT_RUNNING |No difference between them
|Blocked |THRD_STAT_BLOCK |No difference between them
|Ready |THRD_STAT_CREATING |'Ready' means 'Run-able'. A bit difference between them.
| |THRD_STAT_DETACH |Thread is not schedulable -- could be used to block caller if it caused a serious error.|
The existing scheduler design is straight, which does not distinguish
the run-able and running status.
#### Partition priority
The priority set in Secure Partition manifest are:
- HIGH
- NORMAL
- LOW
The scheduler set the priority of a thread as an integer value within
the range 0 ~ 255. The relationship between Secure Partition priority
and thread priority could be hard mapped:
|Partition priority |Thread priority (value)|
|-------------------- |----------------------------|
|HIGH |THRD_PRIOR_HIGHEST (0x0)|
|NORMAL |THRD_PRIOR_MEDIUM(0x7f)|
|LOW |THRD_PRIOR_LOWEST(0xff)|
#### Scheduling policy
In isolation level 2, the privileged bit needs to be set correctly for
partition. The steps need to be done for scheduler are:
1. Get next partition to be run
2. Check if next partition is PSA RoT partition
3. Clear/Set CONTROL.nPRIV if the next partition is privileged/non-privileged
4. Call scheduler API to switch partitions
### Regions clean-up
Below MPU regions are not used for IPC mode:
|Region Index |Description |Attribute |Status|
|-------------- |------------------------------- |----------|-------|
|2 |Privileged RW, Un-privileged RO data |Read-only, Non-executable|**Not used**|
|3 |Non-Secure data region |Read-write, Non-executable |**Not used**|
|7 |Shared region |Read-write, Non-executable |**Not used**|
There are some existing un-privileged code been included in IPC mode but never get called at current, change the makefile to move these files out of IPC mode:
- **tfm_spm_services.o**
- **dummy_crypto_keys.o**
- **dummy_nv_counters.o**
- **dummy_boot_seed.o**
- **dummy_device_id.o**
- **platform_retarget_dev.o**
- **SFN**
- **armlib**
//NOTE://
- The clean-up needs to be done step by step in case breaks existing runtime behaviour. In very start implementation, these files may still be seen in project files but not linked since no one references them.
### Functions to be re-design
#### printf
Log functions call 'printf' in toolchain lib to output debug messages. This function needs to access privileged data such as UART driver to output data. Calling this function in the un-privileged App RoT partitions can cause a memory accessing violation.
The printf and Log functions need to be re-design. The printf itself need to be implemented in privileged mode. And an interface for calling this needs to be provided.
There is an implementation in library isolation level 3 already. This implementation needs to be moved into IPC mode.
## Tests
This chapter describes the tests to be created to validate the isolation
level 2 implementation.
### Test design
Two specified Secure Partitions are created for these test cases. One Secure Partition contains App RoT services, and the other one contains
PSA RoT services. They provided services to show internal memories to the caller, and caller access it. Two types of memory are defined inside of each partition: Read-only (RO) memory and Read-write (RW) memory.
For the memory accessing test inside Secure Partition such as access internal read-only data, it could be done directly with accessing give memory.
{F28367}
For the accessing happen between partitions, one SID is provided for these tests. The following table describes the services partition provided:
|SID |Description|
|-------------------------------- |-------------------------------------------|
|TEST_PSAROT_ISOLATION_ACCESS_MEMORY |PSA RoT service for accessing caller provided memory|
|TEST_APPROT_ISOLATION_ACCESS_MEMORY |APP RoT service for accessing caller provided memory|
The client partition provides memory inside itself to the service partition by requesting dedicated services, and the service partition accesses
the provided memory.
The access sequence for both services:
1. Convert start address of memory into "uint8_t *"
2. Increase each byte of provided memory with 1.
### Test cases
This chapter describes detail test steps and the expected result.
1. 1. A PSA RoT service can access App RoT secure partition read-write memory
|Steps |Description |
|-------------- |------------------------------- |
|1 |An App RoT service connects to PSA RoT service TEST_PSAROT_ISOLATION_ACCESS_MEMORY|
|2 |App RoT service calls psa_call to provide an internal read-write memory address to PSA RoT service for access|
|3 |App RoT service calls psa_close to close the connection|
Expected result:
PSA RoT service change memory content to specified value and App RoT service confirms the change.
2. An App RoT service cannot access PSA RoT secure partition memory
2.1 Check by software memory check function
|Steps |Description |
|-------------- |------------------------------- |
|1 |An App RoT service connects to PSA RoT service TEST\_PSAROT\_ISOLATION\_ACCESS\_MEMORY|
|2 |App RoT service calls psa_call with one outvec parameter to require one PSA RoT service partition memory to write back in outvec|
|3 |PSA RoT service calls psa_write to write back the internal memory to outvec|
|4 |App RoT service calls psa_call again with one invec parameter of the obtained memory address to PSA RoT service for access|
|5 |App RoT service calls psa_close to close the connection|
Expected result:
The obtained memory address is not in the accessible memory region for App RoT
service. Software memory check fails and gets panic.
Note: This case should be the last test case and disabled as default since it
would block other tests.
2.2 Check by MPU
|Steps |Description |
|-------------- |------------------------------- |
|1 |A PSA RoT service connects to App RoT service TEST_APPROT_ISOLATION_ACCESS_MEMORY|
|2 |PSA RoT service calls psa_call to provide an internal memory address to App RoT service for access|
|3 |PSA RoT calls psa_close to close the connection|
Expected result:
App RoT service tries to change memory content and gets panic.
Note: This case should be the last test case and disabled as default since it
would block other tests.
3. A PSA RoT service cannot write App RoT secure partition read-only memory
|Steps |Description |
|-------------- |------------------------------- |
|1 |An App RoT service connects to PSA RoT service TEST_PSAROT_ISOLATION_ACCESS_MEMORY|
|2 |App RoT calls psa_call to provide an internal read-only memory address in outvec to PSA RoT service for write|
|3 |App RoT calls psa_close to close the connection|
Expected result:
PSA RoT service tries to change memory content and gets panic.
Note:
This case is disabled as default since it would block other tests. Enable it manually.
### Reference Document
|Document Number|Document Name|
|--------------|-------------|
|ARM DEN 0063 |PSA Firmware Framework|
|ARM DEN 0079 |PSA Security Model |
Copyright (c) 2019, Arm Limited. All rights reserved.