Introduction to ARM TrustZone (Cortex-M)
-Aviral Mittal avimit att yahu dat cam.

This techerature introduces the TrustZone on ARM Cortex-M Processors.
To understand ARM's TrustZone, you may want to visit ARM's User/Privilege Levels Page.
Certain ARM-Cortex-M processors e.g. M33 or M23, implements the ARM v8.Main Instruction set Architecture. One of the main features of the ARM v8 Instruction Set Architecture is enhanced security using what ARM calls as 'TrustZone' Technology.

Why do you need TrustZone? What is the need for TrustZone? Some Background and Motivation
The Classification of Privileged/Non-Privileged 'Access Level' provides some basic form of security mechanism, which the users may use to implement access rights of software running on the processor on system's memory space.
However the Privilege Level classification had one shortcomings.
The Handler mode always had 'Privileged' level of access. This meant that if the user wants to write an application, then they cannot normally write interrupt service routines, as ISRs can only run in 'Privileged' access levels, and as a system designer you may not want to give 'Privileged' access level to normal user software, which can easily be un-trusted. However there are workarounds. I.e. the 'handlers' can be made to run in 'unprivileged' level, by using a software wrapper around them, for example, when an interrupt occurs, and the user indents to run their own code following this interrupt, their code can still run, but only after the 'handler' has re-programmed the MPU to restrict the memory visibility, and then switching to the 'user/unprivileged' mode of operation. This is called sandboxing. The user's code is now 'sandboxed' and its capabilities are restricted. This sandboxing wrapper will protect the system memory from user code, which would run as a result of an interrupt, but still in thread mode and will have restricted view of the memory. 
But the problem with this arrangement is the software over-head of sandboxing the user's code. Imagine a system with 100s of interrupt, each has some user code 'sandboxed' in a way just described above. This clearly isn't the way to go.
It is clear that, may be a mechanism that would allow the users to run their code directly as an exceptional handler is needed.
Arm TrustZone on Cortex-M is a solution to the above problem. It introduces another 'Level' of Access rights, which is called 'Secure/Non-Secure'. This is also at times called 'trusted/Non-Trusted'.
Now the processor can have 4 Levels of Access.
In ARM's words, the TrustZone feature adds two processor 'states', i.e. Secure/Non-Secure.

A new signal which will indicate Secure/Non-Secure was then required.
For AXI, this signal is already there. AxPROT[1]. But then what ARM Cortex-M has AXI interface and implements ARM's TrustZone? None-at the moment (Dec 2019), but something might be coming.
For AHB, this signal is called HNONSEC. When HNONSEC = '1', the transfer is Not-Secure. Tie this signal to '1', if TrustZone support is NOT required.
The AHB protocol up to AMBA4 does not support this signal. Hence to support ARM's TrustZone technology on AHB, AMBA 5 AHB is required or alternative custom HW design will be required to add this signal as an extra bit on AMBA 4 AHB or earlier versions of AHB protocol.

TrustZone allows the user to have two more 'access levels' i.e. Secure and Non-Secure levels in addition to already existing privileged and unprivileged level. This means that the user now has two different access levels while the processor is in 'Handler Mode' as well i.e. Secure handler mode and  Non-Secure handler mode. This allows the users to write Interrupt Service Routines (ISRs), which still has limited 'access rights', but it runs directly in 'handler' mode as 'non-secure' handler mode code.  Sandboxing of the user code is no longer required as the user's code can now be identified as 'Non-Secure' that can still run in directly in 'handler' mode, and the access rights of this 'Non-Secure' code in handler mode still restricted. This can be done as now there are 2 MPUs on offer, a secure MPU and a non-secure MPU. The non secure MPU will still restrict the memory visibility of user's handler code, giving flexibility to user, without risking the system security.

All of the above theory means, that form HW point of view, and for the system designer designing the system around the processor with TrustZone support, 1 bit of signal i.e. HNONSEC Or AxPORT[1], is very important.

Now looking from the point of view of the Processor itself, the processor has to implement a method which the software will exploit to make the switch between this newly introduced Secure/Non-Secure world.
For this the processor now has
Looking from the point of view of the programmer, i.e form the Software point of view, the TrustZone requires the following the memory to be partitioned such that it now has the following 3 memory regions
To partition the memory space into the 3 above said regions, the processor has SAU (Security Attribution Unit). Its in a way similar to the MPU (Memory Protection Unit).
The above said 'Secure Region' and 'Non-Secure' regions are very intuitive to understand, and they are what they sound like. But the 3rd region called 'Non-Secure Callable' requires some explanation. But first its important to understand how the processor switches from Secure-Non-Secure and vice-versa.
Before the processor makes a switch, obviously the programmer will partition the memory space into 'secure' and 'non-secure' regions. This is done by programming the SAU. Taking a very simple example, the user may just partition the entire memory space into 8 Secure and 8 Non-Secure regions.
Upon reset, the processor's access Level is 'Secure' if the TrustZone is opted in, while configuring the processor.
This means that HNONSEC signal will be '0', and if there is an AXI I/F then AxPROT[1] will be '0' for any instructions that are executed from Reset, till the point an explicit change of processor's state has been done from Secure to Non-Secure.
There is also a signal on the processor called 'CURNS' which indicates the processor's Access Level.
CURRNS = '0' => means Secure
CURRNS = '1' => means Non-Secure.

Switching from Secure to Non-Secure:
The ARM v8.Main then provides instructions BLXNS and BLNX which can be used by Software to make a switch from Secure to Non-Secure memory regions.
Switching form Non-Secure to Secure:
This involves the code running with Non-Secure Access level to execute 'SG' instruction. SG=SecureGateway. The SG instruction must always be placed into memory region defined as 'Non-Secure Calleable'. And this is why this 'Non-Secure Calleable Region' definition is needed while partitioning the memory regions. This is the only memory region the Non-Secure code can branch out to, apart from of course any other Non-Secure region.

Again form Software point of veiw, the software architecture will now need to define for all the images, if they will be kept at 'Secure' Or 'Non-Secure' Regions. This can be done via using linker options or via using Scatter-Load files.

Behind the Scene:
When the Secure-to-NonSecure Switch instruction is executed e.g. BLXNS,(which would change the processor's State to Non-Secure form Secure), the context of the processor is stored in 'secure-stack' which is pointed to by the Secure Stack pointer.
Likewise when the Non-Secure-to-Secure Switch instruction is executed (SG), the context of the processor is stored in 'non-secure' stack which is pointed to by the Non-Secure Stack pointer. However it is to be noted that this context save is not an automatic process. Not at least if you are writing assembly code. However while writing C-Code, ARM provides some functions, which when called form C-Code will produce all he assembly code to switch the processors' Security state, and save the processor's context at appropriate stack.

The ARM Cortex-M TrustZone is nothing but an addition of a secure/non secure access level distinction in addition to already existing privilege/Non privileged levels, to indicate Secure/Non-Secure Processor State. These access levels when used in conjunction with the secure and non-secure MPUs gives the user a very powerful technique for a secure system design.
In terms of Hardware the ARM's TrustZone just adds an extra signal i.e Secure/Non-Secure however from Software point of view, things are more complex, as it is evident form ARM's documentation here.
If you are after some C/Assembly code for ARM TZ, Click Here: This is an example full code to make a processor state switch from Secure to Non-Secure World.

<= PREV  : ARM User/Privilege Levels                                      Next => ARM Cortex-M MPU

Click Here to Make Comments or ask Questions