Arm TrustZone®
The Arm TrustZone® technology is a System on Chip (SOC) and CPU system-wide approach to security.
Arm TrustZone was introduced in Armv6KZ and is supported also in Armv7-A and Armv8-A. It does not require any specific tool support. Similar capabilities were introduced for Cortex-M as Arm TrustZone for Armv8-M, also known as CMSE (Cortex-M Security Extension). CMSE does require tool support, and there is a standard interface for development tools that target CMSE. This extension includes two modes of execution—secure and non-secure. It also adds memory protection and instructions for validating memory access and controlled transition between the two modes.
In 32-bit mode
To use TrustZone for Armv8-M, build two separate images—one for secure mode and one for non-secure mode. The secure image can export function entries that can be used by the non-secure image.
The IAR build tools support TrustZone by means of intrinsic functions, linker options, compiler options, predefined preprocessor symbols, extended keywords, and the section Veneer$$CMSE.
You can find the data types and utility functions needed for working with TrustZone in the header file arm_cmse.h.
The function type attributes __cmse_nonsecure_call and __cmse_nonsecure_entry add code to clear the used registers when calling from secure code to non-secure code.
The IAR build tools follow the standard interface for development tools targeting Cortex-M Security Extensions (CMSE), with the following exceptions:
Variadic secure entry functions are not allowed.
Secure entry functions with parameters or return values that do not fit in registers are not allowed.
Non-secure calls with parameters or return values that do not fit in registers are not allowed.
Non-secure calls with parameters or return values in floating-point registers.
The compiler option
‑‑cmserequires the architecture Armv8-M with security extensions, and is not supported when building ROPI (read-only position-independent) images or RWPI (read-write position-independent) images.
For more information about Arm TrustZone, see www.arm.com.
An example using the Armv8-M Security Extensions (CMSE)
In the arm\src\ARMv8M_Secure directory, you can find an example project that demonstrates the use of Arm TrustZone and CMSE.
The example consists of two projects:
hello_s: The secure part of the applicationhello_ns: The non-secure part of the application
Note
You must build the secure project before building the non-secure project.
There are two entry functions in hello_s, available to hello_ns via secure gateways in a non-secure callable region:
secure_hello: Prints a greeting, in the style of the classicHello worldexample.register_secure_goodbye: A callback that returns a string printed on exiting the secure part.
The linker will automatically generate the code for the needed secure gateways and place them in the section Veneers$$CMSE.
Open the example workspace
hello_s.ewwlocated inarm\src\ARMv8M_Secure\Hello_Secure.Set up the project
hello_sto run in secure mode by choosing Project>Options>General Options>32-bit and then selecting the options TrustZone and Mode: Secure.Set up the project
hello_nsto run in non-secure mode by choosing Project>Options>General Options>32-bit and then selecting the options TrustZone and Mode: Non-secure.The non-secure part must populate a small vector at
0x200000with addresses to the initialization routine, non-secure top of stack, and non-securemain. This vector is used by the secure part to set up and interact with the non-secure part. In this example, this is done with the following code innonsecure_hello.c:/* Interface towards the secure part */ #pragma location=NON_SECURE_ENTRY_TABLE __root const non_secure_init_t init_table = { __iar_data_init3, /* initialization function */ __section_end("CSTACK"), /* non-secure stack */ main_ns /* non-secure main */ };When the secure project is built, the linker will automatically generate an import library file for the non-secure part that only includes references to functions in the secure part that can be called from the non-secure part. Specify this file by using Project>Options>Linker>Output>TrustZone import library.
Build the secure project.
Include the TrustZone import library file manually in the project
hello_nsby specifying an additional library: Project>Options>Linker>Library>Additional libraries.Build the non-secure project.
The secure project must specify the non-secure project output file as an extra image that should be loaded by the debugger. To do this, use Project>Options>Debugger>Images>Download extra images.
To debug in the simulator, set the
hello_sproject as the active project by right-clicking on the project and choosing Set as Active.Choose Project>Options>Debugger>Driver and select Simulator.
Choose Simulator>Memory Configuration. Make sure that the option Use ranges based on is deselected.
Select Use manual ranges and add the following new ranges:
Access type
Start address
End address
RAM
0x0000'0000
0x003F'FFFF
RAM
0x2000'0000
0x203F'FFFF
SFR
0x4000'0000
0x5FFF'FFFF
SFR
0xE000'0000
0xE00F'FFFF
Table 90. Memory ranges for TrustZone exampleClick OK to close the Memory Configuration dialog box.
Start C-SPY by choosing Project>Download and Debug.
Choose View>Terminal I/O to open the Terminal I/O window.
Choose Debug>Go to start the execution.
The Terminal I/O window should now print this text:
Hello from secure World! Hello from non-secure World! Goodbye, for now.