TrustZone technology is introduced in the Cortex-M series (Cortex-M33 and Cortex-M23) microcontrollers based on the ARMv8-M architecture. TrustZone enables two security domains in a single processor, dividing the execution space into secure and non-secure partitions. Complete isolation is achieved between trusted software executed on the secure side and untrusted software executed on the non-secure side to enhance security.
If the functions provided by the secure side are allowed to be called by the non-secure side software, these functions must be placed in the memory area marked as non-secure callable (NSC).
With TrustZone, the application consists of two separate projects:
1. Secure applications running on secure terminals
2. Applications running on the non-secure side
After the ARMv8-M kernel is started, it defaults to the secure side. The security software is responsible for programming the Security Attribute Unit (SAU) and Implementation Defined Attribute Unit (IDAU) to divide the memory space into secure and non-secure areas. Software on the secure side can access secure and non-secure memory, while software on the non-secure side can only access non-secure memory.
How to use FreeRTOS on an ARMv8-M architecture processor that supports TrustZone?
1. FreeRTOS for ARMv8-M porting
The FreeRTOS kernel provides ARMv8-M (ARM Cortex-M33 and ARM Cortex-M23) porting code:
Can run on the secure or non-secure side. Allows non-secure tasks (or threads) to call secure side functions.
TrustZone support is optional when the FreeRTOS kernel is running on the non-secure side, allowing privilege escalation only for FreeRTOS kernel code.
In applications, FreeRTOS usually runs on the non-secure side, and user tasks can call functions exported by the secure side software.
2. FreeRTOS example project
The easiest way to get started is to use the example projects in FreeRTOS/Demo:
Keil simulator based on Keil uVision IDE
NXP LPCXpresso55S69 development board example based on MCUXpresso IDE
Nuvoton NuMaker-PFM-M2351 development board example based on Keil uVision and IAR IDE
These projects can be used directly or as reference examples of source files, configuration options, and compiler settings.
FreeRTOSConfig.h configuration
When FreeRTOS is running on the non-secure side, to enable FreeRTOS tasks to call NSC secure functions, you need to enable TrustZone support in FreeRTOSConfig.h:
#define configENABLE_TRUSTZONE 1
Build Project
In addition to the FreeRTOS kernel source code, you also need to add porting files to the safety project and the non-safety project:
Source files compiled in the secure project: FreeRTOS\Source\portable\[compiler]\[architecture]\secure
Source files compiled in a non-secure project: FreeRTOS\Source\portable\[compiler]\[architecture] \non_secure
Where [architecture] is ARM_CM23 or ARM_CM33, depending on the target hardware.
Define the security function as NSC
Use the secureportNON_SECURE_CALLABLE macro to declare that a secure function is callable from the non-secure side.
SecureportNON_SECURE_CALLABLE void NSCFunction(void);
The NSC function needs to be placed in the NSC memory area in the linker script of the security project. The GCC placement example is as follows:
Assigning a security context to a non-security task
The FreeRTOS task that needs to call the NSC function must call the portALLOCATE_SECURE_CONTEXT macro to allocate a security context:
Through the above operations, FreeRTOS can be easily integrated into the TrustZone architecture processor. FreeRTOS has now passed the Level 2 certification of the Security Evaluation Standard for IoT Platforms (SESIP) and the Level 1 certification of the Platform Security Architecture Specification (PSA), better meeting the information security (Security) application requirements based on TrustZone hardware.