Introduction to ARM
TrustZone (Cortex-M)
SITE HOME
Scope:
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.
- Non-Secure, Unprivileged
- Secure, Unprivileged
- Non-Secure, Privileged
- Secure, Privileged.
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
- Secure Region
- Non-Secure Region
- Non-Secure Callable region.
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.
Conclusion:
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
SITE HOME