Switching between Secure and Non-secure states
The ARMv8-M Security Extensions allow direct calling between Secure and Non-secure software.
Several instructions are available for state transition handling in ARMv8-M processors:
Used for switching from Non-secure to Secure state at the first instruction of Secure entry point.
Branch with exchange to Non-secure state.
Used by Secure software to branch or return to Non-secure program.
Branch with link and exchange to Non-secure state.
Used by Secure software to call Non-secure functions.
The following figure shows the security state transitions.
A direct API function call from Non-secure to Secure software
entry points is allowed if the first instruction of the entry point is
and it is in a Non-secure callable memory location, as in the following figure:.
When a Non-secure program calls a Secure API, the API
completes by returning to a Non-secure state using a
BXNS instruction. If a
Non-secure program attempts to branch, or call a Secure program address without using a
valid entry point, a fault event is generated. In ARMv8-M architecture the HardFault in
Secure state handles the fault event. In ARMv8-M architecture with Main Extension, the
SecureFault exception type is used.
When a Non-secure program calls a Secure API,
the API completes by returning to a Non-secure state using a
instruction. If a Non-secure program attempts to branch, or call a Secure program
address without using a valid entry point, a fault event is generated. In the ARMv8-M
architecture with Main extension, the SecureFault exception type is used. For the
ARMv8-M architecture, the HardFault in Secure state handles the fault event.
ARMv8-M Security Extensions also allow a Secure program to call Non-secure software. In
such a case, the Secure program uses a
BLXNS instruction to call a
Non-secure program. During the state transition, the return address and some processor
state information are pushed onto the Secure stack, while the return address on the Link
Register (LR) is set to a special value called FNC_RETURN. The Least Significant Bit
(LSB) of the function address must be 0.
The following figure shows the software flow when a secure program calls a Non-secure function:
The Non-secure function completes by performing a branch to the FNC_RETURN address. This automatically triggers the unstacking of the true return address from the Secure stack and returns to the calling function. The state transition mechanism automatically hides the return address of the Secure software. Secure software can choose to transfer some of the register values to the Non-secure side as parameters, and clears other Secure data from the register banks before the function call.
Security state changes
Transitions from Secure to Non-secure state
can be initiated by software by using either a
instruction that has the Least Significant Bit (LSB) of the target address unset. This
enables the LSB of an address to denote the security
NoteTransitions from Non-secure to Secure state can be initiated by software in two ways:
- A branch to a Secure gateway.
- A branch to the reserved value FNC_RETURN.
A Secure gateway is an occurrence of the Secure Gateway instruction
SG) in a special type of Secure region, named a Non-secure Callable (NSC)
region. When branching to a Secure gateway from Non-secure state, the
instruction switches to the Secure state and clears the LSB of the return address in the
LR. In any other situation, the
SG instruction does not change the security
state or modify the return address. The
SG instruction must be fetched from
A branch to the reserved value FNC_RETURN causes the hardware to
switch to Secure state, read an address from the top of the Secure stack, and branch to
that address. The reserved value FNC_RETURN is written to the LR when executing the
Security state transitions can be caused by hardware through the handling of interrupts. Those transitions are transparent to software.
Secure gateway veneers
A toolchain must support generating a
Secure gateway veneer (extra code to reset the program counter) for each entry function
with external linkage. It consists of an
SG instruction followed by a
B.W instruction that targets the entry function it
Secure gateway veneers decouple the addresses of Secure gateways (in NSC regions) from the rest of the Secure code. By maintaining a vector of Secure gateway veneers at a forever-fixed address, the rest of the Secure code can be updated independently of Non-secure code. This also limits the amount of code in NSC regions that potentially can be called by the Non-secure state.
Vectors of Secure gateway veneers are expected to be placed in NSC memory. All other code in the Secure executable is expected to be placed in Secure memory regions. This placement is under the control of the developer.
Preventing inadvertent Secure gateways is a responsibility that is shared between a developer and their toolchain. A toolchain must make it possible for a developer to avoid creating inadvertent Secure gateways.
Excluding the first
instruction of a Secure gateway veneer, a veneer must not contain the bit pattern of the
SG instruction on a 2-byte boundary.
A vector of Secure gateway veneers must be aligned to a 32-byte boundary, and must be zero padded to a 32-byte boundary.
The developer must take care that the code or data before the vector of Secure gateway veneers does not create an inadvertent Secure gateway with the first Secure gateway veneer in the vector. ARM recommends placing the vector of Secure gateway veneers at the start of an NSC region.
The position of Secure gateway veneers in a vector must be controllable by the developer.
This last requirement gives the developer complete control over the address of a Secure gateway veneer.
It allows the developer to fix the addresses of the Secure gateway veneers so that Secure code can be updated independently of Non-secure code.
The following figure shows the memory layout of a Secure executable: