Upgrade Existing Application to TrustZone#
The main concerns when upgrading existing deployment to the TrustZone solution are:
The Secure/Non-secure pair for the bootloader (24 kB) does not fit inside the current allotted bootloader space (16 kB).
The Secure/Non-secure pair for the application does not fit inside the current allotted application space.
The PSA ITS moves from a non-encrypted to an encrypted format, so the existing stored cryptographic keys in NVM3 cannot be reused after upgrading the current application to TrustZone.
The Secure Library is based on PSA Crypto, so the existing application cannot integrate with the TrustZone if one of the following conditions is valid.
Use SE Manager APIs for cryptographic and attestation operations.
Use classic Mbed TLS APIs for cryptographic operations (except for X.509 certificate) and Transport Layer Security (TLS) protocol.
System Requirements#
The following table lists the tools and software required for TrustZone development on Series 2 devices.
Tool/Software | Required Version | Description |
---|---|---|
GCC | v10.3.1 | Fix a bug (ID 99271) on cmse_nonsecure_call attribute. |
IAR EWARM | v9.20.4 | Fix a bug (EWARM-9484) on __cmse_nonsecure_call attribute. |
Segger J-Link | ≥ v7.6.2c | v7.6.2c is the first version to add basic TrustZone support on Series 2 devices. |
Simplicity Studio | ≥ v5.6.3.0 | v5.6.3.0 is the first version to support TrustZone software development on Series 2 devices. |
Simplicity Commander | ≥ v1.13.3 | v1.13.3 includes a TrustZone-aware flash loader and supports features required for TrustZone development. |
GSDK | ≥ v4.2.2 | GSDK v4.2.2 is the first version to support TrustZone software development on Series 2 devices. |
SE Firmware | ≥ v1.2.14 | v1.2.14 is the first version to fully support TrustZone on xG21 (HSE) and xG22 (VSE) devices. |
SE Firmware | ≥ v2.2.1 | v2.2.1 is the first version to fully support TrustZone on other Series 2 HSE and VSE devices. |
Notes:
Required GCC and IAR EWARM versions are GSDK-dependent.
Silicon Labs strongly recommends installing the latest SE firmware on Series 2 devices to support the required TrustZone features. The latest SE firmware image and release notes after installing the GSDK (Windows folder):
C:\Users<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public
Peripheral Addresses in Device Header Files#
The device header files (e.g., efr32mg21b020f1024im32.h) need to be configurable for different situations. The SL_TRUSTZONE_SECURE
and SL_TRUSTZONE_NONSECURE
definitions specify whether the compilation is for Secure or Non-secure applications. The SL_TRUSTZONE_SECURE
and SL_TRUSTZONE_NONSECURE
should be exclusive. If none of the definitions are true, the state should be similar to the Non-secure configuration, but the startup code (SystemInit()
in system_*.c) will be responsible for reconfiguring the system.
Define (Software Component) | Default Peripheral Pointer | Startup Code |
---|---|---|
SL_TRUSTZONE_SECURE (TrustZone Secure) | Point to Secure peripherals (*_BASE = *_S_BASE) | No effect on SystemInit() |
SL_TRUSTZONE_NONSECURE (TrustZone Non-Secure) | Point to Non-secure peripherals (*_BASE = *_NS_BASE) | No effect on SystemInit() |
None of the above (-) | Point to Non-secure peripherals (*_BASE = *_NS_BASE) | SystemInit() moves peripherals to Non-secure |
When building a Secure application (SL_TRUSTZONE_SECURE
is true), all peripherals shall have their non-suffixed default address pointing to the Secure location of the peripheral (e.g., EMU). But the definitions in sl_trustzone_secure_config.h can force the addresses of specific peripherals pointing to the Non-secure location.
#ifndef SL_TRUSTZONE_SECURE_CONFIG_H
#define SL_TRUSTZONE_SECURE_CONFIG_H
// Specify security configuration of peripherals. Peripherals that are not
// included here will automatically have their _BASE addresses point to their
// secure address. This might not be true, since most peripherals are configured
// to be non-secure -- but it's also not a problem if the peripheral is not
// accessed from the S app.
// Used in multiple places.
#define SL_TRUSTZONE_PERIPHERAL_CMU_S (0)
// Used by SE Manager service.
#define SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S (0)
// Used by MSC service.
#define SL_TRUSTZONE_PERIPHERAL_LDMA_S (1)
// Used by MSC service.
#define SL_TRUSTZONE_PERIPHERAL_LDMAXBAR_S (1)
#endif // SL_TRUSTZONE_SECURE_CONFIG_H
#if defined(SL_CATALOG_TRUSTZONE_SECURE_CONFIG_PRESENT)
#include "sl_trustzone_secure_config.h"
#endif
#if ((defined(SL_TRUSTZONE_SECURE) && !defined(SL_TRUSTZONE_PERIPHERAL_EMU_S))
|| (defined(SL_TRUSTZONE_PERIPHERAL_EMU_S) && (SL_TRUSTZONE_PERIPHERAL_EMU_S != 0)))
#define EMU_BASE (EMU_S_BASE) /* EMU base address */
#else
In other cases (SL_TRUSTZONE_NONSECURE
is true or both SL_TRUSTZONE_SECURE
and SL_TRUSTZONE_NONSECURE
are false), all peripherals shall have their non-suffixed default address pointing to the Non-secure location of the peripheral (e.g., EMU).
#define EMU_BASE (EMU_NS_BASE) /* EMU base address */
Note: Do not install the TrustZone Secure or TrustZone Non-Secure software component to the TrustZone-unaware application.
Startup Code#
The startup code moves peripherals from Secure to Non-secure to support the default peripheral locations. In a TrustZone-aware application (either SL_TRUSTZONE_SECURE
or SL_TRUSTZONE_NONSECURE
is true), this is the application's responsibility (skip lines 168 to 194 in SystemInit()
) and is done in the Secure firmware of the system.
For the TrustZone-unaware application (both SL_TRUSTZONE_SECURE
and SL_TRUSTZONE_NONSECURE
are false), the SystemInit()
in system_*.c (e.g., system_efr32mg21.c) moves peripherals to the Non-secure location.
The
SystemInit()
sets the accesses of all peripherals to Non-secure except for the SMU and HSE SEMAILBOX (lines 172 to 178).The
SystemInit()
sets the SAU in All Non-secure configuration (lines 180 to 187).It ensures Non-secure access to Non-secure peripherals.
The device component files (e.g.,
efr32mg21b020f1024im32.slcc
) enable the CMSE compiler option (-mcmse
for GCC and--cmse
for IAR) to pass the condition in line 181 to program the SAU.To catch the missing CMSE compiler option, it will generate a preprocessor error (line 186) if the CMSE flag is not set when manually upgrading a project from GSDK v4.0.x to ≥v4.1.x for the TrustZone-unaware application.
The
SystemInit()
does not program the ESAU (default Secure flash is 32 MB), so the whole program is run in the Secure state.The
SystemInit()
also enables theBMPUSEC
andPPUSEC
interrupts in the SMU (lines 189 to 193). It ensures the TrustZone-unaware application catches any violations of Bus Master and peripheral security access permissions.
The SMU_BASE
and HSE SEMAILBOX_HOST_BASE
in device header files must point to the Secure location regardless of the SL_TRUSTZONE_SECURE
and SL_TRUSTZONE_NONSECURE
settings to avoid security violations on peripherals in the TrustZone-unaware application (SMU and HSE SEMAILBOX are set to Secure peripherals).
#if ((defined(SL_TRUSTZONE_SECURE) && !defined(SL_TRUSTZONE_PERIPHERAL_SMU_S))
|| (defined(SL_TRUSTZONE_PERIPHERAL_SMU_S) && (SL_TRUSTZONE_PERIPHERAL_SMU_S != 0)))
#define SMU_BASE (SMU_S_BASE) /* SMU base address */
#else
#define SMU_BASE (SMU_S_BASE) /* SMU base address */
#if ((defined(SL_TRUSTZONE_SECURE) && !defined(SL_TRUSTZONE_PERIPHERAL_SEMAILBOX_HOST_S))
|| (defined(SL_TRUSTZONE_PERIPHERAL_SEMAILBOX_HOST_S) && (SL_TRUSTZONE_PERIPHERAL_SEMAILBOX_HOST_S != 0)))
#define SEMAILBOX_HOST_BASE (SEMAILBOX_S_HOST_BASE) /* SEMAILBOX_HOST base address */
#else
#define SEMAILBOX_HOST_BASE (SEMAILBOX_S_HOST_BASE) /* SEMAILBOX_HOST base address */
Notes:
The CMSE compiler option of GCC is in the Other flagswindow under C/C++ Build → Settings → Tool Settings → GNU ARM C Compiler→ Miscellaneous.
The CMSE compiler option of IAR is in the Command line options: (one per line) window under Options... → C/C++ Compiler → Extra Options.
Linker File#
The template_contribution
defined in the slcp files of Secure and Non-secure projects will override the default memory settings defined in the device component files (e.g., efr32mg21b020f1024im32.slcc
) to generate the linker files for Secure and Non-secure applications.
Memory Region | Default Setting in Device Component File | Override Setting in template_contribution |
---|---|---|
Flash start address | device_flash_addr | memory_flash_start |
Flash size | device_flash_size | memory_flash_size |
RAM start address | device_ram_addr | memory_ram_start |
RAM size | device_ram_size | memory_ram_size |
The ESAU sets the flash and RAM start address, so these addresses should be alignment at 4 kB (0x1000). The Secure project linker file needs to have a section for NSC (Secure Gateway) at the end of the Secure flash section. The SAU sets the start address of the NSC section, so this section only needs to be 32 bytes aligned.
GCC NSC: The
.gnu.sgstubs
region in the Secure application map file (.map)IAR NSC: The
Veneer$$CMSE
region in the Secure application map file (.map)
The Secure and Non-secure flash and RAM sizes are incremented or decremented in 4 kB. The memory configurations in Secure and Non-secure applications are correlated, so the flash and RAM settings are in pairs.
Note: Users should not directly edit the
template_contribution
in theslcp
file, but rather use the Memory Editor in Simplicity Studio to update the memory configuration.
Debugger#
Simplicity Studio supports two debuggers:
GNU Debugger (GDB) client and SEGGER's GDB server
Simplicity Studio Debugger
The TrustZone-unaware and TrustZone-aware applications enable the PPUSEC
interrupts in the SMU. The debugger will trigger the SMU_SECURE_IRQHandler
if the [Registers] or [Peripherals] view feature violates peripheral security access permission.
Simplicity Studio Debugger#
The [Registers] view of Simplicity Studio Debugger can only access the Secure location of a peripheral. The following figure demonstrates the Default_Handler
(SMU_SECURE_IRQHandler
not defined) is triggered (PPUSEC
in SMU->IF
= 1) when viewing the registers of GPIO peripheral (PPUFSPERIPHID
= 13) that is set to Non-secure access in the SMU.
The debugger can access the registers of the SMU since this peripheral is set to Secure access in the SMU.
This limitation does not apply to GSDK < v4.1.0 since no peripherals are configured for Non-secure access.
The Simplicity Studio Debugger is not the preferred choice for TrustZone debugging since it has limitations on viewing Non-secure access peripherals.
GNU Debugger (GDB)#
The [Peripherals] view of GNU Debugger can access either the Secure or Non-secure location of the peripheral to avoid conflicts on security access permission. The following figure shows the registers of GPIO on Secure (GPIO
at 0x4003C000
) and Non-secure (GPIO_NS
at 0x5003C000
) addresses. The GPIO peripheral is set to Non-secure access in the SMU, so the registers in the Secure address are displayed as zero.
The GNU Debugger is the preferred choice for TrustZone debugging and is the default debugger for Simplicity Studio ≥ v5.5.0.0.