Silicon Labs documentation on IoT Security version 1.3.0.

Documentation source: https://docs.silabs.com/iot-security/1.3.0

# IoT Security

## Using Silicon Labs IoT Security Features

Silicon Labs offers a range of security features depending on the part you are using and your application and production needs.

![secure vault with developer](/iot-security-start/0.2/images/secure-vault-image.png)

The content on these pages is intended for those who want to implement security features as part of your IoT device management. If you are looking for an introduction to Silicon Labs Security features and to security issues that confront those implementing IoT systems, see the [Silabs.com Security page](https://www.silabs.com/security).

**For details about this release**: Links to release notes are available on the [silabs.com Gecko SDK](https://www.silabs.com/developers/gecko-software-development-kit) page as part of the Gecko Platform release notes.

**For background on security issues in general**: [IoT Security Fundamentals](/iot-security/1.3.0/iot-endpoint-security-fundamentals) explains some security basics.

**To get started with implementing security**: See the [Getting Started page](/iot-security/1.3.0/iot-security-getting-started) for help determining what features you want to implement based on the series 2 part you are working with. Series 2 devices are the preferred choice for secure system implementation.

**If you are already in development**: See the [Developer's Guide](/iot-security/1.3.0/iot-security-developers-guide-overview) for details. Security APIs are documented in the [Gecko Platform API Reference](https://docs.silabs.com/gecko-platform/latest/).

**For detailed information about implementing some security features with specific protocols**: See the [protocol-specific pages](/iot-security/1.3.0/iot-security-protocol-specific). An extensive body of other protocol-specific content can be accessed through the [docs.silabs.com homepage](https://docs.silabs.com/).

## Getting Started with Silicon Labs IoT Security Features on Series 2 Devices

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys, and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based or virtual (software-based). Here the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|Security Level (1)|SE Support|MCU|Wireless SoC (2)|
|---|---|---|---|
|Secure Vault Base (SVB)|N/A|EFM32JG1, EFM32PG1, EFM32JG12, EFM32PG12, EFM32GG11, EFM32GG12, EFM32TG11|EFR32xG1, EFR32xG12, EFR32xG13, EFR32xG14|
|Secure Vault Mid (SVM)|VSE (VSE-SVM)|EFM32PG22|EFR32xG22|
|”|HSE (HSE-SVM)|EFM32PG23A|EFR32xG21A, EFR32xG23A, EFR32xG24A|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|EFM32PG23B|EFR32xG21B, EFR32xG23B, EFR32xG24B|

Note:

1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security) .
2. The x is a letter B, F, M, or Z.

Secure Vault Mid consists of two core security functions:

- Secure Boot: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- Secure Debug access control: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- Secure Key Storage: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- Anti-Tamper protection: A configurable module to protect the device against tamper attacks.
- Device authentication: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 devices to support the required security features. The latest SE firmware image (.seu and .hex) and release notes can be found in these Windows folders of the GSDK.

`C:\Users\<UserName>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public`

If you have not already installed the GSDK, instructions for doing so with Simplicity Studio are available in the [Getting Started section of the Simplicity Studio 5 User's Guide](https://docs.silabs.com/simplicity-studio-5-users-guide/5.5.0/ss-5-users-guide-getting-started/install-ss-5-and-software).

Refer to [Production Programming of Series 2 and Series 3 Devices](/iot-security/1.3.0/prod-programming-series2-and-series3) for guidance on the SE firmware upgrade procedure. The latest SE firmware shipped with Series 2 devices and modules (if available) at the time of this writing are listed in the following table:

|MCU Series 2 and Wireless SoC Series 2|SE|Shipped SE Firmware Version (Device and Module)|
|---|---|---|
|EFR32xG21A|HSE-SVM|1.2.13|
|EFM32PG23A|HSE-SVM|2.1.7|
|EFR32xG23A|HSE-SVM|2.1.2 (Rev B), 2.1.7 (Rev C)|
|EFR32xG24A|HSE-SVM|2.1.7|
|EFR32xG21B|HSE-SVH|1.2.13|
|EFM32PG23B|HSE-SVH|2.1.7|
|EFR32xG23B|HSE-SVH|2.1.2 (Rev B), 2.1.7 (Rev C)|
|EFR32xG24B|HSE-SVH|2.1.7|
|EFM32PG22 and EFR32xG22|VSE-SVM|1.2.12|

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

## IoT Endpoint Security Fundamentals

### IoT Endpoint Security Fundamentals

> **Note: This section replaces _UG103.05: IoT Endpoint Security Fundamentals_. Further updates to this user guide will be provided here**.

This guide introduces the security concepts that must be considered when implementing an Internet of Things (IoT) system. The guide clearly delineates the solutions Silicon Labs provides to support endpoint security and what you must do outside of the Silicon Labs framework. Where appropriate, Silicon Labs’ approach to our own security is offered as an example. This document is designed for product developers and managers.

Silicon Labs’ _Fundamentals_ series covers topics that project managers, application designers, and developers should understand before beginning to work on an embedded networking solution using Silicon Labs chips, networking stacks such as EmberZNet PRO or Silicon Labs _Bluetooth®_, and associated development tools. The guides can be used as a starting place for anyone needing an introduction to developing wireless networking applications, or who is new to the Silicon Labs development environment.

#### Key Points

- Describes what manufacturers must do to have a secure product
- Reviews the tools and solutions Silicon Labs provides to support product security
- Provides references to other general and product-specific information

### Overview

Securing the IoT is challenging. It is also mission-critical. Threats are continuously evolving, and the demand on product developers to keep up can be burdensome – particularly in low-cost, resource-constrained IoT products. Protecting your product in a connected world is a necessity, as customer data and modern online business models are increasingly targets for costly hacks that jeopardize end-user privacy and corporate brand damage. Silicon Labs is committed to working with the security community, customers, and other experts to bring state-of-the-art technology to help protect your connected portfolio.

### No Universal Passwords

_The product shall not have a universal password; unique security credentials will be required for operation. Universal passwords allow an attacker to easily gain access to any device. Therefore, products shall either have a unique password or require the user to enter a new password immediately upon first use._

It is your responsibility to ensure that your product enforces the creation of a unique password before activation.

Silicon Labs’ products are designed to be configured by the manufacturer before being delivered to customers, and therefore passwords are outside of our scope. However, Silicon Labs tools are designed to support the various levels of security provided by the protocol in question. Most protocols offer different security levels, with tradeoffs between security level and other features such as ease of network formation. You need to review and decide on the level required by your application. For example:

- The EmberZNet Pro SDK supports a highly secure centralized trust-center-controlled method that replaces a device’s factory-programmed link key with a key that is unique to each device on the network.
- Z-Wave 700 products come with a factory-programmed unique S2 keypair on first power-up, and support SmartStart commissioning through a package QR code containing the public key.
- Bluetooth options range from an unsecured “Just Works” approach to a LE Secure Connections Pairing model. Application designers can implement additional device authentication methods, such as through the companion smartphone app, to help ensure secure pairing even for devices without a user interface.

### Secured Interfaces

_All product interfaces shall be appropriately secured by the manufacturer._

The interfaces to be secured will vary by product configuration. For example, in an NCP topology the NCP interface must be secured. Debug interfaces should always be locked. Wireless interfaces should be secured by using strong pairing and commissioning methods and by enabling encrypted and authenticated transmissions.

While securing the interfaces is in the end your responsibility, Silicon Labs provides the tools to enable that security.

Series 1, Series 2 and Series 3 devices are designed to support securing debug access. For Series 1 devices, that functionality is provided through writing a Debug Lock word to the device. Unlocking the device erases the main application and the key material stored in the Lockbits page. For Series 2 and 3 devices, securing debug access is done through the device’s Secure Engine. Both allow the developer to lock the debug port itself. See [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) or _UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower_ for an overview of securing debug access, and [Series 2 and 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) for details on the Series 2 and 3 implementation. [Testing and Debugging Applications for the Silicon Labs EFR32MG Platforms](https://docs.silabs.com/zigbee/latest/test-debug-apps-efr32mg/) provides an overview of the various application testing stages and the debug access (hardware and software) required in each.

For more information on Wireless interface security in the different protocols, see the following:

- [Zigbee Security](https://docs.silabs.com/zigbee/latest/zigbee-security/)
- [Bluetooth LE Fundamentals](https://docs.silabs.com/bluetooth/latest/bluetooth-le-fundamentals/)
- [UG235.03: Architecture of the Silicon Labs Connect Stack v2.x](https://www.silabs.com/documents/public/user-guides/ug235-03-architecture-of-connect.pdf)
- [Architecture of the Silicon Labs Connect Stack v3.x](https://docs.silabs.com/connect-stack/latest/network-co-processor-applications-connect-v3x/)

### Proven Cryptography

_Product security shall use strong, proven, updatable cryptography using open, peer-reviewed methods and algorithms._

An important aspect of any IoT device is how secure the device is when it communicates with other devices, gateways, or the cloud. This standard mandates using proven cryptographic methods rather than attempting to implement your own.

Developers commonly secure communications such as TCP/IP connections, Bluetooth, Zigbee, or Z-Wave using the standardized and proven cryptographic methods native to the protocol. However, if a microcontroller sends sensitive information over a simple interface such as a UART to another microcontroller, it is important to realize that data should also be secured to prevent someone from snooping the UART line.

Silicon Labs offers a hardware accelerator module that provides an efficient acceleration of common cryptographic operations and allows these to be used efficiently with low CPU overhead. The cryptographic accelerator module includes hardware accelerators for the Advanced Encryption Standard (AES), optionally ChaCha20/Poly1305, Secure Hash Algorithm SHA-1 and SHA-2 (SHA-224 and SHA-256), and modular multiplication used in ECC (Elliptic Curve Cryptography) and GCM (Galois Counter Mode). The accelerator module can autonomously execute and iterate a sequence of instructions to aid software and speed up complex cryptographic functions like ECC, GCM, and CCM (Counter with CBC-MAC).

In addition to the cryptographic accelerator module, Silicon Labs includes the PSA Crypto and Mbed TLS libraries as part of the Gecko Platform SDK. Mbed TLS is open source software licensed by ARM Limited. It provides an SSL library that makes it easy to use cryptography and SSL/TLS in applications. Mbed TLS supports software implementations of all crypto algorithms that are supported by TLS 1.3 as well as a build API that allows hardware drivers to replace the software implementations when cipher accelerators are supported by the platform. Its modular framework allows for subcomponents like the crypto libraries to be incorporated into a design independently of the SSL/TLS components, saving valuable code space and runtime RAM. Mbed TLS supports SSLv3 up to TLSv1.3 communication by providing the following:

- TCP/IP communication functions: listen, connect, accept, read/write.
- SSL/TLS communication functions: init, handshake, read/write.
- X.509 functions: CRT, CRL and key handling
- Random number generation
- Hashing
- Encryption/decryption

These functions are split up into logical interfaces. They can be used separately to provide any of the above functions or to mix-and-match into an SSL server/client solution that utilizes a X.509 public key infrastructure (PKI). Examples of such implementations are provided with the source code. Components or plugins and APIs provide configuration interfaces accessible through the various SDK installations.

For more information, see the latest MCU and Peripheral Software Documentation for the target part at [https://docs.silabs.com.](https://docs.silabs.com/).

### Security by Default

_Product security shall be appropriately enabled by default by the manufacturer._

The state in which a product is shipped is up to the manufacturer. This standard mandates that any security features provided with the product be enabled before shipping. Customers should not have to turn security on; rather they should actively have to disable it. For example, Silicon Labs Z-Wave end-nodes and gateway SDKs ship with S2 cryptography and SmartStart network formation enabled by default.

Silicon Labs believes that product security should be considered during product design, and not as an afterthought. Within development environments, all Silicon Labs application security features may be enabled or disabled as appropriate during application development. Security must also be considered during device design and testing. [Bringing Up Custom Devices for the EFR32MG and EFR32FG Families](https://docs.silabs.com/connect-stack/latest/custom-nodes-efr32/) describes the security tokens (keys, certificates, and so on) that can be programmed into a custom device to support various types of security, including that provided by the Gecko Bootloader. See [Signed Software Updates](06-signed-software-updates).

### Signed Software Updates

_The product shall only support signed software updates. While it is critical that all products be updatable, it is just as critical that these update images be secured. A manufacturer must cryptographically sign update images to prevent tampering during deployment. The product must not use unsigned updates, as they could be fraudulent._

Silicon Labs development tools support building signed upgrade images and securely updating devices in the field, through the Silicon Labs Gecko Bootloader. The Gecko Bootloader can be configured to perform a variety of functions, from device initialization to firmware upgrades. Key features of the bootloader are:

- Usable across Silicon Labs Gecko microcontroller and wireless microcontroller families
- In-field upgradeable
- Configurable
- Enhanced security features, including:
- Secure Boot: When Secure Boot is enabled, the bootloader enforces cryptographic signature verification of the application image on every boot, using asymmetric cryptography. This ensures that the application was created and signed by a trusted party.
- Signed upgrade image file: The Gecko Bootloader supports enforcing cryptographic signature verification of the upgrade image file. This allows the bootloader and application to verify that the application or bootloader upgrade comes from a trusted source before starting the upgrade process, ensuring that the image file was created and signed by a trusted party.
- Encrypted upgrade image file: The image file can also be encrypted to prevent eavesdroppers from acquiring the plaintext firmware image.

On Series 1 devices, the Gecko Bootloader has a two-stage design, first stage and main stage, where a minimal first stage bootloader is used to upgrade the main bootloader. The first stage bootloader only contains functionality to read from and write to fixed addresses in internal flash. To perform a main bootloader upgrade, the running main bootloader verifies the integrity and authenticity of the bootloader upgrade image file. The running main bootloader then writes the upgrade image to a fixed location in internal flash and issues a reboot into the first stage bootloader. The first stage bootloader verifies the integrity of the main bootloader firmware upgrade image, by computing a CRC32 checksum before copying the upgrade image to the main bootloader location.

On Series 2 and Series 3 devices, the Gecko Bootloader consists only of the first stage bootloader. The main bootloader is upgradable through the hardware peripheral Secure Engine. The Secure Engine provides functionality to install an image to the base address of flash, by copying from a configurable location in flash. To perform a main bootloader upgrade, the running main bootloader verifies the integrity and authenticity of the bootloader upgrade image file. The running main bootloader then writes the upgrade image to the upgrade location in flash and requests that the Secure Engine install it. The Secure Engine is also capable of verifying the authenticity of the main bootloader update image against a root of trust. The Secure Engine itself is upgradable using the same mechanism.

In summary, Series 2 and Series 3 devices support a hardware root of trust and a Secure Boot process that verifies the authenticity and integrity of Gecko Bootloader, whereas in Series 1 devices, the authenticity and integrity of Gecko Bootloader are assumed trusted and are not explicitly checked.

The Gecko Bootloader can enforce application image security on two levels:

- Secure Boot refers to the verification of the authenticity of the application image in main flash on every boot of the device. When Secure Boot is enabled, the cryptographic signature of the application image in flash is verified on every boot, before the application is allowed to run. Secure Boot is not enabled by default in the example configurations provided by Silicon Labs, but enabling it is highly recommended to ensure the validity and integrity of firmware images.
- Secure Firmware Upgrade refers to the verification of the authenticity of an upgrade image before applying the upgrade and optionally enforcing that upgrade images are encrypted. The Secure Firmware Upgrade process uses symmetric encryption to encrypt the upgrade image, and asymmetric cryptography to sign the upgrade image in order to ensure its integrity and authenticity.

For more information on Silicon Labs’ support for software update security, refer to the following:

- Bootloaders in general: [Bootloader Fundamentals](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/).
- The Gecko Bootloader in general: [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) or _UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower_

Using the Gecko Bootloader with specific protocols:

[Using the Gecko Bootloader with EmberZNet](https://docs.silabs.com/zigbee/latest/using-gecko-bootloader-with-zigbee/)

[Using the Gecko Bootloader with Silicon Labs Connect](https://docs.silabs.com/connect-stack/latest/using-gecko-bootloader-with-connect/)

[Using the Gecko Bootloader with Silicon Labs Bluetooth Applications](https://docs.silabs.com/bluetooth/latest/using-gecko-bootloader-with-bluetooth-apps/)

[Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)

### Automatically Applied Updates

_The manufacturer will act quickly to apply timely security updates. Whenever a security vulnerability is detected, the manufacturer will automatically apply a patch to the product. No user intervention will be required._

It is the manufacturer’s responsibility to develop and implement automatic security updates. The design and methodology of such systems, for example through a Cloud-connected infrastructure or by direct intervention by a service representative, is up to you.

Silicon Labs will notify you of any security-related updates, as described in [Vulnerability Reporting Program](08-vulnerability-reporting-program) Your responsibility is to evaluate the level of risk that vulnerability poses for your particular product and to integrate the update into your platform as appropriate so that your end users are protected. Updated components might include the protocol libraries, Secure Engine firmware inside the Series 2 and Series 3 families, or an SDK module such as the Gecko Bootloader that enforces secure OTA updates and secure boot functionality.

Silicon Labs recommends the following:

- Subscribe to security updates through our [Salesforce portal](https://community.silabs.com/s/support-home). To review or change your subscriptions, log in to the portal, click **HOME** to go to the portal home page, and then click the **Manage Notifications** tile. Make sure that **Software/Security Advisory Notices & Product Change Notices (PCNs)** is checked, and that you are subscribed at minimum for your platform and protocol. Click **Save** to save any changes.  
  ![screenshot](/iot-endpoint-security-fundamentals/0.3/images/sld875-image15.png)
- Do not turn off Simplicity Studio’s update notification. Within Simplicity Studio you can download updates and easily access product release notes.

### Vulnerability Reporting Program

_The manufacturer shall implement a vulnerability reporting program, which will be addressed in a timely manner. All companies that offer Internet-connected devices and services shall provide a public point of contact as part of a vulnerability disclosure policy in order that security researchers and others are able to report issues. Disclosed vulnerabilities should be acted on in a timely manner._

Manufacturers are responsible for implementing their own program. For any individual vulnerability, you will need to weigh the value of transparency with your customers against the risk of malicious use of the information to exploit a vulnerability before it can be addressed. Silicon Labs makes similar decisions about how broadly to report security vulnerabilities discovered in our products.

Silicon Labs customers and security researchers can report security vulnerabilities in Silicon Labs hardware and software products on the Silicon Labs website: [https://www.silabs.com/security/product-security](https://www.silabs.com/security/product-security).

Silicon Labs’ Security Vulnerability Disclosure Policy may be found here: [https://www.silabs.com/security/security-vulnerability-disclosure-policy](https://www.silabs.com/security/security-vulnerability-disclosure-policy).

Silicon Labs has a Product Security Incident Response Team (PSIRT) that is dedicated to the case management of reported security vulnerabilities. The PSIRT works with other Silicon Labs groups including Applications, Developers, Sales, and Marketing to assess reported vulnerabilities, perform technical analysis and determine an appropriate response. The key processes for addressing vulnerabilities include:

- **Triage**: Determines what is needed to reproduce the vulnerability.
- **Technical Analysis and Disposition**: Confirms the validity of the security vulnerability, its scope, and its impact, and provides a resolution or disposition decision. Silicon Labs scores incidents according to CVSS 4.0 (Common Vulnerability Scoring System): low, medium, high, critical.
- **Output**: Communicates with our customers. The level and method of disclosure beyond the reporting entity depends on the severity and scope of the vulnerability.

Silicon Labs’ provides broad vulnerability reporting to customers subscribed through our Salesforce portal (see [Automatically Applied Updates](07-automatically-applied-updates) for information on how to subscribe). A subscribed customer will see Security Advisory notifications something like the following:

![screenshot](/iot-endpoint-security-fundamentals/0.3/images/sld875-image16.jpg)

### Security Expiration Date

_The manufacturer shall be transparent about the period of time that security updates will be provided. Like a manufacturer’s product warranty, there shall be transparency around the support period of security updates._

Manufacturers should provide details about product support at various stages and publish security expiration dates. Z-Wave’s Protocol Lifecycle provides an example.

![diagram](/iot-endpoint-security-fundamentals/0.3/images/sld875-image17.jpg)

The Lifecycle details in what phases updates will be applied, and to what product branch. For details on the various phases and how the lifecycle is implemented for specific Z-Wave products, see:

[https://www.silabs.com/products/development-tools/software/z-wave/embedded-sdk/life-cycle](https://www.silabs.com/products/development-tools/software/z-wave/embedded-sdk/life-cycle)

### Next Steps

The Silicon Labs Security web page ([https://www.silabs.com/security)](https://www.silabs.com/security)) contains links to a variety of general security-related resources. You may wish to bookmark the page, as it will be continually updated with new content, new tools, and new flows.

If you are already in development, we strongly recommend that you implement the standards described here as you develop, test, and release your product to customers.

If you are in the early stages of your product design and have not already selected a device or development environment, we recommend that you include security considerations in your decision. Silicon Labs provides information about the security features of our devices and development environments. [Series 2 and Series 3 Device Security Features](11-series-2-and-series-3-device-security-features) highlights the features and their documentation references. In addition, protocol-specific security information is available in the following documents.

- [Zigbee Security](https://docs.silabs.com/zigbee/latest/zigbee-security/) (contents were previously in this document under the title Application Security Fundamentals)
- [Bluetooth® Low Energy Application Security Design Considerations in SDK v3.x and Higher](https://docs.silabs.com/bluetooth/latest/bluetooth-application-security-design-considerations/)
- [Using Silicon Labs Secure Vault Features with OpenThread](https://docs.silabs.com/openthread/latest/using-secure-vault-openthread/)
- [Bluetooth® LE Fundamentals](https://docs.silabs.com/bluetooth/latest/bluetooth-le-fundamentals/) and relevant Knowledge Base Articles (KBAs)
- [Architecture of the Silicon Labs Connect Stack v3.x](https://docs.silabs.com/connect-stack/latest/architecture-of-connect-v3x/)

### Series 2 and Series 3 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys, and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

On Series 3 devices, the security features are implemented by the Secure Engine and HOSTCRYPTO (if available). The Secure Engine may is hardware-based.

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Security Level (1)**|**SE Support**|**MCU**|**Wireless SoC (2)**|
|---|---|---|---|
|Secure Vault Base (SVB)|N/A|EFM32JG1, EFM32PG1, EFM32JG12, EFM32PG12, EFM32GG11, EFM32GG12, EFM32TG11|EFR32xG1, EFR32xG12, EFR32xG13, EFR32xG14|
|Secure Vault Mid (SVM)|VSE (VSE-SVM)|EFM32PG22C|EFR32xG22C, EFR32xG27C (3)|
|Secure Vault Mid (SVM)|HSE (HSE-SVM)|-|EFR32xG21A, EFR32xG21A (Rev C), EFR32MR21A (Rev C), EFR32xG23A, EFR32xG24A, EFR32xG25A, EFR32xG28A|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|EFM32PG23B, EFMPG26B, EFM32PG28B|EFR32xG21B, EFR32Xg21B (Rev C) EFR32xG23B, EFR32xG24B, EFR32xG25B, EFR32xG26B, EFR32xG28B, EFR32xG29B, SixG301|

> Note:
> 
> 1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security.](https://www.silabs.com/security).
> 2. The x is a letter B, F, M, or Z.
> 3. Unlike other VSE-SVM parts, the EFR32xG27C device has a built-in PUF.

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug access control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper protection**: A configurable module to protect the device against tamper attacks.
- **Device authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

Silicon Labs strongly recommends installing the latest SE FW image on Series 2 and Series 3 devices and updating to the latest GSDK or SiSDK to mitigate security vulnerabilities. The latest SE FW image can be found in this Windows folder for GSDK v4.x:

`C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public`

Or

`C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\simplicity_sdk\util\se_release\public`

Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for guidance on the SE firmware upgrade procedure. The latest SE firmware shipped with Series 2 and Series 3 devices and modules (if available) at the time of this writing are listed in the following table:

|**Series 2 MCU and Wireless SoC VSE - SVM**|**Shipped SE Firmware Version**|
|---|---|
|EFM32PG22C|1.2.12|
|EFR32xG22C|1.2.12|
|EFR32xG22C (Rev D)|1.2.14|
|EFR32xG27C|2.2.1|

|**Series 2 Wireless SoC HSE - SVM**|**Shipped SE Firmware Version**|
|---|---|
|EFR32xG21A|1.2.13|
|EFR32MR21A (Rev C)|1.2.16|
|EFR32xG21A (Rev C)|1.2.16|
|EFR32xG23A|2.1.7|
|EFR32xG24A|2.1.7|
|EFR32xG25A|2.2.1|
|EFR32xG28A|2.2.2|

|**Series 2 MCU and Wireless SoC HSE - SVH**|**Shipped SE Firmware Version**|
|---|---|
|EFR32xG21B|1.2.13|
|EFR32xG21B (Rev C)|1.2.16|
|EFM32PG23B|2.1.7|
|EFR32xG23B|2.1.7|
|EFR32xG24B|2.1.7|
|EFR32xG25B|2.2.1|
|EFM32PG28B|2.2.2|
|EFR32xG28B|2.2.2|

|**Series 3 MCU and Wireless SoC HSE - SVH**|**Shipped SE Firmware Version**|
|---|---|
|SixG301|3.3.2|

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-trustzone/">Series 2 TrustZone</a></p>
            </td>
            <td>
                <p>Describes the basics of TrustZone, secure and privileged programming model, and shows how to upgrade existing application to TrustZone.</p>
            </td>
            <td>
                <p>Series 2 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

|**Document**|**Summary**|**Applicability**|
|---|---|---|
|[Programming Series 2 Devices Using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/)|How to provision and configure Series 2 devices through the DCI and how to program their internal flash memory through the SWD|Series 2|
|[Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS](https://docs.silabs.com/iot-security/latest/mbedtls-psa-crypto-porting-guide/)|How to integrate crypto functionality into applications using Silicon Labs implementation of PSA Crypto compared to Mbed TLS|Series 1, Series 2 and Series 3|

## Developer's Guide

### Silicon Labs IoT Security Developer's Guide

The IoT Security Developer's Guide offers detailed information on how to implement each of the device security features. This content is applicable to any protocol that supports the feature described. Additional protocol-specific information for Bluetooth, Bluetooth Mesh, OpenThread, and Zigbee is available in the [protocol-specific section](/iot-security/1.3.0/iot-security-protocol-specific).

- [**Series 2 and Series 3 Secure Debug**](/iot-security/1.3.0/series2-secure-debug): Explains the different debug lock and unlock features available in Series 2 and Series 3 devices and their capabilities.
- [**Series 2 Secure Boot with RTSL**](/iot-security/1.3.0/series2-secure-boot-with-rtsl): Describes the design of Secure Boot with RTSL (Root of Trust and Secure Loader) on Series 2 and Series 3 devices. It also provides examples of how to implement the Secure Boot process.
- [**Series 2 TrustZone**](/iot-security/1.3.0/series2-trustzone): Covers the basics of ARMv8-M TrustZone, describes how TrustZone is implemented on Series 2 devices, and provides application examples.
- [**Production Programming of Series 2 and Series 3 Devices**](/iot-security/1.3.0/prod-programming-series2-and-series3): Demonstrates how to properly program, provision, and configure Series 2 and Series 3 devices in a production environment.
- [**Anti-Tamper Protection Configuration and Use**](/iot-security/1.3.0/efr32-secure-vault-tamper): Describes how to program, provision, and configure the Secure Engine anti-tamper module. The anti-tamper module is only available on Secure Vault High and Series 3 Secure Vault devices.
- [**Authenticating Silicon Labs Devices using Device Certificates**](/iot-security/1.3.0/authenticating-devices-using-device-certificates):  
  Describes how to authenticate an EFR32 Series 2 device with Secure Vault, using secure device certificates and signatures.
- [**Secure Key Storage**](/iot-security/1.3.0/efr32-secure-key-storage): Explains how to securely "wrap" keys in EFR32 Series 2 devices with Secure Vault, so they can be stored in non-volatile storage.
- [**Programming Series 2 Devices Using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)**](/iot-security/1.3.0/efr32-dci-swd-programming): Describes how to provision and configure Series 2 devices through the DCI and SWD.
- [**Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS**](/iot-security/1.3.0/mbedtls-psa-crypto-porting-guide): Describes how to integrate crypto functionality into applications using PSA Crypto compared to Mbed TLS.

### SE Anti-Rollback OTP Bit Consumption

#### Introduction

Series 3 devices introduce the use of external flash, which requires special attention to maintain device security. Because external flash can be more susceptible to modification, it introduces new challenges to protecting sensitive information stored outside the device. The SE's Multiple Time Programmable (MTP) memory helps mitigate these risks by preventing security settings from being reverted to earlier, potentially less secure states.

The SE MTP is a memory region within the SE that records the completion of certain security-related operations. This ensures the device cannot be rolled back to a previous, less secure configuration. Each time the SE’s MTP is updated, its Anti-Rollback SE OTP bit counter increments, preventing the MTP from being restored to an earlier version.

#### End of Life (EOL) Lifecycle Phase

The SE OTP counter is at least 2 kB in size (~16k bits) and may be allowed to overflow into the next available SE OTP region if space permits. However, once all available OTP space is exhausted, the device enters an EOL (End of Life) state. This means any operation that would require the OTP counter to be incremented, including SE, Bootloader, or Application FW updates will not be able to be performed. A list of operations that consume SE OTP Bits is listed in the table below.

**Note**: Simplicity Commander will return a number of OTP bits consumed and remaining on devices through the command:

```sh
commander security otprollbackcount
```

```sh
Number of used OTP rollback bits: 9
Number of remaining OTP rollback bits: 65526
DONE
```

#### Reducing OTP Bit Consumption in Development Devices

The following commands prevent OTP bits from being consumed, but should be used in a development setting only. While these commands will slow the consumption of OTP bits in development devices, OTP consumption will still occur; therefore, OTP exhaustion remains possible even when these commands are used.

##### Closing a Code Region

When using Simplicity Commander, code regions are closed automatically when using the commander flash command. To avoid closing a code region when running this command, a user can specify the `--noclose` flag during flashing, which will leave the region open. This option is only intended for use to prevent exhaustion of OTP bits on development devices when continuous re-flashing is done.

```sh
commander flash example.hex --noclose -d sixg301
```

```sh
Parsing file example.hex...
Writing 168756 bytes starting at address 0x01000000
Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB)
Erasing range 0x01008000 - 0x010B7FFF (1 sector, 704 KB)
Programming range 0x01000000 - 0x01001FFF (8 KB)
...
Programming range 0x010B6000 - 0x010B7FFF (8 KB)
Flashing completed successfully!
DONE
```

**Note**: Closing a code region is a prerequisite for Secure Boot, as it enables the SE to access Region 0 to perform signature validation on the bootloader firmware. Therefore, on development devices with secure boot enabled, code regions must be closed in order for firmware to be executed by the SE.

##### Skip IV Rolling

In order to avoid resource exhaustion on development devices with AXiP or EXiP enabled, the transition to development command (also referred to as the Skip IV Roll command) can be used to issue a one-time command which will enforce the same IV to be used for the lifetime of the device. As this flag is enabled in OTP, this setting cannot be reversed once enabled. Devices with this option set must only be used for development purposes. Once Skip IV Rolling is enabled, devices should be considered nonsecure and should not enter production, as reusing IVs on devices in the field can introduce vulnerabilities which could lead to data confidentiality being impacted. When this option is not set, IVs will continue to be rolled on each flash erase, which will maintain security of the encrypted data. For more details on AXiP and EXiP, refer to [AN1509](https://www.silabs.com/documents/public/application-notes/an1509-series3-axip.pdf).

```sh
commander security transitiontodevelopment -d sixg301 
```

```sh
================================================================================
THIS IS A ONE-TIME command which permanently changes the security properties of the device.
Once done, the device permanently uses the same IV for encryption of flash, which is not
secure (using the same IV and same key can lead to exposure of the encrypted data).
This should only be enabled on development devices to prevent exhausting OTP rollback
bits after repeated flash/erase cycles.
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
The device has been permanently transitioned to NOT SECURE development mode
DONE
```

#### Sources of OTP Bit Consumption

SE OTP bits are consumed regardless of if these operations are implemented via a DCI command or a SE Manager API.

|Number of OTP Bits|Operation|Notes|
|---|---|---|
|1 bit|Erasing a Code Region|During an erase of a code region, the code region is opened and a new IV is generated, consuming one SE OTP bit per erased code region.<br/><br/>If an erase of a code region is performed during a "flash" procedure, more than 1 SE OTP bit may be consumed. For Commander 1.22.0 and earlier, if the region is larger than 128kB, the memory region will be erased in multiple 128kB partitions of memory, consuming one SE OTP bit per 128kB partition of memory that is erased. As of Commander 1.22.1, the maximum erase block size has been increased from 128 kB to 2 MB.<br/><br/>If the device has disabled IV rolling through the use of the commander `transitiontodevelopment` command, no SE OTP bits will be consumed during erase operations.|
|1 bit|Closing a Code Region|When the code region lockbit is enabled, indicating the code region is closed, one SE OTP bit is consumed. By default, commander will close a code region automatically as part of the flash command.<br/><br/>If the device uses the `--noclose` flag when flashing, this SE OTP bit will not be consumed and the region will remain open.|
|1 bit|Configuring Code Regions|Each time the code region configuration is updated, one SE OTP bit will be consumed. Code region configuration can only be done on open code regions. Any closed code regions must be opened before configuration can begin, which will incur SE OTP bit consumption due to opening/erasing the code regions.|
|3 bits total|SE Firmware Upgrade|Each time the SE Firmware upgrade process is initiated and completed, three total SE OTP bits will be consumed. One bit will be consumed when initiating the upgrade, one when rolling the IV for the region, and one when the upgrade is completed.<br/><br/>If the SE FW Upgrade Image is flashed directly to the device, overwriting other FW in user flash space, the flash space will need to be erased before reprogrammed, incurring the erase SE OTP bit consumption. If the SE FW Upgrade Image is OTA-ed, these additional erase steps do not apply.<br/><br/>**Note**: The number of SE OTP bits consumed during an SE FW upgrade may increase in the future, if necessary.|
|3 bits total|Host Firmware Upgrade (Second Stage Bootloader Upgrade)|Each time the Host Firmware upgrade process is initiated and completed, three total SE OTP bits will be consumed. One bit will be consumed when initiating the upgrade, one when rolling the IV for the region when AXiP or EXiP are enabled, and one when the upgrade is completed.|
|1 bit|Host Firmware Anti-Rollback Increment|When the Host Firmware version is incremented during a Host Firmware Upgrade or through directly flashing a bootloader image with a higher version, one SE OTP bit is consumed.<br/><br/>This only applies to devices with Secure Boot enabled.|
|1 bit|Disable Device Erase|Disabling device erase consumes one SE OTP Bit. This is a one time command, and cannot be disabled.|
|1 bit|Secure Debug Enable/Disable|Enabling or Disabling the Secure Debug feature consumes one SE OTP bit per operation.|
|1 bit|Secure Debug Lock|Applying a Secure Debug lock (where the device can only be unlocked using authorization) consumes one SE OTP bit.|
|1 bit|Write to User Data Space in SE MTP|Each write to user data space consumes one SE OTP bit. This user data space is the location within SE MTP.|
|1 bit|Write/Erase of Static Tokens|Each write or erase of a static token consumes one SE OTP bit per operation.<br/><br/>**Note**: Currently, a 100 write limit is placed on tokens. There is no separate counter to track the number of token writes performed.|
|1 bit|GBL Bundle Version Storage|Storing the [GBL bundle version](https://docs.silabs.com/bluetooth/latest/bootloader-user-guide-series3-and-higher/02-gecko-bootloader-file-format-v4#bundle-version) in SE MTP for rollback protection of GBL upgrade images consumes one SE OTP bit.|

### Series 2 and Series 3 Secure Debug

#### Series 2 and Series 3 Secure Debug

> **Note: This section replaces _AN1190: Series 2 and Series 3 Secure Debug_. Further updates to this application note will be provided here**.

To protect intellectual property and proprietary algorithms from malicious actors, it is important to lock the debug port. This prevents attackers from reading flash contents through the debug  interface  and  reverse  engineering  the application. However, there are situations where it becomes necessary to debug a device already deployed in the field. Silicon Labs Series 2 and 3 devices offer a feature called Secure Debug. This feature allows only authenticated users to unlock the debug port and securely debug the application.

This application note explains the different debug lock and unlock features available in Series 2 and Series 3 devices and their capabilities.

##### Key Points

- Basic overview of the Secure Engine
- Debug port access by Debug Challenge Interface (DCI) or Mailbox Interface
- Locking and unlocking features for Series 2 and Series 3 devices
- Examples for Public Command Key provisioning and Secure Debug Unlock

> **Note**: This application note covers both Series 2 and Series 3 devices. Unless explicitly stated otherwise, all items are applicable to both. If an item is not applicable to one of the series, it will be mentioned separately.

#### Series 2 and Series 3 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. 'Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. Series 3 devices further enhanced these capabilities, offering more advanced security features than their Series 2 counterparts. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based or virtual (software-based). Throughout this application note, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level**|**SE Support**|
|---|---|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|
|Secure Vault Mid (SVM)|HSE (HSE-SVM), VSE (VSE-SVM)|
|Secure Vault Base (SVB)|N/A|

**Notes**:

1. Series 3 devices have no secure vault Base and Mid devices. All devices are Secure Vault High.
2. Refer to [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/11-series-2-device-security-features) for details on supporting devices.

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug Access Control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High (SVH) offers additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper Protection**: A configurable module to protect the device against tamper attacks.
- **Device Authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products, Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Series 2 and Series 3 Secure Debug (this application note)</p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|
|Certificate Key (Used for generating Debug lock token)|Yes|Device authentication token which enabling debug lock port|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 and Series 3 devices and modules.

#### Introduction to Secure Debug

##### Debug Lock

All Silicon Labs Series 2 and Series 3 devices have the capability to lock debug access to the device. This prevents attackers from using the debug interface to perform the following illegal operations:

- Reprogramming the device
- Interrogating the device
- Interfering with the operation of the device

A fairly standard practice during the board-level test in production is to program, test, and lock the parts. Three different locks can be enabled on debug interface:

- Standard debug lock
- Secure debug lock
- Permanent debug lock

Silicon Labs provides Custom Part Manufacturing Service (CPMS) to securely configure the debug port of the chip to one of the three possible locks before the devices leave the factory.

##### Debug Unlock

Users need to unlock parts under a number of circumstances:

- Code development
- Field failure diagnosis
- Product field service
- Existing inventory reprogramming

Two different unlocks can run on debug interface:

- Standard debug unlock
- Secure debug unlock

#### Secure Engine Subsystem

##### Overview

The HSE refers to a separate security co-processor that provides hardware isolation between security functions and the host processor.

The VSE refers to a collection of security functions available to the host processor in Root mode if a separate security co-processor is not provided.

The SE is used to perform a series of cryptographic operations and other secure system operations as described in the following table.

|**Operation**|**VSE-SVM**|**HSE-SVM**|**HSE-SVH**|**Description**|
|---|---|---|---|---|
|Unique ID|Y|Y|Y|Software can identify every device.|
|Secure Boot with RTSL|Y|Y|Y|Only boot authenticated firmware.|
|Secure Debug|Y|Y|Y|Securely lock/unlock debug ports using authorized tokens|
|Crypto Engine (1)|Y|Y|Y|Up to 256-bit ciphers and elliptic curves.|
|TRNG (1)|Y|Y|Y|Generate keys for cryptography.|
|DPA Countermeasures|—|Y|Y|Resist side channel attacks.|
|Secure Key Storage|—|—|Y|Protected by PUF technology.|
|Secure Key Management|—|—|Y|Isolate encrypted keys from application code.|
|Secure Attestation|—|—|Y|Ensure integrity and authenticity.|
|Anti-Tamper|—|—|Y|Detect tamper and protect keys/data.|
|Advanced Crypto|—|—|Y|Up to 512-bit ciphers and P-521-bit elliptic curves.|

**Note**:

1. On VSE-SVM devices, the crypto engine and TRNG (True Random Number Generator) are implemented by the CRYPTOACC (Cryptographic Accelerator) peripheral.

To start using the secure debug unlock functionality, the device needs to be provisioned. These steps include writing one time programmable (OTP) settings to the SE to determine which functionality is enabled, and uploading the Public Command Key to validate a secure debug attempt.

This application note describes how different device debug locks and unlocks are implemented through the SE on Series 2 and Series 3 devices.

The secure debug feature is implemented by Root code executed by the HSE Core. For VSE devices secure debug feature is implemented by Cortex-M33 operating in Root mode.

Silicon Labs strongly recommends installing the latest SE firmware to support the required security features. The latest SE firmware image (`.seu` and `.hex`) and release notes can be found in the Windows folder mentioned below.

`C:\Users\\<userName\>\SimplicityStudio\SDKs\Simplicity_sdk\util\se_release\public`

##### Command Interface

Interaction with the SE is performed over a command interface. The command interface is available through a dedicated Debug Challenge Interface (DCI) as well as through a mailbox interface from the Cortex-M33.

Some commands may not be available at all times and may not be accessible over both interfaces. The DCI typically only contains operations for setting up a new device and for locking it down (meant for production processes), while the mailbox interface also contains commands to support cryptographic operations in HSE.

###### Mailbox

The SE Manager Mailbox Interface is a mechanism used on Silicon Labs Series 2 and Series 3 devices to communicate with the Secure Engine (SE) for cryptographic and security operations. The mailbox interface allows the host processor (such as Cortex-M33) to send commands to the SE, typically for secure key storage, cryptographic operations, device provisioning, and secure identity management.

Secure Engine Manager (SE Manager) provides an abstraction of the Secure Engine's command set. The SE Manager also provides APIs for cryptographic operations and thread synchronization.

![SE Manager Mailbox interface](/series2-secure-debug/0.3/images/sld714-image17.png)

###### Debug Challenge Interface (DCI)

The Debug Challenge Interface (DCI) is made available through commands in Simplicity Studio and Simplicity Commander. This is the easiest way to access and set up the different security options.

For more information about DCI, see [Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/).

#### Debug Lock

##### Overview

The debug access port connected to the Series 2 and Series 3 device's Cortex-M33 processor can be closed by issuing commands to the SE, either from a debugger over DCI or through the mailbox interface. Three properties govern the behavior of the debug lock.

|**Property**|**Description If Set**|**Default Value**|
|---|---|---|
|Debug Lock|The debug port is kept locked on boot.|Disabled|
|Device Erase|The Erase Device command is available.|Enabled|
|Secure Debug|Secure debug unlock is available.|Disabled|

The following sections describe how to interact with these properties and how to enable debug locks using the SE command interface over DCI. The status of the debug lock can be inspected using the [Read Lock Status](#debug-lock-command-reference) command.

##### Standard Debug Unlock

The device is in standard debug unlock state if the debug lock properties are set to the default values.

|**Debug Lock**|**Device Erase**|**Secure Debug**|**Description**|
|---|---|---|---|
|Disabled|Enabled|Disabled|All debug operations are allowed.|

##### Standard Debug Lock

With the default properties in the table above, the device can be locked using the [Apply Lock](#debug-lock-command-reference) command. The typical flow for this configuration is simply to issue the Apply Lock command after the device has been programmed, either using a DCI command from the programming debugger or through the mailbox interface.

|**Debug Lock**|**Device Erase**|**Secure Debug**|**Description**|
|---|---|---|---|
|Enabled|Enabled|Disabled|The Erase Device command will wipe the main flash and RAM, and then a reset will yield an unlocked device.|

The standard debug lock disables debug access port, but issuing a device erase wipes the device and enables the debug port again.

##### Secure Debug Lock

For secure debug lock, the debug interface can temporarily be unlocked by answering a challenge, if the Secure debug property is enabled before locking.

|**Debug Lock**|**Device Erase**|**Secure Debug**|**Description**|
|---|---|---|---|
|Enabled|Disabled (2)|Enabled (1)|Secure debug lock is enabled, which makes it possible to securely open the debug lock temporarily to reprogram or debug a locked device.|

**Notes**:

1. Secure debug lock is enabled in two steps before the debug lock is enabled:  
   1. Install the Public Command Key using Simplicity Studio, Simplicity Commander, or directly through the SE Manager API.  
   2. Enable secure debug using Simplicity Studio, Simplicity Commander, or directly through the SE Manager APIs.
2. Disable the device erase using Simplicity Studio or Simplicity Commander or directly through the SE Manager API. This is an **Irreversible** action and should be disabled **After** the secure debug is enabled.
3. The **Device Erase** option should **Disabled** only during production. If this setting is applied during development, it prevents the device from being re-flashed with new firmware using a debugger and significantly hinders debugging efforts.

##### Secure Debug Unlock

To enable debugging or to reprogram the device, the debug port is temporarily opened. It automatically closes upon a power-on reset or device reset, and the device returns to the Secure Debug Lock state.

|**Debug Lock**|**Device Erase**|**Secure Debug**|**Description**|
|---|---|---|---|
|Enabled|Disabled|Enabled|Device debug port remains unlocked, till power on rest or device rest is performed.|

##### Permanent Debug Lock

The device can enter into **Permanent Debug Lock** state when both the **Device Erase** and **Secure Debug** properties are disabled.

|**Debug Lock**|**Device Erase**|**Secure Debug**|**Description**|
|---|---|---|---|
|Enabled|Disabled|Disabled|The part cannot be unlocked. Devices with Permanent Debug Lock engaged cannot be returned for failure analysis.|

##### Debug Lock State Transition

The following figure describes the transitions between different debug lock states.

![Debug Lock State Transition](/series2-secure-debug/0.3/images/sld714-debug-lock-state-transition.png)

1. Standard debug unlock can transit to **Standard Debug Lock** state, by enabling '**Debug Lock**' flag.
2. Standard debug lock can revert to **Standard debug unlock** via an erasedevice/device unlock command (erases the main flash and RAM). After the device is reset, the debug port remains unlocked until it is explicitly locked again.
3. Device can transit to **Secure Debug lock** state by enabling Secure Debug property.
4. Secure debug lock can use Debug Unlock Token to temporary transit to secure debug unlock, which does not erase the main flash and RAM but enables debug operations. The device reverts to the secure debug lock through a power on or pin reset.

5,6,7. From any state, device can transit to Permanent Debug lock by Disabling **Device erase** and **Secure debug**. This is terminal state and can not transit to any other state. This should be done only after development is completed.

> **Note**: Device can be brought back to "**Standard Debug unlock**" state from "**Secure Debug Lock**" state by erasedevice command, if **Device Erase** is Enabled. So, customerrs are strongly advised to disable "**Device erase**" during production. Failing to do so can expose the device to security risks, as adversaries could reprogram it with unauthorized or potentially malicious firmware.

##### Debug Lock Command Reference

The commands for debug lock are described in the following table.

|**DCI Command (1)**|**Mailbox (SE Manager) API (2)**|**Description**|**Availability**|
|---|---|---|---|
|Apply Lock|sl_se_apply_debug_lock|Enables the debug lock for the part.|While debug is unlocked.|
|Read Lock Status|sl_se_get_debug_lock_status|Returns the current debug lock status and con-figuration.|Always.|
|Disable Device Erase|sl_se_disable_device_erase|Disables the Erase Device command. This command does not lock the debug interface to the part, but it is an IRREVERSIBLE action for the part.|Always.|
|Disable Secure Debug|sl_se_disable_secure_debug|Disables the secure debug functionality that can be used to open a locked debug port.|While secure debug is enabled.|
|Enable Secure Debug|sl_se_enable_secure_debug|Enables the secure debug functionality that can be used to open a locked debug port.|While debug is unlocked and Public Command Key is provisioned.|
|Set debug options|sl_se_set_debug_options|Configures the TrustZone access permissions of the debug interface. (3)|While debug is unlocked.|
|Init Pub Key|sl_se_init_otp_key|Used to provision a single public key during device initialization. The public key cannot be changed once written, and the command will be unavailable for that key.|Available once for each key.|
|Read Pub Key|sl_se_read_pubkey|Reads the stored public key.|Always.|
|Get Challenge|sl_se_roll_challenge|Used to roll the current challenge value (16 bytes) to revoke secure debug access. (4)|While Public Command Key is uploaded.|

**Notes**:

1. Performing these commands over DCI is implemented in Simplicity Studio and Simplicity Commander.
2. The `sl_se_apply_debug_lock`, `sl_se_get_debug_lock_status`, `sl_se_init_otp_key`, and `sl_se_read_pubkey` are available on all Series 2 and Series 3 devices. Other APIs are only available on HSE and Series 3 devices. The SE Manager API document can be found at [https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager](https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager).
3. For more information about debug options, see [TrustZone Debug Authentication](05-debug-unlock#trustzone-debug-authentication).
4. A new challenge will only be generated if the current one has been successfully used at least once. On Series 2 devices, there is no limitation on rolling a challenge. However, on Series 3 devices, challenge rolls are restricted to a maximum of 128. Once a user has rolled the challenge 128 times on a Series 3 device, no further rolls are allowed—but the user can still unlock the device using the last generated challenge.

#### Debug Unlock

##### Overview

The debug access port connected to the device's Cortex-M33 processor can be opened by issuing commands to the SE, either from a debugger over DCI or through the mailbox interface.

When secure debug unlock functionality is enabled, it is possible to request a challenge from the device and, by answering the challenge, debug lock can be disabled until the next power-on or reset.

The status of the debug lock can be inspected using the [Read Lock Status](04-debug-lock#debug-lock-command-reference) command.

##### Standard Debug Unlock

With the properties of the [standard debug lock](04-debug-lock#standard-debug-lock) with Device Erase enabled, the device can be returned to the standard debug unlock state using the Erase Device command. This command will wipe the main flash and RAM and verify they are empty before opening the debug lock. It will not wipe user data (USERDATA section of Flash) and provisioned SE settings.

![Standard Debug Unlock](/series2-secure-debug/0.3/images/sld714-standard-debug-unlock.png)

##### Secure Debug Unlock

In a secure debug unlock setup, the customer owns a private key and installs a matching public key into the device. This public key checks a certificate that shows what actions the customer allows either for themselves or someone they trust. For example, they might allow only the debug port on a Cortex-M33 to be unlocked, or only certain tamper signals to be restored on HSE-SVH devices.

This method is very helpful during failure analysis because it lets the device be unlocked without erasing the data in flash or RAM.

> **Note**: Enabling secure debug lock, without writing command public key into the device key, will cause the device to be permanently locked and cannot be debugged and even cannot be reprogrammed.

###### Secure Debug Lock/Unlock Flow

The secure debug was designed with three organizations in mind:

- Direct Customer to whom Silicon Labs sells the chip. This chip has the Public Command Key installed in the SE OTP.
- That Direct Customer may be creating a white-labeled product for another company or a sub-component that goes into another company’s product. The Product Company is the customer of the direct customer.
- The Debug 3rd Party could be anyone, internal or external, that the Product Company decides is qualified to debug the device.

Because the Public Command Key is installed into the SE OTP of a large number of devices and cannot be changed, the corresponding Private Command Key should be stored securely in HSM. If this Private Command Key is ever leaked, all the devices programmed with the corresponding Public Command Key will be compromised.

A secure debug unlock use case is described in the following figure. The secure debug unlock flow moves across the time axis from left to right.

![image](/series2-secure-debug/0.3/images/sld714-image32.png)

![image](/series2-secure-debug/0.3/images/sld714-debug-unlock-token-contents.png)

1. The Product Company creates a Private/Public Certificate Key pair for each device. Because the key pair is assigned only to a single device the company may not need to protect the Private Certificate key as securely as the Private Command key by the direct customer.
2. The Public Certificate Key (cert_pubkey.pem) for each device is passed to the Silicon Labs Direct Customer. The part number and serial number are also required if Direct Customer cannot access the device.
3. The Direct Customer then places that Public Certificate Key in the access certificate. The access certificate is per-device because it contains the unique device serial number. This certificate is generated once upon creation of the device, and thereafter, is generally only modified when the Private/Public Certificate Key pair is changed by the Product Company.
4. The Access certificate should be signed by Private Command key.
5. The access certificate is passed to the Product Company. The purpose of the access certificate is to grant overall debug access capabilities to the Product Company and authorize them to allow third parties to debug the device. The Product Company can now use the access certificate to generate the Debug Unlock Token. The same access certificate can be used to generate as many Debug Unlock Tokens as necessary without having to ever go back to the Direct Customer.
6. To create the Debug Unlock Token, a debug session must be started with the device and the challenge value (which is a random number) should be read out to generate the challenge response.
7. The challenge response is then cryptographically hashed (SHA-256) to create a digest. The digest is then signed by the Private Certificate Key to generate the debug access command signature.
8. Generate Debug Unlock Token, using access certificate and debug access command signature generated in above steps.
9. **(Alternative)** The key protection is not required if the Private Certificate Key is ephemeral. In such case steps 6 to 8 can be skipped and Debug Unlock Token can be directly generated with the access certificate from direct customer's Private Certificate key.
10. The Debug Unlock Token and the device are now delivered to the Debug 3rd Party.
11. The device compares the Debug Unlock Token contents with its internal serial number, challenge value, and Public Command Key to determine the token’s authenticity. If authentic, it will execute the debug access command to unlock the device; otherwise, it will ignore the command.
12. The Debug 3rd Party can now use this same Debug Unlock Token to unlock the device (step 11), over and over again after each power on or reset, until they have finished debugging the device.
13. Once the Debug 3rd Party has finished debugging, they will send the device back to the Product Company. After receiving the device product company has to invalidate the debug key, so that it should not be misused. To do so product company has to start debug session and should roll the challenge and put the device back into secure debug lock state. Rolling the challenge will effectively invalidate any Debug Unlock Token that has been previously given to any third party.

> **Note**: Direct customer can use the Private Command Key on the connected chip to generate the Debug Unlock Token within the Security Store. However, this method carries a significant risk, as it bypasses the use of an HSM(Hardware Security Module), potentially exposing the Private Command Key to third parties.

###### Debug Unlock Token

The elements of the Debug Unlock Token are described in the following figure and tables.

![image](/series2-secure-debug/0.3/images/sld714-debug-unlock-token.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Debug access command|0xfd010001|The command word of the Debug Unlock Token.|
|Debug mode request|Device dependent|The command parameter of the debug access command.|
|Access certificate (1)|Device dependent|See section Access Certificate.|
|Debug access command signature (1)|Device dependent|See section Challenge Response.|

**Note**:

1. The debug access command payload consists of an access certificate and a debug access command signature.

![Debug Mode Request](/series2-secure-debug/0.3/images/sld714-image35.jpg)

**Notes**:

- Enable debug port - Debug port enabled if set.
- [DBGLOCK](#trustzone-debug-authentication) (Non-secure, Invasive debug lock): The Invasive debug features for the Non-secure state are unlocked if set.
- [NIDLOCK](#trustzone-debug-authentication) (Non-secure, Non-invasive debug lock): The Non-invasive debug features for the Non-secure state are unlocked if set.
- [SPIDLOCK](#figure-54-debug-mode-request) (Secure, Invasive debug lock): The Invasive debug features for the Secure state are unlocked if set.
- [SPNIDLOCK](#figure-54-debug-mode-request) (Secure, Non-Invasive debug lock): The Non-invasive debug features for the Secure state are unlocked if set.
- All reserved bits should be 0, and bit 1 must be 1 to access the debug port.
- For the TrustZone-unaware debugging, bits 2 to 5 are irrelevant, so bits 1 to 5 are usually set (`0x0000003e`) to match with the [Authorizations](#access-certificate) in the access certificate.
- For the TrustZone-aware debugging, bits 2 to 5 are relevant. Refer to [TrustZone Debug Authentication](#trustzone-debug-authentication) for details about these debug options.

###### Access Certificate

The elements of the access certificate are described in the following figures and table.

![Access Certificate](/series2-secure-debug/0.3/images/sld714-access-certificate.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Magic word|0xe5ecce01|A constant value used to identify the access certificate.|
|Authorizations|0x0000003e (1)|A value used to authorize which bit in the debug mode request can be enabled for secure debug.|
|Tamper Authorizations|0x00000000 or 0xffffffb6 (2)|A value used to authorize which bit in the tamper disable mask can be set to disable the tamper response.|
|Serial number|Device dependent|A number used to compare against the on-chip serial number for secure debug or tamper disable.|
|Public Certificate Key (3)|Device dependent|The public key corresponding to the Private Certificate Key (3) used to generate the signature (ECDSA-P256-SHA256) in a challenge response.|
|Access certificate signature|Device dependent|All the content above is signed (ECDSA-P256-SHA256) by the Private Command Key corresponding to the Public Command Key in the SE OTP.|

**Notes**:

1. This value allows all debug options to be reset for secure debug.
2. Value that sets available bits in the tamper disable mask for tamper disable (HSE-SVH device only).
3. The Private/Public Certificate Key is a randomly generated key pair. It can be ephemeral or retainable.

The Private Certificate Key can be used repeatedly to generate the signature in a challenge response on one device until the Private/ Public Certificate Key pair is discarded. This can reduce the frequency of access to the Private Command Key, allowing more restrictive access control on that key.

For more information about tamper disable, see [Anti-Tamper Protection Configuration and Use](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/).

![image](/series2-secure-debug/0.3/images/sld714-image36.jpg)

**Notes**:

- Set the bit to enable the corresponding bit in the debug mode request.
- The Debug Unlock Token will reset the corresponding debug option if the same bit is set in Debug mode request and Authorizations.

###### Challenge Response

The elements of the challenge response are described in the following figure and table.

![Challenge Response](/series2-secure-debug/0.3/images/sld714-challenge-response.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Debug access command|0xfd010001|The command word of the Debug Unlock Token.|
|Debug mode request|Device dependent|The command parameter of the debug access command.|
|Challenge|Device dependent (1)|A random value generated by the SE.|
|Debug access command signature|Device dependent (2)|All the content above is signed (ECDSA-P256-SHA256) by the Private Certificate Key corresponding to the Public Certificate Key in the access certificate.|

**Notes**:

1. The challenge remains unchanged until it is updated to a new random value by rolling the challenge. The Private Certificate Key can be reused for signing when the device challenge is refreshed.
2. This signature is the final argument of the Debug Unlock Token.

###### Debug Access Flow

The debug access flow is described in the following figure.

![Debug Access Flow](/series2-secure-debug/0.3/images/sld714-debug-access-flow.png)

1. Get the serial number and challenge from the SE.
2. Generate the access certificate with the device serial number.
3. Generate the challenge response with device challenge.
4. Generate the debug access command payload with access certificate and debug access command signature.
5. Send the Debug Unlock Token to the SE.
6. Verify the debug access command signature using the Public Certificate Key in the access certificate.
7. Verify the serial number and the access certificate signature using the on-chip serial number and Public Command Key in the SE OTP.
8. Authorize the debug mode request to reset the debug options until the next power-on or pin reset.
9. Roll the challenge to invalidate the current Debug Unlock Token.

###### TrustZone Debug Authentication

The debug and trace support in the Cortex-M33 devices are based on the [CoreSight](https://developer.arm.com/documentation/ihi0029/f?lang=en) architecture, which can be classified into Invasive and Non-invasive debugging features as described in the following table.

|**Classification**|**Debug and Trace Features**|**Description**|
|---|---|---|
|Invasive|Core debug (e.g., single stepping), Breakpoints, Data watchpoints, Halt mode debugging|These features halt the Cortex-M33 core and change the program execution flow.|
|Non-invasive|Embedded Trace Macrocell (ETM), Micro Trace Buffer (MTB), Data trace, Instrumentation Trace Macrocell (ITM), Profiling|These features have a minor or no impact on the program execution flow.|

The separation of Invasive and Non-invasive debug and trace operations in CoreSight architecture can apply to TrustZone debug authentication, which defines the permission levels of the debug and trace features on Secure and Non-secure worlds.

The table below describes four debug options in SE to support TrustZone debug authentication. It is possible to restrict the TrustZone access permissions of the debug interface by setting one or more of the following options.

|**Debug Option**|**Description**|
|---|---|
|DBGLOCK|Non-secure, Invasive debug lock. If this bit is set, the Invasive debug features for the Non-secure state are locked.|
|NIDLOCK|Non-secure, Non-invasive debug lock. If this bit is set, the Non-invasive debug features for the Non-secure state are locked.|
|SPIDLOCK|Secure, Invasive debug lock. If this bit is set, the Invasive debug features for the Secure state are locked.|
|SPNIDLOCK|Secure, Non-invasive debug lock. If this bit is set, the Non-invasive debug features for the Secure state are locked.|

**Notes**:

- Use [Simplicity Commander](07-examples#examples-secure-debug-lock-using-commander-tool) or the SE Manager API to set the debug options.
- The state of the debug options is stored permanently in SE and can only be reset to the default value (0000) through the [Erase Device](#debug-unlock-command-reference) command (if enabled).
- A secure debug lock device [Device Erase](04-debug-lock#secure-debug-unlock) was disabled can only use the Debug Unlock Token to temporarily unlock (reset) the debug options to debug the Secure and Non-secure applications.

The following conditions are recommended (1, 2, and 3) or mandatory (4) when setting up the debug options for secure debug unlock.

1. If SPIDLOCK is unlocked, then DBGLOCK should also be unlocked.
2. If SPNIDLOCK is unlocked, then NIDLOCK should also be unlocked.
3. If DBGLOCK is unlocked, the NIDLOCK should also be unlocked.
4. If SPIDLOCK is unlocked, then SPNIDLOCK is automatically unlocked. The following table lists the recommended combinations of debug options.

|**SPNIDLOCK**|**SPIDLOCK**|**NIDLOCK**|**DBGLOCK**|**Description**|
|---|---|---|---|---|
|0|0|0|0|Allows all debug and trace features for both the Secure and the Non-secure world (default setting).|
|0|1|0|0|Only allows a Non-invasive debug in the Secure world. Allows both Invasive and Non-invasive debugs in the Non-secure world.|
|0|1|0|1|Only allows a Non-invasive debug in the Secure and the Non-secure world.|
|1|1|0|0|Only allows debug and trace features in the Non-secure world.|
|1|1|0|1|Only allows a Non-invasive debug in the Non-secure world.|
|1|1|1|1|All debug and trace features are disabled.|

**Notes**:

- [Trace Point Interface Unit (TPIU) registers' access fault](https://developer.arm.com/documentation/ka005320/latest) will occur and lock the processor in a security assertion if both NIDLOCK and DBGLOCK in debug option are set (xx11). The device will be unrecoverable if it is in the permanent debug lock state.
- The workaround is to avoid using the xx11 debug option or avoid accessing the TPIU registers and upgrade to SE firmware **≥ v1.2.14** (xG21 and xG22) or **≥ v2.2.1** (other Series 2 and all Series 3 devices) so that the debug options cannot be modified after the device is locked.

The highly recommended setting of debug options is to allow debugging in the Non-secure world while, at the same time, disabling debugging for the Secure world (1100).

- Secure memories (flash and RAM) are not accessible by the debugger.
- All debug access is blocked from accessing Secure addresses.
- The debugger will ignore the vector-catch events generated by the Secure exceptions.
- Trace sources (e.g., ETM) will stop generating instruction/data trace packets when the Cortex-M33 is in a Secure state.
- The debugger can neither halt a Secure application (e.g., breakpoint) nor single step into it.
- The Cortex-M33 will not stop when stepping into the Secure application until it returns to the Non-secure state.

The figure below describes the debug scenario of debug options with `1100` configuration.

![image](/series2-secure-debug/0.3/images/sld714-image67.jpg)

The following examples describe the relationship between **debug options** and **debug mode request** when performing a secure debug unlock on Series 2 devices.

**Example 1: All debug and trace features for both the Secure and the Non-secure world are allowed (0000)**

|**Debug Options**|**Authorizations**|**Debug Mode Request**|**Debug options after Secure Debug Unlock**|**Description**|
|---|---|---|---|---|
|0000|00|1111|10|00|xxxx|10|0000|No action|

**Example 2: Only debug and trace features in the Non-secure world are allowed (1100)**

|**Debug Options**|**Authorizations**|**Debug Mode Request**|**Debug options after Secure Debug Unlock**|**Description**|
|---|---|---|---|---|
|1100|00|1111|10|00|00xx|10|1100|No action|
|1100|00|1111|10|00|10xx|10|0100|Unlock SPNIDLOCK|
|1100|00|1111|10|00|01xx|10 or 00|11xx|10|0000 (reset SPIDLOCK will automatically unlock SPNIDLOCK)|Unlock SPNIDLOCK and SPIDLOCK|

**Notes**:

- The bit order of debug options are SPNIDLOCK (MSB), SPIDLOCK, NIDLOCK, and DBGLOCK (LSB).
- Debug options : 0 = Unlocked, 1 = Locked
- Authorizations in the access certificate: 0 = Disable, 1 = Enable
- The authorizations in the access certificate are usually set to 00|1111|10 (0x3e), so the corresponding debug options (bits 2 to 5) can be reset (unlocked) by debug mode request during secure debug unlock.
- Debug mode request (bits 2 to 5) in the Debug Unlock Token:  
  - 0 = No action on the corresponding debug option if it was locked (i.e., 1)  
  - 1 = Reset (unlock) the corresponding debug option from 1 to 0 if it was locked (i.e., 1)  
  - x = No action (either 0 or 1) on the corresponding debug option if it was unlocked (i.e., 0)
- Debug options return to the original state after power-on or pin reset.

##### Debug Unlock Command Reference

The commands for debug unlock are described in the following table.

|**DCI Command (1)**|**Mailbox (SE Manager) API (2)**|**Description**|**Availability**|
|---|---|---|---|
|Erase Device|sl_se_erase_device|Performs a device mass erase and resets the debug configuration to its initial unlocked state.|While Device Erase is enabled.|
|Read Serial Number|sl_se_get_serialnumber|Reads out the serial number (16 bytes) of the Series 2 device.|Always.|
|Get Challenge|sl_se_get_challenge|Reads out the current challenge value (16 bytes) for Secure debug unlock.|While Public Command key is uploaded.|
|Debug Access|sl_se_open_debug|Opens the secure debug access of the Cortex-M33.|Only when Secure Debug is enabled.|

**Notes**:

1. Performing these commands over DCI is implemented in Simplicity Studio and Simplicity Commander.
2. These APIs are only available on HSE devices. The SE Manager API document can be found at [https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager](https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager).

#### Precautions

##### Device Erase for Secure Debug

Disabling the Device Erase is mandatory for secure debug as described in the following table.

<table>
    <thead>
        <tr>
            <th>Device Erase</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Enabled</td>
            <td>By using <code>erasedevice</code> command, entire Flash contents can be erased, except OTP and Userdata contents. If<code>security erasedevice </code> is enabled on production devices, it may expose the device to significant security risks, as malicious actors could potentially reprogram it with unauthorized or malicious firmware.</td>
        </tr>
        <tr>
            <td>Disabled</td>
            <td>
                <ul>
                    <li>Disable device erase command disables the use of the commander security erasedevice command. This will prevent the clearing of the debug lock and secure debug configurations.</li>
                    <li>If <strong>secure Debug</strong> is enabled and <strong> Device Erase </strong> is disabled, device allows only authorized parties to debug the device.</li>
                    <li>If secure boot is also enabled boot loader will accept only authenticated (signed) firmware image, thereby ensures authenticity and integrity of the firmware.</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

1. Advised not to disable **Device Erase** during development phase as it is one time operation.
2. Without enabling **Secure Debug** disabling **Device Erase** will make the device permanently not usable.

Run the `security disabledeviceerase` command to disable **Device Erase**.

```sh
commander security disabledeviceerase --device sixg301 --serialno 440326972
```

```sh
================================================================================
THIS IS A ONE-TIME command which Permanently disables device erase.
If secure debug lock has not been set, there is no way to regain debug access to this device. Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
Disabled device erase successfully
DONE
```

##### Secure Boot and Debug Lock

The following table describes the different debug lock scenarios on the secure boot-enabled device.

|**Secure Debug**|**Device Erase**|**Debug Lock**|**State**|**Recover from Secure Boot Failure**|
|---|---|---|---|---|
|Disabled|Enabled|Disabled|Standard debug unlock|Flash a correctly signed image.|
|Disabled|Enabled|Enabled|Standard debug lock|Flash a correctly signed image after standard debug unlocking the device.|
|Disabled|Disabled|Enabled|Permanent debug lock|There is no way to recover the device. Make sure the programmed image is correctly signed before locking the device.|
|Enabled|Disabled|Enabled|Secure debug lock|Flash a correctly signed image after secure debug unlocking the device.|

**Note**: See _Recover Devices when Secure Boot Fails_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) to flash a correctly signed image on different debug lock scenarios.

##### Limitation on Roll Challenge

On Series 2 devices, challenge can be rolled any number of times, whereas on Series 3, challenge can be rolled a maximum of 128 times.
Once a user has reached the 128 number of maximum rolls for debug challenges, new challenges will no longer be generated. The user will be able to continue to unlock the device using the last generated challenge..

#### Examples

##### Using Commander tool

###### Standard Debug Lock/Unlock using Simplicity Commander

This application note uses Simplicity Commander v1.19.2. The procedures and console output may be different for the other versions of Simplicity Commander. The latest version of Simplicity Commander can be downloaded from silabs.com.

```sh
commander --version
```

```sh
Simplicity Commander 1v19p2b1907

JLink DLL version: 8.44
Qt 5.15.2 Copyright (C) 2017 The Qt Company Ltd.
EMDLL Version: 0v19p19b793 mbed TLS version: 2.16.6

Emulator found with SN=440328778 USBAddr=0

DONE
```

For more information about Simplicity Commander, see [Simplicity Commander Reference Guide](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/).

1. Run the security status command to get the selected device configuration.  
   ```sh  
   commander security status --device sixg301 --serialno 440328778  
   ```  
   ```sh  
   SE ROM version          : 5.3  
   SE Firmware version     : 3.3.2  
   Serial number           : 0000000000000000781c9dfffe58959e  
   Debug lock              : Disabled  
   Device erase            : Enabled  
   Secure debug unlock     : Disabled  
   Tamper status           : OK  
   Secure boot             : Disabled  
   Boot status             : 0x20 - OK  
   Command key installed   : False  
   Sign key installed      : False  
   Security state          : Production  
   DONE  
   ```
2. Run the security lock command to lock the selected device.  
   ```sh  
   commander security lock --device sixg301 --serialno 440328778  
   ```  
   ```sh  
   WARNING: Secure debug unlock is disabled. Only way to regain debug access is to run a device erase.  
   Device is now locked.  
   DONE  
   ```
3. Run the security lock command to lock the selected device.  
   ```sh  
   commander security status --device sixg301 --serialno 440328778  
   ```  
   ```sh  
   SE ROM version        : 5.3  
   SE Firmware version   : 3.3.2  
   Serial number         : 0000000000000000781c9dfffe58959e  
   Debug lock            : Enabled  
   Device erase          : Enabled  
   Secure debug unlock   : Disabled  
   Tamper status         : OK  
   Secure boot           : Disabled  
   Boot status           : 0x20 - OK  
   Command key installed : False  
   Sign key installed    : False  
   Security state        : Production  
   DONE  
   ```
4. Run the `security erasedevice` command to unlock the selected device.  
   ```sh  
   commander security erasedevice --device sixg301 --serialno 440328778  
   ```  
   ```sh  
   Successfully erased device  
   DONE  
   ```  
   > **Note**: Issue a power-on or pin reset to complete the unlock process.
5. Run the `security status` command again to check the device configuration.

```sh
commander security status --device sixg301 --serialno 440328778
```

```sh
SE ROM version          : 5.3
SE Firmware version     : 3.3.2
Serial number           : 0000000000000000781c9dfffe58959e
Debug lock              : Disabled
Device erase            : Enabled
Secure debug unlock     : Disabled
Tamper status           : OK
Secure boot             : Disabled
Boot status             : 0x20 - OK
Command key installed   : False
Sign key installed      : False
Security state          : Production
DONE
```

###### Secure Debug Lock Using Commander Tool

1. Run the `security status` command to get the selected device configuration.  
   ```sh  
   commander security status --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   commander security status --device sixg301 --serialno 440326972  
   ---------------------------------------------------------------  
   SE ROM version          : 5.3  
   SE Firmware version     : 3.3.2  
   Serial number           : 0000000000000000781c9dfffe589591  
   Debug lock              : Disabled  
   Device erase            : Enabled  
   Secure debug unlock     : Disabled  
   Tamper status           : OK  
   Secure boot             : Disabled  
   Boot status             : 0x20 - OK  
   Command key installed   : False  
   Sign key installed      : False  
   Security state          : Production  
   DONE  
   ```
2. Run `util genkey` to generate commander private/public key pair.  
   ```sh  
   commander util genkey --type ecc-p256 --privkey command_key.pem --pubkey command_pubkey.pem  
   ```  
   ```sh  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to command_key.pem  
   Writing public key file in PEM format to command_pubkey.pem  
   DONE  
   ```
3. Run the `security writekey` command to provision the Public Command Key (e.g., `command_pubkey.pem`).  
   ```sh  
   commander security writekey --command command_pubkey.pem --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Device has serial number 0000000000000000781c9dfffe589591  
     
   ================================================================================  
   Please look through any warnings before proceeding.  
   THIS IS A ONE-TIME command which permanently ties debug and tamper access to certificates signed by this key.  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   Command public key stored in: C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/ device_0000000000000000781c9dfffe589591/command_pubkey.pem  
   DONE  
   ```  
   > **Note**: The Public Command Key cannot be changed once written.
4. This step is optional. To verify the public command key written into the device's SE OTP, run the `security readkey` command.  
   ```sh  
   commander security readkey --command --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   50DF50A09242A49F53251xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE6E81C6  
   B3B891B1B9DBFC3D5F2D0yyyyy435DA6E8AFAF60037DA21AD7B2E1  
   DONE  
   ```
5. Run the `security lockconfig` command to enable the secure debug.  
   ```sh  
   commander security lockconfig --secure-debug-unlock enable --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Secure debug unlock was enabled  
   DONE  
   ```
6. a. For the **TrustZone-unaware** application, run the `security lock` command to lock the selected device.  
   ```sh  
   commander security lock --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Device is now locked.  
   DONE  
   ```  
   b. For the **TrustZone-aware** application, run the `security lock --trustzone ####` command to set the [debug options](05-debug-unlock#trustzone-debug-authentication) (e.g., `1100`) and lock the selected device. The bit order of #### is SPNIDLOCK (MSB), SPIDLOCK, NIDLOCK, and DBGLOCK (LSB).  
   ```sh  
   commander security lock --trustzone 1100 --device sixg301 --serialno 440048205  
   ```  
   ```sh  
   Writing debug restriction bits:  
   DBGLOCK:	0  
   NIDLOCK:	0  
   SPIDLOCK:   1  
   SPNIDLOCK:  1  
   Device is now locked.  
   DONE  
   ```  
   **Notes**:  
   - The `--trustzone` option for the `security lock` command requires Simplicity Commander **≥ v1.13.3**.  
   - It is strongly recommended to upgrade to SE firmware **≥ v1.2.14** (xG21 and xG22) or **≥ v2.2.1** (other Series 2 devices). For Series 3 devices, it is strongly recommended to upgrade SE firmware to ≥ v3.3.2 so that the debug options cannot be modified after the device is locked.  
   - Use `commander security lock` without the `--trustzone ####` option if the default setting of debug options (`0000`) is good enough for a TrustZone-aware application.
7. Run the `security disabledeviceerase` command to disable device erase. This is an **IRREVERSIBLE** action, and should be the last step in production. (**It is recommended not to set this option while evaluating secure debug functionality.**)  
   ```sh  
   commander security disabledeviceerase --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   ================================================================================  
   THIS IS A ONE-TIME command which Permanently disables device erase.  
   If secure debug lock has not been set, there is no way to regain debug access to this device. Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   Disabled device erase successfully  
   DONE  
   ```  
   > **Note**: The debug options cannot be reset to the default value 0000 (unlock) if the device erase option is disabled.
8. Read back device status after it is securely locked.  
   a. For the TrustZone-unaware application, run the security status command to check the debug lock status of the device  
   ```sh  
   commander security status --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   SE ROM version        : 5.3  
   SE Firmware version   : 3.3.2  
   Serial number         : 0000000000000000781c9dfffe589591  
   Debug lock            : Enabled  
   Device erase          : Enabled  
   Secure debug unlock   : Enabled  
   Tamper status         : OK  
   Secure boot           : Disabled  
   Boot status           : 0x20 - OK  
   Command key installed : True  
   Sign key installed    : False  
   Security state        : Production  
   DONE  
   ```  
   b. For the TrustZone-aware application, run the `security status --trustzone` command to check the full debug lock status of the device.  
   ```sh  
   commander security status --trustzone --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   SE ROM version          : 5.3  
   SE Firmware version     : 3.3.2  
   Serial number           : 0000000000000000781c9dfffe589591  
   Debug lock              : Enabled  
   Device erase            : Enabled  
   Secure debug unlock     : Enabled  
     
   Debug lock state: Locked  
     
   TrustZone Config:  
   Non-secure, invasive debug lock     (DBGLOCK) : Unlocked  
   Non-secure, non-invasive debug lock (NIDLOCK) : Unlocked  
   Secure, invasive debug lock         (SPIDLOCK) : Unlocked  
   Secure, non-invasive debug lock     (SPNIDLOCK) : Unlocked  
     
   TrustZone State:  
   Non-secure, invasive debug lock state       (DBGLOCK) : Unlocked  
   Non-secure, non-invasive debug lock state   (NIDLOCK) : Unlocked  
   Secure, invasive debug lock state           (SPIDLOCK) : Unlocked  
   Secure, non-invasive debug lock state       (SPNIDLOCK) : Unlocked  
     
   Tamper status          : OK  
   Secure boot            : Disabled  
   Boot status            : 0x20 - OK  
   Command key installed  : True  
   Sign key installed     : False  
   Security state         : Production  
   DONE  
   ```

###### Secure Debug Unlock Using Commander tool

Use case for secure debug unlock is explained in [secure debug unlock](05-debug-unlock#secure-debug-lockunlock-flow) as pictorially. The steps to securely unlock the device securely are explained below.

1. The Product Company creates a Private/Public Certificate Key pair for each device. Because the key pair is assigned only to a single device, the company may not need to protect the Private Certificate Key as securely as the Private Command Key by the Direct Customer.  
   In this example, the Private/Public Certificate Key pair (`cert_key.pem` and `cert_pubkey.pem`) is generated by running the `util genkey` command.  
   ```sh  
   commander util genkey --type ecc-p256 --privkey cert_key.pem --pubkey cert_pubkey.pem  
   ```  
   ```sh  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to cert_key.pem  
   Writing public key file in PEM format to cert_pubkey.pem  
   DONE  
   ```
2. The Public Certificate Key (`cert_pubkey.pem`) for each device is passed to the Silicon Labs Direct Customer. The part number and serial number are also required if Direct Customer cannot access the device.If necessary, run the `security status` command to get the device serial number.  
   ```sh  
   commander security status --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   SE ROM version	        : 5.3  
   SE Firmware version	    : 3.3.2  
   Serial number	        : 0000000000000000781c9dfffe589591  
   Debug lock	            : Enabled  
   Device erase	        : Enabled  
   Secure debug unlock	    : Enabled  
   Tamper status	        : OK  
   Secure boot	            : Disabled  
   Boot status	            : 0x20 - OK  
   Command key installed	: True  
   Sign key installed	    : False  
   Security state	        : Production  
   DONE  
   ```
3. The Direct Customer then places that Public Certificate Key in the [access certificate](05-debug-unlock#access-certificate). The access certificate is unique per device because it contains the unique device serial number. This certificate is generated once upon creation of the device, and thereafter, is generally only modified when the Private/Public Certificate Key pair is changed by the Product Company.  
   Run the `security gencert` command with the following parameters from the Product Company to generate an unsigned access certificate (`access_certificate.extsign`) in Security Store:  
   - Device part number  
   - Device serial number  
   - Public Certificate Key  
   ```sh  
   commander security gencert --device sixg301 --deviceserialno 0000000000000000781c9dfffe589591 --cert-pubkey cert_pubkey.pem --extsign  
   ```  
   ```sh  
   Authorization file written to Security Store:  
   C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/ device_0000000000000000781c9dfffe589591/certificate_authorizations.json Cert key written to Security Store:  
   C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/ device_0000000000000000781c9dfffe589591/cert_pubkey.pem  
   Created an unsigned certificate in Security Store:  
   C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/ device_0000000000000000781c9dfffe589591/access_certificate.extsign  
   DONE  
   ```
4. The signing of the access certificate can be done by passing an unsigned access certificate to a Hardware Security Module (HSM) containing the Private Command Key.  
   In this example, the OpenSSL tool is used instead of HSM. Please install openSSL version above 3.5.0. Sign the access certificate (`access_certificate.extsign`) in Security Store with the Private Command Key (`command_key.pem`). The [access certificate signature](05-debug-unlock#access-certificate) is in the `cert_signature.bin` file.  
   ```sh  
   openssl dgst -sha256 -binary -sign command_key.pem -out cert_signature.bin access_certificate.extsign  
   ```  
   Run the `util signcert` command with the following parameters to verify the signature and generate the signed access certificate (`access_certificate.bin`):  
   - Unsigned access certificate  
   - Access certificate signature  
   - Public Command Key  
   ```sh  
   commander util signcert access_certificate.extsign --cert-type access --signature cert_signature.bin  
   --verify command_pubkey.pem --outfile access_certificate.bin  
   ```  
   ```sh  
   R = D97E43FEA278207080D6D0808B46810C1167F123AF1CA9FAF2DE0F4322B97ACE  
   S = FEDFEA11A3C83AFFCD5293283B13A50580862B9F651AAE08012C2BFB6BA8E697  
   Successfully verified signature  
   Successfully signed certificate  
   DONE  
   ```
5. The access certificate is passed to the Product Company. The purpose of the access certificate is to grant overall debug access capabilities to the Product Company and authorize them to allow third parties to debug the device. The Product Company can now use the access certificate to generate the Debug Unlock Token. The same access certificate can be used to generate as many Debug Unlock Tokens as necessary without having to ever go back to the Direct Customer.
6. To create the Debug Unlock Token, a debug session must be started with the device and the challenge value (which is a random number `Challenge 1` in this example) should be read out to generate the challenge response.  
   Run the `security gencommand` command to generate the challenge response without debug access command signature and store it in a file (`command_unsign.bin`).  
   ```sh  
   commander security gencommand --action debug-unlock --unlock-param 1111 -o command_unsign.bin --nostore  
   --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Unsigned command file written to:  
   command_unsign.bin  
   DONE  
   ```  
   **Notes**:  
   - The data in the `--unlock-param` option are the bits 2 to 5 of debug mode request in the challenge response.  
   - The default value `1111` (reset all debug options) is in place if the `security gencommand` command does not include the `-- un-lock-param` option.
7. The challenge response is then cryptographically hashed (SHA-256) to create a digest. The digest is then signed by the Private Certificate Key to generate the debug access command signature.  
   The signing of the challenge response can be done by passing an unsigned challenge response to a Hardware Security Module (HSM) containing the Private Certificate Key.  
   In this example, OpenSSL is used to sign the challenge response (`command_unsign.bin`) with the Private Certificate Key (`cert_key.pem`). The debug access command signature is in the `command_signature.bin` file.  
   ```sh  
   openssl dgst -sha256 -binary -sign cert_key.pem -out command_signature.bin command_unsign.bin  
   ```
8. Run the `security unlock` command with the access certificate (`access_certificate.bin`) from Direct Customer and debug access command signature (`command_signature.bin`) in step 7 to generate the Debug Unlock Token.  
   ```sh  
   commander security unlock --cert access_certificate.bin --command-signature command_signature.bin -- unlock-param 1111 --device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Certificate written to Security Store:  
   C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000781c9dfffe589591/access_certificate.bin  
   R = B4F5F2628B50BBA54ADAB4EB67CD0F933FE4C01E8BA760915D5167E75330F3A2  
   S = 4D7EEA1B6D8EA61F3140198B26060D9F96D32CDCC5CE58CB4611ECED0D21F9B8  
   Command signature is valid  
   Secure debug successfully unlocked  
   Command unlock payload was stored in Security Store  
   DONE  
   ```  
   **Notes**:  
   - Put the required files in the same folder to run the command.  
   - The debug access command signature can be in a Raw or Distinguished Encoding Rules (DER) format.  
   - It requires Simplicity Commander Version 1.11.2 or above to support signature in DER format.  
   - The data in the `--unlock-param` option are the bits 2 to 5 of debug mode request in the Debug Unlock Token. This value **MUST** be equal to the value of `--unlock-param` option in step 6.  
   - The default value `1111` (reset all debug options) is in place if the `security unlock` command does not include the `--unlock- param` option.
9. **(Alternative)** The key protection is not required if the Private Certificate Key is ephemeral. Steps 6 to 8 can be implemented by running the `security unlock` command with the access certificate (`access_certificate.bin`) from the Direct Customer and Private Certificate Key (`cert_key.pem`) to generate the Debug Unlock Token.  
   ```sh  
   commander security unlock --cert access_certificate.bin --cert-privkey cert_key.pem --unlock-param 1111 -- device sixg301 --serialno 440326972  
   ```  
   ```sh  
   Unlocking with unlock payload:  
   C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000781c9dfffe589591/challenge_a7be6d84d1a41321b1492e643ba626f1/unlock_payload_0000000000111110.bin  
   Secure debug successfully unlocked  
   DONE  
   ```  
   **Notes**:  
   - The data in the `--unlock-param` option are the bits 2 to 5 of debug mode request in the Debug Unlock Token.  
   - The default value `1111` (reset all debug options) is in place if the `security unlock` command does not include the `--unlock-param` option.
10. The Debug Unlock Token (also known as `Command unlock payload`) file (`unlock_payload_0000000000111110.bin`, where `0000000000111110` is the value of debug mode request) is stored in the Security Store. The location in Windows is `C:\Users\<userName>\AppData\Local\SiliconLabs\commander\SecurityStore\device_<Serial number>\challenge_<Challenge value>`.  
    ![screenshot](/series2-secure-debug/0.3/images/sld714-image68.jpg)  
    Users can also use the `security getpath` command to get the path of the Security Store or a specified device.  
    ```sh  
    commander security getpath --device sixg301  
    ```  
    ```sh  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore  
    DONE  
    ```  
    ```sh  
    commander security getpath --deviceserialno 0000000000000000781c9dfffe589591  
    ```  
    ```sh  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000781c9dfffe589591  
    DONE  
    ```
11. The Debug Unlock Token and the device are now delivered to the Debug 3rd Party.  
    Run the `security gencommand` command to create the Security Store to place the Debug Unlock Token file.  
    ```sh  
    commander security gencommand --action debug-unlock --device sixg301 --serialno 440326972  
    ```  
    ```sh  
    Unsigned command file written to Security Store:  
    C:/Users/<userName>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000781c9dfffe589591/challenge_a7be6d84d1a41321b1492e643ba626f1/ unlock_command_to_be_signed22_07_2025.bin  
    DONE  
    ```  
    Copy the Debug Unlock Token file (`unlock_payload_0000000000111110.bin`) from Product Company to the Windows Security Store `challenge_<Challenge value>` folder located in `C:\Users\<PC user name>\AppData\Local\SiliconLabs\commander\SecurityStore\device_<Serial number>challenge_<Challenge value>`.
12. The device compares the Debug Unlock Token contents with its internal serial number, challenge value, and Public Command Key to determine the token’s authenticity. If authentic, it will execute the debug access command to unlock the device; otherwise, it will ignore the command.  
    Run the `security unlock` command to unlock the device.  
    ```sh  
    commander security unlock --unlock-param 1111 --device sixg301 --serialno 440326972  
    ```  
    ```sh  
    Unlocking with unlock payload:  
    C:/Users/<userName>AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000781c9dfffe589591/challenge_a7be6d84d1a41321b1492e643ba626f1/unlock_payload_0000000000111110.bin  
    Secure debug successfully unlocked  
    DONE  
    ```  
    **Notes**:  
    - If the security store has multiple tokens for the selected device, use `--unlock-param` option to specify which unlock token is chosen to unlock the device.  
    - Simplicity Commander will only use the token with value `1111` (error if not available) from the security store to unlock the device if the security unlock command does not include the `--unlock-param` option.
13. Run `security status --trustzone` command to check the full debug lock status of the device.  
    ```sh  
    commander security status --trustzone --device sixg301 --serialno 440326972  
    ```  
    ```sh  
    SE ROM version	        : 5.3  
    SE Firmware version	    : 3.3.2  
    Serial number	        : 0000000000000000781c9dfffe589591  
    Debug lock	            : Disabled  
    Device erase	        : Enabled  
    Secure debug unlock     : Disabled  
      
    Debug lock state: Unlocked  
      
    TrustZone Config:  
    Non-secure, invasive debug lock   (DBGLOCK) : Unlocked  
    Non-secure, non-invasive debug lock (NIDLOCK) : Unlocked  
    Secure, invasive debug lock  (SPIDLOCK) : Unlocked  
    Secure, non-invasive debug lock   (SPNIDLOCK): Unlocked  
      
    TrustZone State:  
    Non-secure, invasive debug lock state  (DBGLOCK) : Unlocked  
    Non-secure, non-invasive debug lock state (NIDLOCK) : Unlocked  
    Secure, invasive debug lock state   (SPIDLOCK) : Unlocked  
    Secure, non-invasive debug lock state   (SPNIDLOCK): Unlocked  
      
    Tamper status	      : OK  
    Secure boot	          : Disabled  
    Boot status	          : 0x20 - OK  
    Command key installed : True  
    Sign key installed	  : False  
    DONE  
    ```
14. The Debug 3rd Party can now use this same Debug Unlock Token to unlock the device (step 12), over and over again after each power-on or pin reset, until they have finished debugging the device.
15. Once the Debug 3rd Party has finished debugging, they will send the device back to the Product Company.
16. Once the Product Company receives the device, they will immediately start a debug session, roll the challenge (from `Challenge 1` to `Challenge 2` in this example), and put the device back into the secure debug lock state. Rolling the challenge will effectively invalidate any Debug Unlock Token that has been previously given to any third party.  
    Run the `security rollchallenge` command and reset the device to invalidate the current Debug Unlock Token. The challenge cannot be rolled before it has been used at least once.  
    ```sh  
    commander security rollchallenge --device sixg301 --serialno 440326972  
    ```  
    ```sh  
    Challenge was rolled successfully.  
    DONE  
    ```  
    The unlock token is invalidated after rolling the challenge because any previously issued Debug Unlock Token now contains a different challenge value (`Challenge 1`) than the challenge value currently in the device (`Challenge 2`).  
    The validation process of any previously issued Debug Unlock Token will always fail until a new Debug Unlock Token is issued with a current matching challenge value (`Challenge 2`).

##### Using Simplicity Studio

The security operations are performed in the Security Settings of Simplicity Studio. This application note uses Simplicity Studio v5.11.0.0. The procedures and pictures may be different for the other versions of Simplicity Studio 5.

###### Standard Debug lock/unlock using Simplicity Studio

1. Right-click the selected debug adapter RB (ID:J-Link serial number) to display the context menu.  
   ![Debug Adapters Context Menu](/series2-secure-debug/0.3/images/sld714-image69.png)
2. Click **Device configuration...** to open the **Configuration of device: J-Link Silicon Labs (serial number)** dialog box. Click the **Security Settings** tab to get the selected device configuration.  
   ![Configuration on Selected Device](/series2-secure-debug/0.3/images/sld714-image70.png)
3. Click [**Enable**] next to **Enable Debug Lock:** to lock the device. The following **Enable Debug Lock Warning** is displayed. Click [**Yes**] to confirm. This configures standard debug lock.  
   ![Enable Debug Lock](/series2-secure-debug/0.3/images/sld714-image71.png)
4. The [**Enable**] controls next to **Enable Secure Debug Unlock:** and **Enable Debug Lock:** are grayed out after standard debug lock is enabled.  
   ![Standard Debug Lock](/series2-secure-debug/0.3/images/sld714-image72.jpg)
5. Click [**Device Erase**] to unlock the device.  
   ![Device Erase](/series2-secure-debug/0.3/images/sld714-image73.png)
6. The device will return to the unlock state. Click [**OK**] to exit.  
   ![Standard Debug Unlock](/series2-secure-debug/0.3/images/sld714-image74.png)

###### Secure Debug Lock Using Simplicity Studio

1. Run the `util keytotoken` command to convert the Public Command Key file (PEM format) into a text file (`command_pubkey.txt`).  
   Refer to [Secure Debug Lock Using Commander tool)](#secure-debug-unlock-using-commander-tool) before performing these steps.  
   ```sh  
   commander util keytotoken command_pubkey.pem --outfile command_pubkey.txt  
   ```  
   ```sh  
   Writing EC tokens to command_pubkey.txt...  
   DONE  
   ```
2. Open **Security Settings** of the selected device
3. Click the **WriteKey** link next to **Command Key:** to open a dialog box.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-write-key-link.png)
4. The **Write Command Key** dialog box is displayed.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image77.png)
5. Open the `command_pubkey.txt` file generated in step 1.  
   ```sh  
   MFG_SIGNED_BOOTLOADER_KEY_X : 50DF50A09242A49F53251D38E1A368C82EC7CA2D33E6E81C6B3B891B1B9DBFC3  
   MFG_SIGNED_BOOTLOADER_KEY_Y : D5F2D045236CBEF3CB46B13BF7527AA36A26435DA6E8AFAF60037DA21AD7B2E1  
   ```
6. Copy Public Command Key (X-point `50DF...` first, then Y-point `D5F2...`) to **Command Key:** box.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image78.png)
7. Click [**Write**] to provision the Public Command Key.
8. Click [**Enable**] next to **Enable Secure Debug Unlock:** to enable the secure debug functionality.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image79.png)
9. Click [**Enable**] next to **Enable Debug Lock:** to lock the device. This configures secure debug lock.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image81.jpg)
10. Click [**Disable**] next to **Disable Device Erase:** to disable the device erase. The following **Disable Device Erase Warning** is displayed. Click [**Yes**] to confirm.

![screenshot](/series2-secure-debug/0.3/images/sld714-image83.png)

> **Important**: This is an **IRREVERSIBLE** action, and should be the last step in production. While evaluating Secure Debug functionality, it is best to not enable this option.

###### Secure Debug Unlock Token Provision Simplicity Studio

Use the Debug Unlock Token file (`unlock_payload_0000000000111110.bin`) generated in [Secure Debug Unlock Using Commander Tool](#secure-debug-unlock-using-commander-tool) steps 8 or 9 to unlock the device with Simplicity Studio.

1. Open the `unlock_payload_0000000000111110.bin` file with the Hex File editor.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image85.jpg)
2. Click **View** to open the context menu, and then select **Group By** → **Double words** to convert the token into a little-endian format.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image86.jpg)
3. Select all (Ctrl+A) and copy (Ctrl+C) the Debug Unlock Token to a text editor.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image87.jpg)
4. Use the text editor to remove all the spaces from the token.
5. Right-click the selected debug adapter **RB (ID:J-Link serial number)** to display the context menu.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image88.png)
6. Click **Set Unlock Token** to open the **Add Debug Unlock Token** dialog box. Enter the name (e.g., `AN1190 Token`) for this Debug Unlock Token, and copy the content in step 4 to the **Debug Unlock Token:** box. Click [**OK**] to confirm and exit.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image89.png)  
   > **Note**: The Simplicity Studio can only keep one Debug Unlock Token on each WSTK.
7. Open Security Settings of the selected device as described in [Standard Debug Lock/Unlock Using Simplicity Studio](#standard-debug-lockunlock-using-simplicity-studio).
8. The token added in step 6 should be displayed on the **Crypto Profile:** field. If not, click the link next to **Crypto Profile:** to select the token from the **Crypto Profile Manager** drop-down list. The Simplicity Studio will automatically add the WSTK J-Link serial number (`-J-Link Silicon Labs (serial number)`) to the token's name.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-jlink-serial-number.png)
9. Click [**Unlock Debug Port**] to use the token in **Crypto Profile:** to unlock the device (invalid token will display an error message). The device stays in the unlock state until the next power-on or pin reset. Click [**OK**] to exit.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image90.png)
10. The Simplicity IDE will automatically use the selected Debug Unlock Token in **Crypto Profile** for debugging and flashing.

After finished debugging, open the Security Settings of the selected device as described in [Standard Debug Lock/Unlock Using Simplicity Studio](#standard-debug-lockunlock-using-simplicity-studio).

###### Roll Challenge Using Simplicity Studio

1. Click [**Roll Challenge**] to generate a new challenge value to invalidate the Debug Unlock Token added in step 6. Click [**OK**] to exit.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image93.png)
2. Right-click the selected debug adapter **RB Board (ID:J-Link serial number)** to display the context menu.  
   ![screenshot](/series2-secure-debug/0.3/images/sld714-image94.png)
3. Click [**Clear Unlock Token**] to delete the WSTK Debug Unlock Token from Simplicity Studio.

##### Using Platform SE - Manager

Simplicity Studio 5 includes the SE Manager platform examples for Secure Tamper. Refer to the corresponding readme file for details about the SE Manager example. This file also includes the procedures to create the project and run the example about the SE Manager example. This file also includes the procedures to create the project and run the example.

<table>
    <thead>
        <tr>
            <th>Category</th>
            <th>SE Manager Platform Example</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Perform Secure Debug</td>
            <td>Platform Security - SoC SE Manager Secure Debug</td>
            <td>Sample application to:
                <ul>
                    <li>Set DEBUG_OPTION for TrustZone aware debug</li>
                    <li>Enable/Disable standard Debug Lock</li>
                    <li>Provision command key</li>
                    <li>Enable/Disable Secure Debug</li>
                    <li>Lock or Unlock debug port securely</li>
                    <li>Disable Device erase</li>
                    <li>Roll challenge</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

#### Failure Analysis

The following table describes the different scenarios when returning a Series 2 device to Silicon Labs for failure analysis.

|**State**|**Secure Boot Disabled**|**Secure Boot Enabled (2)**|
|---|---|---|
|Standard debug unlock|Device erase is not necessary for failure analysis.|Device erase is not necessary, but a correctly signed image is required to perform failure analysis.|
|Standard debug lock|Device erase is required to perform failure analysis.|Require device erase and correctly signed image to perform failure analysis.|
|Permanent debug lock|Cannot perform failure analysis.|Cannot perform failure analysis.|
|Secure debug lock (1)|Require debug unlock token to perform failure analysis.|Require debug unlock token and correctly signed image to perform failure analysis.|

**Notes**:

1. Follow the procedures mentioned in [Debug Access Flow](05-debug-unlock#debug-access-flow) to generate a valid debug unlock token for each device returned to Silicon Labs for failure analysis.
2. Secure boot enabled devices, especially with secure boot failure, may limit Silicon Labs' ability to determine the root cause of failure.

### Series 2 and Series 3 Secure Boot with RTSL

#### Series 2 and Series 3 Secure Boot with RTSL

> **Note: This section replaces _AN1218: Series 2 and Series 3 Secure Boot with RTSL_. Further updates to this application note will be provided here**.

This application note describes the design of Secure Boot with RTSL (Root of Trust and Secure Loader) on Series 2 and Series 3 devices. It also provides examples of how to implement the Secure Boot process.

For more information on using the Gecko Bootloader with Series 2 and Series 3 devices, see the following:

- [Bootloader Fundamentals](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/)
- [UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)
- [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/)
- [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/)

##### Key Points

- Compares the Secure Boot process in Series 1, Series 2, and Series 3 devices
- Describes the Series 2 and Series 3 Secure Boot with RTSL components and process
- Provides examples of configuring Series 2 and Series 3 devices for the Secure Boot process
- Recovers secure boot failure devices

#### Series 2 and Series 3 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 and Series 3 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 and Series 3 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- Series 2 devices: EFR32xx2xx devices
- Series 3 devices: SiG3xxx devices
- HSE: Hardware Secure Engine
- VSE: Virtual Secure Engine
- SE: Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level (1)**|**SE Support**|
|---|---|
|Secure Vault High (SVH) and Series 3 Secure Vault|HSE only (HSE-SVH)|
|Secure Vault Mid (SVM)|HSE (HSE-SVM), VSE (VSE-SVM)|
|Secure Vault Base (SVB)|N/A|

**Notes**:

1. The features of different Secure Vault levels can be found in [Security](https://www.silabs.com/security).
2. Refer to [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/11-series-2-device-security-features) for details on supporting devices.

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug access control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High and Series 3 Secure Vault devices offer additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper protection**: A configurable module to protect the device against tamper attacks.
- **Device authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

> **Note**: Series 3 Secure Vault devices do not include a device certificate for the host MCU.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products, Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Series 2 and Series 3 Secure Boot with RTSL (this application note)</p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|
|AXiP Key|No|Used on Series 3 devices for encryption/ decryption and authentication of firmware placed in flash|
|EXiP Key|No|Used on Series 3 devices for encryption/ decryption of firmware placed in flash|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 and Series 3 devices and modules.

#### Secure Boot Process

##### Introduction

Secure Boot is a foundational component of platform security, as the absence of it can allow malicious code to subvert protections like secure storage, secure data transport, secure identity, and data confidentiality.

Secure Boot works as a process by which each piece of firmware is validated for authenticity and integrity before it is allowed to run. Each authenticated module can also validate additional modules before executing them, forming a chain of trust. If any module fails its security check, it is not allowed to run, and program control will typically stall in the validating module. In most lightweight IoT systems, the behavior of a Secure Boot failure is to cause the device to stop working until an authentically signed image can be loaded onto it. Whereas this may seem extreme, it is a better outcome than a smart light bulb being repurposed to mine crypto-currency, or a smart speaker being repurposed as a surveillance device on the end user’s private conversations.

The first link in the chain of trust is the root of trust. This is often the weakest link in the Secure Boot chain because the root of trust itself is not checked for authenticity or integrity. The security strength of the root of trust lies in its immutability. The strongest roots of trust have their firmware origin in ROM and use a Public Sign Key that is also located in ROM.

Series 1, Series 2, and Series 3 devices use a two-stage boot design consisting of a non-upgradable first stage root of trust followed by an upgradable second stage. In Series 1 devices, the root of trust (also called the first-stage bootloader) is in flash rather than ROM, and the upgradable portion (the main bootloader) is checked for integrity using a CRC32 checksum but is not checked for authenticity using a Public Sign Key. In Series 2 and Series 3 devices, the root of trust is in ROM, and the upgradable portion is checked both for integrity and authenticity.

The Secure Boot with RTSL is implemented by Root code executed by the Hardware Secure Engine (HSE) or the Cortex-M33 operating in Root Mode (VSE). For more information about SE, see section _Secure Engine Subsystem_ in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

In Series 3 devices, once firmware is programmed to the device, the code regions must be closed. Closing a code region locks it to prevent writes, as well as further configuration, and indicates to the SE that it can now be accessed by the SE. After flashing the firmware image, commander automatically closes the code region. To open a closed code region, an erase must be performed. If a code region is not closed, the SE will return a fault when attempting to access the open code region during secure boot verification of the host firmware. Each time a code region is closed, the SE's MTP (Multiple Times Programmable) memory section is updated, which causes an SE OTP bit to be used. More details on SE OTP bits is covered in the following section.

Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://www.silabs.com/developers/custom-part-manufacturing-service) to customize the users' security features and settings. This application note uses the following abbreviations:

- FSB: First Stage Bootloader
- SSB: Second Stage Bootloader
- GBL: Gecko Bootloader
- RTSL: Root of Trust and Secure Loader
- HSM: Hardware Security Module
- OTP: One-Time Programmable
- WSTK: Wireless Starter Kit
- GSDK: Gecko Software Development Kit. For more information, refer to [GSDK](https://github.com/SiliconLabs/gecko_sdk)
- SiSDK: Simplicity Software Development Kit. For more information, refer to [SiSDK](https://github.com/SiliconLabsSoftware/sisdk-release)
- ECDSA-P256-SHA256: Elliptic Curve Digital Signature Algorithm aka ECDSA using a P-256 curve and a SHA256 hash
- PEM (.pem): Privacy Enhanced Mail
- DER (.der): Distinguished Encoding Rules

##### ECDSA-P256-SHA256 Secure Boot in Series 1 Devices

The Secure Boot process for Series 1 (SVB) devices originates in flash, typically with the execution of the first stage of GBL. The first stage of GBL checks to see if an upgrade is pending for the second stage of GBL. If so, it processes the upgrade of the second stage and then executes it. Otherwise, it just executes the second stage. If Secure Boot is enabled, the second stage of GBL checks the integrity and authenticity of the application image before executing it. If the integrity check fails, program control remains in the SSB. The following figure illustrates the Secure Boot process on Series 1 devices.

![Series 1 ECDSA-P256-SHA256 Secure Boot Process](/series2-secure-boot-with-rtsl/0.3/images/sld794-image15.png)

See [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) for more information to generate and download signed firmware images using Simplicity Commander.

##### ECDSA-P256-SHA256 Secure Boot in Series 2 and Series 3 Devices

For Series 2 and Series 3 devices, the Secure Engine (SE) implements the FSB to authenticate and upgrade the SSB. The GBL implements the SSB, also known as, Main Bootloader in _UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower_, [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) or [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) to authenticate and upgrade the application firmware.

Refer to the _Gecko Bootloader Security Features_ section in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf), [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/), or [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) and the [ECDSA-P256-SHA256 Secure Boot](03-examples#signing-for-ecdsa-p256-sha256-secure-boot) example for more information about the ECDSA-P256-SHA256 secure boot process in Series 2 devices and Series 3.

> **Note**: It is possible to have a 2-stage design to skip the SSB between FSB and application. However, the application cannot be upgraded if discarding the SSB, and this application note assumes the SSB is present.

###### HSE

In HSE-SVM, HSE-SVH, and Series 3 Secure Vault devices, the Secure Boot process originates in ROM contained in the security co-processor (HSE). The following figures illustrate the Secure Boot process and flow on Series 2 HSE and Series 3 devices.

![Series 2 HSE and Series 3 ECDSA-P256-SHA256 Secure Boot Process](/series2-secure-boot-with-rtsl/0.3/images/sld794-image16.png)

![Series 2 HSE and Series 3 ECDSA-P256-SHA256 Secure Boot Flow](/series2-secure-boot-with-rtsl/0.3/images/sld794-image17.png)

###### VSE

In VSE-SVM devices, the host MCU (Cortex-M33) assumes an elevated security state out of reset and securely boots itself from code that originates in ROM. The following figures illustrate the Secure Boot process and flow on Series 2 VSE devices.

![Series 2 VSE ECDSA-P256-SHA256 Secure Boot Process](/series2-secure-boot-with-rtsl/0.3/images/sld794-image18.png)

![Series 2 VSE ECDSA-P256-SHA256 Secure Boot Flow](/series2-secure-boot-with-rtsl/0.3/images/sld794-image19.png)

##### Certificate-based Secure Boot in Series 2 and Series 3 Devices

Refer to the _Gecko Bootloader Security Features_ section in [UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) and [Certificate-Based Secure Boot](03-examples#signing-for-certificate-based-secure-boot) example for details about the certificate-based Secure Boot process in Series 2 and Series 3 devices.

The certificate-based Secure Boot process uses key delegation to minimize the exposure of the Private Sign Key, thereby reducing the likelihood that the corresponding Public Sign Key would need to be revoked.

If the certificate’s private key is leaked, all devices that have been programmed with that certificate are at risk until they can be updated with an image containing a certificate with a [higher version](./03-examples.md#certificate-revocation(03-examples.md#certificate-revocation).

##### Secure Loader

In Series 2 and Series 3 devices, the Secure Loader is firmware pre-loaded into the chip. Silicon Labs maintains the Secure Loader and deploys through secure upgrade packages. It is the functional equivalent of the first-stage GBL on Series 1 devices (refer to [UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) for more information). The Secure Loader validates the authenticity and integrity of a staged image before performing an upgrade operation. The Secure Loader requires the staged image to reside on-chip and the staged image must not overlap with the target destination address range. Firmware images that originate from off-chip, either off-chip storage, external NCP/ RCP host interface, or through an OTA update procedure are expected to be staged either by the application or by SSB before calling the Secure Loader to perform the upgrade.

![Series 2 and Series 3 Secure Loader Example](/series2-secure-boot-with-rtsl/0.3/images/sld794-image20.png)

##### Secure Boot Time

Secure boot extends the recovery time from all sources of device reset. The duration of each authentication operation depends on the factors below:

- Computation of the SHA-256 digest (32 bytes) of the associated image, which is proportional to the size of the firmware image.
- Verification of the ECDSA-P256 signature of the SHA-256 digest above, which is independent of image size.
- The clock frequency of the Crypto Engine, which is the HSE or CRYPTOACC in VSE devices.

|**Authentication**|**Enable/Disable**|**Duration**|
|---|---|---|
|FSB code|Enable (cannot disable)|FSB code size dependent|
|SSB code|Disable (by default)|SSB code size and SE firmware version dependent|
|Application code|Disable (by default)|Application code size and SSB firmware (GBL) version dependent|

**Notes**:

- It will extend the boot time for certificates authentication if using [Certificate-Based Secure Boot](03-examples#signing-for-certificate-based-secure-boot).
- Refer to device-specific datasheets (like [EFR32MG21B](https://www.silabs.com/documents/public/data-sheets/efr32mg21b-datasheet.pdf)) for data about the boot timing of Series 2 devices.
- Refer to _Secure Boot Configuration_ below on how to enable the SSB and application code authentication.

##### Secure Boot Configuration

The following sections describe how to configure the Secure Boot of the SSB (GBL) and application firmware.

###### SSB

In Series 2 and Series 3 devices, the immutable OTP memory stores the [Public Sign Key, Secure Boot Enable flag](03-examples#provision-public-sign-key-and-secure-boot-enabling), and Anti-rollback flag. The user cannot change its respective value once either is programmed. Once the Public Sign Key is provisioned, it remains provisioned to that key value for the life of the device. Once Secure Boot and Anti-rollback is enabled, it remains enabled for the life of the device. Both of these assignment operations are **IRREVOCABLE**.

The Public Sign Key used for Series 2 and Series 3 devices is the public portion of an ECDSA key pair over the NIST prime curve P-256. The Public Sign Key is a customer key and is typically provisioned during the initial product manufacturing and device programming phase. It is common for all products that share the same firmware image to be loaded with the same Public Sign Key. The key loaded into the device is a public key and has no confidentiality requirements. The private key associated with that public key, which will be used to sign firmware images or certificates, should be tightly held, ideally secured in the [HSM](03-examples#generate-key-and-signing) or equivalent key storage instrument.

You can use [Simplicity Commander](03-examples#simplicity-commander), [SE Manager](03-examples#se-manager-key-provisioning-platform-example), or [Simplicity Studio](03-examples#simplicity-studio) to program the Public Sign Key and configure the SSB Secure Boot with anti-rollback in SE OTP. The following figures show the Simplicity Studio and Simplicity Commander implementation, for detailed steps refer to the Example section:

![Configuration of SSB using Simplicity Studio](/series2-secure-boot-with-rtsl/0.3/images/sld794-image21.jpg)

![Configuration of SSB using Simplicity Commander](/series2-secure-boot-with-rtsl/0.3/images/sld794-image22.jpg)

###### Application Firmware

You can use the AppBuilder or [Bootloader-core software component](03-examples#bootloader-core-software-component) in the [GBL](03-examples#generate-an-unsigned-gbl-image) project to configure the security options of the application firmware.

You can reconfigure the Secure Boot configuration of the application firmware by upgrading the GBL with the new custom settings.

![Using AppBuilder](/series2-secure-boot-with-rtsl/0.3/images/sld794-image23.png)

Using Bootloader core compoent

![Using Bootloader core component](/series2-secure-boot-with-rtsl/0.3/images/sld794-image24.jpg)

![Security Options of Application Firmware using AppBuilder and Bootloader Core Component](/series2-secure-boot-with-rtsl/0.3/images/sld794-image25.jpg)

> **Note**: Install "Bootloader Core (Series-3)" for series 3 devices.

#### Examples

##### Overview

The following table describes the examples for Series 2 and Series 3 Secure Boot.

> **Note**: Series 3 devices require SE firmware Version 3.1.0 or later to support Secure Boot. However, version 3.3.4 or newer is recommended for full feature support and latest security enhancements.

|**Example**|**Device (Radio Board)**|**Minimum SE Firmware**|**Tool**|
|---|---|---|---|
|Provision Public Sign Key and Secure Boot Enabling|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|"|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|SE Manager|
|"|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Studio 5|
|Provision GBL Decryption Key|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|"|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|SE Manager|
|Signing for ECDSA-P256-SHA256 Secure Boot|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|Signing for Certificate-Based Secure Boot|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|Generate a GBL Upgrade Image File|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|Upgrade to Certificate-Based Secure Boot|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|Certificate Revocation|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|
|Upgrade to Secure Boot with RTSL|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|SE Manager & Simplicity Commander|
|Recover Devices when Secure Boot Fails|EFR32MG21A010F1024IM32 (BRD4181A)|Version 1.2.9|Simplicity Commander|

> **Note**: Unless specified in the example, these examples can be applied to other Series 2 and Series 3 devices.

###### Using Simplicity Commander

1. This application note uses Simplicity Commander v1.19.2. The procedures and console output may be different for the other versions of Simplicity Commander. The latest version of Simplicity Commander can be downloaded from [MCU Programming options](https://www.silabs.com/developer-tools/mcu-programming-options).  
   > **Note**: It is recommended to upgrade to the latest version of Simplicity Commander.  
   ```sh  
   commander --version  
   ```  
   ```sh  
   Simplicity Commander 1v19p2b1907  
     
   JLink DLL version: 7.52d  
   Qt 5.12.10 Copyright (C) 2017 The Qt Company Ltd.  
   EMDLL Version: 0v17p19b0  
   mbed TLS version: 2.16.6  
     
   Emulator found with SN=440048205 USBAddr=0  
     
   DONE  
   ```
2. The Simplicity Commander's Command Line Interface (CLI) is invoked by `commander.exe` in the Simplicity Commander folder. The location for Simplicity Studio 5 in Windows is `C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\commander`. For ease of use, it is highly recommended to add the path of commander.exe to the system PATH in Windows.
3. If more than one WSTK is connected via USB, the target WSTK must be specified using the `--serialno <J-Link serial number>` option.
4. If the WSTK is in debug mode OUT, the target device must be specified using the `--device <device name>` option. For more information about Simplicity Commander, see [Simplicity Commander Reference Guide](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/).

###### Using an External Tool

The [Secure Boot examples](#secure-boot) use the **OpenSSL** to sign the image files and certificates. The Windows version of OpenSSL can be downloaded from [https://slproweb.com/products/Win32OpenSSL.html](https://slproweb.com/products/Win32OpenSSL.html). This application note uses OpenSSL Version 3.5.0 (Win64).

```sh
openssl version
```

```sh
OpenSSL 3.5.0 8 Apr 2025 (Library: OpenSSL 3.5.0 8 Apr 2025)
```

The OpenSSL's Command Line Interface (CLI) is invoked by `openssl.exe` in the OpenSSL folder. The location in Windows (Win64) is `C:\Program Files\OpenSSL-Win64\bin`. For ease of use, it is highly recommended to add the path of `openssl.exe` to the system `PATH` in Windows.

###### Using a Platform Example

Simplicity Studio 5 includes the [SE Manager platform example](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-getting-started/start-a-project#examples) for key provisioning and Secure Boot enabling. This application note uses platform example of SiSDK v2025.6.1. The console output may be different on other versions.

Refer to the corresponding readme file for details about each SE Manager platform example. This file also includes the procedures to create the project and run the example.

###### Generate Key and Signing

This section describes how to generate a key to sign an image file or certificate for Secure Boot using Simplicity Commander or using an HSM with Simplicity Commander (Openssl). For production environments, it is strongly recommended to generate keys with an HSM.

###### Using Simplicity Commander (heading level 7)

1. Run the `util genkey` command to generate the ECDSA-P256 Sign Key pair (`sign_key.pem` and `sign_pubkey.pem)` and Public Sign Key token file (`sign_pubkey.txt`). The Simplicity Commander can program the Public Sign Key in token file (`sign_pubkey.txt`) to the [top page of the main flash](#signing-for-ecdsa-p256-sha256-secure-boot).  
   ```sh  
   commander util genkey --type ecc-p256 --privkey sign_key.pem --pubkey sign_pubkey.pem  
   --tokenfile sign_pubkey.txt  
   ```  
   ```sh  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to sign_key.pem  
   Writing public key file in PEM format to sign_pubkey.pem  
   Writing EC tokens to sign_pubkey.txt...  
   DONE  
   ```  
   > **Note**: The same procedure can apply to generate the bootloader certificate and application certificate key pairs for [Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).
2. Use the convert command with the Private Key (like sign_key.pem) from step 1 to sign an image file or certificate. Refer to [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) and [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) for more information about the Simplicity Commander signing process.

###### Using an HSM and Simplicity Commander (heading level 7)

1. You can use HSM to generate the ECDSA-P256 Sign Key pair. The Private Sign Key is securely held in HSM and the Public Sign Key can be exported in a specific format (like `sign_pubkey.pem`).  
   > **Note**: The same procedure can apply to generate the bootloader certificate and application certificate key pairs for [Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).
2. Use the `util keytotoken` command to convert the Public Sign Key from step 1 to token format (`sign_pubkey.txt`). The Simplicity Commander can program the Public Sign Key in token file (`sign_pubkey.txt`) to the [top page of the main flash](#signing-for-ecdsa-p256-sha256-secure-boot).  
   ```sh  
   commander util keytotoken sign_pubkey.pem --outfile sign_pubkey.txt  
   ```  
   ```sh  
   Writing EC tokens to sign_pubkey.txt...  
   DONE  
   ```
3. Use the `convert` command with `--extsign` option to prepare an unsigned image or certificate for HSM.
4. Use the Private Key from step 1 to generate a signature for the unsigned image or certificate from step 3.
5. Use the `convert` command with the signature from step 4 to generate a signed image or certificate. Refer to [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) and [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) for more information about the HSM and Simplicity Commander signing process.

> **Note**: The Simplicity Commander v1.11.0 or above supports signature in DER format. The older version of Simplicity Commander can only handle signatures in Raw format.

##### Provision Public Sign Key and Secure Boot Enabling

The Public Sign Key in SE OTP is used to verify the host image signature or certificate during Secure Boot. You should provision this key before setting the Secure Boot enabled flag in SE OTP. On HSE-SVH devices, when anti-tamper functionality is needed, you need to provision the [anti-tamper protection configuration](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/) with Secure Boot settings.

If you set the [SECURE_BOOT_ANTI_ROLLBACK](#simplicity-commander) option with Secure Boot, the SE will store the version counter (4 bytes) for anti-rollback of GBL (SSB) to SE flash and check the bootloader version during an upgrade and on every boot. The version counter will not roll to 0 if it reaches the maximum value (bootloader cannot be upgraded anymore). The anti-rollback does not prevent flashing an older signed GBL hex image to the device.

The following table describes the anti-rollback protection on signed GBL when `SECURE_BOOT_ANTI_ROLLBACK` is enabled or disabled.

- The GBL handles the anti-rollback protection when upgrading the GBL through the [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) (`.gbl`).
- The SE handles the anti-rollback protection (if `SECURE_BOOT_ANTI_ROLLBACK` enabled) when booting the image.

|**Action**|**SECURE_BOOT_ANTI_ROLLBACK Disable**|**SECURE_BOOT_ANTI_ROLLBACK Enable**|
|---|---|---|
|Use a GBL upgrade image (`.gbl`) file (e.g., OTA)|Gecko Bootloader rejects upgrade if an equal or lower GBL version is detected.|Gecko Bootloader rejects upgrade if an equal or lower GBL version is detected.|
|Flash and boot a firmware image (`.s32`, `.hex`, `.bin`) directly (e.g., Simplicity Commander)|SE accepts the image to flash and boot regardless of the firmware image version.|The SE accepts and boots the firmware image if its version is equal to or higher than the stored version. A lower version will be blocked at boot.|

> **Note**: [Series 2 devices only] The device needs to execute a mass erase (`commander device masserase` or `commander security erasedevice` then reset) before flashing a GBL hex image (`.s37`) to the device if [SECURE_BOOT_PAGE_LOCK_NARROW](#simplicity-commander) or [SECURE_BOOT_PAGE_LOCK_FULL](#simplicity-commander) option in SE OTP is enabled.

For simplicity, the [Secure Boot examples](#secure-boot) in this application note do not enable the following options for Secure Boot.

- `SECURE_BOOT_PAGE_LOCK_NARROW`
- `SECURE_BOOT_PAGE_LOCK_FULL`

> **Note**: `SECURE_BOOT_PAGE_LOCK_NARROW` and `SECURE_BOOT_PAGE_LOCK_FULL` are only available on Series 2 devices.

###### Simplicity Commander

The following procedures assume the required files are in the same folder.

1. Follow the procedures in [Generate Key and Signing](#generate-key-and-signing) to generate the ECDSA-P256 Sign Key pair (`sign_key.pem` and `sign_pubkey.pem`) and Public Sign Key token file (`sign_pubkey.txt`).
2. Run the `security writekey` command to provision the Public Sign Key (`sign_pubkey.pem`) to the SE OTP slot. The Public Sign Key cannot be changed once written.  
   ```sh  
   commander security writekey --sign sign_pubkey.pem --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   Device has serial number 000000000000000014b457fffe045b21  
     
   ================================================================================  
   Please look through any warnings before proceeding.  
   THIS IS A ONE-TIME command, all code to be run on the device must be signed by this key.  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```
3. Run the `security readkey` command to verify the Public Sign Key with the Public Sign Key in the token file (`sign_pubkey.txt`).  
   ```sh  
   commander security readkey --sign --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   C4AF4AC69AAB9512DB50F7A26AE5B4801183D85417E729A56DA974F4E08A562C  
   DE6019DEA9411332DC1A743372D170B436238A34597C410EA177024DE20FC819  
   DONE  
   ```
4. For Series 2 VSE devices (like EFR32MG22C224F512IM40), run the `flash` command to program the Public Sign Key in the token file (`sign_pubkey.txt`) to the top page of the main flash for [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot). It is optional on Series 2 HSE and Series 3 devices.  
   ```sh  
   commander flash --tokengroup znet --tokenfile sign_pubkey.txt --device EFR32MG22C224F512IM40 --serialno 440048205  
   ```  
   ```sh  
   Writing 8192 bytes starting at address 0x0007e000  
   Comparing range 0x0007E000 - 0x0007FFFF (8 KiB)  
   Programming range 0x0007E000 - 0x0007FFFF (8 KiB)  
   DONE  
   ```  
   > **Note**: The MCU Series 2 devices (like EFM32PG22C200F512IM40) require Simplicity Commander Version 1.12.2 or above to support the `flash --tokengroup znet` command.
5. Run the `security genconfig` command to generate the `user_configuration.json` file for secure boot.  
   ```sh  
   commander security genconfig --nostore --outfile user_configuration.json --device EFR32MG21A010F1024  
   --serialno 440048205  
   DONE  
   ```  
   |**Name**|**Description**|  
   |---|---|  
   |SECURE_BOOT_ENABLE|If set, verifies the host image on the Cortex-M33 before releasing the Cortex-M33 from reset.|  
   |SECURE_BOOT_VERIFY_CERTIFICATE|If set, requires certificate-based signing of the host image.|  
   |SECURE_BOOT_ANTI_ROLLBACK|If set, prevents secure upgrading to a host image with an equal or lower version than the image that is currently stored in flash.|  
   |SECURE_BOOT_PAGE_LOCK_NARROW|If set, locks flash pages that have been validated by the Secure Boot process to prevent re-flashing by other means than through the SE. Write/erase locks pages from 0 through the page where the Secure Boot host image signature is located, not including the last page if the signature is not on a page boundary.|  
   |SECURE_BOOT_PAGE_LOCK_FULL|If set, locks flash pages that have been validated by the Secure Boot process to prevent re-flashing by other means than through the SE. Write/erase locks pages from 0 through the page where the Secure Boot host image signature is located, including the last page if the signature is not on a page boundary.|  
   > **Notes**: The host image is the firmware in the device's flash starting address. It is usually the GBL.  
   >   
   > SECURE_BOOT_PAGE_LOCK_NARROW and SECURE_BOOT_PAGE_LOCK_FULL are not available in Series 3 devices.
6. Use a text editor to modify the default secure boot settings to the desired configurations used in this application note.  
   ![Secure boot settings](/series2-secure-boot-with-rtsl/0.3/images/sld794-image26.jpg)  
   > **Note**: For devices prior to EFR32xG23, if `SECURE_BOOT_ENABLE` is set to false, the SE ignores the other four options regardless of their values, whereas on EFR32xG23 and future Series 2 devices, this configuration cannot be programmed to the SE OTP.
7. Follow the procedure in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) to flash a bootloader image for signature based secure boot.  
   OR  
   Follow the procedure in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to flash a bootloader image for certificate based secure boot.
8. Run the `security writeconfig` command to program the secure boot configuration to the SE OTP. You can execute this command once per device.  
   ```sh  
   commander security writeconfig --configfile user_configuration.json --device EFR32MG21A010F1024  
   --serialno 440048205  
   ```  
   ```sh  
   ================================================================================  
     
   THIS IS A ONE-TIME configuration: Please inspect file before confirming: user_configuration.json  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```
9. Run the `security readconfig` command to check the secure boot configuration of the device.  
   ```sh  
   commander security readconfig --serialno 440048205  
   ```  
   ![Secure Boot configuration](/series2-secure-boot-with-rtsl/0.3/images/sld794-image27.jpg)  
   > **Note**: Enabling Anti-rollback during development involves updating the firmware version every time you decide to flash a new image, this adds complexity. Therefore, it is recommended to enable Anti-rollback during production.

###### SE Manager Key Provisioning Platform Example

1. Click the **View Project Documentation** link to open the readme file.  
   ![Key Provisioning Sample Application](/series2-secure-boot-with-rtsl/0.3/images/sld794-image28.jpg)
2. Modify the default Public Sign Key in `public_sign_key[PUB_KEY_SIZE]` array in `app_process.c` to the desired values.  
   ```sh  
   /// Public sign key  
   SL_ALIGN(4) static const uint8_t public_sign_key[PUB_KEY_SIZE] = {   
     0xc4, 0xaf, 0x4a, 0xc6, 0x9a, 0xab, 0x95, 0x12,  
   0xdb, 0x50, 0xf7, 0xa2, 0x6a, 0xe5, 0xb4, 0x80,   
   0x11, 0x83, 0xd8, 0x54, 0x17, 0xe7, 0x29, 0xa5,  
   0x6d, 0xa9, 0x74, 0xf4, 0xe0, 0x8a, 0x56, 0x2c,  
   0xde, 0x60, 0x19, 0xde, 0xa9, 0x41, 0x13, 0x32,  
   0xdc, 0x1a, 0x74, 0x33, 0x72, 0xd1, 0x70, 0xb4,  
   0x36, 0x23, 0x8a, 0x34, 0x59, 0x7c, 0x41, 0x0e,  
   0xa1, 0x77, 0x02, 0x4d, 0xe2, 0x0f, 0xc8, 0x19  
   };  
   ```
3. Modify the default secure boot settings in `init_se_otp_conf()` function in `app_se_manager_key_provisioning.c` to the desired configuration.  
   ```sh  
   // Overwrite secure boot options in SL_SE_OTP_INIT_DEFAULT if necessary.  
   otp_init.enable_secure_boot = true;  
   otp_init.verify_secure_boot_certificate = false;  
   otp_init.enable_anti_rollback = true;  
   otp_init.secure_boot_page_lock_narrow = false;  
   otp_init.secure_boot_page_lock_full = false;  
   ```  
   > **Note**: If `enable_secure_boot` is false, the SE will ignore the other four options regardless of whether they are true or false. The EFR32xG23 and higher Series 2 devices do not allow this setting to program to the SE OTP.
4. Follow the procedures in [Generate an Unsigned Application Image](#generate-an-unsigned-application-image) to generate the unsigned application image if the GBL is present in the device.
5. Build the project and run the application. Follow the procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) if a signed application image is required.
6. Then press **SPACE** to skip the programming of the AES-128 key (HSE devices only). Optional to press **ENTER** to program the hard-coded [GBL Decryption Key](#se-manager-key-provisioning-platform-example-2) to HSE OTP.  
   ```sh  
   SE Manager Key Provisioning Example - Core running at 38000 kHz.  
   . SE manager initialization... SL_STATUS_OK (cycles: 9 time: 0 us)  
     
   . Get current SE firmware version... SL_STATUS_OK (cycles: 3578 time: 94 us)  
   + Current SE firmware version (MSB..LSB): 00010209  
     
   . Read SE OTP configuration... SL_STATUS_COMMAND_IS_INVALID (cycles: 3908 time: 102 us)  
     
   . Press ENTER to program 128-bit AES key in SE OTP or press SPACE to skip.  
     
   . Encrypt 16 bytes plaintext with 128-bit AES OTP key... SL_STATUS_FAIL (cycles: 4627 time: 121 us)  
     
   . Press ENTER to program public sign key in SE OTP or press SPACE to skip.  
   ```
7. Press **ENTER** to program the hard-coded Public Sign Key to SE OTP.  
   ```sh  
   + Warning: The public sign key in SE OTP cannot be changed once written!  
   + Press ENTER to confirm or press SPACE to skip if you are not sure.  
   ```
8. Press **ENTER** to confirm the operation. The SE returns `SL_STATUS_INVALID_PARAMETER` if the Public Sign Key is present in SE OTP.  
   ```sh  
   . Initialize public sign key... SL_STATUS_OK (cycles: 56052 time: 1475 us)  
     
   . Get public sign key... SL_STATUS_OK (cycles: 8450 time: 222 us)  
   + The public sign key (64 bytes):  
   C4 AF 4A C6 9A AB 95 12 DB 50 F7 A2 6A E5 B4 80  
   11 83 D8 54 17 E7 29 A5 6D A9 74 F4 E0 8A 56 2C  
   DE 60 19 DE A9 41 13 32 DC 1A 74 33 72 D1 70 B4  
   36 23 8A 34 59 7C 41 0E A1 77 02 4D E2 0F C8 19  
     
   . Press ENTER to program public command key in SE OTP or press SPACE to skip.  
   ```  
   ```sh  
   . Initialize public sign key... SL_STATUS_INVALID_PARAMETER (cycles: 4375 time: 115 us)  
     
   . Get public sign key... SL_STATUS_OK (cycles: 8435 time: 221 us)  
   + The public sign key (64 bytes):  
   C4 AF 4A C6 9A AB 95 12 DB 50 F7 A2 6A E5 B4 80  
   11 83 D8 54 17 E7 29 A5 6D A9 74 F4 E0 8A 56 2C  
   DE 60 19 DE A9 41 13 32 DC 1A 74 33 72 D1 70 B4  
   36 23 8A 34 59 7C 41 0E A1 77 02 4D E2 0F C8 19  
     
   . Press ENTER to program public command key in SE OTP or press SPACE to skip.  
   ```
9. Press **SPACE** to skip the programming of the Public Command Key. Optional to press **ENTER** to program the hard-coded Public Command Key to SE OTP.  
   ```sh  
   . Get public command key... SL_STATUS_FAIL (cycles: 4126 time: 108 us)  
     
   . Press ENTER to initialize SE OTP for secure boot configuration or press SPACE to skip.  
   ```
10. Press **ENTER** to program the secure boot configuration.  
    ```sh  
    + Warning: The SE OTP configuration cannot be changed once written!  
    + Press ENTER to confirm or press SPACE to skip if you are not sure.  
    ```
11. Press **ENTER** to confirm the operation. The SE returns `SL_STATUS_COMMAND_IS_INVALID` if an invalid setting from step 2 or the secure boot configuration has been programmed in SE OTP.  
    ```sh  
    . Initialize SE OTP... SL_STATUS_OK (cycles: 267256 time: 7033 us)  
    + Read SE OTP configuration... SL_STATUS_OK (cycles: 6865 time: 180 us)  
    + Secure boot	                 : Enabled  
    + Secure boot verify certificate : Disabled  
    + Secure boot anti-rollback	     : Enabled  
    + Secure boot page lock narrow	 : Disabled  
    + Secure boot page lock full	 : Disabled  
      
    . SE manager deinitialization... SL_STATUS_OK (cycles: 5 time: 0 us)  
    ```  
    ```sh  
    . Initialize SE OTP... SL_STATUS_COMMAND_IS_INVALID (cycles: 3989 time: 104 us)  
      
    . SE manager deinitialization... SL_STATUS_OK (cycles: 5 time: 0 us)  
    ```

###### Simplicity Studio

The security operations are performed in the Security Settings of Simplicity Studio. This application note uses Simplicity Studio v5.2.3.1. The procedures and pictures may be different for the other versions of Simplicity Studio 5.

1. Right-click the selected debug adapter **RB (ID:J-Link serial number)** to display the context menu.  
   ![Debug Adapters Context Menu](/series2-secure-boot-with-rtsl/0.3/images/sld794-image29.jpg)
2. Click **Device configuration...** to open the **Configuration of device: J-Link Silicon Labs (serial number)** dialog box. Click the **Security Settings** tab to get the selected device configuration.  
   ![Configuration on Selected Device](/series2-secure-boot-with-rtsl/0.3/images/sld794-image30.png)
3. Click [**Start Provisioning Wizard…**] in the upper right corner to display the **Secure Initialization** dialog box. Checking the **Enable Version Rollback Prevention of Host Image** option is recommended. The **Verify intermediate certificate before secure boot** option is for [Certificate-based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ![Secure Initialization Dialog Box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image31.png)  
   > **Note**: The [SECURE_BOOT_PAGE_LOCK_NARROW and SECURE_BOOT_PAGE_LOCK_FULL](#simplicity-commander) options are not yet available in Simplicity Studio.
4. Click [**Next >**]. The **Security Keys** dialog box is displayed.  
   ![Security Keys Dialog Box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image32.png)
5. Checking the **Enable Writing Sign Key** checkbox will automatically enable Secure Boot. The following **Secure Boot Warning** is displayed. Click [**Yes**] to confirm.  
   ![Secure Boot Warning](/series2-secure-boot-with-rtsl/0.3/images/sld794-image33.png)
6. Open the [Public Sign Key](#generate-key-and-signing) token file (`sign_pubkey.txt`).  
   ```sh  
   MFG_SIGNED_BOOTLOADER_KEY_X : 997011ED1708580BD4A6B7F8AD6EE19B0B8722611FB76A3A5702D5141180E101  
   MFG_SIGNED_BOOTLOADER_KEY_Y : 0AC8673C8ACC26EE2B534C004F4A4B7EBBC23D04506DD66E3EF0DDC81E3CA55E  
   ```
7. Copy Public Sign Key (X-point `9970...` first, then Y-point `0AC8...`) to **Key:** box under **Sign Key:**.  
   ![Enter Public Sign Key](/series2-secure-boot-with-rtsl/0.3/images/sld794-image34.jpg)
8. Click [**Next >**]. The **Secure Locks** dialog box is displayed. When Secure Boot is enabled, the **Debug Locks** are not set by default. Refer to [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) for more information about these locks.  
   ![Security Locks Dialog Box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image35.png)
9. Click [**Next >**] to display the **Summary** dialog box.  
   ![Summary Dialog Box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image36.jpg)
10. If the information displayed is correct, click [**Provision**]. Click [**Yes**] to confirm. The Public Sign Key and Secure Boot configuration cannot be changed once written.

![One Time Device Provisioning Window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image37.jpg)

1. The **Summary** dialog box displays the **Provisioning Status**.

![Provisioning Status](/series2-secure-boot-with-rtsl/0.3/images/sld794-image38.jpg)

1. Click [**Done**] to exit the provisioning process. The device configuration is updated.

##### Provision GBL Decryption Key

The GBL Decryption Key is used to decrypt the [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) payloads during firmware upgrade. You should provision this key before enabling the **Require encrypted firmware upgrade files** option in AppBuilder plugin and [3.4.1.2 Bootloader-core Software Component](#bootloader-core-software-component).

The following figures and table show the available options, two for VSE and three for HSE, for selecting the GBL Decryption Key used to decrypt the GBL upgrade image (bootloader, SE, or application).

![App Builder Options](/series2-secure-boot-with-rtsl/0.3/images/sld794-image39.jpg)

![Bootloader Software Component Options](/series2-secure-boot-with-rtsl/0.3/images/sld794-image40.jpg)

|**Option for GBL Decryption Key Selection**|**GBL Decryption Key Storage**|
|---|---|
|1. Use symmetric key stored in Secure Element storage (HSE devices only and GSDK ≥ v3.0).|The 128-bit symmetric key stored in HSE OTP is used for GBL upgrade image file decryption.|
|2. Use symmetric key stored in Application Properties Struct (GSDK ≥ v4.1).|The 128-bit symmetric key stored in the GBL Application Properties Struct is used for GBL upgrade image file decryption. The key is stored in the Secure flash if TrustZone is implemented.|
|3. Default storage if none of the above options are selected.|The 128-bit symmetric key stored on the top page of the main flash is used for GBL upgrade image file decryption. The key is stored in the Non-secure flash if TrustZone is implemented.|

**Note**:

- Option 2 requires `ApplicationProperties_t` struct v1.2 or higher (defined in `application_properties.h` in the Windows folder `C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\platform\bootloader\api`) in GSDK v4.1 or higher to store the GBL Decryption Key.

```c
/// Major version number of the ApplicationProperties_t struct #define APPLICATION_PROPERTIES_VERSION_MAJOR (1UL)
/// Minor version number of the ApplicationProperties_t struct #define APPLICATION_PROPERTIES_VERSION_MINOR (2UL)
```

```sh
/// Application Properties struct typedef struct {
/// @brief Magic value indicating this is an ApplicationProperties_t struct.
/// Must equal @ref APPLICATION_PROPERTIES_MAGIC uint8_t magic[16];
/// Version number of this struct uint32_t structVersion;
/// Type of signature this application is signed with uint32_t signatureType;
/// Location of the signature. Typically points to the end of the application uint32_t signatureLocation;
/// Information about the application ApplicationData_t app;
/// Pointer to information about the certificate ApplicationCertificate_t *cert;
/// Pointer to Long Token Data Section uint8_t *longTokenSectionAddress;
/// Parser Decryption Key const uint8_t decryptKey[16];
} ApplicationProperties_t;
```

- Option 2 must be implemented before signing the GBL image for [ECDSA-P256-SHA256](#signing-for-ecdsa-p256-sha256-secure-boot) or [certificate-based](#signing-for-certificate-based-secure-boot) Secure Boot.
- The options for the GBL Decryption Key are mutually exclusive. Either one of the two (VSE) or three (HSE) key storages will be selected for decryption.
- From a security point of view, it is highly recommended to use or upgrade to option 1 for HSE devices and option 2 for VSE devices.
- If the GBL Decryption Key in the selected option is compromised, the simple way is to upgrade the GBL to option 2 (if the existing option is 1 or 3) with the new GBL Decryption Key.

###### Simplicity Commander

The following procedures describe how to program the GBL Decryption Key for the options below. All procedures assume the required files are in the same folder.

- Use symmetric key stored in Secure Element storage (HSE devices only and GSDK ≥ v3.0)
- Use symmetric key stored in Application Properties Struct (GSDK ≥ v4.1)
- Default Storage on the Top Page of the Main Flash

1. Generate a 128-bit Symmetric Key.  
   Run the `util genkey` command to generate the token file for the GBL Decryption Key.  
   ```sh  
   commander util genkey --type aes-ccm --outfile aes_key.txt  
   ```  
   ```sh  
   Using Windows' Cryptographic random number generator  
   DONE  
   ```
2. (**Use symmetric key stored in Secure Element storage**) Run the `security writekey` command to provision the GBL Decryption Key to the SE OTP slot. The GBL Decryption Key cannot be changed once written.  
   ```sh  
   commander security writekey --decrypt aes_key.txt --device EFR32MG21A010F1024 --serialno 440030580  
   ```  
   ```sh  
   Device has serial number 0000000000000000000d6ffffead3d94  
     
   ================================================================================  
   Please look through any warnings before proceeding.  
   THIS IS A ONE-TIME command, any encrypting of GBL files must be done with this key.  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```  
   > **Note**: It cannot read back the GBL Decryption Key from the HSE OTP.
3. (**Use symmetric key stored in Application Properties Struct**) Run the `convert` command to program the GBL Decryption Key to the `Application Properties Struct` of the GBL.  
   ```sh  
   commander convert bootloader-uart-xmodem.s37 --aeskey aes_key.txt --outfile bootloader-uart-xmodem.s37  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing to bootloader-uart-xmodem.s37...  
   Overwriting file: bootloader-uart-xmodem.s37...  
   DONE  
   ```  
   **Notes**:  
   - The `--aeskey` option in the `convert` command requires **Simplicity Commander v1.12.3 or above**.  
   - The GBL Decryption Key can only be added to the GBL with `Application Properties Struct` v1.2 or higher.
4. (**Default Storage on the Top Page of the Main Flash**) Run the `flash` command to program the GBL Decryption Key in the token file to the top page of the main flash.  
   ```sh  
   commander flash --tokengroup znet --tokenfile aes_key.txt --device EFR32MG21A010F1024 --serialno 440030580  
   ```  
   ```sh  
   Writing 8192 bytes starting at address 0x000fe000  
   Comparing range 0x000FE000 - 0x000FFFFF (8 KB)  
   Programming range 0x000FE000 - 0x000FFFFF (8 KB)  
   DONE  
   ```  
   > **Note**: The MCU Series 2 VSE devices (like EFM32PG22C200F512IM40) require Simplicity Commander Version 1.12.2 or above to support the flash --tokengroup znet command.

###### SE Manager Key Provisioning Platform Example

This example only applies to [option 1](#provision-gbl-decryption-key) for Series 2 and Series 3 HSE devices. Click the **View Project Documentation** link to open the readme file.

![Key Provisioning Sample Application](/series2-secure-boot-with-rtsl/0.3/images/sld794-image28.jpg)

1. Modify the default GBL Decryption Key in the `aes_key[16]` array in `app_process.c` to the desired values.  
   ```sh  
   /// 128-bit AES key  
   SL_ALIGN(4) static const uint8_t aes_key[16] = {   
   0x81, 0xa5, 0xe2, 0x1f, 0xa1, 0x52, 0x86, 0xf1,   
   0xdf, 0x44, 0x5c, 0x2c, 0xc1, 0x20, 0xfa, 0x3f  
   };  
   ```
2. Modify the `ciphertext[16]` array in `app_process.c` to the expected ciphertext for AES ECB on 16 bytes zero plaintext to verify the GBL Decryption Key in step 1.  
   ```sh  
   /// Ciphertext to verify 128-bit AES key static const uint8_t ciphertext[16] = {  
   0x66, 0xd2, 0x0f, 0x99, 0x65, 0x3e, 0xa8, 0xd0, 0x83, 0x05, 0xa6, 0x39, 0xd4, 0x4e, 0x98, 0xa6  
   };  
   ```
3. Follow the procedures in [Generate an Unsigned Application Image](#generate-an-unsigned-application-image) to generate the unsigned application image if the GBL is present in the device.
4. Build the project and run the application. Follow the procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) if a signed application image is required.
5. Then press ENTER to program the hard-coded GBL Decryption Key to HSE OTP.  
   ```sh  
   SE Manager Key Provisioning Example - Core running at 38000 kHz.  
   . SE manager initialization... SL_STATUS_OK (cycles: 9 time: 0 us)  
     
   . Get current SE firmware version... SL_STATUS_OK (cycles: 3578 time: 94 us)  
   + Current SE firmware version (MSB..LSB): 00010209  
     
   . Read SE OTP configuration... SL_STATUS_COMMAND_IS_INVALID (cycles: 3908 time: 102 us)  
     
   . Press ENTER to program 128-bit AES key in SE OTP or press SPACE to skip.  
   + Warning: The 128-bit AES key in SE OTP cannot be changed once written!  
   + Press ENTER to confirm or press SPACE to skip if you are not sure.  
   ```
6. Press **ENTER** to confirm the operation. The program either returns `SL_STATUS_OK` or `SL_STATUS_INVALID_PARAMETER` (already present) and performs AES ECB encryption to verify the GBL Decryption Key in HSE OTP.  
   ```sh  
   . Initialize 128-bit AES key... SL_STATUS_OK (cycles: 39059 time: 1027 us)  
     
   . Encrypt 16 bytes plaintext with 128-bit AES OTP key... SL_STATUS_OK (cycles: 11013 time: 289 us)  
   + Compare encrypted message with expected ciphertext... OK  
     
   . Press ENTER to program public sign key in SE OTP or press SPACE to skip.  
   ```  
   ```sh  
   . Initialize 128-bit AES key... SL_STATUS_INVALID_PARAMETER (cycles: 4474 time: 117 us)  
     
   . Encrypt 16 bytes plaintext with 128-bit AES OTP key... SL_STATUS_OK (cycles: 11001 time: 289 us)  
   + Compare encrypted message with expected ciphertext... OK  
     
   . Press ENTER to program public sign key in SE OTP or press SPACE to skip.  
   ```
7. Press **SPACE** to skip the programming of the Public Sign Key.  
   ```sh  
   . Get public sign key... SL_STATUS_FAIL (cycles: 4126 time: 108 us)  
     
   . Press ENTER to program public command key in SE OTP or press SPACE to skip.  
   ```
8. Press **SPACE** to skip the programming of the Public Command Key.  
   ```sh  
   . Get public command key... SL_STATUS_FAIL (cycles: 4126 time: 108 us)  
     
   . Press ENTER to initialize SE OTP for secure boot configuration or press SPACE to skip.  
   ```
9. Press **SPACE** to skip the programming of the secure boot configuration.  
   ```sh  
   . SE manager deinitialization... SL_STATUS_OK (cycles: 10 time: 0 us)  
   ```

##### Secure Boot

You should usually not enable Secure Boot during the development phase to avoid a clash on [debugging](04-debugging-on-secure-boot-enabled-device#debugging-on-secure-boot-enabled-device). The Secure Boot feature is enabled near firmware release and uses the following sections to validate the configuration and system functionality.

###### Generate an Unsigned GBL Image

There are two ways to configure the application firmware through a GBL project.

1. Use [AppBuilder](#appbuilder) (`.isc file`) in **GSDK v3.2 and lower**.
2. Use [Bootloader-core software component](#bootloader-core-software-component) (`.slcp` file) in **GSDK v4.0 and higher**, and **SiSDK v2024.6.0 and higher**.

The following notes apply to the AppBuilder and Bootloader-core software component.

- Enabling the **Allow use of public key from manufacturing token storage** option is mandatory on VSE devices (cannot be disabled in AppBuilder and is discarded in Bootloader-core software component) for [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot).
- The HSE device ignores this default enabled option if the Public Sign Key has been provisioned in OTP.
- When the **Enable application rollback protection** option (GSDK ≥ v3.0) is enabled, the GBL stores an application version counter at the end of the bootloader space in flash. The GBL checks this version during upgrades and at every boot, but it does not prevent flashing an older image onto the device.
- The **Minimum application version allowed** option (GSDK ≥ v3.0) sets the lowest application version that can boot. This option maintains the version counter, which resets to 0 after upgrading the GBL.
- The **Enable application rollback protection** option is not applicable if the [SECURE_BOOT_PAGE_LOCK_FULL](#simplicity-commander) in SE OTP is enabled. See section "_Secure Boot with Application Rollback Protection_" in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf) (for GSDK v3.2 and lower), [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/), or [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) for details about the application rollback protection.
- The GBL size and starting address are device-dependent. For more information about the bootloader size and starting address on Series 2, see section "Memory Space For Bootloading" in [Bootloader Fundamentals](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/).

Refer to [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) to create GBL upgrade image file for the **Require signed firmware upgrade files** and **Require encrypted firmware upgrade files** options. For simplicity, the Secure Boot examples in this application note do not enable these options. Refer to [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf), [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/), or [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) for information about these options.

The following sections describe how to build the unsigned GBL image from the **UART XMODEM Bootloader** (GSDK < v4.1) or **Bootloader - NCP UART XMODEM** (GSDK ≥ v4.1).

![Bootloader options](/series2-secure-boot-with-rtsl/0.3/images/sld794-image41.jpg)

###### AppBuilder (heading level 7)

This application note uses UART XMODEM Bootloader example v1.12.0 in GSDK v3.2.3. The procedures and pictures may be different for the other versions of this example.

1. Create a UART XMODEM Bootloader project.
2. The **Plugins** tab in AppBuilder (bootloader-uart-xmodem.isc) shows the default configurations for the UART XMODEM Bootloader example.
3. Use **Bootloader Core, provides API: core** in the **Plugins** tab to set up the application firmware configurations.  
   a. This application note uses the configuration below for [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot).  
   ```c  
   ![ECDSA-P256-SHA256 Secure Boot configuration](./resources/sld794-image42.jpeg)  
   ```  
   b. This application note uses the configuration below for [Certificate-based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
   ![Certificate-based Secure Boot configuration](./resources/sld794-image43.jpeg)  
   ```
4. Enter a higher version number (default is 0) to the macro **BOOTLOADER_VERSION_MAIN_CUSTOMER** → **Value** in the **Additional Macros** field on the **Other** tab for [anti-rollback protection](#provision-public-sign-key-and-secure-boot-enabling) of GBL.  
   ![Bootloader version macro](/series2-secure-boot-with-rtsl/0.3/images/sld794-image44.png)
5. The default setting of GBL will overwrite the existing application image when upgrading the GBL or SE. It forces to update the application image even without changes on the firmware. Use the AppBuilder settings below to keep the existing application image when upgrading the GBL or SE.  
   a. Enter the required application image size to the macro **BTL_APP_SPACE_SIZE** → **Value** in the **Additional Macros** field on the **Other** tab. Check the **-D?** checkbox to add this definition to the project.  
   ```c  
    This application note uses 507904 (496 kB) to replace the default value of ((FLASH_BASE + FLASH_SIZE) - BTL_APPLICATION_BASE).  
     
    ![Bootloader application size macro](./resources/sld794-image45.jpeg)  
   ```  
   b. The **Base address of bootloader upgrade image** ≥ (**BTL_APP_SPACE_SIZE** + size of the GBL). The example in this application note uses EFR32MG21A010F1024:  
   ```c  
    Base address of bootloader upgrade image = 507904 (496 kB) + 16384 (16 kB for GBL) = 524288 (512 kB)  
     
    ![Base address of bootlader upgrade image](./resources/sld794-image46.png)  
     
    > **Note**: The default value of Base address of bootloader upgrade image is 32768 (32 kB).  
   ```  
   c. The (**Base address of bootloader upgrade image** + size of the GBL or SE + upgrade file overhead) ≤ the available size of the device main flash for application use (see project linker file for details).  
   ```c  
    The example in this application note uses EFR32MG21A010F1024:  
     
    512 kB (Base address of bootloader upgrade image) + 16 kB (GBL) or 48 kB (SE) + overhead bytes \< 1024 kB (size of main flash)  
     
    For more information about the size of the GBL and SE, see section *Storage Space Size Configuration* in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf).  
     
    > **Note**: It requires GBL v1.11.0 or above to support this feature.  
   ```
6. Click [**Generate**] in the right upper corner.
7. In the **Generation Successful** dialog, click [**OK**].
8. Build the project to generate the unsigned GBL image file (`bootloader-uart-xmodem.s37`).
9. **(Optional)** Run the `util appinfo` command to check all available information (application properties) in an unsigned GBL image. The `App version` is the GBL version for the [SECURE_BOOT_ANTI_ROLLBACK](#simplicity-commander) option.

```sh
commander util appinfo bootloader-uart-xmodem.s37
```

```sh
Parsing file bootloader-uart-xmodem.s37...
Found application properties in image.
Application properties info:
Application properties location : 0x00002b1c
Signature location	            : 0x00002d08
Signature type	                : No signature
Long token section address	    : Not set (0x00000000)

Application data info:
For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.
App type	                    : Bootloader (APPLICATION_TYPE_BOOTLOADER)
App version	                    : 0x010c0000
Product ID	                    : Not set (0x00000000000000000000000000000000)

No certificate found in image.
For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.
DONE
```

###### Bootloader-core Software Component (heading level 7)

This application note uses UART XMODEM Bootloader example v2.0.0 in GSDK v4.0. The procedures and pictures may be different for the other versions of this example.

1. Create a UART XMODEM Bootloader project.
2. Checking the **Installed Components** under the **SOFTWARE COMPONENTS** tab shows the list of installed components (`bootloader-uart-xmodem.slcp`) in the UART XMODEM Bootloader example.
3. Click [**Configure**] in the **Bootloader-core** component to open the **Bootloader Core Configuration**.  
   ![Bootloader-core component](/series2-secure-boot-with-rtsl/0.3/images/sld794-image47.jpg)  
   > **Note:** Install "Bootloader Core (Series-3)" for series 3 devices.
4. Use **Bootloader Core Configuration** in **Bootloader-core** to set up the application firmware configurations.
5. This application note uses the configuration below for [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot).  
   ![Bootloader Core configuration for ECDSA-P256-SHA256 Secure Boot](/series2-secure-boot-with-rtsl/0.3/images/sld794-image48.png)
6. This application note uses the configuration below for [Certificate-based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ![Bootloader Core configuration for Certificate-based Secure Boot](/series2-secure-boot-with-rtsl/0.3/images/sld794-image49.png)
7. [For series 2 devices only] Enter a higher version number (default is 0) to **BOOTLOADER VERSION MAIN CUSTOMER** for [anti-rollback protection](#provision-public-sign-key-and-secure-boot-enabling) of GBL.  
   ![screenshot](/series2-secure-boot-with-rtsl/0.3/images/sld794-image50.jpg)
8. [For series 2 devices only] The default setting of GBL will overwrite the existing application image when upgrading the GBL or SE. It forces to update the application image even without changes on the firmware. Use the Bootloader-core settings below to keep the existing application image when upgrading the GBL or SE.  
   a. Enter the required application image size to the **Enter Bootloader App Space Size** dialog box after enabling the **Use custom Bootloader Application Size** option.  
   ```c  
    This application note uses 507904 (496 kB) to replace the default value of 0.  
     
    ![screenshot](./resources/sld794-image51.jpeg)  
   ```  
   b. The **Base address of bootloader upgrade image** ≥ (**Enter Bootloader App Space Size** + size of the GBL). The example in this application note uses EFR32MG21A010F1024:  
   ```c  
    Base address of bootloader upgrade image = 507904 (496 kB) + 16384 (16 kB for GBL) = 524288 or 0x80000 (512 kB)  
     
    ![screenshot](./resources/sld794-image52.png)  
     
    > **Note**: The default value of Base address of bootloader upgrade image is 32768 or 0x8000 (32 kB).  
   ```  
   c. The (**Base address of bootloader upgrade image** + size of the GBL or SE + upgrade file overhead) ≤ the available size of the device main flash for application use (see project linker file for details).  
   ```c  
    The example in this application note uses EFR32MG21A010F1024:  
     
    512 kB (Base address of bootloader upgrade image) + 16 kB (GBL) or 48 kB (SE) + overhead bytes \< 1024 kB (size of main flash)  
     
    For more information about the size of the GBL and SE, see section *Storage Space Size Configuration* in [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/).  
   ```
9. Click [**X**] in the right upper corner to exit the **Bootloader Core Configuration**.
10. Build the project to generate the unsigned GBL image file (bootloader-uart-xmodem.s37).
11. **(Optional)** Run the `convert` command to program the GBL Decryption Key to the Application Properties Struct if this [GBL Decryption Key option](#provision-gbl-decryption-key) in GBL (GSDK ≥ v4.1) is selected.

```sh
commander convert bootloader-uart-xmodem.s37 --aeskey aes_key.txt --outfile bootloader-uart-xmodem.s37
```

```sh
Parsing file bootloader-uart-xmodem.s37...
Writing to bootloader-uart-xmodem.s37...
Overwriting file: bootloader-uart-xmodem.s37...
DONE
```

1. **(Optional)** Run the `util appinfo` command to check all available information (application properties) in an unsigned GBL image. The App version is the GBL version for the [SECURE_BOOT_ANTI_ROLLBACK](#simplicity-commander) option.

```sh
commander util appinfo bootloader-uart-xmodem.s37
```

```sh
Parsing file bootloader-uart-xmodem.s37...
Found application properties in image.
Application properties info:
Application properties location : 0x00002b30
Signature location	            : 0x00002c44
Signature type	                : No signature
Long token section address	    : Not set (0x00000000)

Application data info:
For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.
App type	                    : Bootloader (APPLICATION_TYPE_BOOTLOADER)
App version	                    : 0x02000000
Product ID	                    : Not set (0x00000000000000000000000000000000)

No certificate found in image.
For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.
DONE
```

> **Note**: For TrustZone-aware bootloaders, the unsigned GBL image is the combined image of Secure and Non-secure bootloaders. The **Bootloader-core** component is installed in the Secure bootloader.

###### Generate an Unsigned Application Image

This section describes how to generate an unsigned application image for the GBL.

1. For Series 2 devices, the application image should be placed on the main flash page after the GBL. For more information about the application starting address, see section _Memory Space For Bootloading_ in [Bootloader Fundamentals](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/).
2. For Series 3 devices, the application image should be placed in the code region 1 next to the bootloader which is in region 0, see section _External Flash Architecture in Series 3 Devices_ in [Platform Memory Model](https://docs.silabs.com/gecko-platform/latest/platform-memory-model/).
3. **(Simplicity Studio 5)** You can use the **Bootloader Application Interface** component to set up the start address of the application image. This application note uses **Platform - Blink Bare-metal** example in GSDK v3.2.3. The procedures and pictures may be different on other versions of the GSDK. The following steps can apply to other platform examples in GSDK and SiSDK.  
   a. Create a **Platform - Blink Bare-metal** project.  
   b. The **Software Components** tab shows the list of available components (`blink_baremetal.slcp`) that you can install in the project.  
   c. Select **Platform > Bootloader > Bootloader Application Interface**.  
   d. Click [**Install**].  
   ![Bootloader Application Interface](/series2-secure-boot-with-rtsl/0.3/images/sld794-image53.jpg)  
   > **Note**: For the wireless protocol stack example, the Bootloader Application Interface component is already present in the project.
4. The application image should contain an `ApplicationProperties_t` struct (defined in `application_properties.h` in the Windows folder below) declaring the application version, capabilities, and other metadata.  
   For GSDK v3.2 and lower: `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION>\platform\bootloader\api`  
   For SiSDK v2024.6.0 and higher, or GSDK v4.0 and higher: `C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\platform\bootloader\api`  
   Below is an example source file `app_properties.c` with `ApplicationProperties_t` struct for Secure Boot on GSDK v3.2 and lower.  
   ```sh  
   #include <stddef.h>  
   #include "application_properties.h"  
     
   const ApplicationProperties_t sl_app_properties = {  
   .magic = APPLICATION_PROPERTIES_MAGIC,  
   .structVersion = APPLICATION_PROPERTIES_VERSION,  
   .signatureType = APPLICATION_SIGNATURE_NONE,  
   .signatureLocation = 0,  
   .app = {  
       .type = APPLICATION_TYPE_MCU,  
       .version = 1UL,  
       .capabilities = 0UL,  
       .productId = {0U},  
   },  
   };  
   ```  
   The `signatureType` and `signatureLocation` are filled by Simplicity Commander when signing the application image using the `convert` command.
5. The following table describes how to add the `app_properties.c` file in step 4 to **Platform - Blink Bare-metal** project. For the wireless protocol stack example, the `app_properties.c` file with `ApplicationProperties_t` struct is already present in the project.  
   **App properties for older Simplicity Studio and GSDK versions**  
   |**Simplicity Studio 4 & Simplicity Studio 5 with GSDK v3.2 and lower**|**Simplicity Studio 5 with GSDK v4.0 and higher**|  
   |---|---|  
   |Manually added|Automatically added after installing the Bootloader Application Interface component in step 3 to the project.|  
   > **Note**: Refer to the [Knowledge Article](https://community.silabs.com/s/article/what-are-the-steps-to-add-application-properties-to-a-application-project-x?language=en_US) in Silicon Labs Community to add `app_properties.c` to the project in Simplicity Studio 4.
6. **(Simplicity Studio 4 & Simplicity Studio 5 with GSDK v3.2 and lower)** Enter a higher version number to `.version` in `app_properties.c` for [anti-rollback protection](#generate-an-unsigned-gbl-image) (if enabled) of the application.
7. **(Simplicity Studio 5 with GSDK v4.0 and higher)** Click [**Configure**] in the **App Properties** component under **Platform** > **Bootloader** to open the **App Properties** configuration. The example below uses GSDK v4.0. The procedures and pictures may be different on other versions of the GSDK.  
   ![App Properties component](/series2-secure-boot-with-rtsl/0.3/images/sld794-image54.jpg)
8. Enter a higher version number to **Version number for this application** dialog box in **App Properties settings** for [anti-rollback protection](#generate-an-unsigned-gbl-image) (if enabled) of the application.  
   ![App properties version number dialog box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image55.png)  
   > **Note**: The `app_properties.c` is in the Windows folder below.  
   >   
   > `C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\platform\bootloader\app_properties`
9. Build the project to generate the unsigned application image file (`blink_baremetal.s37`).
10. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in an un-signed application image. The App version is for the **Enable application rollback protection** option in the [AppBuilder](#appbuilder or [Bootloader-core software component](#bootloader-core-software-component).

```sh
commander util appinfo blink_baremetal.s37
```

```sh
Parsing file blink_baremetal.s37...
Found application properties in image. Application properties info:
Application properties location : 0x00006198
Signature location	            : Not set (0x00000000)
Signature type	                : No signature
Long token section address	    : Not set (0x00000000)

Application data info:
For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.
App type	                    : MCU application (APPLICATION_TYPE_MCU)
App version	                    : 0x00000001
Product ID	                    : Not set (0x00000000000000000000000000000000)

No certificate found in image.
For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.
DONE
```

**Note:** For the TrustZone-aware applications, the unsigned application image is the combined image of Secure and Non-secure applications. The `ApplicationProperties_t` struct is located in the Secure application.

###### Signing for ECDSA-P256-SHA256 Secure Boot

The following figure describes the signing and verification for ECDSA-P256-SHA256 Secure Boot.

![ECDSA-P256-SHA256 Sign and Verify](/series2-secure-boot-with-rtsl/0.3/images/sld794-ecdsa-p256-sha256-sign-verify.png)

> **Note**: The bootloader cannot access the Public Sign Key in VSE OTP to verify the application image. Therefore VSE devices need to store a [Public Sign Key copy](#simplicity-commander) on the top page of the main flash (see section _Key Storage_ in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/)).

**Public Sign Key usage for VSE and HSE Devices**

|**Device**|**FSB to Verify the Bootloader Image**|**SSB to Verify the Application Image**|
|---|---|---|
|HSE|Use the Public Sign Key in HSE OTP|Use the Public Sign Key in HSE OTP|
|VSE|Use the Public Sign Key in VSE OTP|Use the Public Sign Key on the top page of the main flash|

The HSE device ignores the default enabled [Allow use of public key from manufacturing token storage option](02-secure-boot-process#application-firmware) once the Public Sign Key has been provisioned.

To have better protection on the Public Sign Key, the [certificate-based](#signing-for-certificate-based-secure-boot) Secure Boot is strongly recommended on VSE devices since the SSB does not require accessing the Public Sign Key to verify the application signature.

The following sections provide two methods to sign the bootloader image and application image files. All procedures assume the required files are in the same folder.

1. Using Simplicity Commander
2. Using an HSM and Simplicity Commander

###### Bootloader Image File (heading level 7)

1. If Secure Boot flag is not enabled in SE OTP, follow the procedures in [Simplicity Commander](#simplicity-commander) to set up the ECDSA-P256-SHA256 Secure Boot configuration for the bootloader.
2. Follow the procedures in [AppBuilder](#appbuilder) or [Bootloader-core Software Component](#bootloader-core-software-component) to set up the ECDSA-P256-SHA256 Secure Boot configuration for the user application to generate an unsigned bootloader image.
3. The following steps show two methods to generate a signed bootloader image—either directly with Simplicity Commander (3a) or using an HSM with Commander (3b).  
   a. **(Using Simplicity Commander)** Run the `convert` command with **Private Sign Key** to overwrite the unsigned bootloader image file with the signed bootloader image file (`bootloader-uart-xmodem.s37`).  
   ```c  
    ```sh  
    commander	convert	bootloader-uart-xmodem.s37	--secureboot	--keyfile	sign_key.pem	--verify sign_pubkey.pem  
    --outfile bootloader-uart-xmodem.s37  
    ```  
     
    ```sh  
    Parsing file bootloader-uart-xmodem.s37... Found Application Properties at 0x00002b1c  
    Writing Application Properties signature pointer to point to 0x00002d08  
    Setting signature type in Application Properties: 0x00000001  
    Image SHA256: c53bb8a3fd88a5071bfb71444324bb136b276160318488ff89011bbd269e114e  
    R = AB62F3A52B13D137FBCC6A2176D4D1852E06B6E4E6B2673DC251FC491450CBDA  
    S = 9C7C7AF2624165FD90FB3B114E3FA6FE4F4C5625B15C9F3D50DCB04DD06A7B19  
     
    Verifying signed image...  
    Writing to bootloader-uart-xmodem.s37...  
    Overwriting file: bootloader-uart-xmodem.s37...  
    DONE  
    ```  
   ```  
   b. **(Using an HSM and Simplicity Commander)** Run the `convert` command with `--extsign` option to generate an external signing bootloader image file (`bootloader-uart-xmodem.extsign`).  
   ```c  
    ```sh  
    commander convert bootloader-uart-xmodem.s37 --secureboot --extsign --outfile bootloader-uart-xmodem  
    ```  
     
    ```sh  
    Parsing file bootloader-uart-xmodem.s37... Found Application Properties at 0x00002b1c  
    Writing Application Properties signature pointer to point to 0x00002d08  
    Setting signature type in Application Properties: 0x00000001  
    Writing to bootloader-uart-xmodem.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key to generate the signature for the external signing bootloader image. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** to simulate this process. The signature is in the `bl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out bl_signature.der bootloader-uart-xmodem.extsign  
    ```  
     
    Run the `convert` command with the **bootloader image signature** to overwrite the unsigned bootloader image file with the signed bootloader image file (`bootloader-uart-xmodem.s37`).  
     
    ```sh  
    commander convert bootloader-uart-xmodem.s37 --secureboot --signature bl_signature.der  
    --verify sign_pubkey.pem --outfile bootloader-uart-xmodem.s37  
    ```  
     
    ```sh  
    Parsing file bootloader-uart-xmodem.s37... Parsing signature file bl_signature.der...  
    R = 0E9FC64F41B55367894908D3ADAC40E8D145E33224C4BAA8151EC3EFD107A154  
    S = F56230AA6484E55270F22A4D164377CA918F66A367656AB6E10CB3F58641CE84  
    Found Application Properties at 0x00002b1c  
    Writing Application Properties signature pointer to point to 0x00002d08  
    Setting signature type in Application Properties: 0x00000001  
     
    Verifying signed image...  
    Writing to bootloader-uart-xmodem.s37...  
    Overwriting file: bootloader-uart-xmodem.s37...  
    DONE  
    ```  
   ```
4. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in a signed GBL image.  
   ```sh  
   commander util appinfo bootloader-uart-xmodem.s37  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37...  
   Found application properties in image.  
   Application properties info:  
   Application properties location : 0x00002b30  
   Signature location	            : 0x00002c44  
   Signature type	                : ECDSA-P256  
   Long token section address	    : Not set (0x00000000)  
     
   Application data info:  
   For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.  
   App type	                    : Bootloader (APPLICATION_TYPE_BOOTLOADER)  
   App version	                    : 0x02000000  
   Product ID	                    : Not set (0x00000000000000000000000000000000)  
     
   No certificate found in image.  
   For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.  
   DONE  
   ```
5. The signed bootloader image file (`.s37`) can be used for [production programming](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) or for generating a [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for bootloader upgrade.
6. Run the `flash` command to program the signed bootloader image (`bootloader-uart-xmodem.s37`) to the device if the device does not have a bootloader.  
   ```sh  
   commander flash bootloader-uart-xmodem.s37 --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing 16384 bytes starting at address 0x00000000  
   Comparing range 0x00000000 - 0x00003FFF (16 KiB)  
   Programming range 0x00000000 - 0x00001FFF (8 KiB)  
   Programming range 0x00002000 - 0x00003FFF (8 KiB)  
   DONE  
   ```  
   Simplicity Commander output for Series 3 devices will look as follows:  
   ```sh  
   WARNING: Failed secure boot detected. Issuing a mass erase before flashing to recover the device...  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing 14280 bytes starting at address 0x01000000  
   Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB)  
   Programming range 0x01000000 - 0x01000FFF (4 KB)  
   Programming range 0x01001000 - 0x01001FFF (4 KB)  
   Programming range 0x01002000 - 0x01002FFF (4 KB)  
   Programming range 0x01003000 - 0x01003FFF (4 KB)  
   Programming range 0x01004000 - 0x01004FFF (4 KB)  
   Programming range 0x01005000 - 0x01005FFF (4 KB)  
   Programming range 0x01006000 - 0x01006FFF (4 KB)  
   Programming range 0x01007000 - 0x01007FFF (4 KB)  
   JLinkError: Failed to halt CPU.  
   Closing region 0 (this consumes one OTP bit, consider --noclose on development/testing devices)  
   Flashing completed successfully!  
   DONE  
   ```

###### Application Image File (heading level 7)

1. Follow the procedures in [Generate an Unsigned Application Image](#generate-an-unsigned-application-image) to generate an unsigned application image for the bootloader.
2. The following steps show two methods to generate a signed application image, either directly with Simplicity Commander (2a) or using an HSM with Commander and OpenSSL (2b).  
   a. **(Using Simplicity Commander)** Run the `convert` command with **Private Sign Key** to overwrite the unsigned application image file with the signed application image file (`blink_baremetal.s37`).  
   ```c  
    ```sh  
    commander convert blink_baremetal.s37 --secureboot --keyfile sign_key.pem --verify sign_pubkey.pem  
    --outfile blink_baremetal.s37  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Found Application Properties at 0x000061bc  
    Writing Application Properties signature pointer to point to 0x000064d8  
    Setting signature type in Application Properties: 0x00000001  
    Image SHA256: 8b58ec567126aa1f6baa88afc916581477745aca6f47697ec093512fc30dcc6f  
    R = 056E3AA36BD882B5467D44A56DB7CC1AEE44D45BC9B98FAB05BE2C032573A1F7  
    S = BE1D27CE7877D0BC761C0F02690CC74251EBE3A458474C573C21B3A738A03577  
     
    Verifying signed image...  
    Writing to blink_baremetal.s37... Overwriting file: blink_baremetal.s37...  
    DONE  
    ```  
   ```  
   b. **(Using an HSM and Simplicity Commander)** Run the `convert` command with `--extsign` option to generate an external signing application image file (`blink_baremetal.extsign`).  
   ```c  
    ```sh  
    commander convert blink_baremetal.s37 --secureboot --extsign --outfile blink_baremetal  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Found Application Properties at 0x00006198  
    Writing Application Properties signature pointer to point to 0x0000643c  
    Setting signature type in Application Properties: 0x00000001  
    Writing to blink_baremetal.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key to generate the signature for the external signing application image. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** to simulate this process. The signature is in the `app_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out app_signature.der blink_baremetal.extsign  
    ```  
     
    Run the `convert` command with the **application image signature** to overwrite the unsigned application image file with the signed application image file. (`blink_baremetal.s37`).  
     
    ```sh  
    commander	convert	blink_baremetal.s37	--secureboot	--signature	app_signature.der	--verify sign_pubkey.pem  
    --outfile blink_baremetal.s37  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Parsing signature file app_signature.der...  
    R = BD5BDC866CE67DA104B1E7B686C45B7BF96F2643154D37ACC63DACDF69C27E89  
    S = 2DD3BFFAC857A5B0BD8C9B4DDB23D21944D062F8E431D36541B84EF411C1CC92  
    Found Application Properties at 0x000061bc  
    Writing Application Properties signature pointer to point to 0x000064d8  
    Setting signature type in Application Properties: 0x00000001  
     
    Verifying signed image...  
    Writing to blink_baremetal.s37... Overwriting file: blink_baremetal.s37...  
    DONE  
    ```  
   ```
3. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in a signed application image.  
   ```sh  
   commander util appinfo blink_baremetal.s37  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found application properties in image. Application properties info:  
   Application properties location : 0x000061bc  
   Signature location	            : 0x000064d8  
   Signature type	                : ECDSA-P256  
   Long token section address	    : Not set (0x00000000)  
     
   Application data info:  
   For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.  
   App type	                    : MCU application (APPLICATION_TYPE_MCU)  
   App version	                    : 0x00000001  
   Product ID	                    : Not set (0x00000000000000000000000000000000)  
     
   No certificate found in image.  
   For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.  
   DONE  
   ```
4. The signed application image file (`.s37`) can be used for [production programming](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) or for generating a [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for application upgrade.

###### Signing for Certificate-Based Secure Boot

The following figure describes the signing and verification for certificate-based Secure Boot. You can freely switch between standard and advanced certificate-based Secure Boot by upgrading the application firmware without and with the application certificate.

![Certificate-Based Sign and Verify](/series2-secure-boot-with-rtsl/0.3/images/certificate-based-sign-verify-standard.png)

![Certificate-Based Sign and Verify](/series2-secure-boot-with-rtsl/0.3/images/certificate-based-sign-verify-advanced.png)

###### Certificate (heading level 7)

The following table describes the elements of a certificate.

|**Element**|**Description**|
|---|---|
|Certificate structure version|The version of the certificate structure.|
|Reserved flags|Reserved in the current certificate structure version.|
|Certificate public key|ECDSA-P256 public key, X and Y coordinates concatenated, used to validate the image.|
|Certificate version|The version of the running certificate.|
|Certificate signature|ECDSA-P256 signature, used for the authentication of the public key and the certificate version.|

**Notes**:

- The `application_properties.h` file in the Windows folder below defines the parameters of the certificate structure (`ApplicationCertificate_t`).  
  For GSDK v3.2 and lower: `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION>\platform\bootloader\api`  
  For GSDK v4.0 and higher: `C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\platform\bootloader\api`
- The certificate is not in X.509 format.

###### Private/Public Key Pair (heading level 7)

The following table describes two Private/Public Key pairs used in certificates for certificate-based Secure Boot. You can use [Simplicity Commander or HSM](#generate-key-and-signing) to generate these key pairs.

|**Certificate**|**Private Key**|**Public Key**|**Description**|
|---|---|---|---|
|Bootloader (bl_cert.bin) (1)|bl_cert_key.pem (Private Bootloader Key)|bl_cert_pubkey.pem (Public Bootloader Key)|The bootloader certificate is signed by the Private Sign Key corresponding to the Public Sign Key in SE OTP.|
|Application (app_cert.bin) (2)|app_cert_key.pem (Private Application Key)|app_cert_pubkey.pem (Public Application Key)|The application certificate is signed by the Private Bootloader Key corresponding to the Public Bootloader Key in the bootloader certificate.|

**Notes**:

1. a. Certificate version in the bootloader certificate < certificate version in SE flash - the certificate is rejected.  
   b. Certificate version in the bootloader certificate = certificate version in SE flash - the certificate is accepted.  
   c. Certificate version in the bootloader certificate > certificate version in SE flash - the certificate is accepted. The certificate version in SE flash is updated to match ([revocation mechanism](#certificate-revocation)).
2. The certificate version in the application certificate is compared with the certificate version in the bootloader certificate. The application certificate is accepted if its version is equal to or higher than the certificate version in the bootloader certificate.

The following sections provide two methods to sign the bootloader image and application image files. All procedures assume the required files are in the same folder.

1. Using Simplicity Commander
2. Using an HSM and Simplicity Commander

###### Bootloader Image File (heading level 7)

1. If Certificated based Secure Boot flag is not enabled in SE OTP, follow the procedures in [Simplicity Commander](#simplicity-commander) to set up the certificate-based Secure Boot configuration for the bootloader.
2. Follow the procedures in [AppBuilder](#appbuilder) or [Bootloader-core Software Component](#bootloader-core-software-component) to set up the certificate-based Secure Boot configuration for the user application to generate an unsigned bootloader image.
3. The following steps show two methods to generate a bootloader certificate, either directly with Simplicity Commander (3a) or using an HSM with Commander (3b).  
   a. **(Using Simplicity Commander)** Run the `util gencert` command with **Public Bootloader Key** and **Private Sign Key** to generate the bootloader certificate (`bl_cert.bin`). Refer to the table abovefor details about the `--cert-version` for bootloader certificate.  
   ```c  
    ```sh  
    commander util gencert --cert-type secureboot --cert-version 1 --cert-pubkey bl_cert_pubkey.pem  
    --sign sign_key.pem --outfile bl_cert.bin  
    ```  
     
    ```sh  
    Successfully signed certificate  
    DONE  
    ```  
     
    Run the `convert` command with **Bootloader Certificate** and **Private Bootloader Key** to overwrite the unsigned bootloader image file with the signed bootloader image file (`bootloader-uart-xmodem.s37`).  
     
    ```sh  
    commander convert bootloader-uart-xmodem.s37 --secureboot --certificate bl_cert.bin  
    --keyfile bl_cert_key.pem --outfile bootloader-uart-xmodem.s37  
    ```  
     
    ```sh  
    Parsing file bootloader-uart-xmodem.s37...  
    Writing certificate to location 0x00002cf0  
    Private key matches public key in certificate.  
    Found Application Properties at 0x00002d78  
    Writing Application Properties signature pointer to point to 0x00002f64  
    Setting signature type in Application Properties: 0x00000001  
    Image SHA256: 3cf574b688853a801e8dc98687414db27f886c60c55dbf7fea2d47633df94e8d  
    R = C866592B4CB7BAD9EFC35985F1B9D52C65C26453D4808597EEEFFB16DC4AA962  
    S = 94CAA21ED5D7772F96BBF4D24A0711A94DCCB6D4D38DFA45182876B9BE2A8DE3  
     
    Verifying signed image...  
    Writing to bootloader-uart-xmodem.s37... Overwriting file: bootloader-uart-xmodem.s37...  
    DONE  
    ```  
   ```  
   b. **(Using an HSM and Simplicity Commander)** Run the `util gencert` command with **Public Bootloader Key** and `--extsign` option to generate an external signing bootloader certificate (`bl_cert.extsign`). Refer to the table above for details about the `--cert-version` for bootloader certificate.  
   ```c  
    ```sh  
    commander util gencert --cert-type secureboot --cert-version 1 --cert-pubkey bl_cert_pubkey.pem  
    --extsign --outfile bl_cert  
    ```  
     
    ```sh  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key to generate the signature for the external signing bootloader certificate. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** to simulate this process. The signature is in the `bl_cert_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out bl_cert_signature.der bl_cert.extsign  
    ```  
     
    Run the `util signcert` command with the **bootloader certificate signature** to generate the bootloader certificate (`bl_cert.bin`).  
     
    ```sh  
    commander util signcert bl_cert.extsign --cert-type secureboot --signature bl_cert_signature.der  
    --verify sign_pubkey.pem --outfile bl_cert.bin  
    ```  
     
    ```sh  
    R = 065A58EA6CE6BBA44F3C59C6D255A901DBBC55FA97F261658B2026ABC8CD9680  
    S = 8A0011AA6393BC284B13C8313EE6772030DE07E213E74CA0FEA740F3D33E6518  
    Successfully verified signature Successfully signed certificate  
    DONE  
    ```  
     
    Run the `convert` command with **Bootloader Certificate** and `--extsign` option to generate an external signing bootloader image file (`bootloader-uart-xmodem.extsign`).  
     
    ```sh  
    commander convert bootloader-uart-xmodem.s37 --secureboot --certificate bl_cert.bin --extsign  
    --outfile bootloader-uart-xmodem  
    ```  
   ```
4. **(Optional)** Run the `util verifysign` command with **Public Sign Key** to verify that the **Bootloader Certificate and image** were correctly signed.  
   ```sh  
   commander util verifysign bootloader-uart-xmodem.s37 --verify sign_pubkey.pem  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37... Found application properties at 0x00002d78 Found certificate at 0x00002cf0  
   Successfully verified certificate signature with verification key.  
   Using certificate key to verify application signature.  
   Successfully verified application signature.  
   DONE  
   ```
5. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in a signed GBL image.  
   ```sh  
   commander util appinfo bootloader-uart-xmodem.s37  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37...  
   Found application properties in image.  
   Application properties info:  
   Application properties location : 0x00002d00  
   Signature location	            : 0x00002e14  
   Signature type	                : ECDSA-P256  
   Long token section address	    : Not set (0x00000000)  
     
   Application data info:  
   For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.  
   App type	                    : Bootloader (APPLICATION_TYPE_BOOTLOADER)  
   App version	                    : 0x02000000  
   Product ID	                    : Not set (0x00000000000000000000000000000000)  
     
   Found certificate at 0x00002c78  
   Application certificate info:  
   Certificate located at	        : 0x00002c78  
   Certificate version	            : 0x00000001  
   Certificate key	                : 0xb1bc6f6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc08440f0a4e1dca4  
                                   7c04119ed6a1be31b7707e5f9d001a659a051003e95e1b936f05c37ea793ad63  
   Certificate signature	        : 0xef3b53368d4cd7821eb30a96140bbde8840378cfea30687a8c10642e1c7728fd  
                                   309f976adf46e4eac62a2233f0c1f08f4e58344bdec61775b5282ceb351bb3d0  
   DONE  
   ```
6. The signed bootloader image file (`.s37`) can be used for [production programming](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) or for generating a [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for bootloader upgrade.
7. Run the `flash` command to program the signed bootloader image (`bootloader-uart-xmodem.s37`) to the device if the device does not have a bootloader.

```sh
commander flash bootloader-uart-xmodem.s37 --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Parsing file bootloader-uart-xmodem.s37...
Writing 16384 bytes starting at address 0x00000000
Comparing range 0x00000000 - 0x00003FFF (16 KiB)
Programming range 0x00000000 - 0x00001FFF (8 KiB)
Programming range 0x00002000 - 0x00003FFF (8 KiB)
DONE
```

Simplicity Commander output for Series 3 devices will look as follows:

```sh
WARNING: Failed secure boot detected. Issuing a mass erase before flashing to recover the device...
Parsing file bootloader-uart-xmodem.s37...
Writing 14280 bytes starting at address 0x01000000
Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB)
Programming range 0x01000000 - 0x01000FFF (4 KB)
Programming range 0x01001000 - 0x01001FFF (4 KB)
Programming range 0x01002000 - 0x01002FFF (4 KB)
Programming range 0x01003000 - 0x01003FFF (4 KB)
Programming range 0x01004000 - 0x01004FFF (4 KB)
Programming range 0x01005000 - 0x01005FFF (4 KB)
Programming range 0x01006000 - 0x01006FFF (4 KB)
Programming range 0x01007000 - 0x01007FFF (4 KB)
JLinkError: Failed to halt CPU.
Closing region 0 (this consumes one OTP bit, consider --noclose on development/testing devices)
Flashing completed successfully!
DONE
```

###### Application Image File (Standard Certificate-Based) (heading level 7)

1. Follow the procedures in [Generate an Unsigned Application Image](#generate-an-unsigned-application-image) to generate an unsigned application image for the bootloader.
2. a. **(Using Simplicity Commander)** Run the convert command with **Private Bootloader Key** to overwrite the unsigned application image file with the signed application image file (`blink_baremetal.s37`).  
   ```sh  
   commander	convert	blink_baremetal.s37	--secureboot	--keyfile	bl_cert_key.pem	--verify bl_cert_pubkey.pem  
   --outfile blink_baremetal.s37  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found Application Properties at 0x000061bc  
   Writing Application Properties signature pointer to point to 0x000064d8  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: 8b58ec567126aa1f6baa88afc916581477745aca6f47697ec093512fc30dcc6f  
   R = 994739A26AB520A88A5550F1643AE263D88A952F185F96EE7021FA43DEA6138C  
   S = 65B7112715E2F999A6B216C32D3331AB63B2D31A0A1311DF36EEE62269F8D6AA  
     
   Verifying signed image...  
   Writing to blink_baremetal.s37...  
   Overwriting file: blink_baremetal.s37...  
   DONE  
   ```  
   b. **(Using an HSM and Simplicity Commander)** Run the `convert` command with `--extsign` option to generate an external signing application image file (`blink_baremetal.extsign`).  
   ```c  
    ```sh  
    commander convert blink_baremetal.s37 --secureboot --extsign --outfile blink_baremetal  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Found Application Properties at 0x000061bc  
    Writing Application Properties signature pointer to point to 0x000064d8  
    Setting signature type in Application Properties: 0x00000001  
    Writing to blink_baremetal.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Bootloader Key to generate the signature for the external signing application image. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Bootloader Key** to simulate this process. The signature is in the `app_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out app_signature.der blink_baremetal.extsign  
    ```  
     
    Run the `convert` command with the **application image signature** to overwrite the unsigned application image file with the signed application image file. (`blink_baremetal.s37`).  
     
    ```sh  
    commander convert blink_baremetal.s37 --secureboot --signature app_signature.der  
    --verify bl_cert_pubkey.pem --outfile blink_baremetal.s37  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Parsing signature file app_signature.der...  
    R = 8DA79B020E954D24C23423D80627E046E44052736F6546902F016D64464E82DE  
    S = 9D5A1CC424E97A5AD0352A4EEA6BBF565FED5FC61FF99E63AA73DFFEAD9EE399  
    Found Application Properties at 0x000061bc  
    Writing Application Properties signature pointer to point to 0x000064d8  
    Setting signature type in Application Properties: 0x00000001  
     
    Verifying signed image...  
    Writing to blink_baremetal.s37...  
    Overwriting file: blink_baremetal.s37...  
    DONE  
    ```  
   ```
3. **(Optional)** Run the `util verifysign` command with **Public Bootloader Key** to verify that the application image file was correctly signed.  
   ```sh  
   commander util verifysign blink_baremetal.s37 --verify bl_cert_pubkey.pem  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found application properties at 0x000061bc  
   Did not find application certificate in file  
   If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.  
   Successfully verified application signature.  
   DONE  
   ```
4. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in a signed application image.  
   ```sh  
   commander util appinfo blink_baremetal.s37  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found application properties in image.  
   Application properties info:  
   Application properties location : 0x000061bc  
   Signature location	            : 0x000064d8  
   Signature type	                : ECDSA-P256  
   Long token section address	    : Not set (0x00000000)  
     
   Application data info:  
   For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.  
   App type	                    : MCU application (APPLICATION_TYPE_MCU)  
   App version	                    : 0x00000001  
   Product ID	                    : Not set (0x00000000000000000000000000000000)  
     
   No certificate found in image.  
   For Series 2 devices: If the configuration flag SECURE_BOOT_VERIFY_CERTIFICATE is set or a device has previously seen certificate based signing, it will not accept direct signing.  
   DONE  
   ```
5. The signed application image file (`.s37`) can be used for [production programming](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) or for generating a [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for application upgrade.

###### Application Image File (Advanced Certificate-Based) (heading level 7)

1. Follow the procedures in [Generate an Unsigned Application Image](#generate-an-unsigned-application-image) to generate an unsigned application image for the bootloader.
2. a. **(Using Simplicity Commander)** Run the `util gencert` command with **Public Application Key** and **Private Bootloader Key** to generate the application certificate (`app_cert.bin`). Refer to [Private/Public Key Pair](#privatepublic-key-pair) for details about the `--cert-version` for application certificate.  
   ```sh  
   commander util gencert --cert-type secureboot --cert-version 1 --cert-pubkey app_cert_pubkey.pem  
   --sign bl_cert_key.pem --outfile app_cert.bin  
   ```  
   ```sh  
   Successfully signed certificate  
   DONE  
   ```  
   Run the `convert` command with **Application Certificate** and **Private Application Key** to overwrite the unsigned application image file with the signed application image file (`blink_baremetal.s37`). This command will inject the application certificate into the application image before signing.  
   ```sh  
   commander	convert	blink_baremetal.s37	--secureboot	--certificate	app_cert.bin	--keyfile  
   app_cert_key.pem  
   --outfile blink_baremetal.s37  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Writing certificate to location 0x000064d8  
   Private key matches public key in certificate.  
   Found Application Properties at 0x000061bc  
   Writing Application Properties signature pointer to point to 0x00006560  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: 38fd11214c36abf3bb4c4eeda8cfdd2ca2ac2ff1e07072d555a06c74700a23f5  
   R = 6B4E3BB454513CAA4569415AE8F79453973AAC7FD1FC4914284B65010F3790A6  
   S = 1657CAAABED579880187261038358C83B1780A67CC41475370D94ED4445A5557  
     
   Verifying signed image...  
   Writing to blink_baremetal.s37...  
   Overwriting file: blink_baremetal.s37...  
   DONE  
   ```  
   b. **(Using an HSM and Simplicity Commander)** Run the `util gencert` command with **Public Application Key** and `--extsign` option to generate an external signing application certificate (`app_cert.extsign`). Refer to [Private/Public Key Pair](#privatepublic-key-pair) for details about the `--cert-version` for application certificate.  
   ```c  
    ```sh  
    commander util gencert --cert-type secureboot --cert-version 1 --cert-pubkey app_cert_pubkey.pem  
    --extsign --outfile app_cert  
    DONE  
    ```  
     
    Use an HSM containing the Private Bootloader Key to generate the signature for the external signing application certificate. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Bootloader Key** to simulate this process. The signature is in the `app_cert_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out app_cert_signature.der app_cert.extsign  
    ```  
     
    Run the `util signcert` command with the **application certificate signature** to generate the application certificate (`app_cert.bin`).  
     
    ```sh  
    commander util signcert app_cert.extsign --cert-type secureboot --signature app_cert_signature.der  
    --verify bl_cert_pubkey.pem --outfile app_cert.bin  
    ```  
     
    ```sh  
    R = 279D4FA1B801D108F82E30B0CF1164BF597549287290BD3883C5847B91095CCE  
    S = 567F0E219D2089EF4D79C3D94E43D2FADFE1899B71492ED358E6A1B46AE8162F  
    Successfully verified signature Successfully signed certificate  
    DONE  
    ```  
     
    Run the `convert` command with the **Application Certificate** and `--extsign` option to generate an external signing application image file (`blink_baremetal.extsign`).  
     
    ```sh  
    commander convert blink_baremetal.s37 --secureboot --certificate app_cert.bin --extsign --outfile blink_baremetal  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Writing certificate to location 0x000064d8  
    ```  
   ```
3. **(Optional)** Run the `util verifysign` command with **Public Bootloader Key** to verify that the **Application Certificate and image** were correctly signed.  
   ```sh  
   commander util verifysign blink_baremetal.s37 --verify bl_cert_pubkey.pem  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found application properties at 0x000061bc Found certificate at 0x000064d8  
   Successfully verified certificate signature with verification key.  
   Using certificate key to verify application signature.  
   Successfully verified application signature.  
   DONE  
   ```
4. **(Optional)** Run the `util appinfo` command to check all available information about `ApplicationProperties_t` struct in a signed application image.  
   ```sh  
   commander util appinfo blink_baremetal.s37  
   ```  
   ```sh  
   Parsing file blink_baremetal.s37...  
   Found application properties in image.  
   Application properties info:  
   Application properties location : 0x000061bc  
   Signature location	            : 0x00006560  
   Signature type	                : ECDSA-P256  
   Long token section address	    : Not set (0x00000000)  
     
   Application data info:  
   For Series 2 devices: If rollback prevention is enabled in the OTP configuration, the device will not boot if the device has seen an application with a higher version number.  
   App type	                    : MCU application (APPLICATION_TYPE_MCU)  
   App version	                    : 0x00000001  
   Product ID	                    : Not set (0x00000000000000000000000000000000)  
     
   Found certificate at 0x000064d8  
   Application certificate info:  
   Certificate located at	        : 0x000064d8  
   Certificate version	            : 0x00000001  
   Certificate key	                : 0xe562003cd86e225decfd35712e431a19ecd5031a079b06c1d473620a6be9f57a  
                                   879820100fee074f28b5885fd6759f480b62aaa0717f96e245aab6635cfb1e11  
   Certificate signature	        : 0x039aaba62b5258e68d16e167c3a611c719c542bb3483f5d4b522472b06adf30f  
                                   8cfcc484bf8551a208256e3d2d8c9194a7d2ac551e2cac659a99822308a40aa6  
   DONE  
   ```
5. The signed application image file (`.s37`) can be used for [production programming](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) or for generating a [GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for application upgrade.

###### Generate a GBL Upgrade Image File

This section provides steps to create GBL files used to upgrade bootloader, application and/or SE firmware on Series 2 and Series 3 devices.

> **Note**: Series 3 devices support only GBLv4 files for firmware upgrade process.

- Follow the procedures in [AppBuilder](#appbuilder) or [Bootloader-core Software Component](#bootloader-core-software-component) to avoid overwriting the existing application image (if necessary) when upgrading the bootloader or SE.
- For a standalone bootloader with communication interface, you can only generate three separate GBL upgrade image files containing bootloader, SE, and application images.
- (Series 2 devices) For an application bootloader with storage, you can generate a single GBL upgrade image file (see example below) with a combination of bootloader, SE, and application images.

```sh
commander gbl create all.gbl --app app.s37 --bootloader bl.s37 --seupgrade se.seu
```

- A signed GBL upgrade image file is required if you enable the **Require signed firmware upgrade files** option in [AppBuilder](#appbuilder) or [Bootloader-core Software Component](#bootloader-core-software-component). The following table shows which private key(s) can be used to sign the GBL upgrade image file (bootloader, SE, or application) on VSE, HSE and Series 3 devices. The VSE devices store a [Public Sign Key](#signing-for-ecdsa-p256-sha256-secure-boot) copy on the top page of the main flash to verify the GBL upgrade image file for ECDSA-P256-SHA256 Secure Boot.

**Private Key(s) usage to sign GBL upgrade image file**

|**Secure Boot**|**HSE and Series 3**|**VSE**|
|---|---|---|
|ECDSA-P256-SHA256|Private Sign Key|Private Sign Key (Public Sign Key in main flash)|
|Certificate-Based|Private Sign Key or Private Bootloader Key|Private Bootloader Key|

- An encrypted GBL upgrade image file is required if you enable the **Require encrypted firmware upgrade files** option in [AppBuilder](#appbuilder) or [Bootloader-core Software Component](#bootloader-core-software-component). Refer to [Provision GBL Decryption Key](#provision-gbl-decryption-key) on how to provision the GBL Decryption Key for this option.
- [Only applicable for Series 2 devices] For an application bootloader with storage, you can enable the **Upgrade SE without using the staging area** option in **GSDK v4.1.1 or higher** to directly fetch the SE image from the GBL upgrade image file in storage instead of copying the image to the pre-configured upgrade location.

![Upgrade SE without using the staging area option](/series2-secure-boot-with-rtsl/0.3/images/sld794-image56.jpg)

To use the above option, the SE image cannot be in the encrypted part of the GBL upgrade image file if the **Require encrypted firmware upgrade files** option is enabled. Use the `--seunencrypted` option in **Simplicity Commander v1.13.0 or higher** (see example below) to generate an encrypted GBL upgrade image file with a SE image outside the encrypted part of the file.

```sh
commander gbl create se-upgrade.gbl --seupgrade secure-element.seu --seunencrypted --app myapp.s37
--encrypt aes_key.txt
```

- In Series 3 devices, the storage bootloader supports direct SE upgrades from the GBL file without the need for staging.

The following sections provide two methods to sign the bootloader, Secure Engine, and application upgrade image files if the **Require signed firmware upgrade files** option is enabled.

1. Using Simplicity Commander
2. Using an HSM and Simplicity Commander

The sections also include encryption examples with an AES-128 key (like `aes_key.txt`) for the **Require encrypted firmware upgrade files** option. All procedures assume the required files are in the same folder.

Series 3 devices require GBLv4. GBLv4 is a new format that supports more command line options than the upgrade file for series 2 devices which do not support GBLv4.

- To compress an upgrade file, append `--compress <compression algorithm>` to the command, supported algorithms are `lz4` and `lzma`.
- To add the product id, append `--productid <16-byte long identifier>` to the command.
- To add the bundle version and minimum version, append `--bundleversion <version number> --minversion <version number>` to the command.

Read more about GBLv4 files and the configurations supported in **Gecko Bootloader File Format v4** section of [Gecko Bootloader User's Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/02-gecko-bootloader-file-format-v4).

- All `gbl create` and `gbl4 create` commands support both encrypted and unencrypted images. To create an unencrypted image, omit the `--encrypt` option. To create an encrypted image, append `--encrypt aes_key.txt` to the command.

###### Bootloader Upgrade (heading level 7)

1. Create an unsigned GBL upgrade image:  
   a. Series 2 devices: Run the `gbl create` command with `--bootloader` option to generate the bootloader GBL upgrade image file (`bootloader-uart-xmodem.gbl`) with the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create bootloader-uart-xmodem.gbl --bootloader bootloader-uart-xmodem.s37  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding bootloader to GBL...  
    Writing GBL file bootloader-uart-xmodem.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` option to generate the bootloader GBL upgrade image file (`bootloader.gbl`) with the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create bootloader.gbl --data bootloader-uart-xmodem.s37 --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bootloader.s37...  
    Writing GBL file bootloader.gbl...  
    DONE  
    ```  
   ```
2. Create a signed GBL upgrade image using Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--bootloader` option to generate the signed bootloader GBL upgrade image file (`bootloader-uart-xmodem.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create bootloader-uart-xmodem.gbl --bootloader bootloader-uart-xmodem.s37 --sign  
    sign_key.pem  
    ```  
     
    ```sh  
    commander gbl create bootloader-uart-xmodem.gbl --bootloader bootloader-uart-xmodem.s37  
    --sign bl_cert_key.pem  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding bootloader to GBL...  
    Signing GBL...  
    Image SHA256: 3eb09993ffca5f9b34df3f38b65ab9d2f6619b828b014a186516016d4bbd80f7  
    R = C21E0C19254AC4F62374BBCA65DEBB42C7349384F5527330CD030A51DC2170F7  
    S = E1680C3670DE68D731086845E2726EF3BF07B96EB54AA2DB2F390F60BDB6DAB2  
    Writing GBL file bootloader-uart-xmodem.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` option to generate the signed bootloader GBL upgrade image file (`bootloader.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the signed bootloader image file (`bootloader-u art-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create bootloader.gbl --data bootloader-uart-xmodem.s37 --sign sign_key.pem  
    --device SIMG301LIL  
    ```  
     
    ```sh  
    commander gbl4 create bootloader.gbl --data bootloader-uart-xmodem.s37 --sign bl_cert_key.pem  
    --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bootloader.s37...  
    Writing GBL file bootloader.gbl...  
    Image SHA256: 5ba67b656103a3539f0f3802a4398f0babb3ff182fe9890962e678052571d42b  
    R = 6845219257E660918B7BAE26FFF3DC7BBE8150DA3281CE8881B7088E9E9736EC  
    S = B8C5B58987FA3C7E44444B7C43096A41F48D245ED148C4E0863F0F910133811E  
    DONE  
    ```  
   ```
3. Creating a signed GBL upgrade image using an HSM and Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--bootloader` and `--extsign` options to generate an external signing bootloader GBL upgrade image file (`bootloader-uart-xmodem.extsign`) with the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create bootloader-uart-xmodem --bootloader bootloader-uart-xmodem.s37 --extsign  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding bootloader to GBL...  
    Preparing GBL for external signing...  
    Writing GBL file bootloader-uart-xmodem.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the external signing bootloader GBL upgrade image file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the gbl_signature.der.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der bootloader-uart-xmodem.extsign  
    ```  
     
    ```sh  
    openssl	dgst	-sha256	-binary	-sign	bl_cert_key.pem	-out	gbl_signature.der	bootloader-uart-xmodem.extsign  
    ```  
     
    Run the `gbl sign` command with the **signature** above to generate a signed bootloader GBL upgrade image file (`bootloader-uart-xmodem.gbl`).  
     
    ```sh  
    commander	gbl	sign	bootloader-uart-xmodem.extsign	--signature	gbl_signature.der	--verify  
    sign_pubkey.pem  
    --outfile bootloader-uart-xmodem.gbl  
    ```  
     
    ```sh  
    commander gbl sign bootloader-uart-xmodem.extsign --signature gbl_signature.der  
    --verify bl_cert_pubkey.pem --outfile bootloader-uart-xmodem.gbl  
    ```  
     
    ```sh  
    Reading GBL data from bootloader-uart-xmodem.extsign...  
    Parsing signature file gbl_signature.der...  
    R = 90F0A3C0D5D9ED2DC10EB3F55595FF21AB31307DC6283E3F3B7494A30FB741D4  
    S = 2765041F515A960F048CA250BFAB92031D4D1E569FB3F917C9329E7362C17B51  
    Writing signature to GBL... Verifying GBL...  
    Successfully verified GBL signature  
    Writing GBL file bootloader-uart-xmodem.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` and `--extsign` options to generate an unsigned and manifest files (`bootloader.unsigned` and `bootloader.manifest`) with the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create bootloader --data bootloader-uart-xmodem.s37 --extsign --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bootloader-uart-xmodem.s37...  
    Writing manifest data (for external signing) to bootloader.manifest  
    Writing unsigned GBL file (for later use in 'gbl4 sign') to bootloader.unsigned...  
    After computing the signature of bootloader.manifest, assemble the GBL4 using:  
    commander gbl4 sign bootloader.unsigned --outfile bootloader --signature <signature.der>  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the manifest file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the `gbl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der bootloader.manifest  
    ```  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out gbl_signature.der bootloader.manifest  
    ```  
   ```
4. Follow the procedures in [Upload a GBL Upgrade Image File](#upload-a-gbl-upgrade-image-file) to upgrade the bootloader with the bootloader GBL upgrade image file.

##### Secure Engine Upgrade

1. Creating an unsigned GBL upgrade image:  
   a. Series 2 devices: Run the `gbl create` command with `--seupgrade` option to generate the SE GBL upgrade image file (`s2c1_se_fw_upgrade_1v2p9.gbl`) with the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`s2c1_se_fw_upgrade_1v2p9.seu`).  
   ```c  
    ```sh  
    commander gbl create s2c1_se_fw_upgrade_1v2p9.gbl --seupgrade s2c1_se_fw_upgrade_1v2p9.seu  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding Secure Element upgrade image to GBL...  
    Writing GBL file s2c1_se_fw_upgrade_1v2p9.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--seupgrade` option to generate the SE GBL upgrade image file (`se-upgrade.gbl`) with the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`x301_se_fw_upgrade_3v3p2.seuv2`).  
   ```c  
    ```sh  
    commander gbl4 create se-upgrade.gbl --seupgrade x301_se_fw_upgrade_3v3p2.seuv2 --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Reading SE upgrade file from x301_se_fw_upgrade_3v3p2.seuv2  
    Writing GBL file se-upgrade...  
    DONE  
    ```  
   ```
2. Creating a signed GBL upgrade image using Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--seupgrade` option to generate the signed SE GBL upgrade image file (`s2c1_se_fw_upgrade_1v2p9.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`s2c1_se_fw_upgrade_1v2p9.seu`).  
   ```c  
    ```sh  
    commander gbl create s2c1_se_fw_upgrade_1v2p9.gbl --seupgrade s2c1_se_fw_upgrade_1v2p9.seu  
    --sign sign_key.pem  
    ```  
     
    ```sh  
    commander gbl create s2c1_se_fw_upgrade_1v2p9.gbl --seupgrade s2c1_se_fw_upgrade_1v2p9.seu  
    --sign bl_cert_key.pem  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding Secure Element upgrade image to GBL...  
    Signing GBL...  
    Image SHA256: 599d7fc35996b4715441b642709ed262525d09d811d4726e423c0d605ec0f0bf  
    R = EF8EC2DDEDDF44DF88FEAD4ED0A9FDC6351B4D745D5A05BFB87204791871A525  
    S = FCB26EF005D97E8C5341153A210AE9927E1CF646A3E473FFB90DA8C857E6421F  
    Writing GBL file s2c1_se_fw_upgrade_1v2p9.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--seupgrade` option to generate the signed SE GBL upgrade image file (`se-upgrade.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`x301_se_fw_upgrade_3v3p2.seuv2`).  
   ```c  
    ```sh  
    commander gbl4 create se-upgrade.gbl --seupgrade x301_se_fw_upgrade_3v3p2.seuv2  
    --sign sign_key.pem --device SIMG301LIL  
    ```  
     
    ```sh  
    commander gbl4 create se-upgrade.gbl --seupgrade x301_se_fw_upgrade_3v3p2.seuv2  
    --sign bl_cert_key.pem --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Reading SE upgrade file from x301_se_fw_upgrade_3v3p2.seuv2  
    Writing GBL file se-upgrade.gbl...  
    Image SHA256: e6462d8810f9afee36974b82b3790af55c94f559c532ee0e264617d705a1fd6b  
    R = 095A9D64BD490FCA444D49DADC53C666B717006D9E7C91C196B259F6E27E5C9C  
    S = 0BFC9B86BA5B3C2A4C98AE5EC8264D905659AE8528433832FAD225D51E9899FD  
    DONE  
    ```  
   ```
3. Creating a signed GBL upgrade image using an HSM and Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--seupgrade` and `--extsign` options to generate an external signing SE GBL upgrade image file (`s2c1_se_fw_upgrade_1v2p9.extsign`) with the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`s2c1_se_fw_upgrade_1v2p9.seu`).  
   ```c  
    ```sh  
    commander gbl create s2c1_se_fw_upgrade_1v2p9 --seupgrade s2c1_se_fw_upgrade_1v2p9.seu --extsign  
    ```  
     
    ```sh  
    Initializing GBL file...  
    Adding Secure Element upgrade image to GBL...  
    Preparing GBL for external signing...  
    Writing GBL file s2c1_se_fw_upgrade_1v2p9.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the external signing SE GBL upgrade image file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the `gbl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der s2c1_se_fw_upgrade_1v2p9.extsign  
    ```  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out gbl_signature.der s2c1_se_fw_upgrade_1v2p9.extsign  
    ```  
     
    Run the `gbl sign` command with the **signature** above to generate a signed SE GBL upgrade image file (`s2c1_se_fw_upgrade_1v2p9.gbl`).  
     
    ```sh  
    commander	gbl	sign	s2c1_se_fw_upgrade_1v2p9.extsign	--signature	gbl_signature.der	--verify  
    sign_pubkey.pem  
    --outfile s2c1_se_fw_upgrade_1v2p9.gbl  
    ```  
     
    ```sh  
    commander gbl sign s2c1_se_fw_upgrade_1v2p9.extsign --signature gbl_signature.der  
    --verify bl_cert_pubkey.pem --outfile s2c1_se_fw_upgrade_1v2p9.gbl  
    ```  
     
    ```sh  
    Reading GBL data from s2c1_se_fw_upgrade_1v2p9.extsign...  
    Parsing signature file gbl_signature.der...  
    R = 2798B98194EE02717C738B5866ABD8D234D0F0E096E90495D371D2507D8E1C67  
    S = 19F2586E2C6177D6B4EEC708E006F67334C989D0398D4233C686C98ECB6992FB  
    Writing signature to GBL... Verifying GBL...  
    Successfully verified GBL signature  
    Writing GBL file s2c1_se_fw_upgrade_1v2p9.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--seupgrade` and `--extsign` options to generate unsigned and manifest files (`se-upgrade.unsigned` and `se-upgrade.manifest`) with the [SE image file](01-series-2-and-series-3-device-security-features#se-firmware) (`x301_se_fw_upgrade_3v3p2.seuv2`).  
   ```c  
    ```sh  
    commander gbl4 create se-upgrade --seupgrade x301_se_fw_upgrade_3v3p2.seuv2 --extsign  
    --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Reading SE upgrade file from x301_se_fw_upgrade_3v3p2.seuv2  
    Writing manifest data (for external signing) to se-upgrade.manifest  
    Writing unsigned GBL file (for later use in 'gbl4 sign') to se-upgrade.unsigned...  
    After computing the signature of se-upgrade.manifest, assemble the GBL4 using:  
    commander gbl4 sign se-upgrade.unsigned --outfile se-upgrade --signature <signature.der>  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the manifest file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the `gbl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der se-upgrade.manifest  
    ```  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out gbl_signature.der se-upgrade.manifest  
    ```  
     
    Run the `gbl4 sign` command with the **signature** above to generate a signed SE GBL upgrade image file (`se-upgrade.gbl`).  
   ```
4. Follow the procedures in [Upload a GBL Upgrade Image File](#upload-a-gbl-upgrade-image-file) to upgrade the SE with the SE GBL upgrade image file.

**Notes**:

- The `sign_key.pem`/`sign_pubkey.pem` key pair is for [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot), and the `bl_cert_key.pem`/`bl_cert_pubkey.pem` key pair is for [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).
- Trying to apply a lower version of the SE image file (`.seu`) to the device will be ignored.

##### Application Upgrade

1. Creating an unsigned GBL upgrade image:  
   a. Series 2 devices: Run the `gbl create` command with `--app` option to generate the application GBL upgrade image file (`blink_baremetal.gbl`) with the signed application image file (`blink_baremetal.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create blink_baremetal.gbl --app blink_baremetal.s37  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Initializing GBL file...  
    Adding application to GBL...  
    Writing GBL file blink_baremetal.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` option to generate the bootloader GBL upgrade image file (`app-upgrade.gbl`) with the signed bootloader image file (`bt_soc_blinky_freertos.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create app-upgrade.gbl --data bt_soc_blinky_freertos.s37 --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bt_soc_blinky_freertos.s37...  
    Writing GBL file app-upgrade.gbl...  
    DONE  
    ```  
   ```
2. Creating a signed GBL upgrade image using Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--app` option to generate the signed application GBL upgrade image file (`blink_baremetal.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the signed application image file (`blink_baremetal.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create blink_baremetal.gbl --app blink_baremetal.s37 --sign sign_key.pem  
    ```  
     
    ```sh  
    commander gbl create blink_baremetal.gbl --app blink_baremetal.s37 --sign bl_cert_key.pem  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Initializing GBL file...  
    Adding application to GBL...  
    Signing GBL...  
    Image SHA256: 116c1be47d799ab75afc7b3f4c9a8023e5cd031103b1d28c578eebfaf1ad73d2  
    R = CE4D85C058301A2437440E00385D97E496F1D8B5CAFFB8C184F8A88B5266E3E9  
    S = 90BBF754EBC0AB343CC32AA06ADED85F9D12D1A67CA6608F9085137142000A40  
    Writing GBL file blink_baremetal.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` option to generate the signed bootloader GBL upgrade image file (`app-upgrade-signed.gbl`) with **Private Sign Key** or **Private Bootloader Key** and the signed bootloader image file (`bt_soc_blinky_freertos.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create app-upgrade-signed.gbl --data bt_soc_blinky_freertos.s37  
    --sign sign_key.pem --device SIMG301LIL  
    ```  
     
    ```sh  
    commander gbl4 create app-upgrade-signed.gbl --data bt_soc_blinky_freertos.s37  
    --sign bl_cert_key.pem --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bt_soc_blinky_freertos.s37...  
    Writing GBL file app-upgrade-signed.gbl...  
    Image SHA256: 665ee8c703bc57ee59078d48183d39087e6a52e564ee3bd73971f33acbd0b009  
    R = 5C72EDFA23B947BAB1827A566C14BDF4542C24CE62F30DE928216AC10FE8AA5B  
    S = 22A4912CA192274681FB000F882D0CE500FC3D29C54CB354430553EC4A61B11A  
    DONE  
    ```  
   ```
3. Creating a signed GBL upgrade image using an HSM and Simplicity Commander:  
   a. Series 2 devices: Run the `gbl create` command with `--app` and `--extsign` options to generate an external signing application GBL upgrade image file (`blink_baremetal.extsign`) with the signed application image file (`blink_baremetal.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl create blink_baremetal --app blink_baremetal.s37 --extsign  
    ```  
     
    ```sh  
    Parsing file blink_baremetal.s37...  
    Initializing GBL file...  
    Adding application to GBL...  
    Preparing GBL for external signing...  
    Writing GBL file blink_baremetal.extsign...  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the external signing application GBL upgrade image file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the `gbl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der blink_baremetal.extsign  
    ```  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out gbl_signature.der blink_baremetal.extsign  
    ```  
     
    Run the `gbl sign` command with the **signature** above to generate a signed application GBL upgrade image file (`blink_baremetal.gbl`).  
     
    ```sh  
    commander gbl sign blink_baremetal.extsign --signature gbl_signature.der --verify sign_pubkey.pem  
    --outfile blink_baremetal.gbl  
    ```  
     
    ```sh  
    commander gbl sign blink_baremetal.extsign --signature gbl_signature.der --verify bl_cert_pubkey.pem  
    --outfile blink_baremetal.gbl  
    ```  
     
    ```sh  
    Reading GBL data from blink_baremetal.extsign...  
    Parsing signature file gbl_signature.der...  
    R = 533499660E24F1620EF25D862FB607F46E9E4ECC41CBDECBE77C64EF1970D96A  
    S = FA8901878218F5F1DB0FAF8B074CE98A27C63FFDE63730CD49EE47E847B9811D  
    Writing signature to GBL...  
    Verifying GBL...  
    Successfully verified GBL signature  
    Writing GBL file blink_baremetal.gbl...  
    DONE  
    ```  
   ```  
   b. Series 3 devices: Run the `gbl4 create` command with `--data` and `--extsign` options to generate an unsigned and manifest files (`app-upgrade.unsigned` and `app-upgrade.manifest`) with the signed bootloader image file (`bootloader-uart-xmodem.s37`) from [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).  
   ```c  
    ```sh  
    commander gbl4 create app-upgrade --data bt_soc_blinky_freertos.s37 --extsign --device SIMG301LIL  
    ```  
     
    ```sh  
    Initializing GBLV4 file...  
    Parsing file bt_soc_blinky_freertos.s37...  
    Writing manifest data (for external signing) to app-upgrade.manifest  
    Writing unsigned GBL file (for later use in 'gbl4 sign') to app-upgrade.unsigned...  
    After computing the signature of app-upgrade.manifest, assemble the GBL4 using:  
    commander gbl4 sign app-upgrade.unsigned --outfile app-upgrade --signature <signature.der>  
    DONE  
    ```  
     
    Use an HSM containing the Private Sign Key or Private Bootloader Key to generate the signature for the manifest file. This example uses the [OpenSSL](#using-an-external-tool) with the **Private Sign Key** or **Private Bootloader Key** to simulate this process. The signature is in the `gbl_signature.der`.  
     
    ```sh  
    openssl dgst -sha256 -binary -sign sign_key.pem -out gbl_signature.der app-upgrade.manifest  
    ```  
     
    ```sh  
    openssl dgst -sha256 -binary -sign bl_cert_key.pem -out gbl_signature.der app-upgrade.manifest  
    ```  
     
    Run the `gbl4 sign` command with the **signature** above to generate a signed bootloader GBL upgrade image file (`bootloader.gbl`).  
   ```
4. Follow the procedures in [Upload a GBL Upgrade Image File](#upload-a-gbl-upgrade-image-file) to upgrade the application with the application GBL upgrade image file.

**Notes**:

- [Series 2 devices] The Simplicity Commander v1.11.0 or above supports GBL upgrade image file in `util verifysign` command.  
  ```sh  
  commander util verifysign blink_baremetal.gbl --verify sign_pubkey.pem  
  ```  
  ```sh  
  Successfully verified GBL signature  
  DONE  
  ```
- [Series 2 devices] The Simplicity Commander v1.12.0 or above fixes a bug introduced in v1.11.0 when using the `--extsign` option on the GBL upgrade image file.

###### Upload a GBL Upgrade Image File

This section describes how to use UART XMODEM Bootloader v2.0.0 in GSDK v4.0 and higher to upload a GBL upgrade image file (`.gbl`) to the device. The procedures and pictures may be different for the other versions of this example.

The GBL upgrade image file uses a proprietary format to store the upgrade image for a firmware upgrade. Use the gbl create command to generate the GBL upgrade image file for bootloader, application, and Secure Engine. Refer to [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) and [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) for more information about GBL upgrade image file creation.

You can use any terminal software that supports the XMODEM-CRC protocol for file transfer. This application note uses [Tera Term](https://ttssh2.osdn.jp/index.html.en) as terminal software. The default serial port setting is 115200 bps 8-N-1.

1. Assume the [UART XMODEM Bootloader](#generate-an-unsigned-gbl-image) and application firmware had already flashed to the radio board on WSTK.
2. Press the **RESET** and **PB0** push buttons on the WSTK.
3. Release the **RESET** push button to run the UART XMODEM Bootloader.  
   ![Options in UART XMODEM Bootloader](/series2-secure-boot-with-rtsl/0.3/images/sld794-image57.png)
4. Release the **PB0** push button. Press 1 (`upload gbl`) in Tera Term to upload a GBL upgrade image file.  
   ![Upload GBL option](/series2-secure-boot-with-rtsl/0.3/images/sld794-image58.png)
5. Transfer a file through XMODEM-CRC in Tera Term, navigate to **File** > **Transfer** > **XMODEM** > **Send...**.  
   ![XMODEM Transfer in Tera Term](/series2-secure-boot-with-rtsl/0.3/images/sld794-image59.png)
6. Select the target GBL upgrade image file. Click [**Open**] to upload.  
   ![Target GBL file location](/series2-secure-boot-with-rtsl/0.3/images/sld794-image60.png)
7. If no error occurs, press 2 (`run`) to start a firmware upgrade.  
   ![Run option](/series2-secure-boot-with-rtsl/0.3/images/sld794-image61.png)

##### Upgrade to Certificate-Based Secure Boot

You can upgrade the Series 2 and Series 3 devices deployed in the field from [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) to [certificate-based Secure Boot](#signing-for-certificate-based-secure-boot) even if the [SECURE_BOOT_VERIFY_CERTIFICATE](#simplicity-commander) option in SE OTP is disabled.

```sh
commander security readconfig --serialno 440048205
```

```sh
MCU Flags
Secure Boot                    : Enabled
Secure Boot Verify Certificate : Disabled
Secure Boot Anti Rollback      : Enabled
Secure Boot Page Lock Narrow   : Disabled
Secure Boot Page Lock Full     : Disabled
```

The following procedures for the upgrade to certificate-based Secure Boot is an **IRREVERSIBLE** process.

1. Follow the procedures in [Generate Key and Signing](#generate-key-and-signing) to generate an ECDSA-P256 bootloader certificate key pair.
2. Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed GBL image file with the bootloader certificate key pair in step 1. The bootloader certificate version `(--cert-version` in the `util gencert` command) in this signed GBL image file must be **equal to or higher than one (≥ 1)**.
3. Follow the procedures in [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) to upgrade the bootloader to certificate-based Secure Boot. Use the [Private Sign Key](#generate-a-gbl-upgrade-image-file) for ECDSA-P256-SHA256 Secure Boot to sign the bootloader GBL upgrade image file if required.  
   SE will use the Public Bootloader Key to [validate](#signing-for-certificate-based-secure-boot) the bootloader image once SE identifies a bootloader certificate in the bootloader image. If the bootloader certificate version from step 2 is **higher than zero (> 0) and gets verified once**, SE will never again accept the [ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) signed bootloader image. Refer to the "_Secure Boot Procedure_" section in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) for more information.  
   ```sh  
   commander security status --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   SE Firmware version : 1.2.9  
   Serial number	    : 000000000000000014b457fffe045a2d  
   Debug lock	        : Disabled  
   Device erase	    : Enabled  
   Secure debug unlock : Disabled  
   Tamper status	    : Not OK  
   Secure boot	        : Enabled  
   Boot status	        : 0x18 - Failed: Secure Boot requires cert, but none found  
   DONE  
   ```
4. **(Standard Certificate-Based)** Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed application image file with the Private Bootloader Key in step 1.
5. **(Advanced Certificate-Based)** Follow the procedures in [Generate Key and Signing](#generate-key-and-signing) to generate an ECDSA-P256 application certificate key pair.  
   Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed application image file with the application certificate key pair in this step and the Private Bootloader Key in step 1. The application certificate version (`--cert-version` in the `util gencert` command) in this signed application image file must be **equal to or higher** than the bootloader certificate version in step 2 ([Private/Public Key Pair](#privatepublic-key-pair)).
6. Follow the procedures in [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) to upgrade application with the signed image from step 4 or 5 for certificate-based Secure Boot. Use the [Private Sign Key](#generate-a-gbl-upgrade-image-file) or [Private Bootloader key](#generate-a-gbl-upgrade-image-file) in **step 1** for certificate-based Secure Boot to sign the application GBL upgrade image file if required.

##### Certificate Revocation

The certificate revocation is the act of invalidating a certificate when its private key shows signs of being compromised. The following procedures describe how to revoke the Series 2 and Series 3 devices' bootloader certificates deployed in the field.

1. Follow the procedures in [Generate Key and Signing](#generate-key-and-signing) to generate a new ECDSA-P256 bootloader certificate key pair.
2. Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed GBL image file with the bootloader certificate key pair in step 1. The bootloader certificate version (`--cert-version` in the `util gencert` command) in this signed GBL image file must be **higher than** the certificate version in SE flash (see [Private/Public Key Pair](#privatepublic-key-pair)).
3. Follow the procedures in [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) to upgrade the bootloader with the signed image from step 2. Use the [Private Sign Key](#generate-a-gbl-upgrade-image-file) or **existing** [Private Bootloader Key](#generate-a-gbl-upgrade-image-file) for certificate-based Secure Boot to sign the bootloader GBL upgrade image file if required.
4. **(Standard Certificate-Based)** Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed application image file with the Private Bootloader Key in step 1.
5. **(Advanced Certificate-Based)** Follow the procedures in [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate the signed application image file with the Private Bootloader Key in step 1. The application certificate version (--cert-version in the util gencert command) in this signed application image file must be **equal to or higher** than the bootloader certificate version in step 2 (see [Private/Public Key Pair](#privatepublic-key-pair)).  
   You should generate a new [ECDSA-P256 application certificate key pair](#generate-key-and-signing) if the Private Application Key for the application certificate is compromised.
6. Follow the procedures in [Generate a GBL Upgrade Image File](#generate-a-gbl-upgrade-image-file) to upgrade the application with the signed image from step 4 or 5. Use the [Private Sign Key](#generate-a-gbl-upgrade-image-file) or [Private Bootloader key](#generate-a-gbl-upgrade-image-file) in **step 1** for certificate-based Secure Boot to sign the application GBL upgrade image file if required.

##### Upgrade to Secure Boot with RTSL

The following procedures describe upgrading Series 2 and Series 3 devices deployed in the field without Secure Boot to Secure Boot with RTSL.

1. **(Recommended)** Upgrade SE firmware to the latest version if available. See the _Gecko Bootloader Operation - Secure Engine Upgrade_ section in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/).
2. Follow the procedures in [AppBuilder](#) or [3.4.1.2 Bootloader-core Software Component](#bootloader-core-software-component) to prepare an unsigned GBL image with the required [Secure Boot configuration](02-secure-boot-process#application-firmware) for the application firmware.
3. Follow the procedures in [Generate Key and Signing](#generate-key-and-signing) to generate the ECDSA-P256 Sign Key pair for Secure Boot. The key pairs for the bootloader certificate and application certificate (advanced) are required if using [Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot).
4. Follow steps 1 to 2 in [SE Manager Key Provisioning Platform Example](#se-manager-key-provisioning-platform-example-2) if this HSE [GBL Decryption Key option](#provision-gbl-decryption-key) is selected. Use the Public Sign Key in step 3 and follow steps 1 to 3 in [SE Manager Key Provisioning Platform Example](#se-manager-key-provisioning-platform-example) to generate an **unsigned** image. Use this image to create an [application GBL upgrade image file](#generate-a-gbl-upgrade-image-file).
5. The original GBL (application Secure Boot is disabled) boots into the **unsigned** SE Manager Key Provisioning Platform Example after upgrading the application with the image file in step 4.
6. Follow steps 5 to 8 in [SE Manager Key Provisioning Platform Example](#se-manager-key-provisioning-platform-example) to install the Public Sign Key to SE OTP and GBL Decryption Key (optional) to HSE OTP. Press **SPACE** instead of **ENTER** in step 9 to **BYPASS** the programming of the [Secure Boot configuration](02-secure-boot-process#ssb) in SE OTP.  
   ```sh  
   . Press ENTER to initialize SE OTP for secure boot configuration or press SPACE to skip.  
     
   . SE manager deinitialization... SL_STATUS_OK (cycles: 5 time: 0 us)  
   ```  
   **Notes**:  
   - Programming the [Public Sign Key](#signing-for-ecdsa-p256-sha256-secure-boot) to the top page of the main flash (not included in this example) is required for the VSE device ECDSA-P256-SHA256 Secure Boot.  
   - Programming the GBL Decryption Key to the top page of the main flash (not included in this example) is required if the [default storage option](#provision-gbl-decryption-key) for GBL Decryption Key is selected and the **Require encrypted firmware upgrade files** option is enabled in step 2.
7. Follow the signing procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) (Bootloader Image File section, skip the Secure Boot configuration for the bootloader) with the required key(s) generated in step 3 to sign the unsigned GBL image generated from step 2. Use this signed image to create a [bootloader GBL upgrade image file](#generate-a-gbl-upgrade-image-file).
8. Follow the signing procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) (Application Image File section) with the required key(s) generated in step 3 to sign the unsigned application image generated from step 4. Use this signed image to create an [application GBL upgrade image file](#generate-a-gbl-upgrade-image-file).  
   > **Note**: For the application bootloader with storage, you can generate a [single GBL upgrade image file](#generate-a-gbl-upgrade-image-file) for signed images from steps 7 and 8.
9. The Secure Boot in SE OTP is not yet enabled, so FSB does not verify the signature when upgrading to the signed GBL in step 7. The updated GBL (application Secure Boot enabled) verifies the signature when upgrading or booting to the signed SE Manager Key Provisioning Platform Example in step 8.
10. Follow steps 9 to 10 (use **SPACE** to skip previous steps for OTP key programming) in [SE Manager Key Provisioning Platform Example](#se-manager-key-provisioning-platform-example) to program the required [Secure Boot configuration](02-secure-boot-process#ssb) in SE OTP for signed GBL.
11. Update a **signed** custom application firmware to replace the signed SE Manager Key Provisioning Platform Example used for Secure Boot with RTSL upgrade.

**Notes**:

- Refer to the "_Enabling Secure Boot RTSL on Series 2 and Series 3 Devices_" section (either Standalone Bootloaders or Application Bootloaders with Storage) in _UG266: Silicon Labs Gecko Bootloader User’s Guide for GSDK 3.2 and Lower_, [Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) or [Silicon Labs Gecko Bootloader User’s Guide for Series 3 and Higher](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-series3-and-higher/) for details.
- The SE Manager Key Provisioning Platform Example used here is just for reference. You can modify or write a new application to automate the processes for the Secure Boot with RTSL upgrade.
- If the [Require signed firmware upgrade files](#generate-a-gbl-upgrade-image-file) option is enabled in step 2, the GBL upgrade image files from steps 8 and 11 must be signed.
- If the [Require encrypted firmware upgrade files](#generate-a-gbl-upgrade-image-file) option is enabled in step 2, the GBL upgrade image files from steps 8 and 11 must be encrypted. And the GBL Decryption Key for the corresponding [option](#provision-gbl-decryption-key) in GBL must be in place.

##### Recover Devices when Secure Boot Fails

If a Secure Boot process fails (meaning firmware image at device starting address validation fails), the only way to recover is to flash a correctly signed image.

There are two scenarios to recover the device from a Secure Boot failure:

1. Debug Lock
2. BUSLOCK

###### DEBUG LOCK

The following table describes the different debug lock scenarios on recovering the Secure Boot failure device.

|**Secure Debug**|**Device Erase**|**Debug Lock**|**State**|**Recover from Secure Boot Failure**|
|---|---|---|---|---|
|Disabled|Enabled|Disabled|Unlock|Flash a correctly signed image.|
|Disabled|Enabled|Enabled|Standard debug lock|Flash a correctly signed image after standard debug unlocking the device.|
|Disabled|Disabled|Enabled|Permanent debug lock|There is no way to recover the device. Make sure the programmed image is correctly signed before locking the device.|
|Enabled|Disabled|Enabled|Secure debug lock|Flash a correctly signed image after secure debug unlocking the device.|

> **Note**: The error code in the **Boot status** of examples below depends on boot failure caused by the host image (GBL).

The following procedures describe how to recover the Secure Boot failure device from the lock states below.

- Unlocked
- Standard debug locked
- Secure debug locked

1. Follow the procedure in [Signing for ECDSA-P256-SHA256 Secure Boot](#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](#signing-for-certificate-based-secure-boot) to generate a correctly signed GBL.
2. **(Unlocked)** Run the `security status` command to get the boot status.  
   ```sh  
   commander security status --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   SE Firmware version : 1.2.9  
   Serial number	    : 000000000000000014b457fffe045afd  
   Debug lock	        : Disabled  
   Device erase	    : Enabled  
   Secure debug unlock : Disabled  
   Tamper status	    : Not OK  
   Secure boot	        : Enabled  
   Boot status	        : 0x12 - Failed: Error while checking signature of host firmware  
   DONE  
   ```  
   Run the `flash` command to flash the correctly signed image (like `bootloader-uart-xmodem.s37`). If a failed Secure Boot is detected, the device will be erased before flashing the new image.  
   ```sh  
   commander flash bootloader-uart-xmodem.s37 --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   WARNING: Failed secure boot detected. Issuing a mass erase before flashing to recover the device...  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing 16384 bytes starting at address 0x00000000  
   Comparing range 0x00000000 - 0x00003FFF (16 KiB)  
   Programming range 0x00000000 - 0x00001FFF (8 KiB)  
   Programming range 0x00002000 - 0x00003FFF (8 KiB)  
   DONE  
   ```
3. **(Standard debug locked)** Run the `security status` command to get the boot status.  
   ```sh  
   commander security status --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   SE Firmware version : 1.2.9  
   Serial number	    : 000000000000000014b457fffe045afd  
   Debug lock	        : Enabled  
   Device erase	    : Enabled  
   Secure debug unlock : Disabled  
   Tamper status	    : Not OK  
   Secure boot	        : Enabled  
   Boot status	        : 0x12 - Failed: Error while checking signature of host firmware  
   DONE  
   ```  
   Run the `security erasedevice` command to unlock the device.  
   ```sh  
   commander security erasedevice --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   Successfully erased device  
   DONE  
   ```  
   > **Note**: Issue a power-on or pin reset to complete the unlock process.  
   Run the `flash` command to flash the correctly signed image (like `bootloader-uart-xmodem.s37`). If a failed Secure Boot is detected, the device will be erased before flashing the new image.  
   ```sh  
   commander flash bootloader-uart-xmodem.s37 --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   WARNING: Failed secure boot detected. Issuing a mass erase before flashing to recover the device...  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing 16384 bytes starting at address 0x00000000  
   Comparing range 0x00000000 - 0x00003FFF (16 KiB)  
   Programming range 0x00000000 - 0x00001FFF (8 KiB)  
   Programming range 0x00002000 - 0x00003FFF (8 KiB)  
   DONE  
   ```
4. **(Secure debug locked)** Run the `security status` command to get the boot status.  
   ```sh  
   commander security status --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   SE Firmware version : 1.2.9  
   Serial number	    : 0000000000000000000d6ffffe0a3a5f  
   Debug lock	        : Enabled  
   Device erase	    : Disabled  
   Secure debug unlock : Enabled  
   Tamper status	    : Not OK  
   Secure boot	        : Enabled  
   Boot status	        : 0x12 - Failed: Error while checking signature of host firmware  
   DONE  
   ```  
   Run the `security unlock` command to unlock the device with the debug unlock token.  
   ```sh  
   commander security unlock --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   Unlocking with unlock payload:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000000d6ffffe0a3a5f/challenge_020fc3cc9e492088d06d75d71b7aabfe/unlock_payload_0000000000111110.bin  
   Secure debug successfully unlocked  
   DONE  
   ```  
   Run the `flash` command with the `--noreset` option to flash the correctly signed image (like `bootloader-uart-xmodem.s37`).  
   ```sh  
   commander flash --noreset bootloader-uart-xmodem.s37 --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   Parsing file bootloader-uart-xmodem.s37...  
   Writing 16384 bytes starting at address 0x00000000  
   Comparing range 0x00000000 - 0x00003FFF (16 KiB)  
   Erasing range 0x00000000 - 0x00003FFF (2 sectors, 16 KiB)  
   Programming range 0x00000000 - 0x00001FFF (8 KiB)  
   Programming range 0x00002000 - 0x00003FFF (8 KiB)  
   DONE  
   ```  
   > **Note**: The `--noreset` option prevents the device from returning to the secure debug lock state before flashing.
5. Run the `security status` command to check the boot status. The example below is an unlocked device.  
   ```sh  
   commander security status --device EFR32MG21A010F1024 --serialno 440048205  
   ```  
   ```sh  
   SE Firmware version : 1.2.9  
   Serial number       : 000000000000000014b457fffe045afd  
   Debug lock          : Disabled  
   Device erase        : Enabled  
   Secure debug unlock : Disabled  
   Tamper status       : OK  
   Secure boot         : Enabled  
   Boot status         : 0x20 - OK  
   DONE  
   ```

###### BUSLOCK

When secure boot is enabled, the SE enforces the secure boot process through a hardware mechanism called BUSLOCK. This BUS-LOCK will halt the host-side (M33) bus so that it will not start the executing code. The BUSLOCK is enabled out of reset when secure boot is enabled.

- **BUSLOCK status for secure boot success**: BUSLOCK is enabled out of reset and is released only when the Secure boot process is successful and returns 0x20 - OK status code.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.9
Serial number       : 000000000000000014b457fffe045afd
Debug lock          : Disabled
Device erase        : Enabled
Secure debug unlock : Disabled
Tamper status       : OK
Secure boot         : Enabled
Boot status         : 0x20 - OK
DONE
```

- **BUSLOCK status for secure boot failure**: BUSLOCK remains applied when the Secure Boot process fails and returns anything but 0x20 - OK status code. This keeps the BUSLOCK intact, and the host CPU is frozen, resulting in halting firmware execution on the M33 core. The device can be recovered from the BUSLOCK state by following these steps:

1. Issue a `security erase` command to the SE:  
   ```sh  
   commander security erasedevice  
   ```  
   ```sh  
   Successfully erased device  
   DONE  
   ```
2. After issuing the `security erase` command to the SE, flash the correctly signed image to recover from a secure boot failure.

#### Debugging on Secure Boot Enabled Device

Assume a correctly signed GBL image has been programmed to the device. Follow the procedures in [Generate an Unsigned Ap- plication Image](03-examples#generate-an-unsigned-application-image) to generate an unsigned application image for the GBL.

The Windows environment variable PATH should include the folder (`C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\commander`) that locates the `commander.exe` of Simplicity Commander.

The following sections describe how to debug an application firmware with Simplicity IDE, or IAR on a Secure Boot enabled device.

##### Simplicity IDE

This application note uses Simplicity Studio v5.2.3.1. The procedures and pictures may be different for the other versions of Simplicity Studio 5.

1. The Simplicity IDE creates a folder below (`<NAME>` is the Windows User Name on PC) in Windows when building the unsigned application image.  
   `C:\Users\<NAME>\SimplicityStudio\v5_workspace\blink_baremetal\GNU ARM v10.2.1 - Default`
2. Follow the procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](03-examples#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](03-examples#signing-for-certificate-based-secure-boot) to create a batch file (Windows) to sign the unsigned application image and then flash it to the device. This application note uses ECDSA-P256-SHA256 Secure Boot (Using Simplicity Commander) as an example to create a `secure_boot_debug.bat` file below.  
   ```sh  
   commander convert blink_baremetal.s37 --secureboot --keyfile sign_key.pem --verify sign_pubkey.pem  
   --outfile blink_baremetal.s37  
   commander flash blink_baremetal.s37  
   ```
3. Copy the batch file in step 2 and files (`sign_key.pem` and `sign_pubkey.pem` in this example) specified in `secure_boot_debug.bat` to the folder in step 1.
4. Right-click the project in the **Project Explorer** window, and then click **Properties** to open the properties dialog.  
   ![Project Explorer window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image62.png)
5. Select **C/C++ Build > Settings > Build Steps**. Enter the phrase below to the **Command:** box under the **Post-build steps** (enter text to **Description:** box is optional) to run the batch file as a post-build action. Click [**Apply and Close**] to exit.  
   ```sh  
   cmd //c 'secure_boot_debug.bat'  
   ```  
   ![Properties dialog box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image63.jpg)
6. After building the project, the batch file in the **Post-build steps** overwrites the unsigned application image with the signed application image.  
   ![Overwriting in Post-build steps](/series2-secure-boot-with-rtsl/0.3/images/sld794-image64.jpg)  
   > **Note**: If the project is already up-to-date, it will not invoke the **Post-build steps** in step 5 to run the batch file. Use a dummy edit (add space or newline) on one of the source files in the project to trigger the build action.  
   ![Console window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image65.jpg)  
   The application starts to run if no error in step 6.
7. Select the project in the **Project Explorer** window, click **Run→Attach to→1 Silicon Labs ARM Program** to attach to the running target for debugging on the signed application image.  
   ![Run window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image66.jpg)

##### IAR

This section uses Simplicity Studio v5.4.2.0 and IAR v9.20.4. The procedures and pictures may be different for the other versions of Simplicity Studio 5 and IAR.

1. The **Overview** tab shows the **Target and Tool Settings** card on the left side. Scroll down if necessary and click [**Change Target/SDK/Generators**].  
   ![Overview tab in SCLP file](/series2-secure-boot-with-rtsl/0.3/images/sld794-image67.jpg)
2. Drop down the **CHANGE PROJECT GENERATORS** list and select **IAR Embedded Workbench Project**. Click [**Save**] to generate an IAR project.  
   ![Target and tool settings dialog box](/series2-secure-boot-with-rtsl/0.3/images/sld794-image68.png)
3. Double click the IAR workspace file (`blink_baremetal.eww`) in the **Project Explorer** window to open the IAR project. The IAR creates a folder below (`<NAME>` is the Windows User Name on PC) in Windows to store the compiled image.  
   `C:\Users\<NAME>\SimplicityStudio\v5_workspace\blink_baremetal\ewarm-iar\exe`  
   ![Project Explorer window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image69.png)
4. Follow the procedures in [Signing for ECDSA-P256-SHA256 Secure Boot](03-examples#signing-for-ecdsa-p256-sha256-secure-boot) or [Signing for Certificate-Based Secure Boot](03-examples#signing-for-certificate-based-secure-boot) to create a batch file (Windows) to sign the unsigned application image. This application note uses ECDSA-P256-SHA256 Secure Boot (Using Simplicity Commander) as an example to create a `secure_boot_debug.bat` file below.  
   ```sh  
   cd C:\Users\<NAME>\SimplicityStudio\v5_workspace\blink_baremetal\ewarm-iar\exe  
   commander convert blink_baremetal.s37 --secureboot --keyfile sign_key.pem --verify sign_pubkey.pem  
   --outfile blink_baremetal.s37  
   ```
5. Copy the batch file in step 4 and files (`sign_key.pem` and `sign_pubkey.pem` in this example) specified in `secure_boot_debug.bat` to the folder in step 3.
6. Right-click the project in the workspace, and then click **Options...**.  
   ![Workspace window](/series2-secure-boot-with-rtsl/0.3/images/sld794-image70.jpg)  
   > **Note**: For GSDK v3.2 and lower, the `app_properties.c` is manually added to the IAR project.
7. Click **Build Actions** to open the **Build Actions Configuration** dialog box. Enter the phrase below to the **Post-build command line:** box to run the batch file as a post-build action. Click [**OK**] to exit.  
   ```sh  
   cmd /c "$PROJ_DIR$\ewarm-iar\exe\secure_boot_debug.bat > $PROJ_DIR$\log.txt 2>&1"  
   ```
8. After building the project, the batch file in the **Post-build command** overwrites the unsigned application image with the signed application image.  
   ![Build messages](/series2-secure-boot-with-rtsl/0.3/images/sld794-image72.png)  
   > **Note**: If the project is already up-to-date, it will not invoke the **Post-build command** in step 7 to run the batch file. Use a dummy edit (add space or newline) on one of the source files in the project to trigger the build action.  
   ![Build messages](/series2-secure-boot-with-rtsl/0.3/images/sld794-image73.png)
9. The `> $PROJ_DIR$\log.txt 2>&1` redirects the batch file output to the `log.txt` file in the IAR project folder.  
   ![Log.txt file](/series2-secure-boot-with-rtsl/0.3/images/sld794-image74.jpg)
10. If no error in step 8, click the ![start](/series2-secure-boot-with-rtsl/0.3/images/sld794-image75.jpg) icon to start debugging on the signed application image.

#### Failure Analysis

The following table describes the different scenarios when returning a Series 2 or Series 3 device to Silicon Labs for failure analysis.

|**State**|**Secure Boot Disabled**|**Secure Boot Enabled (2)**|
|---|---|---|
|Standard debug unlock|Device erase is not necessary for failure analysis.|Device erase is not necessary, but a correctly signed image is required to perform failure analysis.|
|Standard debug lock|Device erase is required to perform failure analysis.|Require device erase and correctly signed image to perform failure analysis.|
|Permanent debug lock|Cannot perform failure analysis.|Cannot perform failure analysis.|
|Secure debug lock (1)|Require debug unlock token to perform failure analysis.|Require debug unlock token and correctly signed image to perform failure analysis.|

**Notes**:

1. Follow the procedures in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) section _Secure Debug Unlock and Roll Challenge - Simplicity Commander_ to generate a valid debug unlock token for each device returned to Silicon Labs for failure analysis.
2. Secure boot enabled devices, especially with secure boot failure, may limit Silicon Labs' ability to determine the root cause of failure.

#### Secure Boot Status Codes

Boot status codes can be used to know the status of the boot mechanism. The `security status` command can be used to get the boot status.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.9
Serial number : 000000000000000014b457fffe045afd
Debug lock : Disabled
Device erase : Enabled
Secure debug unlock : Disabled
Tamper status : OK
Secure boot : Enabled
Boot status : 0x20 - OK
DONE
```

The following table shows Status codes in Secure Boot mechanism and their description:

|**STATUS CODE**|**DESCRIPTION**|
|---|---|
|0x00|Start PUF|
|0x01|Fetch OTP for bootloader|
|0x02|Tamper test|
|0x03|Self-tests|
|0x04|TRNG Initialization failed|
|0x05|NVM Initialization failed|
|0x0B|Jump to main loop|
|0x0C|Fetch OTP for host boot|
|0x0D|Fetch pointers host firmware|
|0x0E|Fetch header host firmware|
|0x0F|Fetch host firmware|
|0x10|Check version host firmware|
|0x11|Check signature on certificate for host firmware|
|0x12|Check signature host firmware|
|0x13|Failed to get data from internal NVM|
|0x14|Finding host application properties pointer|
|0x15|Validating host application properties structure|
|0x16|Validating host application signature pointer|
|0x17|Getting SecureBoot key|
|0x18|SecureBoot requires cert, but none found|
|0x19|Updating required certificate version failed|
|0x1A|Certificate is of an older version as the last cert we validated|
|0x1B|Certificate structure version is not supported by this firmware|
|0x1C|Certificate pointer is out of range|
|0x1D|Region 0 is not closed|
|0x20|Main loop entered|
|0x80|PUF AC was somehow cleared|
|0x81|PUF failed to reconstruct after the longest delay|
|0x90|ESEC aborted booting due to catching too many successive tamper resets|
|0xFF|Finished verifying host app|

### Series 2 TrustZone

#### Series 2 TrustZone

> **Note: This section replaces _AN1374: TrustZone_. Further updates to this user guide will be provided here**.

ARMv8-M TrustZone is a technology that provides a foundation for improved system security in embedded applications. It allows the ARMv8-M to be aware of the security states of the system. Series 2 devices use the Cortex-M33 core to implement the ARMv8-M TrustZone security extension, which provides the ability to restrict access to peripherals and memory regions based on the processor security attribute. TrustZone works with the MPU, which controls privileged/unprivileged execution of code to provide a complete security solution.

ARMv8-M TrustZone is an extensive topic. The references below are publicly available on the [ARM Developer Documentation](https://developer.arm.com/docs) website.

- [ARMv8-M Architecture Reference Manual](https://developer.arm.com/documentation/ddi0553/latest)
- [ARMv8-M Architecture Technical Overview](https://community.arm.com/cfs-file/__key/telligent-evolution-components-attachments/01-2142-00-00-00-00-66-90/Whitepaper-_2D00_-ARMv8_2D00_M-Architecture-Technical-Overview.pdf)
- [ARM Cortex-M33 Processor Technical Reference Manual](https://developer.arm.com/documentation/100230/latest)
- [System Design with ARMv8-M](https://developer.arm.com/documentation/100767/0100/System-Design-for-ARMv8-M)
- [TrustZone technology for ARMv8-M Architecture](https://developer.arm.com/documentation/100690/latest/)
- [ARM Cortex-M33 Devices Generic User Guide](https://developer.arm.com/documentation/100235/latest)
- [Secure software guidelines for ARMv8-M](https://developer.arm.com/documentation/100720/0300)
- [Software Development in ARMv8-M Architecture](https://community.arm.com/cfs-file/__key/telligent-evolution-components-attachments/01-2142-00-00-00-01-27-19/ARM-Cortex-_2D00_-session-11-_2D00_-Yiu-_2D00_-Software-Development-in-ARMv8_2D00_M-Architecture.pdf)Reading guides:
- Beginner
- Minimal experience with TrustZone, starting with [TrustZone Basics](02-r-basic)
- Intermediate - Have a basic understanding of the TrustZone technology, starting with [Bus Level Security](03-r-bls)
- Advanced - Developed experience on TrustZone, starting with [TrustZone Implementation](05-r-implementation)-Demo - Starting with [TrustZone Platform Examples](05-r-implementation)

##### Key Points

- TrustZone Basics
- Bus Level Security (BLS)
- Secure and Privileged Programming Model
- TrustZone Implementation
- Upgrade Existing Application to TrustZone
- TrustZone Platform Examples

#### Series 2 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure communication paths to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys, and to execute cryptographic functions and secure services.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

<table>
    <thead>
        <tr>
            <th>
                <p>Level (1)</p>
            </th>
            <th>
                <p>SE Support</p>
            </th>
            <th>
                <p>Part</p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Secure Vault High (SVH)</p>
            </td>
            <td>
                <p>HSE only (HSE-SVH)</p>
            </td>
            <td>
                <p>Refer to <a href="https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/">IoT Endpoint Security Fundamentals</a> for details on supporting devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Vault Mid (SVM)</p>
            </td>
            <td>
                <p>HSE (HSE-SVM)</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Vault Mid (SVM)</p>
            </td>
            <td>
                <p>VSE (VSE-SVM)</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Vault Base (SVB)</p>
            </td>
            <td>
                <p>N/A</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: 1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security).

Secure Vault Mid consists of two core security functions:

- Secure Boot: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- Secure Debug Access Control: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- Secure Key Storage: Protects cryptographic keys by "wrapping" or encrypting the keys using a root key known only to the HSE-SVH.
- Anti-Tamper protection: A configurable module to protect the device against tamper attacks.
- Device authentication: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

Series 2 devices require a specific [SE firmware version](06-r-migration) to support the TrustZone implementation. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) to learn how to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 devices and modules.

Series 2 devices use Cortex-M33 core to implement the ARMv8-M Mainline TrustZone security extension and refer to TrustZone as [Bus Level Security](03-r-bls). The following table lists the configuration of TrustZone related components in the Series 2 Cortex-M33 core.

<table>
    <thead>
        <tr>
            <th>
                <p>Component</p>
            </th>
            <th>
                <p>Series 2 Configuration</p>
            </th>
            <th>
                <p>Description</p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Security Extension (TrustZone)</p>
            </td>
            <td>
                <p>Enabled</p>
            </td>
            <td>
                <p>The security extension cannot be disabled, and the entire memory after RESET is Secure by default.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Memory Protection Unit (MPU)</p>
            </td>
            <td>
                <p>16 regions (maximum)</p>
            </td>
            <td>
                <p>The MPU regions for both Secure and Non-secure MPUs.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Security Attribution Unit (SAU)</p>
            </td>
            <td>
                <p>8 regions (maximum)</p>
            </td>
            <td>
                <p>The SAU regions for Non-secure and Non-secure Callable.</p>
            </td>
        </tr>
    </tbody>
</table>

#### TrustZone Basics

##### Introduction

TrustZone for ARMv8-M adds extra states to the Cortex-M processor operations to ensure there is  a Secure and Non-secure state. These security states are orthogonal to the existing Thread and Handler modes, thereby having both a Thread and Handler mode in both Secure and Non-secure states. The Thread mode can also be either Privileged or Unprivileged.

![Operation States and Modes of TrustZone Implementation](/series2-trustzone/0.2/images/sld717-operation-states-and-modes-of-trustzone-implementation.png)

_Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

TrustZone for ARMv8-M is an optional architecture extension. By default, the system starts up in a Secure state if the processor implements the TrustZone security extension. The division of Secure and Non-secure worlds is memory-map based (security state depends on the address of the fetched instruction), and the transitions happen automatically. It is also possible to leave the Non-secure state unused and execute the whole application in the Secure state.

##### Memory Security Attributes

TrustZone classifies memory into four security attributes as described in the following table.

<table>
    <thead>
        <tr>
            <th>
                <p>Security Attribute</p>
            </th>
            <th>
                <p>Processor State</p>
            </th>
            <th>
                <p>Description</p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Non-secure (NS)</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
            <td>
                <p>Non-secure and Secure software can access these memory regions.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure (S)</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
            <td>
                <p>Secure software can access these memory regions. Non-secure software cannot gain access to the Secure memory.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Non-secure Callable (NSC)</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
            <td>
                <p>Secure memory with an NSC attribute provides entry points for Secure APIs that can be called from a Non-secure space. It is a region of memory that contains the Secure Gateway (SG) veneers that allow Non-secure code to call secure functions that exist in Secure code. Non-secure software cannot read/write to an NSC memory but can branch into it if the branch target is an SG instruction.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Exempted</p>
            </td>
            <td>
                <p>Secure/Non-secure</p>
            </td>
            <td>
                <p>Non-secure and Secure software can access these memory regions (exempted from security checking). Exempted regions are typically used by debugging components that do not pose any security risk (e.g., system ROM table) when accessed by the Non-secure software.</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note:** The [Non-secure Callable](#switching-from-non-secure-to-secure-state) is also known as Secure Non-secure Callable (Secure NSC) to declare that this region resides in Secure memory.

##### Banked Register

The concept of a banked register in ARMv8-M between Secure and Non-secure states means that there are two copies of the register, and the core automatically uses the copy that belongs to the current security state. When a register is banked, the `_S` and `_NS` suffixes are used in the ARMv8-M architecture to identify whether the resource is for the Secure state or Non-secure state.

###### General-Purpose Registers

The Cortex-M processors have 16 general-purpose registers (R0 - R15) for data processing (R0 - R12) and control. The following figure shows the general-purpose register view of the ARMv8-M system with TrustZone. Refer to the [ARM Cortex-M33 Devices Generic User Guide](https://developer.arm.com/documentation/100235/0100/The-Cortex-M33-Processor/Programmer-s-model/Core-registers) for details about these registers.

![General-Purpose Register View with TrustZone](/series2-trustzone/0.2/images/sld717-general-purpose-register-view-with-trustzone.png)

_Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

The Secure or Non-secure state can access the data processing registers R0 - R12 and special usage registers R13 - R15. The register R13 (banked SP) is the stack pointer alias, and the actual stack pointer (`MSP_NS`, `PSP_NS`, `MSP_S`, `PSP_S`) accessed depends on the state (Secure or Non-secure) and mode (Handler or Thread) as described in the following figure.

In addition, stack limit registers ([special registers](#special-purpose-registers)) enable hardware to detect stack overflow conditions. Two pairs of [stack limit registers](#special-purpose-registers) (`MSPLIM_NS` and `PSPLIM_NS`, `MSPLIM_S` and `PSPLIM_S`) are implemented, one per security state, to protect the Main Stack Pointer (MSP) and Process Stack Pointer (PSP).

![Banked Registers in the General-Purpose Registers](/series2-trustzone/0.2/images/sld717-banked-registers-in-the-general-purpose-registers.png)

_Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

In Thread mode, execution can be privileged or unprivileged. The stack pointer used can be the MSP or PSP, depending on the `SPSEL` bit in the [CONTROL](#special-purpose-registers) register. When in Handler mode, the processor is Privileged. The stack pointer is always MSP.

It is possible to directly [access](https://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html) the stack pointers (MSP and PSP) and stack limit registers (MSPLIM and PSPLIM), providing that the processor is in a privileged state. If the processor is in a Secure privileged state, the software can also access the Non-secure stack pointers (`MSP_NS` and `PSP_NS`) through [Core Register Access Functions](https://arm-software.github.io/CMSIS_5/Core/html/group__coreregister__trustzone__functions.html) in CMSIS-Core.

###### Special-Purpose Registers

Except for the general-purpose registers, there are several special-purpose registers for conditional flags, interrupt masking, control, and stack pointer limit. The following figure shows the special-purpose registers view of the ARMv8-M system with TrustZone. Refer to the [ARM Cortex-M33 Devices Generic User Guide](https://developer.arm.com/documentation/100235/0100/The-Cortex-M33-Processor/Programmer-s-model/Core-registers) for details about these registers.

![Special-purpose Registers View with TrustZone](/series2-trustzone/0.2/images/sld717-special-purpose-registers-view-with-trustzone.png)

Image:_[https://documentation-service.arm.com/](https://documentation-service.arm.com/static/5e7cd7b67158f500bd5c4eea?token=).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

The Combined Program Status Register (xPSR) consists of the Application Program Status Register (APSR), Interrupt Program Status Register (IPSR), and Execution Program Status Register (EPSR).

Some of the special-purpose registers are banked between Secure and Non-secure states. Special-purpose registers are not memory-mapped and can be [accessed](https://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html) using Core Register Access Functions in CMSIS-Core (except for EPSR in xPSR).

Secure privileged software can also access the Non-secure interrupt masking registers (`PRIMASK_NS`, `FAULTMASK_NS`, and `BASEPRI_NS`), CONTROL register (`CONTROL_NS`), and stack limit registers (`MSPLIM_NS` and `PSPLIM_NS`) through [Core Register Access Functions](https://arm-software.github.io/CMSIS_5/Core/html/group__coreregister__trustzone__functions.html) in CMSIS-Core.

###### System Private Peripheral Bus (PPB)

The banking of registers is usually used to separate the Secure and Non-secure information of the system components inside the processor. The following figure shows the System Private Peripheral Bus (PPB) registers view of the ARMv8-M system with TrustZone. Refer to the [ARM Cortex-M33 Devices Generic User Guide](https://developer.arm.com/documentation/100235/0100/The-Cortex-M33-Peripherals/About-the-Cortex-M33-peripherals) for details about the System PPB registers.

![System Private Peripheral Bus (PPB) Registers View with TrustZone](/series2-trustzone/0.2/images/sld717-system-private-peripheral-bus-ppb-registers-view-with-trustzone.png)

**System components for debugging and trace operations (`0xE0000000` to `0xE0002FFF`)**:

- Instrumentation Trace Macrocell (ITM)
- Data Watch point and Trace unit (DWT)
- Flash Patch and Breakpoint unit (FPB)

**System Control Space (SCS)**:

- The registers in SCS address spaces are memory-mapped and can be accessed using pointers in software
- Secure SCS (`0xE000E000` to `0xE000EFFF`) - Secure software using this address space to access the banked Secure SCS registers (e.g., `SCB->CPUID`)
- Non-secure SCS (`0xE000E000` to `0xE000EFFF`) - Non-secure software using this address space to access the banked Non-secure SCS registers (e.g., `SCB->CPUID`)
- Non-secure alias SCS (`0xE002E000` to `0xE002EFFF`) - Secure software using this address space to access the Non-secure SCS registers (e.g., `SCB_NS->CPUID`)

The following table describes some core peripherals in the SCS and corresponding [data structures](https://arm-software.github.io/CMSIS_5/Core/html/annotated.html) defined in the CMSIS-Core header file to access the registers of core peripherals in two SCS address spaces.

<table>
    <thead>
        <tr>
            <th>
                <p>Core Peripheral</p>
            </th>
            <th>
                <p>Data Structure for Secure and NS SCS</p>
            </th>
            <th>
                <p>Data Structure for NS Alias SCS</p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Implementation Control Block</p>
            </td>
            <td>
                <p>SCnSCB (0xE000E004)</p>
            </td>
            <td>
                <p>SCnSCB_NS (0xE002E004)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SysTick Timer</p>
            </td>
            <td>
                <p>SysTick (0xE000E010)</p>
            </td>
            <td>
                <p>SysTick_NS (0xE002E010)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Nested Vectored Interrupt Controller</p>
            </td>
            <td>
                <p>NVIC (0xE000E100)</p>
            </td>
            <td>
                <p>NVIC_NS (0xE002E100)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>System Control Block</p>
            </td>
            <td>
                <p>SCB (0xE000ECFC)</p>
            </td>
            <td>
                <p>SCB_NS (0xE002ECFC)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Memory Protection Unit</p>
            </td>
            <td>
                <p>MPU (0xE000ED90)</p>
            </td>
            <td>
                <p>MPU_NS (0xE002ED90)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Security Attribution Unit</p>
            </td>
            <td>
                <p>SAU (0xE000EDD0)</p>
            </td>
            <td>
                <p>-</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Debug Control Block</p>
            </td>
            <td>
                <p>CoreDebug (0xE000EDF0)</p>
            </td>
            <td>
                <p>CoreDebug_NS (0xE002EDF0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Software Interrupt Generation</p>
            </td>
            <td>
                <p>STIR (0xE000EF00)</p>
            </td>
            <td>
                <p>STIR_NS (0xE002EF00)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Floating-Point Extension</p>
            </td>
            <td>
                <p>FPU (0xE000EF34)</p>
            </td>
            <td>
                <p>FPU_NS (0xE002EF34)</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- The SCB is a group of system control registers for the various usages below.  
  - System Control Register (SCR) to configure processor low power mode  
  - Fault Status Register (xFSR) to provide fault status information  
  - [Vector Table Offset Register (VTOR)](#type-of-exceptions) for vector table relocation
- The [SAU](03-r-bls#security-attribution-unit) register is accessible from the Secure state only.
- The STIR register is not physically banked.
- Core peripherals such as SysTick, SCB, and MPU are duplicated. One instance is Secure and the other one is Non-secure.
- Secure software can use the corresponding functions for ARMv8-M in CMSIS-Core to configure the Non-secure [NVIC](https://arm-software.github.io/CMSIS_5/Core/html/group__nvic__trustzone__functions.html) and [SysTick](https://arm-software.github.io/CMSIS_5/Core/html/group__systick__trustzone__functions.html) through the Non-secure alias SCS.

**Debug or vendor specific components (`0xE0040000` to `0xE00FFFFF`)**:

- Optional debug components (e.g., ETM)
- [External Private Peripheral Bus (EPPB)](03-r-bls#external-secure-attribution-unit-esau) allows designers to add their own debug or vendor-specific components
- [System ROM Table](03-r-bls#external-secure-attribution-unit-esau) is a simple lookup table that enables debug tools to extract the addresses of debug and trace components

##### Secure Attribution Unit (SAU), Implementation Defined Attribution Unit (IDAU), and Memory Protection Unit (MPU)

Two units determine the security attribute of an address:

1. The internal programmable [Secure Attribution Unit (SAU)](https://developer.arm.com/documentation/100690/0201/Attribution-units--SAU-and-IDAU-).
2. The external Implementation Defined Attribution Unit (IDAU), through the IDAU interface, returns the security attribute and region number of an address.

![mpu](/series2-trustzone/0.2/images/sld717-mpu.png)

Three possible configurations to define the security attribute of an address:

1. Internal SAU only
2. External IDAU only
3. A combination of the internal [SAU](03-r-bls#security-attribution-unit) and external IDAU

**Notes**:

- Series 2 devices use configuration 3.
- IDAU in Series 2 devices is the [External Secure Attribution Unit (ESAU)](03-r-bls#external-secure-attribution-unit-esau).

The [Memory Protection Unit (MPU)](https://developer.arm.com/documentation/100699/0100/) is a programmable unit that allows privileged software to define memory access permission. If the TrustZone is enabled, there can be up to two MPUs, one for Secure and one for Non-secure.

- The number of [MPU regions](01-series-2-security-features) for the Secure and the Non-secure MPU can be different.
- The MPU registers are memory-mapped and are placed in the [System Control Space (SCS)](#system-private-peripheral-bus-ppb).
- Secure software can use the [MPU Functions for ARMv8-M](https://arm-software.github.io/CMSIS_5/Core/html/group__mpu8__functions.html) in CMSIS-Core to configure the Non-secure MPU through the [Non-secure alias SCS](#system-private-peripheral-bus-ppb) (`0xE002ED90` - `0xE002EDC4`).

<table>
    <thead>
        <tr>
            <th>Software</th>
            <th>Non-secure MPU Registers</th>
            <th>Secure MPU Registers</th>
            <th>MemManage Fault</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Non-secure privileged</p>
            </td>
            <td>
                <p>0xE000ED90 - 0xE000EDC4</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Non-secure MPU violation</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure privileged</p>
            </td>
            <td>
                <p>0xE002ED90 - 0xE002EDC4</p>
            </td>
            <td>
                <p>0xE000ED90 - 0xE000EDC4</p>
            </td>
            <td>
                <p>Secure MPU violation</p>
            </td>
        </tr>
    </tbody>
</table>

##### Exceptions and Interrupts

###### Type of Exceptions

The following table describes the types of exceptions in the TrustZone implemented system.

<table>
    <thead>
        <tr>
            <th>Section</th>
            <th>Guidance</th>
            <th>Type</th>
            <th>Default State</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>1 (-)</p>
            </td>
            <td>
                <p>Reset</p>
            </td>
            <td>
                <p>Secure only</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2 (-14)</p>
            </td>
            <td>
                <p>NMI</p>
            </td>
            <td>
                <p>Configurable</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>3 (-13)</p>
            </td>
            <td>
                <p>HardFault</p>
            </td>
            <td>
                <p>Configurable</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>4 (-12)</p>
            </td>
            <td>
                <p>MemManage Fault</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>5 (-11)</p>
            </td>
            <td>
                <p>BusFault</p>
            </td>
            <td>
                <p>Configurable</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>6 (-10)</p>
            </td>
            <td>
                <p>UsageFault</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>7 (-9)</p>
            </td>
            <td>
                <p>SecureFault</p>
            </td>
            <td>Secure only<p></p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>11 (-5)</p>
            </td>
            <td>
                <p>SVCall</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>12 (-4)</p>
            </td>
            <td>
                <p>DebugMonitor</p>
            </td>
            <td>
                <p>Configurable</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>14 (-2)</p>
            </td>
            <td>
                <p>PendSV</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>15 (-1)</p>
            </td>
            <td>
                <p>SysTick</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
            <td>
                <p>Banked</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>16 - 495 (0 - 479)</p>
            </td>
            <td>
                <p>IRQ0 - IRQ479</p>
            </td>
            <td>
                <p>Configurable</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- "Secure only" means the system exceptions can only trigger in the Secure state.
- "Configurable" means the system exceptions and interrupts can be configured to target either the Secure state or the Non-secure state.
- Banked means the system exceptions can have Secure and Non-secure versions. Both can be triggered and executed independently and have different priority level settings.

###### Exception Priorities

It may cause a security issue if the Non-secure software uses high priority levels to mask the Secure interrupts. To avoid this issue, TrustZone introduces a programmable bit in the `AIRCR` register called `PRIS` (Prioritize Secure exception) for Secure software to prioritize, if needed, Secure exceptions and interrupts.

The `AIRCR.PRIS` is set to 0 out of reset, which means Secure and Non-secure exceptions/interrupts share the same configurable programmable priority level space (columns 2 and 3 in the following table). When the `AIRCR.PRIS` is set to 1, all Non-secure configurable exceptions/interrupts are placed in the lower half of the priority level space so that Secure exceptions/interrupts can potentially have higher priorities (columns 2 and 4 in the following table).

<table>
    <thead>
        <tr>
            <th>Priority Value</th>
            <th>Secure Priority</th>
            <th>Non-secure Priority (PRIS = 0)</th>
            <th>Non-secure Priority (PRIS = 1)</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>0</p>
            </td>
            <td>
                <p>0</p>
            </td>
            <td>
                <p>0 (0x00)</p>
            </td>
            <td>
                <p>128 (0x80)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>1</p>
            </td>
            <td>
                <p>32</p>
            </td>
            <td>
                <p>32 (0x20)</p>
            </td>
            <td>
                <p>144 (0x90)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2</p>
            </td>
            <td>
                <p>64</p>
            </td>
            <td>
                <p>64 (0x40)</p>
            </td>
            <td>
                <p>160 (0xA0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>3</p>
            </td>
            <td>
                <p>96</p>
            </td>
            <td>
                <p>96 (0x60)</p>
            </td>
            <td>
                <p>176 (0xB0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>4</p>
            </td>
            <td>
                <p>128</p>
            </td>
            <td>
                <p>128 (0x80)</p>
            </td>
            <td>
                <p>192 (0xC0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>5</p>
            </td>
            <td>
                <p>160</p>
            </td>
            <td>
                <p>160 (0xA0)</p>
            </td>
            <td>
                <p>208 (0xD0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>6</p>
            </td>
            <td>
                <p>192</p>
            </td>
            <td>
                <p>192 (0xC0)</p>
            </td>
            <td>
                <p>224 (0xE0)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>7</p>
            </td>
            <td>
                <p>224</p>
            </td>
            <td>
                <p>224 (0xE0)</p>
            </td>
            <td>
                <p>240 (0xF0)</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: This table uses three bits (Bit [7:5]) of the group priority level (`AIRCR.PRIGROUP`) to limit the maximum number of preemption levels to 8. A lower priority value indicates a higher priority.

###### Vector Tables

The following figure shows two vector tables for Secure and Non-secure exceptions and interrupts. The vector table offset is defined by a Vector Table Offset Register (`VTOR` at `0xE000ED08`), which can only be programmed in the privileged state.

![vector-table](/series2-trustzone/0.2/images/sld717-vector-table.png)

Image: _[Vector Table](https://developer.arm.com/documentation/100235/0100/The-Cortex-M33-Processor/Exception-model/Vector-table).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

**Notes**:

- The `VTOR_S` defines the address of the Secure vector table in Secure memory, and the [Secure Main Stack Pointer](#general-purpose-registers) (`MSP_S`) is the default stack for the Secure exception handler.
- The `VTOR_NS` defines the address of the Non-secure vector table in Non-secure memory, and the [Non-secure Main Stack Pointer](#general-purpose-registers) (`MSP_NS`) is the default stack for the Non-secure exception handler.
- Secure privileged software can access the `VTOR_NS` using the [Non-secure SCB alias](#system-private-peripheral-bus-ppb) (`0xE002ED08`).
- The [System Control Space](#system-private-peripheral-bus-ppb) contains registers for the SysTick timer, NVIC, and SCB.
- The interrupt masking registers (PRIMASK, FAULTMASK, and BASEPRI) are [banked](#special-purpose-registers) between security states. The priority level space is shared between the Secure and the Non-secure world, setting an interrupt mask register on one side can block some, or all, of the exceptions on the other side.
- Interrupts (`IRQ0` - `IRQ479`) are defined as Secure by default. Each interrupt can be configured as Secure or Non-secure and is determined by the Interrupt Target Non-secure (`NVIC_ITNS`) register, which is only programmable in the Secure software.

###### State Transitions in Exceptions and Interrupts

The following figure shows transitions between the [processor states](#introduction) in ARMv8-M TrustZone.![State Transitions](/series2-trustzone/0.2/images/sld717-state-transitions.png)

Image (left): _[Switching-between-Secure-and-Non-secure-states](https://developer.arm.com/documentation/100690/0201/Switching-between-Secure-and-Non-secure-states).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

1. Secure Thread → Secure Handler or Non-secure Thread to Non-secure Handler  
   - No security state transition.  
   - The exception sequence is almost identical to the exception stacking mechanism of current Cortex-M processors.  
   - The Interrupt Service Routine (ISR) is executed in the current security state (either Secure or Non-secure).
2. Non-secure Thread → Secure Handler or Non-secure Handler → Secure Handler  
   - The transition from Non-secure to Secure state.  
   - The exception sequence is almost identical to the exception stacking mechanism of current Cortex-M processors.  
   - The ISR is executed in a Secure state.
3. Secure Thread → Non-secure Handler or Secure Handler → Non-secure Handler  
   - The transition from Secure to Non-secure state.  
   - To avoid an information leak when transitioning from the Secure to Non-secure state. The processor automatically pushes all general-purpose registers into the Secure stack and erases the contents of all general-purpose registers before executing the Non-secure ISR. The processor pops the contents of all general-purpose registers from the Secure stack when returning from the Non-secure ISR (right side in [Figure 2.6 State Transitions on page 12](#state-transitions-in-exceptions-and-interrupts)). It incurs a slightly longer interrupt latency.  
   - The ISR is executed in a Non-secure state.
4. Secure Privileged Thread ↔ Non-secure Privileged Thread or Secure Unprivileged Thread ↔ Non-secure Unprivileged Thread  
   - The transition from Secure to Non-secure state or Non-secure to Secure state.  
   - The [Function calls and returns](#switching-between-secure-and-non-secure-states) can be used when the privileged level remains the same.

> **Note**: Subject to interrupt priority, there are no restrictions regarding whether a Non-secure or Secure interrupt can occur when the processor runs Non-secure or Secure code.

##### Switching Between Secure and Non-secure States

The TrustZone allows direct calling between Secure and Non-secure software. The following figure shows how to use an API function call to trigger security state transitions. The state transitions can also happen because of [exceptions and interrupts](#state-transitions-in-exceptions-and-interrupts).

![swich state](/series2-trustzone/0.2/images/sld717-switch-state.png)

Image: _[Switching-between-Secure-and-Non-secure-states](https://developer.arm.com/documentation/100690/0201/Switching-between-Secure-and-Non-secure-states).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

###### Switching from Non-secure to Secure State

When the Non-secure program calls a Secure software, the first instruction must be a Secure Gateway (`SG`) instruction residing in Non-secure Callable memory. The Secure Gateway entry points (veneers) decouple the address of the `SG` instructions in the Non-secure Callable memory region from the rest of the Secure code. It can eliminate the risk of having inadvertent entry points when the Secure software contains a pattern that matches the opcode of the `SG` instruction.

![switch-image](/series2-trustzone/0.2/images/sld717-switch-s.png)

Image (right): _Whitepaper - ARMv8-M Architecture Technical Overview. Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

The bit 0 of the [Link Register (LR)](#special-purpose-registers) is cleared to zero by `SG` instruction to indicate that returning from this function transits from Secure to Non-secure. The processor is still in the Non-secure state when the `SG` instruction is executed. The `BXNS LR` instruction is used when returning since a normal `BX LR` instruction interprets it as an unsupported execution mode change. A [SecureFault](#vector-tables) exception is triggered if the processor returns to a Secure address. It prevents a hacker from calling a Secure API with a fake return address pointing to a Secure program location. If bit 0 of LR is 1, the `BXNS LR` instruction behaves like a normal `BX LR`. Therefore, Secure code can call a Secure API in the NSC region even it is not a usual practice.

<table>
    <thead>
        <tr>
            <th>Program</th>
            <th>Call Instruction</th>
            <th>SG Instruction</th>
            <th>Return Instruction</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Non-secure call Non-secure</p>
            </td>
            <td>
                <p>BL or BLX</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>BX LR (Return to Non-secure state)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Non-secure call Secure</p>
            </td>
            <td>
                <p>BL or BLX</p>
            </td>
            <td>
                <p>Clear bit 0 of LR</p>
            </td>
            <td>
                <p>BXNS LR (Return to Non-secure state)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure call Secure</p>
            </td>
            <td>
                <p>BL or BLX</p>
            </td>
            <td>
                <p>Set bit 0 of LR</p>
            </td>
            <td>
                <p>BXNS LR (Return to Secure state)</p>
            </td>
        </tr>
    </tbody>
</table>

To help software developers create Secure APIs in C/C++, the [Cortex-M Security Extension (CMSE)](https://developer.arm.com/documentation/ecm0359818/latest) defines a C function attribute called `cmse_nonsecure_entry`.

- GCC — `__attribute__((cmse_nonsecure_entry))`
- IAR — `__cmse_nonsecure_entry`

###### Test Target (TT) Instruction

The software can use an ARMv8-M instruction called Test Target (TT) and the region number generated by the SAU or the IDAU to determine if a contiguous range of memory shares common security attributes and privilege levels.

The TT instruction returns the [SAU/IDAU](#secure-attribution-unit-sau-implementation-defined-attribution-unit-idau-and-memory-protection-unit-mpu) region number, security attributes (S/NS), and MPU region number after passing the start and end addresses of the memory range to the TT instruction. The software can determine whether the memory range has required security attributes and resides in the same region number.

![tt-instruction](/series2-trustzone/0.2/images/sld717-tt-instruction.png)

Image: _[Test-target-instruction](https://developer.arm.com/documentation/100690/0201/Test-target-instruction).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

This mechanism allows security checking at the beginning of the API service (instead of during the operation) to determine if the memory referenced by a pointer from Non-secure software points to the Non-secure address. It prevents Non-secure software from using those APIs in Secure software to access or modify Secure data.

To make these operations easier in a C/C++ programming environment, the [Cortex-M Security Extension (CMSE)](https://developer.arm.com/documentation/ecm0359818/latest) has defined a range of [intrinsic functions](https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_pge1446715440722.htm) for dealing with pointer checks with the TT instructions.

###### Switching from Secure to Non-secure State

When the Secure program calls a Non-secure software, the Secure program must use a `BLXNS <reg>` instruction to invoke the process. If bit 0 of the `<reg>` is 0, the processor must switch to the Non-secure state when branching to the target address. 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)](#special-purpose-registers) is set to a special value called `FNC_RETURN` (`0xFEFFFFFF`).

The Non-secure function completes by performing a branch (`BX LR`) to the `FNC_RETURN` address (bit 0 is 1 to indicate the function was called from the Secure state). It automatically triggers the unstacking of the actual return address from the Secure stack and returns to the calling function. The `FNC_RETURN` hides the return address of the Secure program from the Non-secure software to avoid the leakage of any secret information. It also prevents Non-secure software from modifying the Secure return address stored in the Secure stack.

![switch_ns](/series2-trustzone/0.2/images/sld717-switch-ns.png)

Image: _[Switching-between-Secure-and-Non-secure-states](https://developer.arm.com/documentation/100690/0201/Switching-between-Secure-and-Non-secure-states).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

To help software developers declare Non-secure function pointers in C/C++, the [Cortex-M Security Extension (CMSE)](https://developer.arm.com/documentation/ecm0359818/latest) defines a C function attribute called `cmse_nonsecure_call`.

- GCC: `__attribute__((cmse_nonsecure_call))`
- IAR: `__cmse_nonsecure_call`

##### Software Flow

The following figure describes a software flow example in a TrustZone implemented system.

![Execution Flow of a TrustZone Implemented System](/series2-trustzone/0.2/images/sld717-execution-flow-of-a-trustzone-implemented-system.png)

Image: _[Software Development in ARMv8-M Architecture](https://community.arm.com/cfs-file/__key/telligent-evolution-components-attachments/01-2142-00-00-00-01-27-19/ARM-Cortex-_2D00_-session-11-_2D00_-Yiu-_2D00_-Software-Development-in-ARMv8_2D00_M-Architecture.pdf).Copyright © 1995-2022 Arm Limited (or its affiliates). All rights reserved._

1. The system starts executing code in the Secure state after a power-on or reset (Secure boot).  
   - The Secure [stack pointer](#general-purpose-registers) (`MSP_S`) is set from the address of the Secure vector table (`VTOR_S`).  
   - The Secure Reset Handler pointed by the `VTOR_S` is called.  
   - Perform various initialization tasks such as C startup code.  
   - Place peripherals and associated interrupts in either Secure or Non-secure applications.  
   - Program [SAU/IDAU](04-r-programming) to partition the entire memory into Secure, Non-secure Callable, and Non-secure regions.  
   - Program the address of the Non-secure vector table (`VTOR_NS`).  
   - Initialize the two first entries of the table for the Non-secure stack pointer (`MSP_NS`) and Reset Handler to emulate a Non-secure reset.
2. The Secure firmware branches to the entry point (Reset Handler pointed by the `VTOR_NS`) of the Non-secure application.  
   - The Non-secure software has its Reset Handler.  
   - Perform various initialization tasks such as C startup code and hardware initialization (e.g., Non-secure peripherals).  
   - It does not conflict with initialization from the Secure code as the stack and heap spaces of Secure and Non-secure code are separated.
3. During the execution of Non-secure applications, the application could call Secure APIs through the [Secure Gateway (SG) veneer](#switching-from-non-secure-to-secure-state) in the Non-secure Callable region.
4. In some cases, Secure APIs might need to call [Non-secure call-back functions](#switching-from-non-secure-to-secure-state) (e.g., a hardware driver).

#### Bus Level Security (BLS)

##### System Design

The following figure shows two system designs:

- The sample system contains an ARMv8-M processor and the required components to support TrustZone.
- Bus Level Security (BLS) on Series 2 devices implements the concepts introduced in the ARM TrustZone sample system. BLS enforces Secure and privileged programming models and uses security components (colored blocks) to configure the security attribute and privileged level of peripherals and Bus Masters.

![ARMv8-M TrustZone Implementation](/series2-trustzone/0.2/images/sld717-armv8-m-trustzone-implementation.png)

###### ARMv8-M Processor

The ARMv8M processor is TrustZone capable of Secure and Non-secure states. It has a dedicated internal [SAU](#security-attribution-unit) that is fully programmable up to 8 different memory regions. Out of reset, the processor is in a Secure state and every transaction is a Secure transaction.

ARMv8-M Processor in Series 2 devices is the Cortex-M33.

###### System Security Controller

The system security controller is the central location for all security settings in the system. Each type of controller, IDAU, and wrapper receives its security configuration and bus response configuration from this block.

System Security Controller in Series 2 devices is the [Security Management Unit (SMU)](#security-management-unit-smu).

###### Implementation Defined Attribution Unit (IDAU)

The [IDAU](02-r-basic) generates the security attribute for a given address. All IDAUs in the system have the same memory partitioning. The IDAU is intended only for ARMv8-M cores and utilizes the entire IDAU interface for the core. The lite IDAU uses only the Secure and Non-secure interface from the IDAU and is intended for Non-ARMv8-M Bus Masters.

IDAU in Series 2 devices is the [External Secure Attribution Unit (ESAU)](#external-secure-attribution-unit-esau).

###### Security Wrapper

The Security Wrapper gives a legacy Bus Master the ability to drive security attribution. The security wrapper outputs the transaction address to the lite IDAU which returns the security attribute of the address. If the wrapper is configured as Non-secure, any transactions to a Secure address are blocked.

Security Wrapper in Series 2 devices is the [Bus Master Protect Unit (BMPU)](#bus-master-protection-unit-bmpu).

###### Memory Protection Controller (MPC)

MPC has a security configuration for a per block of memory or memory above and below the watermark. If the security attribute of the block or memory region does not match the security attribute of the address, the transaction is blocked. This controller is used in a system that alias RAM or flash memory locations. This controller is not needed when the memory region size is programmable in an IDAU.

Series 2 devices have a programmable flash and RAM region in the [ESAU](#external-secure-attribution-unit-esau) (equivalent to IDAU) and are not implementing this block.

###### Peripheral Protection Controller (PPC)

PPC has a security configuration for every peripheral. If the security attribute of the selected peripheral does not match the security attribute of the address, the transaction is blocked. This controller is used in systems that alias the peripheral memory locations.

PPC in Series 2 devices is the [Peripheral Protection Unit (PPU)](#peripheral-protection-unit-ppu).

Hardware security is now extended to the peripheral bus system of the processor. Each component on the bus can verify and propagate the security level for each bus operation.  The following sections describe the individual security component for BLS on Series 2 devices.

##### Security Management Unit (SMU)

The SMU is the only user-facing block in the BLS architecture and houses all the configuration and status for the [ESAUs, BMPUs, and PPUs](#bus-level-security-bls).

- Thirteen memory regions ([ESAU](#external-secure-attribution-unit-esau))
- Per Bus Master privileged and security attribute ([BMPU](#bus-master-protection-unit-bmpu))
- Interrupt flag for Bus Master security fault (fault table in BMPU section)
- Per peripheral privileged and security attribute ([PPU](#peripheral-protection-unit-ppu))
- Interrupt flags for privileged, security, and instruction peripheral access faults (fault tables in PPU section)
- Separate Secure and Privileged IRQ

The SMU configurations can be [locked](04-r-programming) down and protected from runaway code. The `SMU_LOCK` register resets to UNLOCK. Any write other than the unlock code (`0xACCE55`) locks all SMU registers from further updates. The `SMU_STATUS` register contains a `SMULOCK` bitfield with the current lock state of the SMU.

The `SMU_M33CTRL` register can [lock](04-r-programming) down internal security and privileged configurations below.

- Cortex-M33 SAU
- Non-secure MPU
- Secure MPU
- Non-secure Vector Table Offset Register (VTOR)
- Secure AIRCR register

Interrupt flags in the `SMU_IF` register can generate a [Secure or Privileged interrupt](04-r-programming) in the table below when its corresponding interrupt enable bit in the `SMU_IEN` register is set and `IRQn` is enabled.

<table>
    <thead>
        <tr>
            <th>Enable Bit in SMU_IEN Register</th>
            <th>IRQn</th>
            <th>Interrupt Handler</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>BMPUSEC, PPUSEC</p>
            </td>
            <td>
                <p>SMU_SECURE_IRQn</p>
            </td>
            <td>
                <p>SMU_SECURE_IRQHandler()</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PPUPRIV, PPUINST</p>
            </td>
            <td>
                <p>SMU_PRIVILEGED_IRQn</p>
            </td>
            <td>
                <p>SMU_PRIVILEGED_IRQHandler()</p>
            </td>
        </tr>
    </tbody>
</table>

Each interrupt flag in the `SMU_IF` register can be cleared by writing 1 to the corresponding bit of the `SMU_IF_CLR` register.

##### External Secure Attribution Unit (ESAU)

The ESAU is responsible for determining the memory region and [security attribute](02-r-basic) of a given address. Referring to [ARMv8-M TrustZone Implementation on page 16](03-r-bls#system-design), the Cortex-M33 interfaces with an ESAU  and the BMPUs of other Bus Masters interface with lite ESAUs to determine the security attribute of all transactions. The following figure describes the security attributes of different memory regions defined by the ESAU on Series 2 devices.

![System Memory Map of Series 2 Device with TrustZone](/series2-trustzone/0.2/images/sld717-system-memory-map-of-series-2-device-with-trustzone.png)

**Notes**:

- For Series 2 devices with base address `0x08000000` in region 0, the memory address from `0x0` to `0x07FFFFFF` is an invalid region.
- The invalid regions are deemed as Secure.
- The NSC and Exempted attributes are only available to the ESAU, and all lite ESAUs in the system view these attributes as [Secure](05-r-implementation).

The ESAU divides the memory map into 13 memory regions and has a maximum of 6 Non-secure regions.

- Four Movable Region Boundaries (MRBs) determine the size of 6 regions.
- Two regions have configurable security attributes.
- Each memory region consists of a base address that specifies the start of the region and a limit address that specifies the end of the region plus one (**+ 1**).
- The address is valid if it falls between the base (≥ base) and limit (< limit) of a region.
- If the memory region is not defined, it is deemed invalid and Secure.

The MRBs distinguish the Secure, Non-secure Callable, and Non-secure regions in flash and RAM. The two configurable regions determine if the Info flash and Cortex-M33 [EPPB](02-r-basic) regions are Secure or Non-secure. The MRBs have a specific programming sequence. Any [misprogramming](04-r-programming) results in a `SMUPRGERR` in the `SMU_STATUS` register.

###### ARMv8-M CODE Regions

- [Regions 0, 1, and 2](04-r-programming) are in the Main space of flash. Region 3 is the info space of flash.
- The mrb01 (`ESAUMRB01` in `SMU_ESAURMBR01` register) determines the end of region 0 and the start of region 1.
- The mrb12 (`ESAUMRB12` in `SMU_ESAURMBR12` register) determines the end of region 1 and the start of region 2.
- The size of region 3 is device-dependent.
- Three regions' security attributes are static, and one region is configurable. Region 0 is always Secure, region 1 is always Non-secure Callable, and region 2 is always Non-secure. [Region 3](04-r-programming) is configurable as either Secure or Non-secure (`ESAUR3NS` in `SMU_ESAURTYPES0` register, default is secure after reset).
- Sizes of regions 0, 1, and 2 are adjusted in **4 kB increments** with the lower 12 bits of `ESAUMRB##` in `SMU_ESAURMBR##` ignored.  
  - The Secure region can be set to size 0 when mbr01 = base address of region 0.  
  - The Non-secure Callable regions can be set to size 0 when mbr01 = mbr12.
- The default value of mbr01 is equal to base address + `0x02000000`, so the size of region 0 is 32 MB. Out of reset, all flash is Secure since all Series 2 devices have less than 32 MB of flash.

<table>
    <thead>
        <tr>
            <th>Region</th>
            <th>Memory</th>
            <th>Base Address</th>
            <th>Limit Address</th>
            <th>Security Attribute</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>0</p>
            </td>
            <td>
                <p>Main flash</p>
            </td>
            <td>
                <p>0x00000000 or 0x08000000</p>
            </td>
            <td>
                <p>(0x00000000 or 0x08000000) | mbr01</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>1</p>
            </td>
            <td>
                <p>Main flash</p>
            </td>
            <td>
                <p>(0x00000000 or 0x08000000) | mbr01</p>
            </td>
            <td>
                <p>(0x00000000 or 0x08000000) | mbr12</p>
            </td>
            <td>
                <p>Non-secure Callable</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2</p>
            </td>
            <td>
                <p>Main flash</p>
            </td>
            <td>
                <p>(0x00000000 or 0x08000000) | mbr12</p>
            </td>
            <td>
                <p>0x0FE00000</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>3</p>
            </td>
            <td>
                <p>Info flash</p>
            </td>
            <td>
                <p>0x0FE0000</p>
            </td>
            <td>
                <p>0x10000000</p>
            </td>
            <td>
                <p>Secure or Non-secure</p>
            </td>
        </tr>
    </tbody>
</table>

###### ARMv8-M RAM Regions

- [Regions 4, 5, and 6](04-r-programming) cover the entire available RAM in the device.
- The mrb45 (`ESAUMRB45` in `SMU_ESAURMBR45` register) determines the end of region 4 and the start of region 5.
- The mrb56 (`ESAUMRB56` in `SMU_ESAURMBR56` register) determines the end of region 5 and the start of region 6.
- All three regions' security attributes are static. Region 4 is always Secure, region 5 is always Non-secure Callable, and region 6 is always Non-secure.
- Sizes of all three regions are adjusted in **4 kB increments** with the lower 12 bits of `ESAUMRB##` in `SMU_ESAURMBR##` ignored.  
  - The Secure region can be set to size 0 when mbr45 = base address of region 4.  
  - The Non-secure Callable region can be set to size 0 when mbr45 = mbr56.
- The default value of mbr45 is equal to `0x02000000`, so the size of region 4 is 32 MB. Out of reset, all RAM is Secure since all Series 2 devices have less than 32 MB of RAM.

<table>
    <thead>
        <tr>
            <th>Region</th>
            <th>Memory</th>
            <th>Base Address</th>
            <th>Limit Address</th>
            <th>Security Attribute</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>4</p>
            </td>
            <td>
                <p>SRAM</p>
            </td>
            <td>
                <p>0x20000000</p>
            </td>
            <td>
                <p>0x20000000 | mbr45</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>5</p>
            </td>
            <td>
                <p>SRAM</p>
            </td>
            <td>
                <p>0x20000000 | mbr45</p>
            </td>
            <td>
                <p>0x20000000 | mbr56</p>
            </td>
            <td>
                <p>Non-secure Callable</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>6</p>
            </td>
            <td>
                <p>SRAM</p>
            </td>
            <td>
                <p>0x20000000 | mbr56</p>
            </td>
            <td>
                <p>0x30000000</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
        </tr>
    </tbody>
</table>

###### ARMv8-M Peripheral Regions

- These regions are aliases to the [chip peripherals and SE mailbox](04-r-programming) (a device with HSE).
- Both regions have a fixed size.
- Both regions' security attributes are static. Region 7 is always Secure, and region 8 is always Non-secure.

<table>
    <thead>
        <tr>
            <th>Region</th>
            <th>Memory</th>
            <th>Base Address</th>
            <th>Limit Address</th>
            <th>Security Attribute</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>7</p>
            </td>
            <td>
                <p>Chip Peripherals</p>
            </td>
            <td>
                <p>0x40000000</p>
            </td>
            <td>
                <p>0x50000000</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>8</p>
            </td>
            <td>
                <p>Chip Peripherals</p>
            </td>
            <td>
                <p>0x50000000</p>
            </td>
            <td>
                <p>0x60000000</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
        </tr>
    </tbody>
</table>

###### ARMv8-M Device Regions

- These regions are aliases to all radio peripherals and radio RAM.
- Both regions have a fixed size.
- Both regions' security attributes are static. Region 9 is always Secure, and region 10 is always Non-secure.
- From the perspective of the device bus system, the [radio is one peripheral that is either Secure or Non-secure](04-r-programming). So any Bus Master accessing the radio needs to know the security attribute of the radio. From the perspective of the radio, all of its radio bus peripherals are accessible regardless of the security attribute. However, the radio needs to know the security attribute of chip bus peripherals to access them through the correct alias.

<table>
    <thead>
        <tr>
            <th>Region</th>
            <th>Memory</th>
            <th>Base Address</th>
            <th>Limit Address</th>
            <th>Security Attribute</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>9</p>
            </td>
            <td>
                <p>Radio Peripherals</p>
            </td>
            <td>
                <p>0xA0000000</p>
            </td>
            <td>
                <p>0xB0000000</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>10</p>
            </td>
            <td>
                <p>Radio Peripherals</p>
            </td>
            <td>
                <p>0xB0000000</p>
            </td>
            <td>
                <p>0xC0000000</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
        </tr>
    </tbody>
</table>

###### ARMv8-M System Private Peripheral Bus (PPB) Regions

- Both regions have a fixed size.
- [Region 11](04-r-programming) is the Cortex-M33 EPPB memory region and is configurable as either Secure or Non-secure (`ESAUR11NS` in `SMU_ESAURTYPES1` register, default is secure after reset). It is important to note that the Cortex-M33 core is the only Bus Master that sees these memory regions. All other Bus Masters in the system do not have access to the System PPB, and it is an invalid region.
- Region 12 has a static security attribute of Exempted. It means that the Cortex-M33 core allows the transaction in all cases. It permits debuggers to read the system ROM Table regardless of the state of the Cortex-M33 core.

<table>
    <thead>
        <tr>
            <th>Region</th>
            <th>Memory</th>
            <th>Base Address</th>
            <th>Limit Address</th>
            <th>Security Attribute</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>11</p>
            </td>
            <td>
                <p>EPPB</p>
            </td>
            <td>
                <p>0xE0044000</p>
            </td>
            <td>
                <p>0xE00FE000</p>
            </td>
            <td>
                <p>Secure or Non-secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>12</p>
            </td>
            <td>
                <p>System ROM Table</p>
            </td>
            <td>
                <p>0xE00FE000</p>
            </td>
            <td>
                <p>0xE00FF000</p>
            </td>
            <td>
                <p>Exempted</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- The regions in flash (0/1/2) and RAM (4/5/6) can only create in the order of Secure, Non-secure Callable, and Non-secure.
- The [ESAU and lite ESAUs](#bus-level-security-bls) handle the transactions of Bus Masters and must have consistent security attribute mapping. Therefore, configurations in the SMU registers apply to ESAU and lite ESAUs.
- Unlike other Bus Masters using BMPU and lite ESAU, merging the address lookup results from the [internal SAU and ESAU](02-r-basic) determines the [security attribute](#security-attribution-unit) of the Cortex-M33 transaction.

<table>
    <thead>
        <tr>
            <th>Bus Master</th>
            <th>Security Attribution</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Cortex-M33</p>
            </td>
            <td>
                <p>SAU and ESAU</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Other</p>
            </td>
            <td>
                <p>Lite ESAU</p>
            </td>
        </tr>
    </tbody>
</table>

##### Security Attribution Unit

In Series 2 devices, the combination of the integrated SAU in the Cortex-M33 processor and an ESAU determine the security attribute of a Cortex-M33 transaction.

The SAU consists of several [programmable registers](https://developer.arm.com/documentation/100690/0201/SAU-register-summary). These registers are placed in the [System Control Space (SCS)](02-r-basic) and are only accessible from the Secure privileged state.

- SAU Control Register (`SAU_CTRL`) — The SAU is disabled after RESET
- SAU Type Register (`SAU_TYPE`) — Indicates the number of [available regions](01-series-2-security-features) (read-only)
- SAU Region Number Register (`SMU_RNR`) — Assigns a region number
- SAU Region Base Address Register (`SAU->RBAR`) — Configures selected region base address
- SAU Region Limit Address Register (`SAU->RLAR`) — Configures selected region limit address and security attribute (NSC or NS), enable or disable the region

The following figure shows three different SAU configurations for determining the security attribute of a Cortex-M33 transaction.

![Configuration of SAU_CTRL Register](/series2-trustzone/0.2/images/sld717-configuration-of-sau-ctrl-register.png)

**Notes**:

- All address ranges after RESET in SAU are Secure by default.
- The SAU can configure a **32 bytes aligned** region as Non-secure or Non-secure Callable. Any address not defined in the SAU defaults to Secure.
- An [ESAU](#external-secure-attribution-unit-esau) can configure or hard-code a region as Secure, Non-secure Callable, Non-secure, or Exempted. An [Exempted](02-r-basic) region enables Non-secure debuggers to access debugging components and establish a debug connection to the processor before the SAU is configured.
- The processor determines the final attribute of the address based on the higher security attribute (Exempted > S > NSC > NS) from either the SAU or the ESAU.  
  ![state_hierarchy](/series2-trustzone/0.2/images/sld717-state-hierarchy.png)

###### All Secure Configuration

Highlights:

- SAU is disabled.
- `ALLNS` bit in the SAU Control register is clear.
- The whole memory is in a Secure state (highest security attribute apart from Exempted).
- All Cortex-M33 transactions in this configuration are Secure or Exempted and give the Cortex-M33 access to all memory locations through either the Secure or Non-secure alias after RESET.  
  ![all_s](/series2-trustzone/0.2/images/sld717-all-s.png)
- It is up to the boot procedure in a Secure state to keep the current configuration or use other configurations once the boot process is complete.

###### All Non-secure Configuration

Highlights:

- SAU is disabled.
- `ALLNS` bit in the SAU Control register is set.
- The whole memory is in a Non-secure state (lowest security attribute).
- Therefore the [ESAU configuration](#external-secure-attribution-unit-esau) determines the security attribute of all Cortex-M33 transactions.  
  ![all_ns](/series2-trustzone/0.2/images/sld717-all-ns.png)
- Except for the `SAU_CTRL` [register](04-r-programming), this configuration does not require programming on other SAU registers.

###### Configurable Configuration

Highlights:

- SAU is enabled.
- `ALLNS` bit in the SAU Control register can be 0 or 1 (do not care).
- The `NSC` bit on the `SAU_RLAR` register determines the security attribute of an address as Non-secure or Non-secure Callable if an address matches an SAU region.
- The security attribute of an address is Secure by default if the address does not match any SAU region.
- This configuration [programs](04-r-programming)`SAU_RNR`, `SAU_RBAR`, and `SAU_RLAR` registers to correlate the [Non-secure regions](03-r-bls#configurable-configuration) in ESAU.
- The SAU or ESAU [overrides](02-r-basic) the attribute to a [higher security level](#security-attribution-unit) if any security attribute mismatch occurs in a memory region.  
  ![address_lookup](/series2-trustzone/0.2/images/sld717-address-lookup.png)
- The following figure is an example of a configurable configuration with the size of ESAU regions 0 and 5 are set to zero.  
  ![all_config](/series2-trustzone/0.2/images/sld717-all-config.png)

> **Note**: The Cortex-M33 has an internal SAU that defaults all undefined addresses to Secure if enabled. If the Secure regions do not align between the [Cortex-M33 (SAU + ESAU) and other Bus Masters (lite ESAU)](#bus-level-security-bls), the Cortex-M33 treats a memory region as Secure while other Bus Masters treat it as Non-secure. It can lead to the leaking of secure data if the Cortex-M33 stores secure data in what other Bus Masters think is a Non-secure area ([Main Flash Layout on page 34](05-r-implementation)).

##### Bus Master Protection Unit (BMPU)

The BMPU is a security wrapper used for assigning a Bus Master specific security and privileged states. Referring to [Figure 3.1 ARMv8-M TrustZone Implementation on page 16](#system-design), the BMPU generally lies between the Bus Master and the Advanced High-performance Bus (AHB) Matrix. BMPU interfaces with a [lite ESAU](#bus-level-security-bls) to determine the security attribute of all Bus Master transactions.

The registers below in SMU configure the [security](04-r-programming) and [privileged](04-r-programming) state of a Bus Master. The Bus Masters in group 0 are device-dependent. Out of reset, each Bus Master is Secure and privileged.

<table>
    <thead>
        <tr>
            <th>Register</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMU_BMPUPATD0</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for privileged attribute configuration on Bus Master group 0</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_BMPUSATD0</p>
            </td>
            <td>
                <p>Bitfields (Secure if set) for security attribute configuration on Bus Master group 0</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The Bus Master privileged attribute only applies to peripheral accesses. Flash and RAM accesses ignore the privileged attribute of the Bus Master.

The BMPU generates a security fault when the security attribute of the bus transaction is Secure, and the security attribute (`SMU_BMPUSATD0`) for the BMPU is configured as Non-secure.

Below is the security fault table that shows how the security attribute on the bus is driven based on the lite ESAU attribute and the BMPU security configuration. The interrupt is triggered if `BMPUSEC` in `SMU_IEN` is set and the `SMU_SECURE_IRQn` is enabled.

<table>
    <thead>
        <tr>
            <th>Lite ESAU Attribute</th>
            <th>Secure Bus Master</th>
            <th>Non-secure Bus Master</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Non-secure</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
            <td>
                <p>Non-secure</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure</p>
            </td>
            <td>
                <p>Secure</p>
            </td>
            <td>
                <p>FAULT</p>
            </td>
        </tr>
    </tbody>
</table>

Upon a BMPU fault, the registers in SMU below notify that a BMPU security fault occurred and on which Bus Master. The registers also identify the offending fault address. If a fault is detected, the response is Read As Zero (RAZ) or Write Ignored (WI) and the corresponding interrupt flag is set in the `SMU_IF` register. The values in `SMU_BMPUFS` and `SMU_BMPUFSADDR` do not change until the BMPU fault (`BMPUSEC`) in the `SMU_IF` register is cleared by software.

<table>
    <thead>
        <tr>
            <th>Register</th>
            <th>Bitfield</th>
            <th>Fault</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMU_IF</p>
            </td>
            <td>
                <p>BMPUSEC</p>
            </td>
            <td>
                <p>Security Fault if set</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_BMPUFS</p>
            </td>
            <td>
                <p>BMPUFSMASTERID</p>
            </td>
            <td>
                <p>ID of the Bus Master that triggered the fault</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_BMPUFSADDR</p>
            </td>
            <td>
                <p>BMPUFSADDR</p>
            </td>
            <td>
                <p>Access address that triggered the fault</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: No privileged fault is generated because all the other Bus Masters in the system do not drive the privileged attribute.

##### Peripheral Protection Unit (PPU)

The PPU is a security wrapper used for assigning a Bus Slave peripheral specific security and privileged states. Referring to [Figure
3.1 ARMv8-M TrustZone Implementation on page 16](#system-design), the PPU comes in the form of a PPU in Advanced High-performance Bus (AHB) and a PPU in Advanced Peripheral Bus (APB).

- The PPU AHB generally lies between the Bus Matrix and an AHB Bus Slave peripheral.
- The PPU APB lies between the output of an AHB to APB bridge and all of the APB Slaves on that APB bus.

The registers below in SMU configure the [security](04-r-programming) and [privileged](04-r-programming) state of a peripheral. The peripherals in groups 0 and 1 are device-dependent. Out of reset, each peripheral is Secure and privileged. While each peripheral in address `0x40000000` (region 7) or `0x50000000` (region 8) can be configured independently, the radio subsystem in `0xA0000000` (region 9) or `0xB0000000` (region 10) is configured as a [unit](04-r-programming).

<table>
    <tbody>
        <tr>
            <th>Register</th>
            <th>Description</th>
        </tr>
        <tr>
            <td>SMU_PPUPATD0</td>
            <td>Bitfields (privileged if set) for privileged access configuration on peripheral group 0</td>
        </tr>
        <tr>
            <td>SMU_PPUPATD1</td>
            <td>Bitfields (privileged if set) for privileged access configuration on peripheral group 0</td>
        </tr>
        <tr>
            <td>SMU_PPUSATD0</td>
            <td>Bitfields (Secure if set) for security access configuration on peripheral group 0</td>
        </tr>
        <tr>
            <td>SMU_PPUSATD1</td>
            <td>Bitfields (Secure if set) for security access configuration on peripheral group 1</td>
        </tr>
    </tbody>
</table>

The PPU can generate three types of faults:

1. Privileged faults occur on unprivileged transactions to privileged peripherals. Below is the privileged fault table that shows when a privileged fault occurs based on the PPU peripheral privileged configuration and the bus transaction privileged attribute. The interrupt is triggered if `PPUPRIV` in `SMU_IEN` is set and the `SMU_PRIVILEGED_IRQn` is enabled.  
   <table>  
       <thead>  
           <tr>  
               <th>Bus Attribute</th>  
               <th>Privileged Peripheral</th>  
               <th>Unprivileged Peripheral</th>  
           </tr>  
       </thead>  
       <tbody>  
           <tr>  
               <td>  
                   <p>Privileged</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
           </tr>  
           <tr>  
               <td>  
                   <p>Unprivileged</p>  
               </td>  
               <td>  
                   <p>FAULT</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
           </tr>  
       </tbody>  
   </table>
2. Security faults occur on Secure transactions to Non-secure peripherals and Non-secure transactions to Secure peripherals. Below is the security fault table that shows when a security fault occurs based on the PPU Peripheral security configuration and the bus transaction security attribute. The interrupt is triggered if `PPUSEC` in `SMU_IEN` is set and the `SMU_SECURE_IRQn` is enabled.  
   <table>  
       <thead>  
           <tr>  
               <th>Bus Attribute</th>  
               <th>Secure Peripheral</th>  
               <th>Non-secure Peripheral</th>  
           </tr>  
       </thead>  
       <tbody>  
           <tr>  
               <td>  
                   <p>Secure</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
               <td>  
                   <p>FAULT</p>  
               </td>  
           </tr>  
           <tr>  
               <td>  
                   <p>Non-secure</p>  
               </td>  
               <td>  
                   <p>FAULT</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
           </tr>  
       </tbody>  
   </table>
3. Instruction faults occur on any transaction marked as an instruction fetch. Below is the instruction fault table that shows when a PPU instruction fault occurs based on the bus transaction instruction attribute. The interrupt is triggered if `PPUINST` in `SMU_IEN` is set and the `SMU_PRIVILEGED_IRQn` is enabled.  
   <table>  
       <thead>  
           <tr>  
               <th>Bus Attribute</th>  
               <th>Secure Peripheral</th>  
               <th>Non-secure Peripheral</th>  
           </tr>  
       </thead>  
       <tbody>  
           <tr>  
               <td>  
                   <p>Secure</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
               <td>  
                   <p>FAULT</p>  
               </td>  
           </tr>  
           <tr>  
               <td>  
                   <p>Non-secure</p>  
               </td>  
               <td>  
                   <p>FAULT</p>  
               </td>  
               <td>  
                   <p>SUCCESS</p>  
               </td>  
           </tr>  
       </tbody>  
   </table>

Upon a [PPU fault](04-r-programming), the registers below in [SMU](#security-management-unit-smu) notifies which PPU fault occurred and on which peripheral. If a fault is detected, the response is Read As Zero (RAZ) or Write Ignored (WI) and set the corresponding interrupt flag in the `SMU_IF` register. The values in `SMU_IF` and `SMU_PPUFS` do not change until all PPU faults in the `SMU_IF` register are cleared by software.

<table>
    <thead>
        <tr>
            <th>Register</th>
            <th>Bitfield</th>
            <th>Fault</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMU_IF</p>
            </td>
            <td>
                <p>PPUPRIV</p>
            </td>
            <td>
                <p>Privilege Fault if set</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_IF</p>
            </td>
            <td>
                <p>PPUSEC</p>
            </td>
            <td>
                <p>Security Fault if set</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_IF</p>
            </td>
            <td>
                <p>PPUINST</p>
            </td>
            <td>
                <p>Instruction Fault if set</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_PPUFS</p>
            </td>
            <td>
                <p>PPUFSPERIPHID</p>
            </td>
            <td>
                <p>ID of the peripheral that caused the fault</p>
            </td>
        </tr>
    </tbody>
</table>

##### Compatibility

Secure software usually controls the [SYSCFG and SMU](05-r-implementation) peripherals to prevent Non-secure software from changing critical configurations in the Secure domain. It requires switching between Secure and Non-secure states when Non-secure software wants to update the registers in these peripherals. Therefore dedicated registers for Non-secure access are added to SYSCFG and SMU peripherals on newer Series 2 devices.

###### System Configuration (SYSCFG)

Except for EFR32xG21 devices, the following tables apply to all Series 2 devices.

**Table**: Dedicated Bitfield to Configure Access for Non-secure SYSCFG Registers

<table>
    <thead>
        <tr>
            <th>Bitfield (Register)</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SYSCFGCFGNS (SMU_PPUPATD0)</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for privileged access configuration on NS SYSCFG registers</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SYSCFGCFGNS (SMU_PPUSATD0)</p>
            </td>
            <td>
                <p>Bitfields (Secure if set) for security access configuration on NS SYSCFG registers</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: Reset `SYSCFGCFGNS` bit in `SMU_PPUSATD0` to allow Non-secure software to access NS SYSCFG registers.

**Table**: Dedicated SYSCFG Registers for Non-secure State

<table>
    <thead>
        <tr>
            <th>SYSCFG Non-secure Registers</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SYSCFG_CFGNS_CFGNSTCALIB</p>
            </td>
            <td>
                <p>NS SysTick calibration value register</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SYSCFG_CFGNS_ROOTNSDATA0</p>
            </td>
            <td>
                <p>NS root data register 0</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SYSCFG_CFGNS_ROOTNSDATA0</p>
            </td>
            <td>
                <p>NS root data register 1</p>
            </td>
        </tr>
    </tbody>
</table>

###### Security Management Unit (SMU)

Except for EFR32xG21 devices, the following tables apply to all Series 2 devices.

**Table**: Dedicated Bitfield to Configure Access for Non-secure SMU Registers

<table>
    <thead>
        <tr>
            <th>Bitfield (Register)</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMUCFGNS (SMU_PPUPATD1)</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for privileged access configuration on NS SMU registers</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMUCFGNS (SMU_PPUSATD1)</p>
            </td>
            <td>
                <p>Bitfields (Secure if set) for security access configuration on NS registers</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: Reset `SMUCFGNS` bit in `SMU_PPUSATD1` to allow Non-secure software to access NS SMU registers.

The SMU_CFGNS register file is for the TrustZone Non-secure state and has its register lock (`NSLOCK`). It allows hardware to maintain the privileged assignments for the NS state. The privileged configuration within the NS state is the same as the Secure state, except it has an "NS" to differentiate the registers.

**Table**: Dedicated SMU Registers for Non-secure State

<table>
    <thead>
        <tr>
            <th>SMU Non-secure Registers</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMU_CFGNS_NSSTATUS</p>
            </td>
            <td>
                <p>Lock status of SMU_CFGNS registers</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_NSLCOK</p>
            </td>
            <td>
                <p>Lock and unlock the SMU_CFGNS registers</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_NSIF</p>
            </td>
            <td>
                <p>Interrupt flags for NS privilege (PPUNSPRIVIF) and instruction (PPUNSINSTIF) faults</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_NSIEN</p>
            </td>
            <td>
                <p>Interrupt enable flags for NS privilege (PPUNSPRIVIEN) and instruction (PPUNSINSTIEN) faults</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_PPUNSPATD0</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for NS privileged access configuration on peripheral group 0</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_PPUNSPATD1</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for NS privileged access configuration on peripheral group 1</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_PPUNSFS</p>
            </td>
            <td>
                <p>ID (PPUFSPERIPHID) of the NS peripheral that caused the fault</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SMU_CFGNS_BMPUNSPATD0</p>
            </td>
            <td>
                <p>Bitfields (privileged if set) for privileged attribute configuration on NS Bus Master group 0</p>
            </td>
        </tr>
    </tbody>
</table>

**Table**: Fault Statuses Only for Secure State

<table>
    <thead>
        <tr>
            <th>Bitfield (Register)</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>PPUPRIV (SMU_IF)</p>
            </td>
            <td>
                <p>Fault status now limited only to Secure state</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PPUINST (SMU_IF)</p>
            </td>
            <td>
                <p>Fault status now limited only to Secure state</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PPUPRIV (SMU_IEN)</p>
            </td>
            <td>
                <p>Fault status now limited only to Secure state</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PPUINST (SMU_IEN)</p>
            </td>
            <td>
                <p>Fault status now limited only to Secure state</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PPUFSPERIPHID (SMU_PPUFS)</p>
            </td>
            <td>
                <p>Fault status now limited only to Secure state</p>
            </td>
        </tr>
    </tbody>
</table>

**Table** Dedicated SMU Interrupt for Non-secure State

<table>
    <thead>
        <tr>
            <th>Interrupt</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SMU_NS_PRIVILEGED_IRQHandler()</p>
            </td>
            <td>
                <p>An interrupt flag in the SMU_CFGNS_NSIF register can generate an NS privileged interrupt when its corresponding interrupt enable bit in the SMU_CFGNS_NSIEN register is set and SMU_NS_PRIVILEGED_IRQn is enabled, and in which the peripheral (ID) that triggers the fault is in the SMU_CFGNS_PPUNSFS register.</p>
            </td>
        </tr>
    </tbody>
</table>

#### Secure and Privileged Programming Model

The implementation of BLS on Series 2 devices, both flash and RAM, use a programmable watermark to delineate Secure, Non-secure Callable, and Non-secure regions. On the other hand, peripherals exist in both a Secure and Non-secure alias of memory.

##### BLS SMU Programming

###### Enabling SMU Clock

Except for the EFR32xG21 devices, all Series 2 devices enable the SMU clock in CMU before programming the SMU registers.

```C

#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
  CMU->CLKEN1_SET = CMU_CLKEN1_SMU;
#endif

```

###### Cortex-M33 Lock Control

The Cortex-M33 security and privileged configurations can be locked by programming the `SMU_M33CTRL` register.

```C

  // Lock Secure MPU configuration
  SMU->M33CTRL |= SMU_M33CTRL_LOCKSMPU;

```

###### Locking SMU Configuration

Th entire SMU configuration can be locked down to avoid runaway code. Below is an example of how to lock and unlock the SMU.

```C

  uint32_t lock_status;
  // Lock Down SMU
  SMU->LOCK = ~SMU_LOCK_SMULOCKKEY_UNLOCK;
  // Grab Lock Status
  lock_status = (SMU->STATUS & _SMU_STATUS_SMULOCK_MASK) >> _SMU_STATUS_SMULOCK_SHIFT;
  // Unlock SMU
  SMU->LOCK = SMU_LOCK_SMULOCKKEY_UNLOCK;

```

###### Interrupt Control

Each interrupt flag in `SMU_IF` can generate an interrupt when its corresponding interrupt enable flag in the `SMU_IEN` register is set. Each interrupt flag can be cleared by writing the clear alias of the `SMU_IF` register.

```C

  // Clear and enable the SMU PPUSEC and BMPUSEC interrupt
  NVIC_ClearPendingIRQ(SMU_SECURE_IRQn);
  SMU->IF_CLR = SMU_IF_PPUSEC | SMU_IF_BMPUSEC;
  NVIC_EnableIRQ(SMU_SECURE_IRQn);
  SMU->IEN = SMU_IEN_PPUSEC | SMU_IEN_BMPUSEC;

```

##### BLS ESAU Programming

###### Region Types

The `SMU_ESAURTYESn` registers are used to configure memory regions with a specific security attribute. All configurable memory regions reset to Secure. Below is an example of programming regions 3 and 11 to Non-secure.

```C

  // Region 3 (Info flash) is Non-secure
  SMU->ESAURTYPES0 = SMU_ESAURTYPES0_ESAUR3NS;
  // Region 11 (EPPB) is Non-secure
  SMU->ESAURTYPES1 = SMU_ESAURTYPES1_ESAUR11NS;

```

###### Region Sizes

The code and figure below highlight how to program the Movable Region Boundaries (MRBs) of ESAU.

```C

  // ESAU region 0/1/2 programming
  // Boundary01 at 252kB and  Boundary12 at 256kB
  SMU->ESAUMRB01 = 0x0003F000U & _SMU_ESAUMRB01_MASK;
  SMU->ESAUMRB12 = 0x00040000U & _SMU_ESAUMRB12_MASK;
  // ESAU region 4/5/6 programming
  // Boundary45 at 44kB and Boundary56 at 44kB (region 5 size = 0)
  SMU->ESAUMRB45 = 0x0000B000U & _SMU_ESAUMRB45_MASK;
  SMU->ESAUMRB56 = 0x0000B000U & _SMU_ESAUMRB56_MASK;

```

![esau_prog](/series2-trustzone/0.2/images/sld717-esau-prog.png)

**Notes**:

- The mrb12 (`ESAUMRB12` in `SMU_ESAURMBR12`) has to be greater than or equal to mrb01 (`ESAUMRB12` in `SMU_ESAURMBR12`).
- The mrb56 (`ESAUMRB56` in `SMU_ESAURMBR562`) has to be greater than or equal to mrb45 (`ESAUMRB45` in `SMU_ESAURMBR45`).
- If one of the rules above is violated, the `SMU_STATUS.SMUPRGERR` is asserted.
- When mrb01 and mrb12 are equal, region 1 (NSC) is a size of 0 and is not seen by the system.
- When mrb45 and mrb56 are equal, region 5 (NSC) is a size of 0 and is not seen by the system.

##### BLS SAU Programming

###### All Secure Configuration

[All secure configuration](03-r-bls) is the default state after reset. It clears the `SAU_CTRL.ENABLE` and the `SAU_CTRL.ALLNS` bits in SAU, and the entire memory is in a Secure attribute.

###### All Non-secure Configuration

[All Non-secure Configuration](03-r-bls) occurs when the `SAU_CTRL.ENABLE` bit is cleared, and the `SAU_CTRL.ALLNS` bit is set. The ESAU controls the security attribute of a Cortex-M33 transaction.

```C

  // Disable SAU (ALLNS = 1) and clear data and instruction pipe
  SAU->CTRL = SAU_CTRL_ALLNS_Msk;
  __DSB();
  __ISB();

```

###### Configurable Configuration

[Configurable configuration](03-r-bls) occurs when the `SAU_CTRL.ENABLE` bit is set (`SAU_CTRL.ALLNS` is irrelevant). Both SAU and [ESAU](#region-sizes) determine the security attribute of a Cortex-M33 transaction. The code and figure below highlight how to program the SAU regions.

```C

  // Define all Non-secure (NS) and Non-secure Callable (NSC) Regions
  #define REGION0_BASE 0x0001E000UL
  #define REGION1_BASE 0x00020000UL
  #define REGION2_BASE 0x20004000UL
  #define REGION0_LIMIT 0x0001FFFFUL
  #define REGION1_LIMIT 0x000FFFFFUL
  #define REGION2_LIMIT 0x20017FFFUL
  // CMSIS calls to enable SAU Regions
  // SAU region 0 - Flash NSC at 120 kB to 128 kB (0x0001E000 - 0x0001FFFF)
  SAU->RNR = (0UL & SAU_RNR_REGION_Msk);
  SAU->RBAR = (REGION0_BASE & SAU_RBAR_BADDR_Msk);
  SAU->RLAR = (REGION0_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_NSC_Msk | SAU_RLAR_ENABLE_Msk;
  // SAU region 1 - Flash NS at 128 KB to 1024 kB (0x00020000 - 0x000FFFFF)
  SAU->RNR = (1UL & SAU_RNR_REGION_Msk);
  SAU->RBAR = (REGION1_BASE & SAU_RBAR_BADDR_Msk);
  SAU->RLAR = (REGION1_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
  // SAU region 2 - RAM NS at 16 kB to 96 kB (0x20004000 - 0x20017FFF)
  SAU->RNR = (2UL & SAU_RNR_REGION_Msk);
  SAU->RBAR = (REGION2_BASE & SAU_RBAR_BADDR_Msk);
  SAU->RLAR = (REGION2_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
  // CMSIS functions to enable SAU and clear data and instruction pipe
  TZ_SAU_Enable();
  __DSB();
  __ISB();

```

![sau-frog](/series2-trustzone/0.2/images/sld717-sau-prog.png)

##### BLS BMPU Programming

###### Bus Master Privileged Attribute

A Bus Master can be configured as either privileged (default) or unprivileged by programming the corresponding index in the `SMU_BMPUPATDn` register.

```C

  // Configure all odd Bus Masters unprivileged
  for (i = 0; i < SMU_NUM_BMPUS; i++) {
    if (i & 0x01) {
      SMU->BMPUPATD0 &= ~(1 << i);
    }
  }

```

###### Bus Master Security Attribute

A Bus Master can be configured as either Secure (default) or Non-secure by programming the corresponding index in the `SMU_BMPUPATDn` register. Configure a Bus Master as Non-secure results in the Bus Master only being able to access Non-secure addresses.

```C

  // Configure all odd Bus Masters Non-secure
  for (i = 0; i < SMU_NUM_BMPUS; i++) {
    if (i & 0x01) {
      SMU->BMPUSATD0 &= ~(1 << i);
    }
  }

```

###### Bus Master Fault Status

The Bus Master ID and the address that triggered the fault can be read from the `SMU_BMPUFS` and `SMU_BMPUFSADDR` registers.

```C

  uint32_t fs_bmpu_id;
  uint32_t fs_bmpu_addr;
  uint32_t fs_bmpu_secfault;
  // Read Bus Master fault status
  fs_bmpu_id = SMU->BMPUFS;
  fs_bmpu_addr = SMU->BMPUFSADDR;
  fs_bmpu_secfault = (SMU->IF & _SMU_IF_BMPUSEC_MASK) >> _SMU_IF_BMPUSEC_SHIFT;
  // Clear the IF to capture a new fault
  SMU->IF_CLR = SMU_IF_BMPUSEC;

```

##### BLS PPU Programming

###### Peripheral Privileged Attributes

A peripheral can be configured as either privileged (default) or unprivileged by programming the corresponding index in the `SMU_PPUPATDn` register.

```C

  // Configure all odd peripherals unprivileged
  for (i = 0; i < SMU_NUM_PPU_PERIPHS; i++) {
    if (i & 0x01) {
      if (i >= 32){
        SMU->PPUPATD1 &= ~(1 << (i-32));
      } else {
        SMU->PPUPATD0 &= ~(1 << i);
      }
    }
  }

```

**Notes**:

- The peripherals in `SMU_PPUPATD0` and `SMU_PPUPATD0` are device-dependent.
- The privileged attribute of the radio subsystem (`AHBRADIO` index) is configured as a unit.

###### Peripheral Security Attributes

A peripheral can be configured as either Secure (default) or Non-secure by programming the corresponding index in the `SMU_PPUSATDn` register. The figure below shows the memory map when the ADC, I2C0, USART1, and RADIO are configured as Non-secure and other peripherals (e.g., SMU, RTCC, TIMER1, TIMER0, USART0...) as Secure.

```C

  // Configure all the Non-secure peripherals
  SMU->PPUSATD0 &= ~SMU_PPUSATD0_USART1;
  SMU->PPUSATD1 &= ~(SMU_PPUSATD1_I2C0 | SMU_PPUSATD1_IADC0 | SMU_PPUSATD1_AHBRADIO);

```

![ppu_prog](/series2-trustzone/0.2/images/sld717-ppu-prog.png)

**Notes**:

- The peripherals in `SMU_PPUSATD0` and `SMU->PPUSATD1` are device-dependent.
- The security attribute of the radio subsystem (`AHBRADIO` index) is configured as a unit.

###### Peripheral Fault Status

The peripheral ID that triggered the fault can be read from the `SMU_PPUFS` register.

```C

  uint32_t fs_ppu_periph_id;
  uint32_t fs_sec_fault;
  uint32_t fs_priv_fault;
  uint32_t fs_inst_fault;
  // Read peripheral fault status
  fs_ppu_periph_id = SMU->PPUFS;
  fs_sec_fault = (SMU->IF & _SMU_IF_PPUSEC_MASK) >> _SMU_IF_PPUSEC_SHIFT;
  fs_priv_fault = (SMU->IF & _SMU_IF_PPUPRIV_MASK) >> _SMU_IF_PPUPRIV_SHIFT;
  fs_inst_fault = (SMU->IF & _SMU_IF_PPUINST_MASK) >> _SMU_IF_PPUINST_SHIFT;
  // Clear the IF to capture a new fault
  SMU->IF_CLR = SMU_IF_PPUSEC | SMU_IF_PPUPRIV | SMU_IF_PPUINST;

```

##### Floating Point Unit (FPU) Programming

If the Non-secure application enables the FPU at initialization, the Secure software needs to set up the `NSACR` register in [SCB](02-r-basic) to grant the FPU access for Non-secure software.

```C

  // Enable Non-secure access to the FPU
  SCB->NSACR |= SCB_NSACR_CP10_Msk + SCB_NSACR_CP11_Msk;

```

#### TrustZone Implementation

The goal of TrustZone implementation is to provide Secure Key Storage that can keep access to keys limited to Secure applications while at the same time allowing Non-secure applications to exercise the keys. It is an added feature for the SVM devices that do not have dedicated hardware for [Secure Key Storage](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/) as in SVH devices.

The [PSA Crypto](https://docs.silabs.com/iot-security/latest/mbedtls-psa-crypto-porting-guide/) is placed in a Secure region to keep key material hidden from the Non-secure application. The exposed PSA Crypto APIs stay the same while the backend provides persistent key encryption and decryption similar to the key wrapping and unwrapping functionality of the SVH device.

The following items need to be considered when upgrading the existing system for Secure Key Storage with TrustZone.

- [System Configuration](#system-configuration)
- [Gecko Bootloader](#gecko-bootloader)
- [Secure Library](#secure-library)
- [TrustZone Secure Key Storage](#trustzone-secure-key-storage)
- [PSA Attestation](#psa-attestation)
- [SE Manager](#se-manager)
- [Common Vulnerabilities and Exposures (CVE)](#common-vulnerabilities-and-exposures-cve)

##### System Configuration

The system configuration includes the following items:

- Enable system exceptions in the Secure state.
- Set the security attributes of different regions in the SAU and ESAU.
- Place peripherals and associated interrupts in either Secure or Non-secure applications.
- Assign the Bus Masters' security attributes.
- The system has two Secure/Non-secure pairs for the bootloader and application. The Secure part of each pair is responsible for properly configuring the split in its Secure application before branching to the Non-secure application.

> **Note**: The secure application will issue a software reset at startup (fatal error) if the device's SE firmware version is lower than the [first version](06-r-migration) that supports TrustZone.

###### System Exceptions

The following [system exceptions](02-r-basic#type-of-exceptions) are enabled in the Secure state for the bootloader and application.

- MemManage Fault
- BusFault
- UsageFault
- SecureFault

###### Main Flash Layout

The following figure is an overview of the main flash layout that covers the isolation requirements for the Secure Key Storage solution. The SAU and ESAU configurations provide the required security to the Cortex-M33 and other Bus Masters during boot and normal operation.

![Main Flash Layout](/series2-trustzone/0.2/images/sld717-main-flash-layout.png)

1. Settings:  
   - The application is set to non-executable (XN) by [Secure MPU](02-r-basic#secure-attribution-unit-sau-implementation-defined-attribution-unit-idau-and-memory-protection-unit-mpu) to avoid any code execution in this area during boot.  
   - The bootloader is set to non-executable (XN) by Secure MPU to avoid any code execution in this area during normal operation.
2. The ESAU configuration only uses the NSC section by setting mrb01 to the [base address of region 0](04-r-programming). The reason is that lite ESAU in other Bus Masters treats both S and NSC as a Secure attribute. For the Cortex-M33, the SAU upgrades the NSC in the ESAU to Secure. The 32 bytes region alignment of SAU also relaxes the 4 kB alignment restriction on the start address of the NSC in ESAU.
3. The whole application area is set to Secure in SAU for Cortex-M33 during boot to hide details from the bootloader NS part.
4. The ESAU cannot mark any region that comes after a Non-secure section as Secure (must be in the order of S/NSC/NS). Therefore the Secure application area does not align between the Cortex-M33 (SAU + ESAU) and other Bus Masters (lite ESAU) during boot. The secrets stored in that Secure region expose as Non-secure for other Bus Masters during boot (no such issue in normal operations). So the application must not save any plaintext secrets in that Secure region to overcome this limitation during boot.
5. The NVM storage is in the Non-secure region, so the application must [encrypt](05-r-implementation#secure-library) the persistent keys before storing them in this area.

###### RAM Layout

The following figure is an overview of the RAM layout used for the bootloader and application. The SAU and ESAU are used to split the RAM into a Secure and Non-secure region (Non-secure Callable is not required).

![RAM Layout](/series2-trustzone/0.2/images/sld717-ram-layout.png)

In practice, the Secure part (bootloader or application) takes ownership of the amount of RAM it needs from the beginning of RAM and leaves the rest (up to the ESAU 4 kB alignment requirement) configured as Non-secure.

The bootloader does not know how the application partitions the RAM between Secure and Non-secure. So bootloader removes any secrets from RAM before handing control to the application.

###### Info Flash and EPPB

The following figure is an overview of the Info flash and EPPB layout for the application. The Cortex-M33 core is the only Bus Master that can access the EPPB region.

![Info Flash and EPPB Layout](/series2-trustzone/0.2/images/sld717-info-flash-and-eppb-layout.png)

###### Peripheral and Device

The following figure is an overview of the peripheral and device layout for the bootloader and application. The SAU and ESAU are used to split the peripheral and device into a Secure and Non-secure region.

![Peripheral and Device Layout](/series2-trustzone/0.2/images/sld717-peripheral-and-device-layout.png)

The Secure software is responsible for moving all peripherals and associated interrupts to the Non-secure state at startup, except for the peripherals and interrupts that need to be Secure. The Non-secure software must not include code that attempts to directly access any peripheral that is used by the Secure software.

**Peripherals owned by the Secure software (application)**

1. Security Management Unit (SMU)  
   - It prevents Non-secure software from changing the configuration for the ESAUs, BMPUs, and PPUs.  
   - Except for EFR32xG21 devices, some features are also available in the dedicated [Non-secure version of SMU registers](03-r-bls) (`SMU_CFGNS`).
2. CRYPTOACC (VSE devices) or SEMAILBOX (HSE devices)  
   - The crypto engine is placed in the Secure domain for [Secure library](#secure-library).
3. System Configuration (SYSCFG)  
   - It prevents Non-secure software from changing system configurations for Secure software.  
   - Except for EFR32xG21 devices, some features are also available in the dedicated [Non-secure version of SYSCFG registers](03-r-bls) (`SYSCFG_CFGNS`).
4. Memory System Controller (MSC)  
   - It prevents Non-secure software from writing to Secure flash.

**Peripheral interrupts owned by the Secure software**:

**Table**: Secure Peripheral Interrupts (Application)

<table>
    <tbody>
        <tr>
            <td>VSE Device</td>
            <td>HSE Device</td>
        </tr>
        <tr>
            <td>SMU_SECURE_IRQn</td>
            <td>SMU_SECURE_IRQn</td>
        </tr>
        <tr>
            <td>SYSCFG_IRQn</td>
            <td>SYSCFG_IRQn</td>
        </tr>
        <tr>
            <td>MSC_IRQn</td>
            <td>MSC_IRQn</td>
        </tr>
        <tr>
            <td>CRYTOACC_IRQn</td>
            <td>SEMBRX_IRQn</td>
        </tr>
        <tr>
            <td>TRNG_IRQn</td>
            <td>SEMBTX_IRQn</td>
        </tr>
        <tr>
            <td>PKE_IRQn</td>
            <td></td>
        </tr>
    </tbody>
</table>

The `PRIS` bit in the `AIRCR` register is set to 1 to place all Non-secure exceptions/interrupts in [lower priority level space](02-r-basic). Therefore any Secure exceptions/interrupts can be programmed with higher priority than Non-secure ones.

The [`BMPUSEC`](03-r-bls) and [`PPUSEC`](03-r-bls) interrupt enable flags in the `SMU_IEN` register are set to enable the SMU security fault interrupts (`SMU_SECURE_IRQn`) on Bus Masters and peripherals.

**Floating Point Unit (FPU)**:

The Secure application does not use the FPU. But the Secure startup code also enables the [FPU](04-r-programming) for use by the Non-secure application.

###### Bus Masters

To keep all secrets from the Non-secure world, only the Bus Masters in the table below can access data in the Secure world. For the Bus Masters living in the Secure world, the secure application must configure their corresponding control interfaces in the peripheral space to Secure. The Cortex-M33 core as a Bus Master is split to run in Secure and Non-secure contexts.

**Table**: Secure Bus Masters (Application)

<table>
    <thead>
        <tr>
            <th>Device</th>
            <th>Secure Bus Master</th>
            <th>Control Interface of Bus Master</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>VSE</p>
            </td>
            <td>
                <p>CRYPTOACC</p>
            </td>
            <td>
                <p>CRYTPOACC</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>HSE</p>
            </td>
            <td>
                <p>SEDMA or SEEXTDMA</p>
            </td>
            <td>
                <p>SEMAILBOX</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- Use `SMU_BMPUSATD0` register to [configure](04-r-programming) the security attribute of a Bus Master.
- Use `SMU_PPUSATDn` register to [configure](04-r-programming) the control interface of Bus Master as a Secure peripheral.
- LDMA is set as a Non-secure Bus Master to make sure it cannot be used to copy out data from the Secure memory.

###### Application Transitions

The system contains two Secure/Non-secure pairs.

1. The [bootloader pair](#bootloader pair) has a Secure bootloader and a Non-secure bootloader containing the communication interfaces.
2. The [application pair](#application pair) has a Secure application and a Non-secure application consisting of the wireless stacks (if applicable) and application layers.

As described in the preceding sections, the Secure part of these pairs is responsible for setting the security configurations of the system during startup. For the handover between Secure/Non-secure pairs, the software must restore the system so the Secure part of the other pair can execute and reconfigure the system.

The software must reconfigure the following items before transitioning to the next Secure/Non-secure pair:

- Restored all peripherals and interrupts to Secure
- Reset ESAU to default configuration (all configurable regions to Secure)
- Reset SAU to default configuration (Secure for everything)
- Reset MPU to default configuration (removes any XN)

##### Gecko Bootloader

The [Gecko bootloader](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) ensures the Secure assets are protected during the boot flow and normal operation.

![Gecko Bootloader Flow](/series2-trustzone/0.2/images/sld717-gecko-bootloader-flow.png)

1. The SAU and [Secure MPU](02-r-basic) mark all the flash for application and NVM as Secure and non-executable (XN) during boot. It guards against bootloader NS code execution branching into the application code.
2. The bootloader needs to split into Secure and Non-secure software to protect secrets in the system. Secure code can access the entire flash to validate or upgrade the system.
3. For VSE devices, the [GBL Decryption Key (AES-128 key)](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) is moved from the NS memory (last page of the main flash) to the Secure part of the bootloader. The Simplicity Commander v1.13 or higher provides a feature to inject the AES-128 key to the bootloader binary file.  
   ```C  
   commander convert <BL image file> --aeskey <decryption key file> --outfile <BL image with decryption key>  
   ```
4. The bootloader communication interfaces are placed in the NS area to support various [communication components](https://docs.silabs.com/mcu-bootloader/latest/group-Communication) below for firmware upgrades.  
   - BGAPI UART  
   - EZSP-SPI  
   - UART XMODEM
5. The NS communication functions call into the [bootloader APIs](https://docs.silabs.com/mcu-bootloader/latest/group-Interface) placed in the bootloader NSC region. The Secure application [validates](02-r-basic) all input arguments before processing the request.
6. Before transiting from bootloader to normal operation, it resets the SAU to default configuration to make all the flash for bootloader as Secure.
7. The Non-secure application software can call [bootloader APIs](https://docs.silabs.com/mcu-bootloader/latest/group-Interface) through application NSC, and the corresponding Secure function releases the non-executable (XN) restriction on the bootloader during normal operation.

##### Secure Library

The goal of the Secure library is to keep the [PSA Crypto key](#trustzone-secure-key-storage) and [attestation token](#psa-attestation) protected from malicious code on the NSPE. The following figure overviews multiple components to support the Secure library.

![Secure Library Components](/series2-trustzone/0.2/images/sld717-secure-library-components.png)

1. The NS interfaces in NSPE are responsible for packing and passing all input arguments over the [NSC](02-r-basic) functions on wrappers in SPE.
2. The wrappers in SPE validate all input arguments before calling into the corresponding APIs in different drivers.
3. Because of the system memory layout limitation, the [flash](#main-flash-layout) for NVM3 storage is located in the NSPE. Therefore the updated PSA Internal Trusted Storage (ITS) driver needs to encrypt all crypto keys before storing them in Non-secure NVM.
4. Data stored directly using the NVM3 APIs are not encrypted.

The following table describes the new and updated components of the Secure library.

<table>
    <thead>
        <tr>
            <th>Component</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SE Manager NS interface</p>
            </td>
            <td>
                <p>This component contains SE Manager API callable from the NSPE. It packages the list of input arguments in the appropriate format before calling into the SE Manager wrapper's NSC functions.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE manager wrapper</p>
            </td>
            <td>
                <p>This component contains the interface into SE Manager exposed to the NSPE. These NSC functions grant access to the SE Manager utility API and validate all input arguments before calling into SE Manager.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto &amp; Attestation NS interface</p>
            </td>
            <td>
                <p>This component contains PSA Crypto and attestation API callable from the NSPE. It packages the list of input arguments in the appropriate format before calling into the PSA Crypto and attestation wrapper's NSC functions.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto &amp; Attestation wrapper</p>
            </td>
            <td>
                <p>This component contains the interface into PSA Crypto and attestation exposed to the NSPE. These NSC functions grant access to the entire PSA Crypto and attestation API and validate all input arguments before calling into PSA Crypto and attestation.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA attestation</p>
            </td>
            <td>
                <p>This component in SPE provides the functionality required by the PSA attestation specification.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Encrypted PSA ITS</p>
            </td>
            <td>
                <p>The PSA ITS layer builds on top of NVM3. This component is updated to support encrypted storage to secure stored keys. The encryption is based on the device's TrustZone Root Key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>NVM3 NS interface</p>
            </td>
            <td>
                <p>This component contains NVM3 API callable from the NSPE. It packages the list of input arguments in the appropriate format before calling into the NVM3 wrapper's NSC functions.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>NVM3 wrapper</p>
            </td>
            <td>
                <p>This component contains the interface into NVM3 exposed to the NSPE. These NSC functions grant access to the NVM3 API and validate all input arguments before calling into NVM3.</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- The SE Manager NS interface, PSA Crypto NS interface, and NVM3 NS interface in the NSPE provide drop-in replacement on [SE Manager utility](#se-manager), [PSA Crypto](https://armmbed.github.io/mbed-crypto/html/about.html), and [NVM3](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3) APIs for existing wireless stacks and user applications.
- The NSC calls can only take a limited number of arguments, so all NSC functions take a pointer to a list of parameters to support a long list of arguments. All arguments must be validated using the [intrinsic functions](02-r-basic) from CMSIS.

##### TrustZone Secure Key Storage

The TrustZone Secure Key Storage provides a solution to store a user key in Secure RAM or an encrypted form in Non-secure flash.

The TrustZone Root Key stored in the SE NVM for Secure Key Storage encryption is generated or renewed by following operations.

- The TrustZone Root Key had already existed if the shipped Series 2 device with [SE firmware version](06-r-migration) supports this key.
- Generate a TrustZone Root Key when upgrading from a SE firmware version that did not support this key to the one that does.
- Renew a TrustZone Root Key after performing a [Device Erase](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

> **Note**: The TrustZone Root Key cannot be renewed if Device Erase is disabled.

The TrustZone Root Key is not exposable to the NSPE, and access to this key in SPE is different in HSE and VSE devices.

- HSE - The SPE can access the TrustZone Root Key as a built-in non-exportable key in HSE NVM.
- VSE - The SPE can access the TrustZone Root Key in Secure RAM, which is copied from VSE NVM during boot.

The TrustZone Root Key value after reset is identical to the value before reset. TrustZone Root Keys are unique on each device. The key allows a user to securely store a key in the Non-secure flash, limiting the number of keys that can be saved only by the amount of Non-secure storage. The following figure describes using the TrustZone Root Key to encrypt a plaintext key and store it in Non-secure NVM.

![root_encrypt](/series2-trustzone/0.2/images/sld717-root-encrypt.png)

1. After power-on, the device's TrustZone Root Key is available for the SPE.
2. A user key is generated and imported into the device's Non-secure memory. In this example, the key is imported into Non-secure RAM for easy deletion, and the key is lost if device power is removed.
3. Call PSA Crypto API (`psa_import_key()` or `psa_generate_key()`) through SG in NSC to generate a key for crypto operations.
4. The plaintext key is passed to the PSA Crypto in SPE, where it is encrypted (AES-GCM) with the TrustZone Root Key.
5. The encrypted key is stored to the NVM in NSPE through the PSA ITS and NVM3 drivers.
6. The plaintext key can now be deleted from the Non-secure RAM.
7. Only the PSA Crypto in SPE can retrieve the encrypted key from NVM in NSPE and decrypt it for crypto operations in SPE.

> **Note**: Ignore steps 2 and 6 if the plaintext key is randomly generated by the PSA Crypto.

The following tables describe the storage differences between SVM and SVH devices with and without TrustZone Secure Key Storage (SKS).

<table>
    <thead>
        <tr>
            <th>Key Type</th>
            <th>Storage on SVM Device</th>
            <th>Storage on SVH Device</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Volatile Plaintext (without TrustZone SKS)</p>
            </td>
            <td>
                <p>RAM</p>
            </td>
            <td>
                <p>RAM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Plaintext (without TrustZone SKS)</p>
            </td>
            <td>
                <p>NVM</p>
            </td>
            <td>
                <p>NVM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Volatile Wrapped (without TrustZone SKS)</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>RAM (1)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Wrapped (without TrustZone SKS)</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>NVM (1)</p>
            </td>
        </tr>
    </tbody>
</table>

<table>
    <thead>
        <tr>
            <th>Key Type</th>
            <th>Storage on SVM Device</th>
            <th>Storage on SVH Device</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Volatile Plaintext (with TrustZone SKS)</p>
            </td>
            <td>
                <p>Secure RAM (2)</p>
            </td>
            <td>
                <p>Secure RAM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Plaintext (with TrustZone SKS)</p>
            </td>
            <td>
                <p>Encrypted plaintext key in NS NVM (2)</p>
            </td>
            <td>
                <p>Encrypted plaintext key in NS NVM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Volatile Wrapped (with TrustZone SKS)</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>Secure RAM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Wrapped (with TrustZone SKS)</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>Encrypted wrapped key in NS NVM</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- The NVM or [NS NVM](#main-flash-layout) is at the last part of the main flash.
- It is possible to replace the [wrapped key](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/) solution on the SVH device (1) with TrustZone Secure Key Storage on the SVM device (2), but this is a less secure approach.

##### PSA Attestation

The device attestation service creates a token that contains a fixed set of device-specific data when requested by the caller. Each device must have a unique Initial Attestation Key (IAK) pair. The device uses the private IAK to sign the token, and the caller uses the public IAK to verify the token's authenticity.

The generation of the private IAK is different in SVM and SVH devices.

- SVM - If the private IAK does not exist in NVM3, it is randomly generated when requested from the [PSA Attestation](#secure-library) driver and saved to NVM3 through the [TrustZone Secure Key Storage](#trustzone-secure-key-storage).
- SVH - The private IAK is generated and securely stored in the HSE during chip production.

An Entity Attestation Token (EAT) is a mini-report that is cryptographically signed. An EAT is encoded in either one of two standardized data formats: a Concise Binary Object Representation ([CBOR](https://www.rfc-editor.org/info/rfc7049)) or in the text-based format JSON. A digital signature is then used to protect its content. The technical specification defining the content of the EAT, which are claims about the hardware and the software running on a device, is specified by the Internet Engineering Task Force ([IETF](https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat-11)).

The EAT is a crypto-signed report card with claims. A claim is a data item that is represented as a Key-Value pair. Claims can relate to the device's pedigree or anything one wants the device to attest. Collected data can originate from the Root of Trust (RoT), any protected area, or non-protected areas.

The EAT must be signed following the structure of the CBOR Object Signing and Encryption ([COSE](https://www.rfc-editor.org/info/rfc8152)) specification. For asymmetric key algorithms, the signature structure must be COSE-Sign1. A COSE-Sign1 is a CBOR encoded, self-secured data blob that contains headers, a payload, and a signature.

The primary need for EAT verification is to check correct formation and signing as for any token. In addition, though, the verifier can operate a policy where values of some of the claims in this profile can be compared to reference values that are registered with the verifier for a given deployment, to confirm that the device is endorsed by the manufacturer supply chain.

The [PSA attestation token](https://www.ietf.org/archive/id/draft-tschofenig-rats-psa-token-21.html) (aka Initial Attestation Token - IAT) is a profiled EAT. The Series 2 device will generate this token by (Nonce claim below) unless the SE OTP is uninitialized or the [`SECURE_BOOT_ENABLE`](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) option in SE OTP is disabled.

The following tables describe claims used in the PSA attestation token of the Series 2 device.

**Table**: Claims of PSA Attestation Token

<table>
    <thead>
        <tr>
            <th>Key</th>
            <th>Claim Name (Present)</th>
            <th>Claim Description</th>
            <th>Claim Value</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>265 (-75000)</p>
            </td>
            <td>
                <p>Profile Definition (Must)</p>
            </td>
            <td>
                <p>The Profile Definition claim encodes the unique identifier corresponds to the EAT profile.</p>
            </td>
            <td>
                <p>http://arm.com/psa/2.0.0</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2394 (-75001)</p>
            </td>
            <td>
                <p>Client ID (Must)</p>
            </td>
            <td>
                <p>The Client ID claim represents the security domain of the caller.</p>
            </td>
            <td>
                <p>See note below (2 byes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2395 (-75002)</p>
            </td>
            <td>
                <p>Security Lifecycle (Must)</p>
            </td>
            <td>
                <p>The Security Lifecycle claim represents the current lifecycle state of the PSA RoT.</p>
            </td>
            <td>
                <p>Device dependent (2 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2396 (-75003)</p>
            </td>
            <td>
                <p>Implementation ID (Must)</p>
            </td>
            <td>
                <p>The Implementation ID claim uniquely identifies the implementation of the immutable PSA RoT.</p>
            </td>
            <td>
                <p>Device dependent (32 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2397 (-75004)</p>
            </td>
            <td>
                <p>Boot Seed (Optional)</p>
            </td>
            <td>
                <p>The Boot Seed claim represents a value created at system boot time that will allow differentiation of reports from different boot sessions.</p>
            </td>
            <td>
                <p>Device dependent (32 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2399 (-75006)</p>
            </td>
            <td>
                <p>Software Components (Must)</p>
            </td>
            <td>
                <p>The Software Components claim is a list of software components that includes all the software loaded by the PSA RoT.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>10 (-75008)</p>
            </td>
            <td>
                <p>Nonce (Must)</p>
            </td>
            <td>
                <p>The Nonce claim is used to carry the challenge provided by the caller to demonstrate freshness of the generated token. The length must be either 32, 48, or 64 bytes.</p>
            </td>
            <td>
                <p>Random nonce (32/48/64 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>256 (-75009)</p>
            </td>
            <td>
                <p>Instance ID (Must)</p>
            </td>
            <td>
                <p>The Instance ID claim represents the unique identifier of the IAK. The length must be 33 bytes.</p>
            </td>
            <td>
                <p>SHA-256 hash of public IAK (32 bytes) with header 0x01</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- Some claims MUST be present in a PSA attestation token.
- The keys `-7500x` were defined in a previous version of the PSA attestation token specification (`PSA_IOT_PROFILE_1` profile) that is still used in the HSE-SVH firmware.
- The actual claims returned from the tokens on the SVH device are HSE firmware version-dependent.
- Key 2394: In PSA, a security domain is represented by a signed integer where negative values represent callers from the NSPE and positive IDs represent callers from the SPE. The value 0 is not permitted.
- Key 2395 (For the definitions of these lifecycle states, refer to the ARM [PSA Security Model](https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0079_PSA_SM_ALPHA-03_RC01.pdf)):  
  - UNKNOWN (`0x0000 - 0x00ff`)  
  - ASSEMBLY_AND_TEST (`0x1000 - 0x10ff`)  
  - PSA_ROT_PROVISIONING (`0x2000 - 0x20ff`)  
  - SECURED (`0x3000 - 0x30ff`)  
  - NON_PSA_ROT_DEBUG (`0x4000 - 0x40ff`)  
  - RECOVERABLE_PSA_ROT_DEBUG (`0x5000 - 0x50ff`)  
  - DECOMMISSIONED (`0x6000 - 0x60ff`)
- Key 2396:  
  - Word[0]: Die revision  
  - Word[1]: SE OTP version (return 0 for VSE SE firmware < [v1.2.14](06-r-migration))  
  - Word[2]: Security capability (not applicable to HSE-SVH device, always returns 1 in this word)    
    - 0: Unknown security capability    
    - 1: Security capability not applicable    
    - 2: Basic security capability    
    - 3: Root of Trust security capability    
    - 4: HSE-SVM security capability    
    - 5: HSE-SVH security capability (run HSE-SVM binary on HSE-SVH device)  
  - Word[3]: Production version  
  - Word[4:7]: Reserved (zeros)
- Key 2399: Each software component uses the attributes described in the following table, and some MUST be present in a software component claim.

<table>
    <thead>
        <tr>
            <th>Key</th>
            <th>Attribute (Present)</th>
            <th>Description</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>1</p>
            </td>
            <td>
                <p>Measurement Type (Optional)</p>
            </td>
            <td>
                <p>The Measurement Type attribute is a short string representing the role of this software component.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2</p>
            </td>
            <td>
                <p>Measurement Value (Must)</p>
            </td>
            <td>
                <p>The Measurement Value attribute represents a hash of the invariant software component in memory at startup time.</p>
            </td>
            <td>
                <p>SHA-256 hash (32 bytes) of the firmware</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>4</p>
            </td>
            <td>
                <p>Version (Optional)</p>
            </td>
            <td>
                <p>The Version attribute is the issued software version in the form of a text string.</p>
            </td>
            <td>
                <p>A string of 8 bytes</p>
            </td>
        </tr>
    </tbody>
</table>

The following measurement types may be used for Key 1:

- "BL": a Bootloader
- "PRoT": a component of the PSA Root of Trust
- "ARoT": a component of the Application Root of Trust
- "App": a component of the NSPE application
- "TS": a component of a Trusted Subsystem

The PSA Attestation API allows access to the PSA attestation token, so an external entity can cryptographically verify the identity and trust status of the device.

**Table**: PSA Attestation API

<table>
    <thead>
        <tr>
            <th>PSA Attestation API</th>
            <th>Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>psa_initial_attest_get_token</p>
            </td>
            <td>
                <p>Retrieve the PSA attestation Token.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>psa_initial_attest_get_token_size</p>
            </td>
            <td>
                <p>Calculate the size of a PSA attestation Token.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_tz_attestation_get_public_key</p>
            </td>
            <td>
                <p>Get the public IAK key for PSA attestation token signature verification.</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The `sl_tz_attestation_get_public_key` is a Silicon Labs custom API.

##### SE Manager

SE Manager is the foundation for the [Secure library](#secure-library) cryptographic operations on HSE devices. It means that SE Manager has to move into the SPE.

The following SE Manager [core](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager-core) APIs are always available in the NSPE.

<table>
    <thead>
        <tr>
            <th>SE Manager Core API</th>
            <th>VSE-SVM</th>
            <th>HSE-SVM</th>
            <th>HSE-SVH</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_init</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_deinit</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_init_command_context</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_deinit_command_context</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_set_yield</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
    </tbody>
</table>

The following SE Manager [core](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager-core) APIs expose to the NSPE through the NSC interface for the VSE devices.

<table>
    <thead>
        <tr>
            <th>SE Manager Core API</th>
            <th>VSE-SVM</th>
            <th>HSE-SVM</th>
            <th>HSE-SVH</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_read_executed_command</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_ack_command</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
        </tr>
    </tbody>
</table>

The following SE Manager [utility](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager-util) APIs expose to the NSPE through the NSC interface for configuring the security features of HSE or VSE devices.

<table>
    <thead>
        <tr>
            <th>SE Manager Utility API</th>
            <th>VSE-SVM</th>
            <th>HSE-SVM</th>
            <th>HSE-SVH</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_check_se_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_apply_se_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_upgrade_status_se_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_check_host_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_apply_host_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_upgrade_status_host_image</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_init_otp_key</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_pubkey</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_init_otp</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_otp</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_se_version</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_debug_lock_status</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_apply_debug_lock</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_otp_version</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_write_user_data</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_erase_user_data</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_reset_cause</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
            <td>
                <p>Y (EFR32xG21 only)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_status</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_serialnumber</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_enable_secure_debug</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_disable_secure_debug</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
    </tbody>
</table>

<table>
    <thead>
        <tr>
            <th>SE Manager Utility API</th>
            <th>VSE-SVM</th>
            <th>HSE-SVM</th>
            <th>HSE-SVH</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_set_debug_options</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_erase_device</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_disable_device_erase</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_get_challenge</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_roll_challenge</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_open_debug</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_disable_tamper</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_cert_size</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_cert</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>Y</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The NSPE cannot access the other [SE Manager APIs](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager) for cryptographic and attestation operations.

##### Common Vulnerabilities and Exposures (CVE)

At this writing, the following known TrustZone CVE had been fixed in the current implementation.

- [CVE-2020-16273](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-16273): Stack sealing
- [CVE-2021-36465](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35465): VLLDM instruction/floating-point vulnerability

#### 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](05-r-implementation) (24 kB) does not fit inside the current allotted bootloader space (16 kB).
- The [Secure/Non-secure pair for the application](07-r-ex) does not fit inside the current allotted application space.
- The [PSA ITS](05-r-implementation) 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](05-r-implementation) 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](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager) 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.

<table>
    <thead>
        <tr>
            <th>Tool/Software</th>
            <th>Required Version</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>GCC</p>
            </td>
            <td>
                <p>v10.3.1</p>
            </td>
            <td>
                <p>Fix a bug (ID 99271) on cmse_nonsecure_call attribute.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>IAR EWARM</p>
            </td>
            <td>
                <p>v9.20.4</p>
            </td>
            <td>
                <p>Fix a bug (EWARM-9484) on __cmse_nonsecure_call attribute.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Segger J-Link</p>
            </td>
            <td>
                <p>≥ v7.6.2c</p>
            </td>
            <td>
                <p>v7.6.2c is the first version to add basic TrustZone support on Series 2 devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Simplicity Studio</p>
            </td>
            <td>
                <p>≥ v5.6.3.0</p>
            </td>
            <td>
                <p>v5.6.3.0 is the first version to support TrustZone software development on Series 2 devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Simplicity Commander</p>
            </td>
            <td>
                <p>≥ v1.13.3</p>
            </td>
            <td>
                <p>v1.13.3 includes a TrustZone-aware flash loader and supports features required for TrustZone development.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>GSDK</p>
            </td>
            <td>
                <p>≥ v4.2.2</p>
            </td>
            <td>
                <p>GSDK v4.2.2 is the first version to support TrustZone software development on Series 2 devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE Firmware</p>
            </td>
            <td>
                <p>≥ v1.2.14</p>
            </td>
            <td>
                <p>v1.2.14 is the first version to fully support TrustZone on xG21 (HSE) and xG22 (VSE) devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE Firmware</p>
            </td>
            <td>
                <p>≥ v2.2.1</p>
            </td>
            <td>
                <p>v2.2.1 is the first version to fully support TrustZone on other Series 2 HSE and VSE devices.</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- Required GCC and IAR EWARM versions are GSDK-dependent.
- [Bug list of GCC v10.3](https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED&resolution=FIXED&target_milestone=10.3)
- [IAR EWARM release note](https://updates.iar.com/?product=EWARM)
- [Segger J-Link release note](https://www.segger.com/downloads/jlink/ReleaseNotes_JLink.html)
- [Simplicity Studio user guide](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-overview/)
- [Latest version of Simplicity Commander](https://www.silabs.com/developers/mcu-programming-options)
- [GSDK release note](https://github.com/SiliconLabs/gecko_sdk/releases)
- 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](#startup-code) (`SystemInit()` in system_*.c) will be responsible for reconfiguring the system.

<table>
    <thead>
        <tr>
            <th>Define (Software Component)</th>
            <th>Default Peripheral Pointer</th>
            <th>Startup Code</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SL_TRUSTZONE_SECURE (TrustZone Secure)</p>
            </td>
            <td>
                <p>Point to Secure peripherals (*_BASE = *_S_BASE)</p>
            </td>
            <td>
                <p>No effect on SystemInit()</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SL_TRUSTZONE_NONSECURE (TrustZone Non-Secure)</p>
            </td>
            <td>
                <p>Point to Non-secure peripherals (*_BASE = *_NS_BASE)</p>
            </td>
            <td>
                <p>No effect on SystemInit()</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>None of the above (-)</p>
            </td>
            <td>
                <p>Point to Non-secure peripherals (*_BASE = *_NS_BASE)</p>
            </td>
            <td>
                <p>SystemInit() moves peripherals to Non-secure</p>
            </td>
        </tr>
    </tbody>
</table>

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.

```C

#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

```

```C

#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).

```C

#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](#startup-code) application.

##### Startup Code

The startup code moves peripherals from Secure to Non-secure to support the [default peripheral locations](#peripheral-addresses-in-device-header-files). 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](02-r-basic) 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](03-r-bls) and HSE SEMAILBOX (lines 172 to 178).
- The `SystemInit()` sets the SAU in [All Non-secure](03-r-bls) 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](https://developer.arm.com/documentation/ecm0359818/latest) 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](03-r-bls) (default Secure flash is 32 MB), so the whole program is run in the **Secure** state.
- The `SystemInit()` also enables the [`BMPUSEC`](03-r-bls) and [`PPUSEC`](03-r-bls) 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.

![system_init](/series2-trustzone/0.2/images/sld717-system-init.png)

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).

```C

#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 */

```

```C

#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.  
  ![gcc_cmse](/series2-trustzone/0.2/images/sld717-gcc-cmse.png)
- The CMSE compiler option of IAR is in the Command line options: (one per line) window under Options... → C/C++ Compiler → Extra Options.  
  ![iar_cmse](/series2-trustzone/0.2/images/sld717-iar-cmse.png)

##### Linker File

The [`template_contribution`](https://siliconlabs.github.io/slc-specification/latest/format/component/template_contribution/) defined in the [slcp](https://siliconlabs.github.io/slc-specification/latest/format/project/) files of [Secure and Non-secure projects](07-r-ex) will override the default memory settings defined in the device component files (e.g., `efr32mg21b020f1024im32.slcc`) to generate the linker files for [Secure](07-r-ex) and [Non-secure](07-r-ex) applications.

<table>
    <thead>
        <tr>
            <th>Memory Region</th>
            <th>Default Setting in Device Component File</th>
            <th>Override Setting in template_contribution</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Flash start address</p>
            </td>
            <td>
                <p>device_flash_addr</p>
            </td>
            <td>
                <p>memory_flash_start</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Flash size</p>
            </td>
            <td>
                <p>device_flash_size</p>
            </td>
            <td>
                <p>memory_flash_size</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>RAM start address</p>
            </td>
            <td>
                <p>device_ram_addr</p>
            </td>
            <td>
                <p>memory_ram_start</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>RAM size</p>
            </td>
            <td>
                <p>device_ram_size</p>
            </td>
            <td>
                <p>memory_ram_size</p>
            </td>
        </tr>
    </tbody>
</table>

![linker_file](/series2-trustzone/0.2/images/sld717-linker-file.png)

The [ESAU](03-r-bls) 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](02-r-basic) (Secure Gateway) at the end of the Secure flash section. The [SAU](03-r-bls) 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.

![mem_config](/series2-trustzone/0.2/images/sld717-mem-config.png)

> **Note**: Users should not directly edit the `template_contribution` in the `slcp` file, but rather use the [Memory Editor](07-r-ex) in Simplicity Studio to update the memory configuration.

##### Debugger

Simplicity Studio supports two [debuggers](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-testing-and-debugging/using-the-debugger):

- GNU Debugger (GDB) client and SEGGER's GDB server
- Simplicity Studio Debugger

The [TrustZone-unaware](#startup-code) and [TrustZone-aware](05-r-implementation) applications enable the [`PPUSEC`](03-r-bls) 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.

![ppusec_fault](/series2-trustzone/0.2/images/sld717-ppusec-fault.png)

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.

![register-view](/series2-trustzone/0.2/images/sld717-register-view.png)

The GNU Debugger is the preferred choice for TrustZone debugging and is the default debugger for Simplicity Studio ≥ v5.5.0.0.

#### TrustZone Platform Examples

The following TrustZone platform examples located in the C:\Users<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\app\common\example folder (Windows) demonstrate the TrustZone implementation on Series 2 devices. All TrustZone platform examples do not include [Gecko Bootloader](05-r-implementation).

##### TrustZone PSA Attestation

![tz_attestation](/series2-trustzone/0.2/images/sld717-tz-attestation.png)

![tz_attestation_folder](/series2-trustzone/0.2/images/sld717-tz-attestation-folder.png)

<table>
    <thead>
        <tr>
            <th>Example Folder</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>tz_psa_attestation</p>
            </td>
            <td>
                <p>The workspace description file (tz_psa_attestation_ws.slcw) creates the TrustZone PSA Attestation example. The project description file (tz_psa_attestation_s.slcp) configures a Secure application that provides the Secure Library functionality required by the Non-secure application.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>tz_psa_attestation_ns</p>
            </td>
            <td>
                <p>The project description file (tz_psa_attestation_ns.slcp) configures a Non-secure application for the TrustZone PSA Attestation example.</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- This example cannot run if the `SECURE_BOOT_ENABLE` (root of trust of the attestation) option in SE OTP is disabled.
- The combined image of Secure and Non-secure applications is signed by the `example_signing_key.pem` (private key) in C:\Users<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\platform\commonfolder (Windows). The `example_signing_pubkey.pem` (public key) in the same folder is installed to the SE OTP to verify the image signature during [Secure Boot](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/).

##### TrustZone PSA Crypto ECDH

![tz-ecdh](/series2-trustzone/0.2/images/sld717-tz-ecdh.png)

![tz-cdh-folder](/series2-trustzone/0.2/images/sld717-tz-ecdh-folder.png)

|Example Folder|Description|
|---|---|
|tz_psa_crypto_ecdh|The workspace description file (tz_psa_crypto_ecdh_ws.slcw) upgrades the existing Platform - PSA Crypto ECDH example to TrustZone-aware. The project description file (tz_psa_crypto_ecdh_s.slcp) configures a Secure application that provides the Secure Library functionality required by the Non-secure application.|
|tz_psa_crypto_ecdh_ns|The project description file (tz_psa_crypto_ecdh_ns.slcp) configures the existing Platform - PSA Crypto ECDH example as a Non-secure application. The source code can be reused without changes.|

The following sections use Simplicity Studio v5.6.3.0 and GSDK v4.2.2. The procedures and pictures may be different if using higher versions of Simplicity Studio 5 and GSDK.

##### Project Description File

The project description file ([`.slcp`](https://siliconlabs.github.io/slc-specification/1.0/format/project/)) contains references to the GSDK used and a list of components to use from these. The TrustZone-aware application requires separate `slcp` files for the Secure and Non-secure applications.

Users should not directly edit the `slcp` files, but rather use the [Memory Editor](#memory-editor) and Post Build Editor in Simplicity Studio to update the [memory configuration](#memory-configuration) and post-build actions.

###### Secure Application

The following figure describes which TrustZone software components are installed for the TrustZone Secure library of the [TrustZone PSA Crypto ECDH](#trustzone-platform-examples) example.

![tz_secure_component](/series2-trustzone/0.2/images/sld717-tz-secure-component.png)

**Notes**:

- The services provided by the Secure library are standardized.
- The source files for the Secure library will be automatically added to the application when generating the Secure project from the `slcp` file. For the current TrustZone implementation, modifications of the source files of the Secure library are not recommended.

###### Non-secure Application

The following figure describes which TrustZone software components are installed for the Non-secure application of the [TrustZone PSA Crypto ECDH](#trustzone-platform-examples) example.

![tz_nonsecure_component](/series2-trustzone/0.2/images/sld717-tz-nonsecure-component.png)

**Notes**:

- The following software components are automatically installed when [PSA Crypto and ITS](05-r-implementation) services are used on the Non-secure application.  
  - MSC Service for TrustZone Secure Key Library  
  - NVM3 Service for TrustZone Secure Key Library  
  - PSA Crypto Service for TrustZone Secure Key Library  
  - PSA ITS Service for TrustZone Secure Key Library  
  - SYSCFG Service for TrustZone Secure Key Library
- The following software components can be installed to the Non-secure application when those services are required.  
  - [PSA Attestation Service for TrustZone Secure Key Library](05-r-implementation#psa-attestation)  
  - [SE Manager Service for TrustZone Secure Key Library](05-r-implementation#se-manager)

##### Workspace

A workspace is a structure that can contain multiple projects. 'Workspace' is a generic term for this construct. In the context of Simplicity Studio, where workspace has a different, Eclipse-based, meaning, workspaces are referred to as [Solutions](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-developing-with-project-configurator/project-solutions).

The workspace description file ([`.slcw`](https://siliconlabs.github.io/slc-specification/latest/format/workspace/)) contains references to projects ([`.slcp`](https://siliconlabs.github.io/slc-specification/latest/format/project/)) that make up the workspace. Users should not directly edit the `slcw` file, but rather use the Post Build Editor in Simplicity Studio to update the post-build actions.

##### Memory Configuration

The [memory configurations](06-r-migration#linker-file) in the TrustZone platform examples are based on the Series 2 radio board with minimum flash (512 kB) and RAM (32 kB), so these configurations can run on all Series 2 radio boards. Users can customize the settings when more flash and RAM are available on the selected device.

- Memory flash size (total) = `memory_flash_size` (S) + `memory_flash_size` (NS) = 512 kB
- Memory RAM size (total) = `memory_ram_size` (S) + `memory_ram_size` (NS) = 32 kB

###### Secure Application

The project description file of the Secure application (`*_s.slcp`) uses the default memory setting below to generate the [Secure linker file](06-r-migration) (linkerfile.ld for GCC and linkerfile.icf for IAR in the project autogen folder).

The actual memory usage during software development is unknown, so it needs to reserve enough flash (`memory_flash_size`: 176 kB) and RAM (`memory_ram_size`: 12 kB) for the Secure part of all TrustZone platform examples. The bigger RAM size (including stack and heap) is mainly for the software fallback on cryptographic operations in PSA Crypto.

<table>
    <thead>
        <tr>
            <th>Default Memory Setting (Secure)</th>
            <th>xG21 and xG22 Devices</th>
            <th>Other Series 2 Devices</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>memory_flash_start</p>
            </td>
            <td>
                <p>0x00000000</p>
            </td>
            <td>
                <p>0x08000000</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_flash_size</p>
            </td>
            <td>
                <p>0x0002C000 (176 kB)</p>
            </td>
            <td>
                <p>0x0002C000 (176 kB)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_ram_start</p>
            </td>
            <td>
                <p>0x20000000</p>
            </td>
            <td>
                <p>0x20000000</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_ram_size</p>
            </td>
            <td>
                <p>0x00003000 (12 kB)</p>
            </td>
            <td>
                <p>0x00003000 (12 kB)</p>
            </td>
        </tr>
    </tbody>
</table>

```C

 MEMORY
 {
   FLASH   (rx)  : ORIGIN = 0x0, LENGTH = 0x2c000
   RAM     (rwx) : ORIGIN = 0x20000000, LENGTH = 0x3000
 }

```

###### Non-secure Application

The project description files of the Non-secure application (*_ns.slcp) use the default memory setting below to generate the [Non-secure linker file](06-r-migration) (linkerfile.ld for GCC and linkerfile.icf for IAR in the project autogen folder).

The actual memory usage during software development is unknown, so the remaining flash (`memory_flash_size`: 336 kB) and RAM (`memory_ram_size`: 20 kB) should be big enough for the Non-secure part of all TrustZone platform examples.

<table>
    <thead>
        <tr>
            <th>Default Memory Setting (Non-secure)</th>
            <th>xG21 and xG22 Devices</th>
            <th>Other Series 2 Devices</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>memory_flash_start</p>
            </td>
            <td>
                <p>0x0002C000 (176 kB)</p>
            </td>
            <td>
                <p>0x0802C000 (176 kB)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_flash_size</p>
            </td>
            <td>
                <p>0x00054000 (336 kB)</p>
            </td>
            <td>
                <p>0x00054000 (336 kB)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_ram_start</p>
            </td>
            <td>
                <p>0x20003000 (12 kB)</p>
            </td>
            <td>
                <p>0x20003000 (12 kB)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>memory_ram_size</p>
            </td>
            <td>
                <p>0x00005000 (20 kB)</p>
            </td>
            <td>
                <p>0x00005000 (20 kB)</p>
            </td>
        </tr>
    </tbody>
</table>

```C

 MEMORY
 {
   FLASH   (rx)  : ORIGIN = 0x2c000, LENGTH = 0x54000
   RAM     (rwx) : ORIGIN = 0x20003000, LENGTH = 0x5000
 }

```

> **Note**: The usable flash for Non-secure code should be equal to `memory_flash_size` - `NVM size` (default is 40 kB) if NVM3 storage is required.

###### Memory Editor

The default memory setting of [Secure](#secure-application) and [Non-secure](#non-secure-application) applications are good enough for software development and debugging. The final memory layouts of Secure and Non-secure projects are deduced by inspecting the flash and RAM usage in the Secure application memory map file (.map).

The [Memory Editor](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-getting-started/start-a-project#memory-editor) in Simplicity Studio 5 is a graphical tool for editing the memory layout (flash and RAM) of the applications in the workspace. The Memory Editor will update the linker file in the project `autogen` folder with the custom settings. [Rebuild](#build) the projects to use the new memory configurations in the linker files.

The Memory Editor is located at the **Quick Links** and **CONFIGURATION TOOLS** of Secure or Non-secure `slcp` file.

![quick_links](/series2-trustzone/0.2/images/sld717-quick-links.png)

![conf_tools](/series2-trustzone/0.2/images/sld717-conf-tools.png)

The following items will be determined by the flash usage in the Secure application memory map file:

- memory_flash_size (S)
- memory_flash_start (NS)
- memory_flash_szie (NS)

![memory_edit_flash](/series2-trustzone/0.2/images/sld717-memory-edit-flash.png)

> **Note**: The Memory Editor in Simplicity Studio v5.6.3.0 can only adjust the flash size in **8 kB** (page size) alignment, which may not fit the [4kB alignment](06-r-migration) between the Secure and Non-secure flash boundary.

The following items will be determined by the RAM usage in the Secure application memory map file:

- memory_ram_size (S)
- memory_ram_start (NS)
- memory_ram_szie (NS)

![memory_edit_ram](/series2-trustzone/0.2/images/sld717-memory-edit-ram.png)

##### Build

The Secure project must be built first to create the Secure object library (trustzone_secure_library.o) with function entries for the Non-secure project. Both projects need to be rebuilt if any changes in the Secure project. Users can use Simplicity IDE in Simplicity Studio 5 or IAR EWARM v9.20.4 to build the TrustZone platform examples.

###### Simplicity IDE

The following procedures are based on the **TrustZone PSA Crypto ECDH** example on BRD4182A Radio Board (EFR32MG22C224F512IM40).

1. Use the `tz_psa_crypto` keyword to search in **EXAMPLE PROJECTS & DEMOS** tab. Select the **`tz_psa_crypto_ecdh_ws`** example.

![tz_gcc_search_ws](/series2-trustzone/0.2/images/sld717-tz-gcc-search-ws.png)
2. Click **[CREATE]** to generate the [solution](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-developing-with-project-configurator/project-solutions).

![./resources/sld717-tz_ecdh](/series2-trustzone/0.2/images/sld717-tz-ecdh.png)
3. The **Project Configuration** dialog shows the Secure and Non-secure projects in the target solution. Click **[FINISH]** to start the creation process.

![tz_gcc_proj_conf](/series2-trustzone/0.2/images/sld717-tz-gcc-proj-conf.png)
4. The Simplicity IDE perspective opens after finishing the solution creation. Click **Build** on the Simplicity IDE perspective toolbar to build the projects of a selected solution in order (Secure then Non-secure).

![tz_gcc_build](/series2-trustzone/0.2/images/sld717-tz-gcc-build.png)
5. The post-build actions (`.slpb` files) of the Secure project, Non-secure project, and workspace will be processed in sequence if the solution is successfully built. The combined image (tz_psa_crypto_ecdh_ws-combined.s37) in the Secure project artifact folder can be used for programming the device or debugging.

![tz_gcc_combine](/series2-trustzone/0.2/images/sld717-tz-gcc-combine.png)
6. Use [Memory Editor](#memory-editor) to finalize the memory layouts of Secure and Non-secure applications and rebuild the solution to update the memory configurations.

> **Note**: The Simplicity IDE can only apply the post-build action to a particular project if multiple Secure or Non-secure projects exist in the solution.

###### IAR EWARM

The following procedures are based on the **TrustZone PSA Crypto ECDH** example on BRD4181A Radio Board (EFR32MG21A010F1024IM32).

1. Follow steps 1 to 3 in [TrustZone PSA Crypto ECDH](#simplicity-ide) to generate the solution for the `tz_psa_crypto_ws`. Select the `tz_psa_crypto_ecdh_s.slcp` file.
2. The **Overview** tab shows the **Target and Tool Settings** card on the left side. Scroll down if necessary and click **[ChangeTarget/SDK/Generators]**.

![tz_iar_s_change](/series2-trustzone/0.2/images/sld717-tz-iar-s-change.png)
3. Drop down the **CHANGE PROJECT GENERATORS** list and select **IAR Embedded Workbench Project**.

![tz_iar_s_select](/series2-trustzone/0.2/images/sld717-tz-iar-s-select.png)
4. Click **[Save]** to generate an IAR **Secure** project (tz_psa_crypto_ecdh_s.ewp).

![tz_iar_s_save](/series2-trustzone/0.2/images/sld717-tz-iar-s-save.png)
5. Select the `tz_psa_crypto_ecdh_ns.slcp` file. Repeat steps 2 to 4 to generate an IAR **Non-secure*** project (tz_psa_crypto_ecdh_ns.ewp).
6. Use a text editor to create an IAR tz_psa_crypto_ecdh_ws.ewwfile (shown below) to house the projects (tz_psa_crypto_ecdh_s.ewpand tz_psa_crypto_ecdh_ns.ewp) generated in steps 4 and 5. The location of the tz_psa_crypto_ecdh_ws.eww is the directory for WS_DIR.

```C

<?xml version ="1.0" encoding="iso-8859-1"?>
<workspace>
  <project>
    <path>$WS_DIR$\tz_psa_crypto_ecdh_s\tz_psa_crypto_ecdh_s.ewp</path>
  </project>
  <project>
    <path>$WS_DIR$\tz_psa_crypto_ecdh_ns\tz_psa_crypto_ecdh_ns.ewp</path>
  </project>
  <batchBuild/>
</workspace>

```

![./resources/sld717-tz_iar_folder](/series2-trustzone/0.2/images/sld717-tz-iar-folder.png)
7. Double-click the tz_psa_crypto_ecdh_ws.ewwfile to open the workspace that includes Secure and Non-secure projects.
![./resources/sld717-tz_iar_ws](/series2-trustzone/0.2/images/sld717-tz-iar-ws.png)
8. Click the tz_psa_crypto_ecdh_s tab to open the Secure project. Click ![tz_iar_make_icon](/series2-trustzone/0.2/images/sld717-tz-iar-make-icon.png) (Make) to build. It exports the Secure object library (trustzone_secure_library.o) for function entries that will be used by the Non-secure project.

![tz_iar_s](/series2-trustzone/0.2/images/sld717-tz-iar-s.png)
9. Click the tz_psa_crypto_ecdh_ns tab to open the Non-secure project.

![./resources/sld717-tz_iar_ns](/series2-trustzone/0.2/images/sld717-tz-iar-ns.png)
10. The [`SL_TRUSTZONE_NONSECURE`](06-r-migration#peripheral-addresses-in-device-header-files) defined in the Non-secure project disables the [CMSE compiler option](06-r-migration#startup-code) (`--cmse`) regardless of whether the **Project → Options... → General Options → 32-bit → TrustZone → Mode:** setting is Secure or Non-secure. So changing this configuration from Secure to Non-secure is optional. Click **[OK]** to exit.

![tz_iar_select_ns](/series2-trustzone/0.2/images/sld717-tz-iar-select-ns.png)
11. Click ![tz_iar_make_icon](/series2-trustzone/0.2/images/sld717-tz-iar-make-icon.png) (Make) to build the Non-secure project. The post-build actions of the workspace (tz_psa_crypto_ecdh_ws.slpb) will be triggered in IAR to combine the Secure and Non-secure images (tz_psa_crypto_ecdh_ws-combined.s37) to the artifact folder of `tz_psa_crypto_ecdh_s` for programming the device.

![tz_iar_combine](/series2-trustzone/0.2/images/sld717-tz-iar-combine.png)
12. Use [Memory Editor](#memory-editor) to finalize the memory layouts of Secure and Non-secure applications and rebuild the Secure and Non-secure projects to update the memory configurations.

> **Note**: The IAR EWARM can only apply the workspace post-build action to a particular project if multiple Secure or Non-secure projects exist in the workspace.

##### Debugging

Users can use Simplicity IDE in Simplicity Studio 5 or IAR EWARM v9.20.4 to debug the TrustZone platform examples. Building the projects with Optimization Level None (-O0) is recommended for debugging.

###### Simplicity IDE

The TrustZone debugging process on Simplicity IDE is similar to the existing sample projects in Simplicity Studio.

1. [GNU Debugger (GDB)](06-r-migration#debugger) is recommended to debug TrustZone applications.
2. Flash the combined image (tz_psa_crypto_ecdh_ws-combined.s37) generated in [Simplicity IDE](#simplicity-ide) to the device.
3. Select the Secure or Non-secure project and use the **Debug** icon to launch a debug session.

![gcc_debug_launch](/series2-trustzone/0.2/images/sld717-gcc-debug-launch.png)
4. Follow the instructions in the **[Using the Debugger](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-testing-and-debugging/using-the-debugger)** section in Simplicity Studio 5 User's Guide to debug the Secure or Non-secure application.
5. The debugger cannot step into the function in a Non-secure application when debugging the Secure application and vice versa. Use the **Program Counter** (PC in Secure or Non-secure address) in the **Registers** window to determine the program status.

![gcc_debug_state](/series2-trustzone/0.2/images/sld717-gcc-debug-state.png)

###### IAR EWARM

Use the tz_psa_crypto_ecdh_ws.eww workspace created in [IAR EWARM](#iar-ewarm) for the debugger settings. Except for a minor difference in step 3, the following steps are the same as those to set up the Secure (tz_psa_crypto_ecdh_s) and Non-secure (tz_psa_crypto_ecdh_ns) projects for debugging.

1. Select **Options...** in the ![tools_menu](/series2-trustzone/0.2/images/sld717-tools-menu.png) context menu of the Secure or Non-secure project and open the **IDE Options → Stack** dialog. Uncheck the **Stack pointer(s) not valid until program reaches*** checkbox. Click **[OK]** to exit.

![uncheck_stack](/series2-trustzone/0.2/images/sld717-uncheck-stack.png)
2. Select **Options...** in the ![project_menu](/series2-trustzone/0.2/images/sld717-project-menu.png) context menu of the Secure or Non-secure project and open the window for **Debugger** options. Click the **Setup** tab to open a dialog, and uncheck the **Run to → main** checkbox. Click the **Images** tab to set up another option.

![uncheck_main](/series2-trustzone/0.2/images/sld717-uncheck-main.png)
3. Check the **ownload extra image** option. Enter the location of the .out file to **Path:** with **Offset:** set to 0. All project relative paths are resolved from the directory location of the tz_psa_crypto_ecdh_ws.eww workspace file.

Location of Non-secure .out file for Secure project: tz_psa_crypto_ecdh_ns\ewarm-iar\exe\tz_psa_crypto_ecdh_ns.out

![set_image_s](/series2-trustzone/0.2/images/sld717-set-image-s.png)

Location of Secure .out file for Non-secure project: tz_psa_crypto_ecdh_s\ewarm-iar\exe\tz_psa_crypto_ecdh_s.out

![set_image_ns](/series2-trustzone/0.2/images/sld717-set-image-ns.png)
4. Click the **Extra Options** tab to set up another option.
5. Check the **Use command line options**. Enter --drv_vector_table_base=0x00000000 to **Command line options: (one per line)** window. Click **[OK]** to exit.

![set_extra](/series2-trustzone/0.2/images/sld717-set-extra.png)
6. Finish the debug settings in Secure and Non-secure projects, and click ![debug_icon](/series2-trustzone/0.2/images/sld717-debug-icon.png) (Download and Debug) in the Secure or Non-secure project to download the Secure and Non-secure images for debugging (assume both projects had successfully [built](#iar-ewarm) before). Click ![go_icon](/series2-trustzone/0.2/images/sld717-go-icon.png) (Go) to start running the code in a Secure or Non-secure project.
7. The debugger will automatically switch between Secure and Non-secure projects when stepping into a function or hitting a breakpoint in a Secure or Non-secure project. Use the **Program Counter** (PC in Secure or Non-secure address) or **SECURE** (0 or 1) in the **Registers** window to determine the program status.

![debug_state](/series2-trustzone/0.2/images/sld717-debug-state.png)
8. Click ![stop_icon](/series2-trustzone/0.2/images/sld717-stop-icon.png) (Stop Debugging) to end the debug session.

##### Benchmark

The TrustZone implementation will affect the memory footprint and performance of cryptographic operations. The following comparisons are based on the **TrustZone PSA Crypto ECDH** example on BRD4182A Radio Board (EFR32MG22C224F512IM40) with SE firmware v1.2.14.

###### Memory Footprint

The memory footprint of a TrustZone project depends on which services (software components in the figure below) provided by the [Secure Library](05-r-implementation) are used in the Non-secure application (`tz_psa_crypto_ecdh_ns` project).

![tz_nonsecure_component](/series2-trustzone/0.2/images/sld717-tz-nonsecure-component.png)

The following tables compare the memory footprint of the [TrustZone-unaware](06-r-migration#startup-code) (`Platform - PSA Crypto ECDH`) and [TrustZone-aware](07-r-ex#memory-configuration) projects (`tz_psa_crypto_ecdh_ws`) based on the following conditions.

- The `tz_psa_crypto_ecdh_ns` reuses the source code from the `Platform - PSA Crypto ECDH` example without any changes.
- The total size in `tz_psa_crypto_ecdh_ns` does not consider the [4 kB alignment](06-r-migration) on the Secure and Non-secure flash and RAM. The 4 kB alignment requirement will increase the actual usage of flash and RAM.
- All source code is compiled with Optimize for size (-Os) in Simplicity IDE (GNU ARM v10.3.1) of Simplicity Studio 5.

**Table**: Flash Size Comparison

<table>
    <thead>
        <tr>
            <th>Platform Example</th>
            <th>Secure</th>
            <th>NSC</th>
            <th>Non-secure</th>
            <th>Total</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Platform - PSA Crypto ECDH</p>
            </td>
            <td>
                <p>64688 B</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>64688 B</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>tz_psa_crypto_ecdh_ws</p>
            </td>
            <td>
                <p>79172 B</p>
            </td>
            <td>
                <p>288 B</p>
            </td>
            <td>
                <p>29264 B</p>
            </td>
            <td>
                <p>108724 B</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The NSC is part of the Secure code, and the total size does not include the flash for NVM3 storage.

**Table**: RAM Size Comparison

<table>
    <thead>
        <tr>
            <th>Platform Example</th>
            <th>Secure</th>
            <th>NSC</th>
            <th>Non-secure</th>
            <th>Total</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Platform - PSA Crypto ECDH</p>
            </td>
            <td>
                <p>3784 B</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>3764 B</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>tz_psa_crypto_ecdh_ws</p>
            </td>
            <td>
                <p>2156 B</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>1200 B</p>
            </td>
            <td>
                <p>3356 B</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The total size does not include the RAM for the stack and heap. The Secure and Non-secure applications have their independent stack and heap.

###### PSA Crypto Performance

The following sections compare the PSA Crypto performance of the [TrustZone-unaware](06-r-migration) (`Platform - PSA Crypto ECDH`) and [TrustZone-aware](#memory-configuration) projects (`tz_psa_crypto_ecdh_ws`) based on the following conditions.

- The `tz_psa_crypto_ecdh_ns` reuses the source code from the `Platform - PSA Crypto ECDH` example without any changes.
- All source code is compiled with Optimize most (-O3) in Simplicity IDE (GNU ARM v10.3.1) of Simplicity Studio 5.
- Use ECC curve `SECP256R1` on volatile and persistent keys.
- The EFR32MG22C224 runs at 38 MHz HFRCODPLL.

###### Volatile key ECDH operation on `Platform - PSA Crypto ECDH` (heading level 7)

```C

  . ECDH Client
  + Creating a SECP256R1 (256-bit) VOLATILE PLAIN client key... PSA_SUCCESS (cycles: 2928 time: 77 us)
  + Creating a SECP256R1 (256-bit) VOLATILE PLAIN server key... PSA_SUCCESS (cycles: 2960 time: 77 us)
  + Exporting a public key of a SECP256R1 (256-bit) VOLATILE PLAIN server key... PSA_SUCCESS (cycles: 332134 time: 8740 us)
  + Computing client shared secret with a SECP256R1 (256-bit) server public key... PSA_SUCCESS (cycles: 336860 time: 8864 us)

```

###### Volatile key ECDH operation on `tz_psa_crypto_ecdh_ws` (heading level 7)

```C

  . ECDH Client
  + Creating a SECP256R1 (256-bit) VOLATILE PLAIN client key... PSA_SUCCESS (cycles: 5047 time: 132 us)
  + Creating a SECP256R1 (256-bit) VOLATILE PLAIN server key... PSA_SUCCESS (cycles: 5067 time: 133 us)
  + Exporting a public key of a SECP256R1 (256-bit) VOLATILE PLAIN server key... PSA_SUCCESS (cycles: 333956 time: 8788 us)
  + Computing client shared secret with a SECP256R1 (256-bit) server public key... PSA_SUCCESS (cycles: 338470 time: 8907 us)

```

###### Persistent key ECDH operation on `Platform - PSA Crypto ECDH` (heading level 7)

```C

  . ECDH Client
  + Creating a SECP256R1 (256-bit) PERSISTENT PLAIN client key... PSA_SUCCESS (cycles: 27489 time: 723 us)
  + Creating a SECP256R1 (256-bit) PERSISTENT PLAIN server key... PSA_SUCCESS (cycles: 27587 time: 725 us)
  + Exporting a public key of a SECP256R1 (256-bit) PERSISTENT PLAIN server key... PSA_SUCCESS (cycles: 332949 time: 8761 us)
  + Computing client shared secret with a SECP256R1 (256-bit) server public key... PSA_SUCCESS (cycles: 337803 time: 8889 us)

```

###### Persistent key ECDH operation on `tz_psa_crypto_ecdh_ws` (heading level 7)

```C

  . ECDH Client
  + Creating a SECP256R1 (256-bit) PERSISTENT PLAIN client key... PSA_SUCCESS (cycles: 46998 time: 1236 us)
  + Creating a SECP256R1 (256-bit) PERSISTENT PLAIN server key... PSA_SUCCESS (cycles: 45962 time: 1209 us)
  + Exporting a public key of a SECP256R1 (256-bit) PERSISTENT PLAIN server key... PSA_SUCCESS (cycles: 334127 time: 8792 us)
  + Computing client shared secret with a SECP256R1 (256-bit) server public key... PSA_SUCCESS (cycles: 338321 time: 8903 us)

```

The overheads on the TrustZone-aware project (`tz_psa_crypto_ecdh_ws`) are due to the following operations of [Secure Library](05-r-implementation) implementation.

- Packages the list of input arguments in the appropriate format before calling into the NSC function.
- Switches from a Non-secure to a Secure state.
- Validates all input arguments before calling into the function in SPE.
- Encrypts PSA ITS if using a persistent key.
- Returns to a Non-secure state.

### Production Programming of Series 2 and Series 3 Devices

#### Production Programming of Series 2 and Series 3 Devices

> **Note: This section replaces _AN1222: Production Programming of Series 2 and Series 3 Devices_. Further updates to this application note will be provided here**.

This application note demonstrates how to properly program, provision, and configure Series 2 and Series 3 devices in a production environment.

Series 2 and Series 3 devices contain a Secure Engine, which runs Secure Engine firmware. When a newer version of Secure Engine firmware is released, the firmware may be upgraded either in the production programming process for devices still in manufacturing or via a field update for deployed devices. Keys must be provisioned to the Secure Engine's one-time-programmable (OTP) memory to use the Secure Boot and Secure Debug features.

For more information about Secure Engine, see [Secure Engine Subsystem](https://docs.silabs.com/iot-security/latest/series2-secure-debug/03-secure-engine-subsystem) in _Series 2 and Series 3 Secure Debug_.

##### Key Points

- It is the customer's responsibility to ensure the Secure Engine firmware is up-to-date
- The Secure Engine firmware can be upgraded via the Serial Wire Debug (SWD) interface
- Secure Engine firmware is protected from downgrade
- Secure Engine's OTP memory prevents re-writing of:  
  - GBL Decryption Key  
  - Public Sign Key  
  - Public Command Key  
  - Secure Boot Enable flag and Tamper Configuration

#### Series 2 and Series 3 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this application note, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

On Series 3 devices, the security features are implemented by the Secure Engine and SYMCRYPTO (if available). The Secure Engine is hardware-based.

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level (1)**|**SE Support**|**Part (2)**|
|---|---|---|
|Series 3|Series 3 Secure Vault|Refer to (2) for details on supporting devices.|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|“|
|Secure Vault Mid (SVM)|HSE (HSE-SVM)|"|
|"|VSE (VSE-SVM)|"|
|Secure Vault Base (SVB)|N/A|"|

> **Notes**:
> 
> 1. The features of different Secure Vault levels can be found in the [Silicon Labs IoT Security](https://docs.silabs.com/iot-security/latest/iot-security-start/) documentation site.
> 2. [Device Security Features](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/11-series-2-and-series-3-device-security-features).

Secure Vault Mid consists of two core security functions:

- Secure Boot: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- Secure Debug access control: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- Secure Key Storage: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- Anti-Tamper protection: A configurable module to protect the device against tamper attacks.
- Device authentication: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

Series 3 Secure Vault offers the same features as Secure Vault High, except

- Device identity certificates are only installed for the SE, not the host core
- Support for AXiP/EXiP is added

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products, Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Production Programming of Series 2 and Series 3 Devices (this application note)</p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|
|AXiP Key|No|Used on Series 3 devices for encryption/decryption and authentication of firmware placed in flash|
|EXiP Key|No|Used on Series 3 devices for encryption/decryption of firmware placed in flash|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 and Series 3 devices and modules.

#### Overview

More steps are involved in the production programming process of Series 2 and Series 3 devices compared to Series 1 devices. The steps vary if the device is to have Secure Boot enabled or disabled. For more information about Secure Boot, see [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/). Enabling Secure Debug is a recommended step in the process. For more information about Secure Debug, see [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

A general overview of the production programming steps is described in the following sections.

Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://docs.silabs.com/iot-security/latest/iot-security-cpms/) to customize the users' security features and settings.

##### Production Programming for Secure Boot-Disabled Device

The following figure illustrates the production programming flow for Secure Boot-disabled devices. It is possible to upgrade Series 2 and Series 3 devices deployed in the field without Secure Boot to Secure Boot with RTSL.

![Series 2 and Series 3 High-Level Production Programming Flowchart for Secure Boot-Disabled Devices](/prod-programming-series2-and-series3/0.2/images/sld952-prod-program-flowchart.png)

Upgrading the SE Firmware and flashing the bootloader and application firmware are required in the production programming process. Provisioning the GBL Decryption Key for GBL payload decryption, Public Sign Key for Secure Boot, Public Command Key for Secure Debug Unlock, and enabling the Debug Lock are strongly recommended.

A more detailed version of the Series 2 and Series 3 production programming flowchart for a Secure Boot-disabled device is illustrated in the following figure.

![Series 2 and Series 3 Step-by-Step Production Programming Flowchart for a Secure Boot-Disabled Device](/prod-programming-series2-and-series3/0.2/images/sld952-prod-program-stepbystep-flowchart.png)

**Notes**:

1. Refer to [Provisioning the GBL Decryption Key in Simplicity Commander](07-key-provisioning#provisioning-the-gbl-decryption-key-in-simplicity-commander) on how to program the GBL Decryption Key to the Series 2 or Series 3 device.
2. The VSE devices store a Public Sign Key copy on the top page of the main flash for Secure Boot (see _Signing for ECDSA-P256-SHA256 Secure Boot_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)).
3. The Public Command Key can also be used to temporarily disable anti-tamper protection on HSE-SVH devices (see [Anti-Tamper Protection Configuration and Use](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/)).
4. Enabling the debug lock should be the final step in production, and the following debug lock options are available on Series 2 and Series 3 devices.  
   - [Standard Debug Lock](10-enabling-debug-lock#standard-debug-lock)  
   - [Secure Debug Lock](10-enabling-debug-lock#secure-debug-lock) (Public Command Key was provisioned)  
   - [Permanent Debug Lock](10-enabling-debug-lock#permanent-debug-lock)  
   For more information about these debug lock options, see the section _Debug Lock State Transition_ in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).
5. For Series 3, the final  step is to close all code regions. See [_Bootloader Firmware Programming](05-bootloader-firmware-programming) and [Application Firmware Programming](06-application-firmware-programming) for instructions.

##### Production Programming for Secure Boot-Enabled Device

The following figure illustrates the production programming flow for Secure Boot-enabled devices.

![Series 2 and Series 3 High-Level Production Programming Flowchart for Secure Boot-Enabled Devices](/prod-programming-series2-and-series3/0.2/images/sld952-high-level-prod-program-flow-secureboot-enabled.png)

Upgrading the SE Firmware and flashing the **SIGNED** bootloader and application firmware are required in the production programming process. Provisioning the Public Sign Key and enabling Secure Boot are also needed in the production programming process to enable the Secure Boot option. Provisioning the GBL Decryption Key for GBL payload decryption, Public Command Key for Secure Debug Unlock, and enabling the Debug Lock are strongly recommended. Provisioning Tamper Configuration (HSE-SVH and Series 3 Secure Vault only) is also recommended.

A more detailed version of the Series 2 and Series 3 production programming flowchart for a Secure Boot-enabled device is illustrated in the following figure.

![Series 2 and Series 3 High-Level Production Programming Flowchart for Secure Boot-Enabled Devices](/prod-programming-series2-and-series3/0.2/images/sld952-stepbystep-prod-program-flow-secureboot-enabled.png)

**Notes**:

1. The device will enter the Secure Boot failed state if the bootloader firmware is either unsigned or incorrectly signed (see [Bootloader Firmware Programming](05-bootloader-firmware-programming)).
2. If the Secure Boot option is enabled in the bootloader, the application firmware must be signed (see [Application Firmware Programming](06-application-firmware-programming)).
3. The VSE devices store a Public Sign Key copy on the top page of the main flash for Secure Boot (see section _Signing for ECDSA-P256-SHA256 Secure Boot_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)).
4. On HSE-SVH and Series 3 Secure Vault devices, the anti-tamper protection configuration is provisioned with Secure Boot settings (see [Enabling Secure Boot and Tamper Configuration](09-enabling-secure-boot-and-tamper-configuration)).
5. Refer to [Provisioning the GBL Decryption Key in Simplicity Commander](07-key-provisioning#provisioning-the-gbl-decryption-key-in-simplicity-commander) on how to program the GBL Decryption Key to Series 2 or Series 3 devices.
6. The Public Command Key can also be used to temporarily disable anti-tamper protection on HSE-SVH devices (see [Anti-Tamper Protection Configuration and Use](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/)).
7. Enabling the debug lock should be the final step in production, and the following debug lock options are available on the Series 2 device.  
   - [Standard Debug Lock](10-enabling-debug-lock#standard-debug-lock)  
   - [Permanent Debug Lock](10-enabling-debug-lock#permanent-debug-lock)  
   - [Secure Debug Lock](10-enabling-debug-lock#secure-debug-lock) (Public Command Key was provisioned)  
   For more information about these debug lock options, see the section _Debug Lock State Transition_ in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).
8. For Series 3, the final step is to close all code regions. See [Bootloader Firmware Programming](05-bootloader-firmware-programming) and [Application Firmware Programming](06-application-firmware-programming) for instructions.

#### Using Simplicity Commander

1. This application note uses Simplicity Commander v1.19.2. The procedures and console output may be different for the other versions of Simplicity Commander. The latest version of Simplicity Commander can be downloaded from [https://www.silabs.com/developers/mcu-programming-options](https://www.silabs.com/developers/mcu-programming-options).  
   ```sh  
   commander --version  
   ```  
   ```sh  
   Simplicity Commander 1v19p2b1907  
     
   JLink DLL version: 8.44  
     
   Qt 5.15.2 Copyright (C) 2017 The Qt Company Ltd.  
     
   EMDLL Version: 0v19p19b793  
     
   mbed TLS version: 2.16.6  
     
   Emulator found with SN=440329507 USBAddr=0  
     
   DONE  
   ```
2. The Simplicity Commander's Command Line Interface (CLI) is invoked by `commander.exe` in the Simplicity Commander folder. The location for Simplicity Studio 5 in Windows is `C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\commander`. For ease of use, it is highly recommended to add the path of `commander.exe` to the system PATH in Windows.
3. If more than one Wireless Starter Kit (WSTK) is connected via USB, the target WSTK must be specified using the `--serialno <J-Link serial number>` option.
4. If the WSTK is in debug mode OUT, the target device must be specified using the `--device <device name>` option. For more information about Simplicity Commander, see [Simplicity Commander Reference Guide](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/).

#### SE Firmware Programming

##### Overview

Consistent with best practices for Internet of Things (IoT) security, the SE Firmware provided with Series 2 and Series 3 devices supports secure firmware updates. Silicon Labs will periodically release new versions of the SE Firmware to fix bugs and patch vulnerabilities, which may require updates to devices on the manufacturing line or to devices already in the field.

Silicon Labs operates under a **Security as a Shared Responsibility Model**. This model provides flexibility to system integrators to manage SE Firmware security updates on their own timetable based on their product's use case, risk assessment, agility of their manufacturing flow, and the agility of their field firmware deployment flow.

Series 2 and Series 3 devices are rarely shipped with the latest SE Firmware installed, meaning system integrators must add SE Firmware programming to their production programming flow.

In all cases, Silicon Labs recommends that system integrators:

Subscribe to security notifications by managing their notification settings in the Silicon Labs Support Portal. This is the easiest method to be notified of SE Firmware updates and discovered vulnerabilities.

Instructions for subscribing to notifications can be found here [https://community.silabs.com/s/article/get-notified-when-a-document-changes](https://community.silabs.com/s/article/get-notified-when-a-document-changes)

- Ensure they are installing the latest SE Firmware release in their manufacturing line.
- Be prepared to deploy [security-related field updates](11-field-upgrade-the-se-firmware) to devices in the field.

##### How to Check the SE Firmware Version on a Device

The SE Firmware version of the device can be found in two ways.

- Simplicity Studio
- Simplicity Commander

This application note mainly uses Simplicity Commander.

###### Check the SE Firmware Version Using Simplicity Commander

To check the SE Firmware version on the device, issue the Simplicity Commander `security status` command.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Disabled
Device erase	    : Enabled
Secure debug unlock : Disabled
Tamper status	    : OK
Secure boot	        : Disabled
Boot status	        : 0x20 - OK
DONE
```

In this example, the SE Firmware version on the EFR32MG21A is 1.2.14.

##### How to Find the Latest SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. The latest SE firmware image (`.seu` or `.seuv2` and `.hex`) and release notes can be found in the Windows folder below.

For GSDK v3.2 and lower:

`C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION>\util\se_release\public`

For GSDK v4.0 and higher:

`C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public`

For Simplicity SDK

`C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\simplicity_sdk\util\se_release\public`

##### Serial Wire Debug (SWD)

The SE Firmware cannot be directly programmed to the SE using the SWD interface. Instead, an image containing the loader application and SE Firmware is flashed onto the host MCU. The SE Firmware is encrypted, versioned, and signed.

![SWD SE Firmware Upgrade Block Diagram](/prod-programming-series2-and-series3/0.2/images/sld952-swd-se-firmware-upgrade-diagram.png)

Using the SWD interface, the user flashes the loader application onto the host. The host then runs the loader application, which checks the signature and version of the SE Firmware. If the signature check passes and the upgrade's version number is higher than the device's SE Firmware version, the firmware is applied to the SE.

The upgrade will not be applied if the signature check fails or if the upgrade's version number is less than or equal to the device's SE Firmware version. Trying to apply a lower SE Firmware version to the device does no harm, but the upgrade will be ignored. This also means the device's SE Firmware cannot be downgraded.

After the SE Firmware has been upgraded, the loader application can be overwritten with the application firmware via the SWD interface.

As detailed in diagrams in the [Overview](02-overview), the steps to upgrade the SE Firmware are:

1. Connect Hardware: Connect the device's SWD interface with the WSTK and ensure proper connections.
2. Check Version: Check the SE Firmware version already on the device.
3. Flash SE Firmware: Flash the loader application onto the host processor.
4. Run: Allow the loader application to run and install the SE Firmware.
5. Re-Check Version: Ensure the update succeeded.

Each of these steps is described in more detail in the next sections.

###### Connect Hardware

After connecting the device's SWD interface to the WSTK, try to read the device information using Simplicity Commander, to verify that proper connections were established to the device.

```sh
commander device info --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Part Number	   : EFR32MG21A010F1024IM32
Die Revision   : A1
Production Ver : 2
Flash Size	   : 1024 kB
SRAM Size	   : 96 kB
Unique ID      : 14b457fffe045a8e
DONE
```

###### Check Version

To check the SE Firmware version on the device, issue the Simplicity Commander `security status` command.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.13
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Disabled
Device erase	    : Enabled
Secure debug unlock : Disabled
Tamper status	    : OK
Secure boot	        : Disabled
Boot status	        : 0x20 - OK
DONE
```

**Notes**:

- The `Tamper status` item is device dependent.
- Updating SE firmware on Series 3 takes significantly longer than Series 2. If the SE firmware on your device is already up to date, skip the next step for efficiency.

###### Flash SE Firmware

To flash the SE Firmware upgrade application, run:

```sh
commander flash --masserase s2c1_se_fw_upgrade_app_1v2p14.hex --device EFR32MG21A010F1024 --serialno 440048205
```

where `s2c1_se_fw_upgrade_app_1v2p14.hex` is replaced with the name of the SE Firmware upgrade application file.

```sh
Parsing file s2c1_se_fw_upgrade_app_1v2p14.hex...
Erasing chip...
Flash was erased successfully
Writing 57344 bytes starting at address 0x00000000
Comparing range 0x00000000 - 0x0000DFFF (56 KB)
Programming range 0x00000000 - 0x00001FFF (8 KB)
Programming range 0x00002000 - 0x00003FFF (8 KB)
Programming range 0x00004000 - 0x00005FFF (8 KB)
Programming range 0x00006000 - 0x00007FFF (8 KB)
Programming range 0x00008000 - 0x00009FFF (8 KB)
Programming range 0x0000A000 - 0x0000BFFF (8 KB)
Programming range 0x0000C000 - 0x0000DFFF (8 KB)
DONE
```

###### Run

Allow the SE Firmware upgrade application to run for at least two seconds on Series 2 devices and for at least 10 seconds on Series 3 devices. After this time has elapsed, the SE Firmware should have been upgraded.

###### Re-Check Version

Run the `security status` command again to check the upgraded SE Firmware version.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Disabled
Device erase	    : Enabled
Secure debug unlock : Disabled
Tamper status	    : OK
Secure boot	        : Disabled
Boot status	        : 0x20 - OK
DONE
```

The version is now upgraded to 1.2.14.

#### Bootloader Firmware Programming

If Secure Boot is enabled, a **SIGNED** version of the bootloader firmware must be programmed to the flash.

Instructions on how to sign the bootloader firmware can be found in sections _Signing for ECDSA-P256-SHA256 Secure Boot_ and _Signing for Certificate-Based Secure Boot_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/).

The bootloader starting address is device dependent. For more information about the bootloader starting address, see [Memory Space for Bootloading](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/03-memory-space-for-bootloading).

Flashing the bootloader firmware using Simplicity Commander is similar to flashing the SE Firmware upgrade application.

```sh
commander flash --masserase <bootloader file> --device <device name> --serialno <J-Link serial number>
```

where `<bootloader file>` is the name of the bootloader firmware file.

For TrustZone-aware bootloaders, the `<bootloader file>` is the combined image of Secure and Non-secure bootloaders. To check the Boot status of the device, run the security status command.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Disabled
Device erase	    : Enabled
Secure debug unlock : Disabled
Tamper status	    : OK
Secure boot	        : Disabled
Boot status	    : 0x20 - OK
DONE
```

Any Boot status other than `0x20 – OK` indicates that the secure boot process has failed. It means the bootloader firmware is either unsigned or incorrectly signed. The only way to recover is to flash a correctly-signed image (see section _Recover Devices when Secure Boot Fails_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)).

For Series 3, make sure that code region 0 is closed.

```sh
commander security readregionconfig -d sixg301
```

```sh
Index        : 0
Size         : 32 kB
Protection   : Encrypted and authenticated
Closed       : False

Index        : 1
Size         : 1984 kB
Protection   : Encrypted and authenticated
Closed       : False

DONE
```

To close region 0, run the following command:

```sh
commander security closeregion 0 -d sixg301
```

> **Note**: the default behavior of the commander flash command is to close regions once programming is complete.

```sh
Successfully closed code region 0 (version 0x00000000)
DONE
```

#### Application Firmware Programming

If the Secure Boot option is enabled in the bootloader, a **SIGNED** version of the application firmware must be programmed to the flash.

Instructions on how to sign the application firmware can be found in sections _Signing for ECDSA-P256-SHA256 Secure Boot_ and _Signing for Certificate-Based Secure Boot_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/).

The application firmware starting address is device dependent. For more information about the application starting address, see section _Memory Space For Bootloading_ in [Bootloader Fundamentals](https://docs.silabs.com/mcu-bootloader/latest/bootloader-fundamentals/).

Flashing the application firmware using Simplicity Commander is similar to flashing the SE Firmware upgrade application.

```sh
commander flash <application file> --device <device name> --serialno <J-Link serial number>
```

where `<application file>` is the name of the application firmware file.

For TrustZone-aware applications, the `<application file>` is the combined image of Secure and Non-secure applications.

> **Note**: Do not use the `--masserase` option to flash the application firmware since it will erase the bootloader at the starting address.

For Series 3 devices, make sure that  all code regions are closed

```sh
commander security closeregion 1 -d simg301
```

If the region was not previously closed, the command completes successfully:

```sh
Successfully closed code region 1 (version 0x00000000)
DONE
```

If the region was already closed, the response is as follows:

```sh
ERROR: DCI command failed due to: Invalid command
DONE
```

**Notes**:

1. The default configuration is for the entire application to reside in region 1, applications that use additional regions must close those regions as well.
2. The default behavior of the commander flash command is to close the region once programming is complete.

#### Key Provisioning

##### Overview

The symmetric GBL Decryption Key is used to decrypt GBL files. All encrypted GBL images on this device must be encrypted with the same 128-bit AES key. _Provisioning the GBL Decryption Key in Simplicity Commander_ below describes different ways to program the GBL Decryption Key to the Series 2 and Series 3 devices.

If the Secure Boot feature is to be used, the Public Sign Key must be provisioned to the device.

If the Secure Debug or tamper feature is to be used, the Public Command Key must be provisioned to the device.

The GBL Decryption Key (HSE device), Public Sign Key, and the Public Command Key are written to one-time-programmable (OTP) memory. Once written, they cannot be changed.

> **Note**: Silicon Labs strongly recommends provisioning these keys for future-proofing even if the device does not use the GBL Encryption, Secure Boot, and Secure Debug features.

##### Provisioning the GBL Decryption Key in Simplicity Commander

To generate the text file for the GBL Decryption Key, run the command:

```sh
commander util genkey --type aes-ccm --outfile aes_key.txt
```

```sh
Using Windows' Cryptographic random number generator
DONE
```

where `aes_key.txt` contains the randomly generated AES-128 key.

To write the GBL Decryption Key to the HSE device, run the command:

```sh
commander security writekey --decrypt aes_key.txt --device EFR32MG21A010F1024 --serialno 440048205
```

This command can be executed only once per device.

```sh
Device has serial number 000000000000000014b457fffe045a8e

================================================================================
Please look through any warnings before proceeding.
THIS IS A ONE-TIME command, any encrypting of GBL files must be done with this key.
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
DONE
```

> **Note**: The GBL Decryption Key cannot be read back from the HSE OTP.

To write the GBL Decryption Key to the `Application Properties` struct of the GBL, run the command:

```sh
commander convert bootloader-uart-xmodem.s37 --aeskey aes_key.txt --outfile bootloader-uart-xmodem.s37
```

```sh
Parsing file bootloader-uart-xmodem.s37...
Writing to bootloader-uart-xmodem.s37...
Overwriting file: bootloader-uart-xmodem.s37...
DONE
```

where `bootloader-uart-xmodem.s37` is the GBL image file.

**Notes**:

- The `--aeskey` option for the convert command requires Simplicity Commander **v1.12.3** or above.
- The GBL Decryption Key can only be added to the GBL with `Application Properties` struct **v1.2** or higher (GSDK ≥ v4.1.0 or with SiSDK).
- This procedure must be implemented before signing the GBL image for Secure Boot.

To write the GBL Decryption Key to the top page of the main flash of a Series 2 VSE device, run the command:

```sh
commander flash --tokengroup znet --tokenfile aes_key.txt --device EFR32MG22C224F512 --serialno 440048205
```

```sh
Writing 8192 bytes starting at address 0x0007e000
Comparing range 0x0007E000 - 0x0007FFFF (8 KB)
Erasing range 0x0007E000 - 0x0007FFFF (1 sector, 8 KB)
Programming range 0x0007E000 - 0x0007FFFF (8 KB)
DONE
```

> **Note**: The MCU Series 2 devices (like EFM32PG22C200F512IM40) require Simplicity Commander Version 1.12.2 or above to support the flash `--tokengroup znet` command.

##### Generate the Sign Key pair

Silicon Labs recommends using an HSM for the creation and storage of the Sign Key pair. The instructions for OpenSSL are shown here for simplicity.

1. Create a keypair for the SECP256r1 curve by running the following command:  
   ```sh  
   openssl ecparam -genkey -name prime256v1 -out sign_key.pem  
   ```
2. Export the public key from this keypair using the following command:

```sh
openssl ec -in sign_key.pem -pubout -out sign_pubkey.pem
```

```sh
read EC key
writing EC key
```

##### Provisioning the Public Sign Key in Simplicity Commander

To write the Public Sign Key to the device, run the command:

```sh
commander security writekey --sign sign_pubkey.pem --device EFR32MG21A010F1024 --serialno 440048205
```

where `sign_pubkey.pem` is the Public Sign Key in Privacy Enhanced Mail (PEM) format. This command can be executed only once per device.

```sh
Device has serial number 000000000000000014b457fffe045a8e

================================================================================
Please look through any warnings before proceeding.
THIS IS A ONE-TIME command, all code to be run on the device must be signed by this key.
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
DONE
```

To read the Public Sign Key on the device, run the command:

```sh
commander security readkey --sign --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
C4AF4AC69AAB9512DB50F7A26AE5B4801183D85417E729A56DA974F4E08A562C
DE6019DEA9411332DC1A743372D170B436238A34597C410EA177024DE20FC819
DONE
```

To generate the Public Sign Key token file for VSE devices, run the command:

```sh
commander util keytotoken sign_pubkey.pem --outfile sign_pubkey.txt
```

```sh
Writing EC tokens to sign_pubkey.txt...
DONE
```

To store a Public Sign Key copy on the top page of the main flash in the VSE device for ECDSA-P256-SHA256 Secure Boot, run the command:

```sh
commander flash --tokengroup znet --tokenfile sign_pubkey.txt --device EFR32MG22C224F512 --serialno 440048205
```

```sh
Writing 8192 bytes starting at address 0x0007e000
Comparing range 0x0007E000 - 0x0007FFFF (8 KB)
Erasing range 0x0007E000 - 0x0007FFFF (1 sector, 8 KB)
Programming range 0x0007E000 - 0x0007FFFF (8 KB)
DONE
```

> **Note**: The MCU Series 2 VSE devices (like EFM32PG22C200F512IM40) require Simplicity Commander Version 1.12.2 or above to support the `flash --tokengroup znet` command.

##### Generate the Command Key Pair

Silicon Labs recommends using an HSM for the creation and storage of the Command Key pair. The instructions for OpenSSL are shown here for simplicity.

1. Create a keypair for the SECP256r1 curve by running the following command:  
   ```sh  
   openssl ecparam -genkey -name prime256v1 -out command_key.pem  
   ```
2. Export the public key from this keypair using the following command:  
   ```sh  
   openssl ec -in command_key.pem -pubout -out command_pubkey.pem  
   ```  
   ```sh  
   read EC key  
   writing EC key  
   ```

##### Provisioning the Public Command Key in Simplicity Commander

To write the Public Command Key to the device, run the command:

```sh
commander security writekey --command command_pubkey.pem --device EFR32MG21A010F1024 --serialno 440048205
```

where `command_pubkey.pem` is the Public Command Key in PEM format. This command can be executed only once per device.

```sh
Device has serial number 000000000000000014b457fffe045a8e

================================================================================
Please look through any warnings before proceeding.
THIS IS A ONE-TIME command which permanently ties debug and tamper access to certificates signed by this key.
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
DONE
```

To read the Public Command Key on the device, run the command:

```sh
commander security readkey --command --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4
7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63
DONE
```

#### Configuring AXiP/EXiP (Series 3 only)

The Authenticated eXecute in-Place feature is available for Series 3 devices with QSPI flash. This feature is provided to resist attempts to

extract the contents of the executable code in the QSPI flash and modify it. Series 3 can configure up to 8 code regions in flash with

the protection level set separately for each region. By default, SixG301 devices have 2 code regions as follows:

|Flash size|Region 0|Region 1(2)|Protection|
|---|---|---|---|
|2 MB|32 kB|864 kB|AXiP|
|3 MB|32 kB|1408 kB|AXiP|
|4 MB|32 kB|1984 kB|AXiP|
|External|32 kB|1.|AXiP|

**Notes**:

1. Region 1 size = (size of flash – 192 kB (SE Firmware) – 32 kB)/2
2. Sizes shown in this column are logical, not physical, sizes

To verify the AXiP configuration for your device, run the following command:

```sh
commander security readregionconfig --device SixG301 --outfile region-config.yaml
```

```sh
Writing parsed configuration to file region-config.yaml...
DONE
```

To view the configuration, open `region-config.yaml` in a text editor. The default configuration looks like this:

```sh
regions:
  - size_kb: 32
    protection: encrypted_authenticated
  - size_kb: 1408
    protection: encrypted_authenticated
```

This is the recommended configuration for most applications. For instructions on modifying the default configuration, refer to AN1509.

To write a new region configuration to the device, run the following command:

```sh
commander security writeregionconfig region-config.yaml -d simg301
```

```sh
Reading configuration from file region-config.yaml...
Writing region configuration to device...
DONE
```

#### Enabling Secure Boot and Tamper Configuration

The Secure Boot feature verifies the integrity and authenticity of the host application before allowing it to execute. Enabling this feature is **IRREVERSIBLE**, which means once enabled, Secure Boot can no longer be disabled throughout the life of the device. The Secure Boot settings are written to the one-time-programmable (OTP) memory. They cannot be changed once programmed.

On HSE-SVH and Series 3 Secure Vault devices, the anti-tamper configuration is provisioned with Secure Boot settings. The anti-tamper configuration determines the response from the HSE-SVH device if a tamper event occurs.

**Notes**:

- All tamper-related information in the following sections is only valid on HSE-SVH devices.
- For more information about anti-tamper configuration, see [Anti-Tamper Protection Configuration and Use](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/).
- Except for the EFR32xG21B devices, other HSE-SVH devices require Simplicity Commander Version 1.12.2 or above for tamper configuration.
- Series 3 devices require Simplicity Commander Version 1.18.0, or higher

The `user_configuration.json` is a JSON file that contains the desired Secure Boot settings and anti-tamper configuration. Use the following command on the target device (e.g., EFR32MG21B010F1024) to generate a default configuration file.

```sh
commander security genconfig --nostore -o user_configuration.json --device EFR32MG21B010F1024
--serialno 440048205
```

```sh
DONE
```

> **Note**: The content of the JSON file is device dependent (`--device <device name>`).

The `security genconfig` command above generates a generic configuration file for **EFR32MG21B010F1024** consisting of the properties listed in the tables below. A text editor can be used to modify the default settings shown below to the desired configuration.

```sh
{
    "mcu_flags": { "SECURE_BOOT_ENABLE": true,
        "SECURE_BOOT_VERIFY_CERTIFICATE": false,
        "SECURE_BOOT_ANTI_ROLLBACK": true,
        "SECURE_BOOT_PAGE_LOCK_NARROW": false,
        "SECURE_BOOT_PAGE_LOCK_FULL": true
    },
    "tamper_levels": {
        "FILTER_COUNTER": 0,
        "WATCHDOG": 4,
        "SE_RAM_CRC": 4,
        "SE_HARDFAULT": 4,
        "SOFTWARE_ASSERTION": 4,
        "SE_CODE_AUTH": 4,
        "USER_CODE_AUTH": 0,
        "MAILBOX_AUTH": 0,
        "DCI_AUTH": 0,
        "OTP_READ": 4,
        "SELF_TEST": 4,
        "TRNG_MONITOR": 0,
        "PRS0": 0,
        "PRS1": 0,
        "PRS2": 0,
        "PRS3": 0,
        "PRS4": 0,
        "PRS5": 0,
        "PRS6": 0,
        "PRS7": 0,
        "DECOUPLE_BOD": 4,
        "TEMP_SENSOR": 0,
        "VGLITCH_FALLING": 0,
        "VGLITCH_RISING": 0,
        "SECURE_LOCK": 4,
        "SE_DEBUG": 0,
        "DGLITCH": 0,
        "SE_ICACHE": 4
    },
    "tamper_filter": {
        "FILTER_PERIOD": 0,
        "FILTER_THRESHOLD": 0,
        "RESET_THRESHOLD": 0
    },
    "tamper_flags": {
        "DGLITCH_ALWAYS_ON": false
    }
}

```

> **Note**: For `USER_CODE_AUTH` (user secure boot failed), recommended setting is 0 (Ignore) to avoid boot loops.

**Table: Secure Boot Items (mcu_flags) for Series 2 Devices**

|**Name**|**Description**|
|---|---|
|SECURE_BOOT_ENABLE|If set, verifies the host image on the Cortex-M33 before releasing the Cortex-M33 from reset.|
|SECURE_BOOT_VERIFY_CERTIFICATE|If set, requires certificate-based signing of the host image.|
|SECURE_BOOT_ANTI_ROLLBACK|If set, prevents secure upgrading to a host image with a lower version than the image that is currently stored in flash.|
|SECURE_BOOT_PAGE_LOCK_NARROW|If set, locks flash pages that have been validated by the Secure Boot process to prevent re-flashing by other means than through the SE. Write/erase locks pages from 0 through the page where the Secure Boot host image signature is located, not including the last page if the signature is not on a page boundary.|
|SECURE_BOOT_PAGE_LOCK_FULL|If set, locks flash pages that have been validated by the Secure Boot process to prevent re-flashing by other means than through the SE. Write/erase locks pages from 0 through the page where the Secure Boot host image signature is located, including the last page if the signature is not on a page boundary.|

> **Note**: The host image is usually the Gecko Bootloader (GBL).

**Table: Secure Boot Items (mcu_flags) for Series 3 Secure Vault Devices**

|**Name**|**Description**|
|---|---|
|SECURE_BOOT_ENABLE|If set, verifies the host image on the Cortex-M33 before releasing the Cortex-M33 from reset.|
|SECURE_BOOT_VERIFY_CERTIFICATE|If set, requires certificate-based signing of the host image.|
|SECURE_BOOT_ANTI_ROLLBACK|If set, prevents secure upgrading to a host image with a lower version than the image that is currently stored in flash.|

##### Table: Tamper Items for HSE-SVH and Series 3 Secure Vault Devices

|**Name**|**Description**|
|---|---|
|tamper_levels|The tamper levels of different tamper sources.|
|tamper_filter|The settings for tamper filters.|
|tamper_flags|The settings for tamper flags.|

The following command writes the Secure Boot settings and anti-tamper configuration in `user_configuration.json` file to the device. This command can be executed only once per device.

```sh
commander security writeconfig --configfile user_configuration.json --device EFR32MG21B010F1024
--serialno 440048205
```

```sh
================================================================================

THIS IS A ONE-TIME configuration: Please inspect file before confirming: user_configuration.json
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
DONE
```

To check the device's Secure Boot settings and anti-tamper configuration, run the `security readconfig` command.

```sh
commander security readconfig --serialno 440048205
```

```sh
MCU Flags
Secure Boot                    : Enabled
Secure Boot Verify Certificate : Disabled
Secure Boot Anti Rollback	   : Enabled
Secure Boot Page Lock Narrow   : Disabled
Secure Boot Page Lock Full	   : Enabled

Tamper Levels
FILTER_COUNTER      : 1
WATCHDOG            : 4
SE_RAM_CRC          : 4
SE_HARDFAULT        : 4
SOFTWARE_ASSERTION  : 4
SE_CODE_AUTH	    : 4
USER_CODE_AUTH	    : 0
MAILBOX_AUTH	    : 1
DCI_AUTH	        : 0
OTP_READ	        : 4
SELF_TEST	        : 4
TRNG_MONITOR	    : 1
PRS0	            : 1
PRS1	            : 1
PRS2	            : 2
PRS3	            : 2
PRS4	            : 4
PRS5	            : 4
PRS6	            : 7
PRS7	            : 7
DECOUPLE_BOD	    : 4
TEMP_SENSOR	        : 2
VGLITCH_FALLING	    : 2
VGLITCH_RISING	    : 2
SECURE_LOCK	        : 4
SE_DEBUG	        : 0
DGLITCH	            : 2
SE_ICACHE	        : 4

Tamper Filter
Filter Period    : 10
Filter Threshold : 6
Reset Threshold  : 5

Tamper Flags
Digital Glitch Detector Always On: Disabled
DONE
```

#### Enabling Debug Lock

The debug lock is an important feature to prevent attackers from using the debug interface to perform unauthorized operations on the device. The following sections describe how to apply three different locks to the Series 2 and Series 3 debug interface.

##### Standard Debug Lock

The following command locks the debug interface.

```sh
commander security lock --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
WARNING: Secure debug unlock is disabled. Only way to regain debug access is to run a device erase.
Device is now locked.
DONE
```

To check the debug lock status of the device, run the `security status` command:

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Enabled
Device erase	    : Enabled
Secure debug unlock : Disabled
Tamper status	    : OK
Secure boot	        : Disabled
Boot status	        : 0x20 - OK
DONE
```

##### Permanent Debug Lock

The following command locks the debug interface.

```sh
commander security lock --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
WARNING: Secure debug unlock is disabled. Only way to regain debug access is to run a device erase. Device is now locked.
DONE
```

After locking the device, disable the device erase using the following command. This is an **IRREVERSIBLE** action and should be the last step in production.

```sh
commander security disabledeviceerase --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
================================================================================
THIS IS A ONE-TIME command which Permanently disables device erase.
If secure debug lock has not been set, there is no way to regain debug access to this device.
Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
Disabled device erase successfully
DONE
```

To check the debug lock status of the device, run the `security status` command.

```sh
commander security status --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Enabled
Device erase        : Disabled
Secure debug unlock : Disabled
Secure boot         : Disabled
Boot status         : 0x20 - OK
DONE
```

##### Secure Debug Lock

The Secure Debug feature is enabled through the `security lockconfig` command. After locking the device, the security unlock command securely unlocks the device for debugging until the next device reset without erasing flash and RAM contents. For more information about Secure Debug Unlock, see [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

The following command enables the secure debug unlock.

```sh
commander security lockconfig --secure-debug-unlock enable --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Secure debug unlock was enabled
DONE
```

For **TrustZone-unaware** applications, after enabling the Secure Debug feature, lock the debug interface using the following command.

```sh
commander security lock --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Device is now locked.
DONE
```

For **TrustZone-aware** applications, after enabling the Secure Debug feature, set the debug options (e.g., `1100`) and lock the debug interface using the following command.

```sh
commander security lock --trustzone 1100 --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Writing debug restriction bits:
DBGLOCK:	0
NIDLOCK:	0
SPIDLOCK: 1
SPNIDLOCK: 1
Device is now locked.
DONE
```

**Notes**:

- The `--trustzone` option for the `security lock` command requires Simplicity Commander **≥ v1.13.3**.
- It is strongly recommended to upgrade to SE firmware **≥ v1.2.14** (xG21 and xG22) or **≥ v2.2.1** (other Series 2 devices) so that the debug options cannot be modified after the device is locked.
- Use `commander security lock` without the `--trustzone ####` option if the default setting of debug options (`0000`) is good enough for a TrustZone-aware application.
- For more information about debug options, see the _TrustZone Debug Authentication_ section in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

After locking the device, disable the device erase using the following command. This is an **IRREVERSIBLE** action and should be the last step in production.

```sh
commander security disabledeviceerase --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
================================================================================
THIS IS A ONE-TIME command which Permanently disables device erase.
If secure debug lock has not been set, there is no way to regain debug access to this device. Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
Disabled device erase successfully
DONE
```

> **Note**: The debug options cannot be reset to the default value `0000` (unlock) if the `device erase option` is disabled.

Run the `security status --trustzone` command to check the full debug lock status of the device.

```sh
commander security status --trustzone --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
SE Firmware version : 1.2.14
Serial number	    : 000000000000000014b457fffe045a8e
Debug lock	        : Enabled
Device erase	    : Disabled
Secure debug unlock : Enabled

Debug lock state: Locked

Non-secure, invasive debug lock     (DBGLOCK) : Unlocked
Non-secure, non-invasive debug lock (NIDLOCK) : Unlocked 
Secure, invasive debug lock	        (SPIDLOCK) : Locked 
Secure, non-invasive debug lock	    (SPNIDLOCK): Locked

Non-secure, invasive debug lock state     (DBGLOCK) : Unlocked
Non-secure, non-invasive debug lock state (NIDLOCK) : Unlocked
Secure, invasive debug lock state	      (SPIDLOCK) : Locked
Secure, non-invasive debug lock state	  (SPNIDLOCK): Locked

Tamper status:      : OK
Secure boot         : Disabled
Boot status         : 0x20 - OK 
DONE
```

> **Note**: For more information about Secure and Non-secure debug locks, see the _TrustZone Debug Authentication_ section in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

#### Field Upgrade the SE Firmware

##### Secure Boot-Disabled Device

Simplicity Commander or Gecko Bootloader can be used to upgrade the SE Firmware on a Secure Boot-disabled device. The following table lists the scenarios of SE Firmware upgrade on the Secure Boot-disabled device.

|**Secure Debug**|**Device Erase**|**Debug Lock**|**State**|**SE Firmware Upgrade**|
|---|---|---|---|---|
|Disabled|Enabled|Disabled|Unlock|Simplicity Commander or Gecko Bootloader|
|Disabled|Enabled|Enabled|Standard debug lock|Simplicity Commander or Gecko Bootloader|
|Enabled|Disabled|Enabled|Secure debug lock|Simplicity Commander or Gecko Bootloader|
|Disabled|Disabled|Enabled|Permanent debug lock|Gecko Bootloader|

###### Simplicity Commander

To flash the SE Firmware upgrade application (e.g., `s2c1_se_fw_upgrade_app_1v2p9.hex`), run:

```sh
commander flash s2c1_se_fw_upgrade_app_1v2p9.hex --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Parsing file s2c1_se_fw_upgrade_app_1v2p9.hex...
Writing 49152 bytes starting at address 0x00000000
Comparing range 0x00000000 - 0x0000BFFF (48 KB)
Programming range 0x00000000 - 0x00001FFF (8 KB)
Programming range 0x00002000 - 0x00003FFF (8 KB)
Programming range 0x00004000 - 0x00005FFF (8 KB)
Programming range 0x00006000 - 0x00007FFF (8 KB)
Programming range 0x00008000 - 0x00009FFF (8 KB)
Programming range 0x0000A000 - 0x0000BFFF (8 KB)
DONE
```

The device should be unlocked before upgrading the SE Firmware if the standard or secure debug lock has been applied. The sections _Standard Debug Lock and Unlock_ and _Secure Debug Unlock and Roll Challenge_ in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/) describe how to unlock the device.

> **Note**: This method will **OVERWRITE** the bootloader and application firmware on the device. The user should then re-program the [bootloader](05-bootloader-firmware-programming) and [application firmware](06-application-firmware-programming) after the SE Firmware upgrade.

###### Gecko Bootloader

Refer to section _Generate a GBL Upgrade Image File_ (Secure Engine Upgrade) in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) for details.

The Gecko Bootloader can still parse the SE GBL upgrade image file and flash its content to the device even if a debug lock is applied. The application firmware must be updated through the Gecko Bootloader after the SE Firmware upgrade if the SE GBL upgrade image file storage overwrites the existing application. Refer to section "Gecko Bootloader Operation - Secure Engine Upgrade" in [UG266](https://www.silabs.com/documents/public/user-guides/ug266-gecko-bootloader-user-guide.pdf)/[Silicon Labs Gecko Bootloader User's Guide for GSDK 4.0 and Higher (series 1 and 2 devices)](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) for details.

##### Secure Boot-Enabled Device

Simplicity Commander or Gecko Bootloader can be used to upgrade the SE Firmware on a Secure Boot-enabled device. The following table lists the scenarios of SE Firmware upgrade on the Secure Boot-enabled device.

|**Secure Debug**|**Device Erase**|**Debug Lock**|**State**|**SE Firmware Upgrade**|
|---|---|---|---|---|
|Disabled|Enabled|Disabled|Unlock|Simplicity Commander or Gecko Bootloader|
|Disabled|Enabled|Enabled|Standard debug lock|Simplicity Commander or Gecko Bootloader|
|Disabled|Disabled|Enabled|Permanent debug lock|Gecko Bootloader|
|Enabled|Disabled|Enabled|Secure debug lock|Gecko Bootloader|

> **Note**: Using Simplicity Commander to upgrade the SE Firmware on a Secure Debug Locked device is not recommended. It causes Secure Boot failure since the SE Firmware upgrade erases the signed host image for Secure Boot. The user may have issues when recovering a Secure Boot failure device with Device Erase disabled. See section _Recover Devices when Secure Boot Fails_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) for details.

###### Simplicity Commander

A signed SE Firmware upgrade application must be used for the upgrade. Instructions for signing the SE Firmware upgrade application are found in the sections "Signing for ECDSA-P256-SHA256 Secure Boot" and _Signing for Certificate-Based Secure Boot_ in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/).

If the `SECURE_BOOT_PAGE_LOCK_NARROW` or `SECURE_BOOT_PAGE_LOCK_FULL` in the [Secure Boot Items (mcu_flags) for Series 2](09-enabling-secure-boot-and-tamper-configuration) table was enabled for Secure Boot or the standard debug lock applies, run:

```sh
commander security erasedevice --device EFR32MG21A010F1024 --serialno 440048205
```

to perform a device erase. Issue a power-on or pin reset to complete the device erase process.

```sh
Successfully erased device
DONE
```

To flash the signed SE Firmware upgrade application (`s2c1_se_fw_upgrade_app_1v2p9_signed.hex`), run:

```sh
commander flash s2c1_se_fw_upgrade_app_1v2p9_signed.hex --device EFR32MG21A010F1024 --serialno 440048205
```

```sh
Parsing file s2c1_se_fw_upgrade_app_1v2p9_signed.hex...
Writing 49152 bytes starting at address 0x00000000
Comparing range 0x00000000 - 0x0000BFFF (48 KB)
Erasing range 0x00000000 - 0x00007FFF (4 sectors, 32 KB)
Erasing range 0x00008000 - 0x0000BFFF (2 sectors, 16 KB)
Programming range 0x00000000 - 0x00001FFF (8 KB)
Programming range 0x00002000 - 0x00003FFF (8 KB)
Programming range 0x00004000 - 0x00005FFF (8 KB)
Programming range 0x00006000 - 0x00007FFF (8 KB)
Programming range 0x00008000 - 0x00009FFF (8 KB)
Programming range 0x0000A000 - 0x0000BFFF (8 KB)
DONE
```

**Notes**:

1. This method will **OVERWRITE** the signed bootloader and application firmware on the device. The user should then re-program the **SIGNED** [bootloader](05-bootloader-firmware-programming) and [application firmware](06-application-firmware-programming) after the SE Firmware upgrade.
2. If the `SECURE_BOOT_ANTI_ROLLBACK` in the tables in [Enabling Secure Boot and Tamper Configuration](09-enabling-secure-boot-and-tamper-configuration) was enabled for Secure Boot, the device will prevent the signed SE Firmware upgrade when the host image version (e.g., Gecko Bootloader v1.12.0) is equal to or higher than the SE Firmware version (e.g., v1.2.9). Under this situation, the Gecko Bootloader should be used to upgrade the SE firmware. This method will **OVERWRITE** the bootloader version in SE flash with the SE Firmware version after the upgrade.

```sh
Parsing file s2c1_se_fw_upgrade_app_1v2p9_signed.hex...
Writing 49152 bytes starting at address 0x00000000
Comparing range 0x00000000 - 0x0000BFFF (48 KB)
Erasing range 0x00000000 - 0x00007FFF (4 sectors, 32 KB)
Programming range 0x00000000 - 0x00001FFF (8 KB)
Programming range 0x00002000 - 0x00003FFF (8 KB)
Programming range 0x00004000 - 0x00005FFF (8 KB)
Programming range 0x00006000 - 0x00007FFF (8 KB)
Programming range 0x00008000 - 0x00009FFF (8 KB)
Programming range 0x0000A000 - 0x0000BFFF (8 KB)
JLinkError: Failed to halt CPU.
DONE
```

###### Gecko Bootloader

Refer to section _Generate a GBL Upgrade Image File_ (Secure Engine Upgrade) in [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) for details.

The Gecko Bootloader can still parse the SE GBL upgrade image file and flash its content to the device even if a debug lock applies. The application firmware must be updated through the Gecko Bootloader after the SE Firmware upgrade if the SE GBL upgrade image file storage overwrites the existing application. Refer to section _Gecko Bootloader Operation - Secure Engine Upgrade_ in [Developing and Debugging a Gecko Bootloader](https://docs.silabs.com/mcu-bootloader/latest/gecko-bootloader-developing-debugging/) for details.

### Anti-Tamper Protection Configuration and Use

#### Anti-Tamper Protection Configuration and Use

> **Note: This section replaces _AN1247: Anti-Tamper Protection Configuration and Use_. Further updates to this application note will be provided here**.

This application note describes how to program, provision, and configure the Secure Engine anti-tamper module. Many aspects of the anti-tamper module, including disabling the anti-tamper response when needed, are discussed.

The anti-tamper module is only available on Secure Vault High and Series 3 Secure Vault devices. The external tamper detect module is available on some Secure Vault Mid devices (e.g. xG27), Secure Vault High devices (e.g. xG25B) and Series 3 Secure Vault devices.

##### Key Points

- Tamper responses
- Tamper sources
- Tamper configuration
- Tamper disable
- Examples of provisioning and disabling the anti-tamper module

#### Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine, this continues in Series 3. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE: Hardware Secure Engine
- VSE: Virtual Secure Engine
- SE: Secure Engine (either HSE or VSE)

On Series 3 devices, the security features are implemented by the Secure Engine and SYMCRYPTO. The Secure Engine and SYMCRYPTO are hardware-based.

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level (1)**|**SE Support**|**Part (2)**|
|---|---|---|
|Series 3 Secure Vault|HSE only|Refer to [Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for details on supporting devices.|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|“|
|Secure Vault Mid (SVM)|HSE (HSE-SVM)|"|
|"|VSE (VSE-SVM)|"|
|Secure Vault Base (SVB)|N/A|"|

**Notes**:

1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security).
2. [Series 2 and Series 3 Device Security Features](https://docs.silabs.com/iot-security/latest/11-series-2-device-security-features11-series-2-and-series-3-device-security-features/).

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug access control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper protection**: A configurable module to protect the device against tamper attacks.
- **Device authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

Series 3 Secure Vault offers the same features as Secure Vault High except:

- Device Authentication is only available for the SE

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Anti-Tamper Protection Configuration and Use (this application note)</p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|
|Authenticated eXecute in Place (AXiP) key|No|Authenticate and decrypt executable in external flash on Series 3 devices|
|Encrypted eXecute in Place (EXiP) key|No|Decrypt executable code in external flash on Series 3 devices|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 and Series 3 devices and modules.

#### Overview

The HSE-SVH and Series 3 Secure Vault Anti-Tamper module is used to hamper or prevent both reverse engineering and re-engineering of proprietary software systems or applications.

Tamper attacks come from one or more vectors. Common attacks include voltage glitching, magnetic interference, and forced temperature adjustment. The HSE-SVH and Series 3 Secure Vault Anti-Tamper module provides fast hardware detection of external tamper signals such as case opening, glitching, and logical attacks allowing analysis and escalation up to and including bricking the device.

The anti-tamper module connects a number of hardware and software-driven tamper signals to a set of configurable hardware and software responses. This can be used to program the device to automatically respond to external events that could signal that someone is trying to tamper with the device, and very rapidly remove secrets stored in the HSE.

The available tamper signals range from signals based on failed authentication and secure boot to specialized glitch detectors. When any of these signals fire, the tamper block can be configured to trigger several different responses, ranging from triggering an interrupt to erasing the One-Time-Programmable (OTP) memory, removing all HSE secrets and resulting in a permanently destroyed device.

Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://www.silabs.com/developers/custom-part-manufacturing-service) to protect the users' privacy by configuring the most effective tamper detection features at the Silicon Labs factory. For more information about CPMS, see [Custom Part Manufacturing Service User's Guide](https://docs.silabs.com/iot-security/latest/iot-security-cpms/).

Some SVM devices (e.g. xG25A and xG27) and SVH devices (e.g. xG25B) and Series 3 Secure Vault devices (e.g. xG301) feature an External Tamper Detect module which is used to detect signals such as case opening. The ETAMPDET signal on SVH and Series 3  Secure Vault devices is routed to the SE as an Anti-Tamper module tamper source, in addition to being a stand-alone module. For more information about ETAMPDET operation, refer to the device reference manual. Examples demonstrating how to use ETAMPDET can be found on the [Silicon Labs peripheral_example github repository](https://github.com/SiliconLabs/peripheral_examples/tree/master/series2/etampdet). The peripheral reflex system (PRS) can also be routed as a tamper source. For more information on PRS, refer to your device’s reference manual.

#### Secure Engine Manager

The Secure Engine Manager provides thread-safe APIs for the SE's mailbox interface. The SE Manager APIs related to tamper operations are listed in the following table.

For the SE's mailbox interface, see _Secure Engine Subsystem_ in [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

|**SE Manager API**|**Usage**|
|---|---|
|sl_se_init_otp|Initialize SE OTP configuration (including tamper configuration on HSE-SVH and Series 3 Secure Vault devices).|
|sl_se_read_otp|Read SE OTP configuration (including tamper configuration on HSE-SVH and Series 3 Secure Vault devices).|
|sl_se_init_otp_key|Used during device initialization to upload the Public Command Key.|
|sl_se_read_pubkey|Read the stored Public Command Key.|
|sl_se_get_serialnumber|Read out the serial number (16 bytes) of the HSE device.|
|sl_se_get_challenge|Read out the current challenge value (16 bytes) for tamper disable.|
|sl_se_roll_challenge|Used to roll the current challenge value (16 bytes) to invalidate the Disable Tamper Token.|
|sl_se_disable_tamper|Temporarily disable tamper configuration using the Disable Tamper Token.|
|sl_se_get_status|Read the current HSE status (including recorded tamper status on HSE-SVH devices).|
|sl_se_get_reset_cause|Read the EMU->RSTCAUSE register from HSE devices after a tamper reset.|
|sl_se_get_tamper_reset_cause|Read the cached value of the EMU->TAMPERRSTCAUSE register after a tamper reset.|
|sl_se_enter_active_mode|Force the SE to remain active to enable the detection of glitch tamper events on the host Cortex-M33 core (see fourth note below)|
|sl_se_exit_active_mode|Exit active mode and allow the SE to sleep when not performing operations. This will prevent the detection of glitch tamper events when the SE is sleeping. This API should only be used if active mode was entered by calling `sl_se_enter_active_mode`. If active mode is set through a DCI command, it can only be disabled through a DCI command. (see fourth note below)|

**Notes**:

- The `sl_se_get_reset_cause` is only available on EFR32xG21B devices. The `EMU->RSTCAUSE` register can be directly read on other HSE-SVH and Series 3 Secure Vault devices.
- The `sl_se_get_tamper_reset_cause` is unavailable on EFR32xG21B devices, and SE firmware ≥ v2.2.1 is required.
- The SE Manager API document can be found at [https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager](https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager).
- Does not apply to EFR32MG21B parts.

#### Tamper Responses

A [tamper source](05-tamper-sources) can lead to a series of different autonomous responses from the HSE. These responses are listed in the following table.

|**Level (1)**|**Response (2)**|**Description**|
|---|---|---|
|0|Ignore|No action is taken|
|1|Interrupt|Triggers the SETAMPERHOST interrupt on the host|
|2|Filter|Increases a counter in the tamper filter|
|4|Reset|Resets the device|
|7|Erase OTP|Erases the device's OTP configuration|

**Notes**:

1. Levels 3, 5, and 6 are reserved.
2. These responses are cumulative:  
   - If a filter response is triggered, it will also trigger an interrupt.  
   - If a reset response is triggered, it will supersede the interrupt. The filter counter and interrupt flag are cleared at reset.  
   - If an erase OTP response is triggered, it will erase the OTP and reset the device. The device will fail to boot and become unusable.

##### Interrupt

If a tamper source is configured to respond with the interrupt response or higher (≥ level 1), the `SETAMPERHOST` interrupt line to the host Cortex-M33 will be pulsed and make the NVIC trigger the corresponding interrupt handler (`SETAMPERHOST_IRQHandler`).

After the interrupt has been handled, the tamper status can be found by reading the HSE status (using `sl_se_get_status` in the [SE Manager](03-secure-engine-manager)), which contains a list of all the tamper sources that have been triggered since the last time the status was read. Reading HSE status clears the registered tamper sources.

> **Note**: Enabling the `SEMAILBOXHOST` clock for the tamper source is required to trigger the `SETAMPERHOST` interrupt in most HSE-SVH and Series 3 Secure Vault devices. EFR32xG21B does not require this.

##### Filter

The HSE has a filter to debounce spurious tamper events. The filter has a counter that is periodically reset. If a tamper source is configured to the filter response (level 2), when it is triggered, the counter is increased. If the counter value reaches a configurable threshold, the `Filter counter` tamper source is triggered, which can configure to lead to any other responses (1, 4, or even 7).

Only a single shared filter counter is available, so the cumulative triggering of all tamper sources configured to the filter level will increase the same counter. The filter can be programmed to use one of the trigger thresholds and reset periods provided below. The filter counter is zero upon a tamper or normal reset.

##### Filter Trigger Threshold

- Value (n): 0 to 7
- Filter Trigger Threshold: 256/2^n (256 to 2)

##### Filter Reset Period

- Value (n): 0 to 31
- Filter Reset Period: 32 ms * 2^n (32 ms to ~795.4 days)

##### Example Filter Configuration

For example, consider a device with a Filter Trigger Threshold of 3 and Filter Reset Period of 5. If that device detects 32 (256/2^3) Filter response events in 1.024 seconds (32 ms * 2^5), the `Filter counter` tamper source will trigger.

##### Reset

The reset response resets the HSE and Cortex-M33. After a tamper reset, the last reset cause can be directly read from `EMU-\>RSTCAUSE` register or using `sl_se_get_reset_cause` in the [SE Manager](03-secure-engine-manager). In cases where the reset was caused by a tamper response, the source of the tamper can be determined by calling `sl_se_get_tamper_reset_cause` in the SE Manager. (Note that this API is not available for EFR32xG21B-based parts). See [Tamper Sources](05-tamper-sources) for more information. Tamper reset occurs when the HSE sends a request to the Cortex-M33’s EMU, which issues a hard reset.

If a tamper reset is triggered during boot, this can lead to a boot loop. To debug such a scenario, the HSE has a tamper reset counter and enters diagnostic mode if the counter reaches a programmable threshold. Users can issue a non-tamper reset to clear the tamper reset counter before the programmable threshold is reached.

In diagnostic mode, the Cortex-M33 is held in reset and only DCI commands are available. The device will remain in diagnostic mode until a power-on or pin reset occurs.

For more information on the SE's DCI, see [Secure Engine Subsystem](https://docs.silabs.com/iot-security/latest/series2-secure-debug/03-secure-engine-subsystem/) in _Series 2 and Series 3 Secure Debug_.

##### Erase OTP

The Erase OTP response is the strongest reaction the HSE can take, and it will make the device and all wrapped secrets unrecoverable. After this response, the device will no longer be able to boot or connect to a debugger.

This response should typically only be used in situations where the device believes that it is under an actual attack, for instance through the detection of several voltage or digital glitches in a short time window.

#### Tamper Sources

The following table lists the available tamper sources and the default level on the EFR32xG21B. Refer to Appendix C for the other HSE-SVH and Series 3 devices. The tamper sources with the default level higher than 0 (Ignore) are always in effect even if the user does not initialize the tamper configuration in HSE OTP. Users can keep or escalate the default tamper responses (≥ 0 for Ignore and ≥ 4 for Reset) of any sources when initially configuring the part.

|**Type**|**Number**|**Name**|**Description**|**Default Level**|
|---|---|---|---|---|
|SE Hardware|0|Reserved|—|—|
|"|1|Filter counter|Filter counter reached the configured threshold value|0 (Ignore)|
|"|2|SE watchdog|Internal SE watchdog expired|4 (Reset)|
|"|3|Reserved|—|—|
|"|4|SE RAM CRC|A 2-bit, non-correctable error in the SE RAM has occurred.|4 (Reset)|
|"|5|SE hard fault|The SE core has encountered a hard fault exception indicating that an invalid memory access was attempted.|4 (Reset)|
|"|6|Reserved|—|—|
|SE Software|7|SE software assertion|SE firmware has triggered an assertion, indicating that one of several sanity checks has failed and that normal operation cannot continue without a reset.|4 (Reset)|
|"|8|SE secure boot|Secure boot of SE firmware failed|4 (Reset)|
|"|9|User secure boot|Secure boot of host firmware failed|0 (Ignore)|
|"|10|Mailbox authorization|Unauthorized command received over the Mailbox interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|11|DCI authorization|Unauthorized command received over the DCI interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|12|OTP read|OTP or flash content could not be properly authenticated.|4 (Reset)|
|"|13|Reserved|—|—|
|"|14|Self test|A check of the integrity of the SE's internal storage failed during boot up.|4 (Reset)|
|"|15|TRNG monitor|The TRNG monitor performs a number of tests on the collected entropy data. If any of these tests fail, this tamper source is triggered.|0 (Ignore)|
|Hardware|16 - 23|PRS0 - 7 [1]|PRS consumer for SE Tamper 0 - 7 asserted|0 (Ignore)|
|"|24|Decouple BOD [1]|Decouple Brown-Out-Detector threshold alert|4 (Reset)|
|"|25|Temperature sensor [1]|SE temperature is monitored to be within 5 degrees C of the limits for the device. If the limit is exceeded, this tamper source will be triggered.|0 (Ignore)|
|"|26|Voltage glitch falling|Voltage glitch detector detected a falling glitch|0 (Ignore)|
|"|27|Voltage glitch rising|Voltage glitch detector detected a rising glitch|0 (Ignore)|
|"|28|Secure lock|This tamper source indicates that the guarding mechanism (comparing the locks with their logical complement) of the debug port locks has failed.|4 (Reset)|

|**Type**|**Number**|**Name**|**Description**|**Default Level**|
|---|---|---|---|---|
|"|29|SE debug|Debug access to SE|0 (Ignore)|
|"|30|Digital glitch|Digital glitch detector detected an event|0 (Ignore)|
|"|31|SE ICACHE|The SE's instruction cache uses a checksum to verify the integrity of the data. This tamper source is triggered if the checksum is invalid.|4 (Reset)|

**Notes**:

- [1] These tamper sources are available down to EM2. Other sources are available in EM1 and above.
- In EFR32xG21B devices, hardware tamper sources 24 to 27 can operate down to Energy Mode 3 (EM3), whereas other hardware tamper sources (16 - 23 and 28 - 31) can be active down to Energy Mode 1 (EM1).
- For devices other than EFR32xG21B see [Appendix C](12-appendix-c-tamper-sources-reference) for tamper sources
- User configuration or tamper disable cannot reduce the tamper response below the default Level.
- The **User secure boot** source gets triggered if secure boot is enabled and host image verification fails. It is likely to put the device in the boot loop if users escalate the tamper response of this source to 4 (Reset).
- The **Mailbox and DCI authorizations** get triggered whenever one of the following conditions has occurred. The mailbox returns `SE_RESPONSE_AUTHORIZATION_ERROR`, and [DCI](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/) returns `AUTH_ERROR = 2`.

1. A mailbox or DCI command tries to exercise a key that it is not allowed to use (e.g., trying to export a non-exportable key).
2. A secure debug access or tamper disable request over the mailbox or DCI is invalidly signed.
3. A malformed HSE firmware upgrade over the mailbox or DCI is attempted.

- The **OTP read** gets triggered if there is an issue when decrypting and authenticating settings in HSE OTP or flash.
- The HSE has redundancy built into the locking mechanism, and the **Secure lock** source is used to detect errors in that redundancy.
- PRS inputs can allow user applications to implement additional tamper sources and feed them into the tamper response mechanism. The **PRS** tamper sources are under the control of the user application and could be reconfigured or disabled if the user application is compromised.
- The **Temperature sensor** source is not completely accurate and is generally only suitable for systems that expect to stay well within the specified temperature range. Users requiring a tighter temperature limit can implement their temperature monitor and provide the results as a tamper source via PRS.

#### Anti-Tamper Configuration

The user can provision the anti-tamper configuration in HSE OTP detailed in the following table through `sl_se_init_otp` in the [SE Manager](03-secure-engine-manager). Tamper configurations must be programmed with secure boot settings and are immutable once written.

For more information on enabling the OTP tamper configuration along with the secure boot settings, see _Enabling Secure Boot and Tamper Configuration_ in [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/09-enabling-secure-boot-and-tamper-configuration/).

|**Setting**|**Description**|
|---|---|
|Tamper response levels|A user response level for each tamper source (1)|
|Filter settings|The tamper filter counter has two settings: trigger threshold and reset period|
|Digital Glitch Detector Always On|Bit 1 of tamper flag: 0 — Digital glitch detector runs only when the HSE is executing a command; 1 — Digital glitch detector runs even when the HSE is not performing any operations (note that this leads to increased energy consumption)|
|Keep Tamper Alive During Sleep (2)|Bit 2 of tamper flag: 0 — The tamper module stops running in sleep mode; 1 — The tamper module keeps running in sleep mode (down to EM3)|
|Reset threshold|The number of consecutive tamper resets (up to 255) before the part enters diagnostic mode (3)|

**Notes**:

1. The effective response of a tamper source is the maximum value between the default level and user level (Active level = MAX(`default level`, `user level`)). If the user sets the response of a tamper source to a level lower than the default level, the setting will still be saved to HSE OTP but does not take any effect. The HSE returns the user levels instead of active levels of all tamper sources when reading back `sl_se_read_otp` the tamper configuration from the HSE OTP.
2. This flag is not available on EFR32xG21B devices.
3. If the threshold is set to 0, the part will never enter the diagnostic mode due to tamper reset.

#### Typical Configuration

Several of the available [tamper sources](05-tamper-sources) report internal HSE errors. A number of these sources are configured to reset the device (level 4) by default. Custom handling of internal and external tamper sources (default level 0) can be configured to trigger an interrupt (level 1) on the Cortex-M33 or trigger an interrupt and increase a counter in the tamper filter (level 2) as in the following figure for EFR32xG21B devices.

![Custom Handling of Tamper Sources (EFR32xG21B Devices)](/efr32-secure-vault-tamper/0.3/images/sld715-custom-handling-tamper-sources.png)

> **Note**: The actions for level 1 on the right side are implemented by the tamper interrupt handler.

##### Typical Configuration Highlights

- The response of the TRNG monitor depends on the failure rate due to lack of entropy.
- The voltage and digital glitch detectors can see spurious activations. They should typically not be used to drive a high-level tamper response directly. Instead, they should feed their signals into a tamper interrupt, which activates a high-level action (e.g., Reset in this example) through PRS tamper if a certain number of detections (noise filter) occur in a short time window.
- The operating conditions decide the time out of the specification filter for the temperature sensor. For some systems, any time out of specification should trigger a reset.
- Mailbox authorization is handled similarly for voltage and digital glitch detectors.
- A PRS tamper implements a high-level response for a tamper interrupt, which issues a tamper reset (level 4) to prevent or slow further attacks.
- In extreme cases, if the system identifies an attack with high confidence, a PRS tamper can be configured as [Erase OTP](04-tamper-responses#erase-otp) (level 7) to brick the part and prevent further attacks. This is recommended only when the destruction of parts is acceptable and where high confidence of an attack can be achieved.
- Another PRS tamper detects enclosure opening from GPIO. This source feeds into the tamper filter counter (level 2), which will trigger an interrupt cumulative effect and activate a `Filter counter` number 1 response (Reset in this example) if the filter counter reaches the trigger threshold within the filter reset period. This filter counter response approach is less flexible than the interrupt response approach since the trigger threshold and filter reset period are one-time programmable.

#### Tamper Disable

For diagnostic purposes, it may be necessary to disable the tamper response. For example, if a user has configured the part to [Erase OTP](04-tamper-responses#erase-otp) on external tamper detection, disabling the tamper response is required to open the unit and perform failure analysis or field service activities.

After the tamper configuration has been initialized, users can temporarily restore the tamper response to default for a set of tamper sources via a Disable Tamper Token authenticated against the Public Command Key in HSE OTP (similar to secure debug unlock). This is only possible if the Public Command Key has been provisioned in the device.

![Tamper Disable on the EFR32xG21B Devices](/efr32-secure-vault-tamper/0.3/images/sld715-tamper-disable-efr32xg21b-devices.png)

**For default tamper settings on other devices, refer to [Appendix C – Tamper Sources Reference](12-appendix-c-tamper-sources-reference).**

##### Disable Tamper Token

The elements of the Disable Tamper Token are described in the following figure and tables.

![Disable Tamper Token](/efr32-secure-vault-tamper/0.3/images/sld715-disable-tamper-token.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Disable tamper command|0xfd020001|The command word of the Disable Tamper Token.|
|Tamper disable mask|Device-dependent|The command parameter of the Disable Tamper Token.|
|Access certificate (1)|Device-dependent|See [Access Certificate](#access-certificate).|
|Disable tamper command signature (1)|Device-dependent|See [Challenge Response](#challenge-response).|

**Note**:

1. The disable tamper command payload consists of an access certificate and a disable tamper command signature.

![Tamper Disable Mask](/efr32-secure-vault-tamper/0.3/images/sld715-tamper-disable-mask.png)

**Note**: Set bit to restore the default response of the corresponding tamper source.

The Disable Tamper Token temporarily reverts all masked tamper sources in the figure above to the hard-coded configuration.

The Disable Tamper Token can only restore the escalated user-level configuration to default. It cannot degrade the default level of a tamper source.

##### Access Certificate

The elements of the access certificate are described in the following figure and table.

![Access Certificate](/efr32-secure-vault-tamper/0.3/images/sld715-access-certificate.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Magic word|0xe5ecce01|A constant value used to identify the access certificate.|
|Authorizations|0x0000003e (1)|A value used to authorize which bit in the debug mode request can be enabled for secure debug.|
|Tamper Authorizations|0xffffffb6 (2)|A value used to authorize which bit in the tamper disable mask can be set to disable the tamper response.|
|Serial number|Device-dependent|A number used to compare against the on-chip serial number for secure debug or tamper disable.|
|Public Certificate Key (3)|Device-dependent|The public key corresponding to the Private Certificate Key (3) used to generate the signature (ECDSA-P256-SHA256) in a challenge response.|
|Access certificate signature|Device-dependent|All the content above is signed (ECDSA-P256-SHA256) by the Private Command Key corresponding to the Public Command Key in the HSE OTP.|

**Notes**:

1. The value allows all debug options to be reset for secure debug. Note that the commands for debug unlock and tamper disable are separate, so the secure debug lock will not be disabled when issuing a tamper disable command.
2. Value that sets available bits in the tamper disable mask for tamper disable.
3. The Private/Public Certificate Key is a randomly generated key pair. It can be ephemeral or retainable.

The Private Certificate Key can be used repeatedly to generate the signature in a challenge response on one device until the Private/ Public Certificate Key pair is discarded. This can reduce the frequency of access to the Private Command Key, allowing more restrictive access control on that key.

For more information about secure debug, see [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

![Tamper Authorizations](/efr32-secure-vault-tamper/0.3/images/sld715-image43.jpg)

**Notes**:

- Set the bit to enable the corresponding bit in the tamper disable mask.
- The Disable Tamper Token will restore the default response of the corresponding tamper source if the same bit is set in the tamper disable mask and tamper authorizations. If the same bit is not set, the tamper response for that tamper source will be untouched.

##### Challenge Response

The elements of the challenge response are described in the following figure and table.

![Challenge Response](/efr32-secure-vault-tamper/0.3/images/sld715-challenge-response.png)

|**Element**|**Value**|**Description**|
|---|---|---|
|Disable tamper command|0xfd020001|The command word of Disable Tamper Token.|
|Tamper disable mask|Device-dependent|The command parameter of Disable Tamper Token.|
|Challenge|Device-dependent (1)|A random value generated by the HSE.|
|Disable tamper command signature|Device-dependent (2)|All the content above is signed (ECDSA-P256-SHA256) by the Private Certificate Key corresponding to the Public Certificate Key in the access certificate.|

**Notes**:

1. The challenge remains unchanged until it is updated to a new random value by rolling the challenge. The Private Certificate Key can be reused for signing when device challenge is refreshed.
2. This signature is the final argument of the Disable Tamper Token.

##### Tamper Disable Flow

The tamper disable flow is described in the following figure.

![Tamper Disable Flow](/efr32-secure-vault-tamper/0.3/images/sld715-tamper-disable-flow.png)

1. Get the serial number and challenge from the HSE.
2. Generate the access certificate with device serial number.
3. Generate the challenge response with device challenge.
4. Generate the disable tamper command payload with access certificate and disable tamper command signature.
5. Send the Disable Tamper Token to the HSE.
6. Verify the disable tamper command signature using the Public Certificate Key in the access certificate.
7. Verify the serial number and the access certificate signature using the on-chip serial number and Public Command Key in the HSE OTP.
8. Restore default levels on tamper disable mask until the next power-on or pin reset.
9. Roll the challenge to invalidate the current Disable Tamper Token.

> **Note**: Refer to the [Simplicity Commander example](09-examples#using-simplicity-commander) for details on how to follow this flow using Simplicity Commander.

#### Examples

##### Overview

The examples for HSE-SVH and Series 3 Secure Vault Anti-Tamper module are described in the following table.

|**Example**|**Device (Radio Board)**|**HSE Firmware**|**Tool**|
|---|---|---|---|
|Provision Tamper configuration|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|SE Manager|
|Provision Public Command Key & Tamper configuration|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|Simplicity Commander|
|"|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|Simplicity Studio 5|
|Tamper disable and Roll challenge|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|SE Manager|
|"|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|Simplicity Commander|
|Roll challenge|EFR32MG21B010F1024IM32 (BRD4181C)|Version 1.2.9|Simplicity Studio 5|

> **Note**: Unless specified in the example, these examples can be applied to other HSE-SVH and Series 3 Secure Vault devices.

###### Using Simplicity Commander

1. This application note uses Simplicity Commander v1.14.6. The procedures and console output may be different on other versions of Simplicity Commander. The latest version of Simplicity Commander can be downloaded from [https://www.silabs.com/developers/mcu-programming-options](https://www.silabs.com/developers/mcu-programming-options/).  
   ```sh  
   commander --version  
   ```  
   ```sh  
   Simplicity Commander 1v14p6b1289  
     
   JLink DLL version: 7.70d  
   Qt 5.12.10 Copyright (C) 2017 The Qt Company Ltd.  
   EMDLL Version: 0v18p9b677 mbed TLS version: 2.16.6  
     
     
   DONE  
   ```
2. The Simplicity Commander's Command Line Interface (CLI) is invoked by `commander.exe` in the Simplicity Commander folder. The location for Simplicity Studio 5 in Windows is `C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\commander`. For ease of use, it is highly recommended to add the path of `commander.exe` to the system PATH in Windows.
3. If more than one Wireless Starter Kit (WSTK or WPK) is connected via USB, the target WSTK must be specified using the `--serialno \<J-Link serial number\>` option.
4. If the WSTK or WPK is in debug mode OUT, the target device must be specified using the --device <device name> option. For more information about Simplicity Commander, see [Simplicity Commander Reference Guide](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/).
5. The minimum recommended version of Simplicity Commander for SixG301 devices is v1.19.2.

###### Using an External Tool

The tamper disable example uses **OpenSSL** to sign the access certificate and challenge response. The Windows version of OpenSSL can be downloaded from [https://slproweb.com/products/Win32OpenSSL.html](https://slproweb.com/products/Win32OpenSSL.html). This application note uses OpenSSL Version 3.5.0 (Win64).

```sh
openssl version
```

```sh
OpenSSL 3.5.0 8 Apr 2025
```

The OpenSSL's Command Line Interface (CLI) is invoked by openssl.exe in the OpenSSL folder. The location in Windows (Win64) is `C:\Program Files\OpenSSL-Win64\bin`. For ease of use, it is highly recommended to add the path of `openssl.exe` to the system PATH in Windows.

##### Provision Public Command Key and Tamper Configuration

The Public part of the Command Key pair can be generated from the “unsafe” private key delivered with Simplicity Studio, by Simplicity Commander, or by a Hardware Security Module (HSM). Using an HSM is recommended for production systems.

###### Public Command Key Extracted from “Unsafe” Private Key using OpenSSL

External tools such as openssl can be used to generate a public key from the reference private key provided in Simplicity Studio. Note that this private key is well known and must not be used in production devices.

Run the `openssl ec` command to generate the Public Command Key from the Private Command Key.

```sh
openssl ec -in /c/SiliconLabs/SimplicityStudio/v5/developer/adapter_packs/secmgr/scripts/offline/cmd-unsafe-privkey.pem -pubout -out cmd-unsafe-pubkey.pem
```

###### Command Keypair Generated Randomly Using Simplicity Commander

Run the `util genkey` command to generate the Public Command Key pair (`command_key.pem` and `command_pubkey.pem`) and Public Command Key token file (`command_pubkey.txt`).

```sh
commander util genkey --type ecc-p256 --privkey command_key.pem --pubkey command_pubkey.pem
--tokenfile command_pubkey.txt
```

```sh
Generating ECC P256 key pair...
Writing private key file in PEM format to command_key.pem
Writing public key file in PEM format to command_pubkey.pem
Writing EC tokens to command_pubkey.txt...
DONE
```

```sh
commander util keytotoken command_pubkey.pem --outfile command_pubkey.txt
```

```sh
Writing EC tokens to command_pubkey.txt...
DONE
```

###### Provision Public Command Key and Tamper Configuration

1. Run the `security writekey` command to provision the Public Command Key (e.g., `command_pubkey.pem`).  
   ```sh  
   commander security writekey --command command_pubkey.pem --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   Device has serial number 000000000000000014b457fffe0f77ce  
     
   ================================================================================  
   Please look through any warnings before proceeding.  
   THIS IS A ONE-TIME command which permanently ties debug and tamper access to certificates signed by this key.  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```  
   > **Note**: The Public Command Key cannot be changed once written.
2. Run the `security readkey` command to read the Public Command Key from the HSE OTP for verification with the key in step 1.  
   ```sh  
   commander security readkey --command --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4  
   7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63  
   DONE  
   ```
3. Run the `security genconfig` command to generate a default `user_configuration.json` file for secure boot and tamper configuration.  
   ```sh  
   commander security genconfig --nostore -o user_configuration.json --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   Configuration file written to user_configuration.json  
   DONE  
   ```  
   > **Note**: Simplicity Commander Version 1.14.6 or above is required to support tamper configuration for all Series 2 HSE-SVH devices.
4. Use a text editor to modify the default tamper responses in `user_configuration.json` to the desired configuration as below.  
   ```sh  
   {  
   "OPN": "EFR32MG21B010F1024", "VERSION": "1.0.0",  
   "mcu_flags": { "SECURE_BOOT_ANTI_ROLLBACK": false, "SECURE_BOOT_ENABLE": false, "SECURE_BOOT_PAGE_LOCK_FULL": false, "SECURE_BOOT_PAGE_LOCK_NARROW": false, "SECURE_BOOT_VERIFY_CERTIFICATE": false  
   },  
   "tamper_filter": { "FILTER_PERIOD": 10,  
   "FILTER_THRESHOLD": 6,  
   "RESET_THRESHOLD": 5  
   },  
   "tamper_flags": { "DGLITCH_ALWAYS_ON": false  
   },  
   "tamper_levels": { "DCI_AUTH": 0,  
   "DECOUPLE_BOD": 4,  
   "DGLITCH": 2,  
   "FILTER_COUNTER": 1,  
   "MAILBOX_AUTH": 1,  
   "OTP_READ": 4,  
   "PRS0": 1,  
   "PRS1": 1,  
   "PRS2": 2,  
   "PRS3": 2,  
   "PRS4": 4,  
   "PRS5": 4,  
   "PRS6": 7,  
   "PRS7": 7,  
   "SECURE_LOCK": 4,  
   "SELF_TEST": 4,  
   "SE_CODE_AUTH": 4,  
   "SE_DEBUG": 0,  
   "SE_HARDFAULT": 4,  
   "SE_ICACHE": 4,  
   "SE_RAM_CRC": 4,  
   "SOFTWARE_ASSERTION": 4,  
   "TEMP_SENSOR": 2,  
   "TRNG_MONITOR": 1,  
   "USER_CODE_AUTH": 0,  
   "VGLITCH_FALLING": 2,  
   "VGLITCH_RISING": 2,  
   "WATCHDOG": 4  
   }  
   }  
   ```  
   **Notes**:  
   - This example does not enable the secure boot.  
   - The `SECURE_BOOT_PAGE_LOCK_FULL` and `SECURE_BOOT_PAGE_LOCK_NARROW` flags are not supported in Series 3.
5. Run the `security writeconfig` command to program the secure boot and tamper configuration to the HSE OTP. This command can be executed once per device.  
   ```sh  
   commander security writeconfig --configfile user_configuration.json --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   THIS IS A ONE-TIME configuration: Please inspect file before confirming:  
   user_configuration.json  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```
6. Run the `security readconfig` command to check the secure boot and tamper configuration of the device.  
   ```sh  
   commander security readconfig --serialno 440030580  
   ```  
   ```sh  
   MCU Flags  
   Secure Boot                    : Disabled  
   Secure Boot Verify Certificate : Disabled  
   Secure Boot Anti Rollback      : Disabled  
   Secure Boot Page Lock Narrow   : Disabled  
   Secure Boot Page Lock Full     : Disabled  
     
   Tamper Levels  
     
   FILTER_COUNTER     : 1  
   WATCHDOG           : 4  
   SE_RAM_CRC         : 4  
   SE_HARDFAULT       : 4  
   SOFTWARE_ASSERTION : 4  
   SE_CODE_AUTH	   : 4  
   USER_CODE_AUTH	   : 0  
   MAILBOX_AUTH	   : 1  
   DCI_AUTH	       : 0  
   OTP_READ	       : 4  
   SELF_TEST	       : 4  
   TRNG_MONITOR	   : 1  
   PRS0	           : 1  
   PRS1	           : 1  
   PRS2	           : 2  
   PRS3	           : 2  
   PRS4	           : 4  
   PRS5	           : 4  
   PRS6	           : 7  
   PRS7	           : 7  
   DECOUPLE_BOD	   : 4  
   TEMP_SENSOR	       : 2  
   VGLITCH_FALLING	   : 2  
   VGLITCH_RISING	   : 2  
   SECURE_LOCK	       : 4  
   SE_DEBUG	       : 0  
   DGLITCH	           : 2  
   SE_ICACHE	       : 4  
     
   Tamper Filter  
   Filter Period   : 10  
   Filter Threshold : 6  
   Reset Threshold  : 5  
     
   Tamper Flags  
   Digital Glitch Detector Always On: Disabled  
   DONE  
   ```  
   > **Note**: The `SECURE_BOOT_PAGE_LOCK_FULL` and `SECURE_BOOT_PAGE_LOCK_NARROW` flags are not supported in Series 3.

##### Tamper Disable and Roll Challenge

See Platform Sample app for PRS connections.

The tamper disable was designed with three organizations in mind:

1. The Direct Customer to whom Silicon Labs sells the chip. This chip has the Public Command Key installed in the SE OTP.
2. The Product Company is a customer of the Direct Customer. This is applicable if the Direct Customer is creating a white-labeled product for another company or a sub-component that goes into another company’s product.
3. The Debug 3rd Party could be anyone, internal or external, that the Product Company decides is qualified to debug the device.

Because the Public Command Key is installed into the SE OTP of a large number of devices and cannot be changed, the corresponding Private Command Key must be guarded by a very stringent process. If this Private Command Key is ever leaked, all the devices programmed with the corresponding Public Command Key will be compromised.

A tamper disable use case is described in the following figure, and the signing process is performed by a Hardware Security Module (HSM).

![Tamper Disable Use Case](/efr32-secure-vault-tamper/0.3/images/sld715-tamper-disable-use-case.png)

The tamper disable flow moving across the time axis from left to right is explained below:

1. The Product Company creates a Private/Public Certificate Key pair for each device. Because the key pair is assigned only to a single device, the company may not need to protect the Private Certificate Key as securely as the Private Command Key by the Direct Customer.  
   In this example, the Private/Public Certificate Key pair (`cert_key.pem` and `cert_pubkey.pem`) is generated by running the `util genkey` command.  
   ```sh  
   commander util genkey --type ecc-p256 --privkey cert_key.pem --pubkey cert_pubkey.pem  
   ```  
   ```sh  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to cert_key.pem  
   Writing public key file in PEM format to cert_pubkey.pem  
   DONE  
   ```
2. The Public Certificate Key (`cert_pubkey.pem`) for each device is passed to the Silicon Labs Direct Customer. The part number and serial number are also required if Direct Customer cannot access the device.  
   Run the security status command to get the device serial number. The `--serialno` option is for the J-Link serial number of the WSTK.  
   ```sh  
   commander security status --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   SE Firmware version	   : 1.2.9  
   Serial number	       : 000000000000000014b457fffe0f77ce  
   Debug lock	           : Disabled  
   Device erase	       : Enabled  
   Secure debug unlock	   : Disabled  
   Tamper status	       : OK  
   Secure boot	           : Disabled  
   Boot status	           : 0x20 - OK  
   Command key installed  : True  
   Sign key installed	   : False  
   DONE  
   ```
3. The Direct Customer then places that Public Certificate Key in the access certificate. The access certificate is per device because it contains the unique device serial number. This certificate is generated once upon creation of the device, and thereafter, is generally only modified when the Private/Public Certificate Key pair is changed by the Product Company.  
   The following two steps are **OPTIONAL** for customization of Authorizations and Tamper Authorizations.  
   - (Optional) Run the `security genauth` command to generate the default certificate authorization file (`certificate_authorization.json`).    
     ```sh    
     commander security genauth -o certificate_authorizations.json --nostore --serialno 440030580    
     ```    
     ```sh    
     DONE    
     ```  
   - (Optional) Use a text editor to modify the default Authorizations and Tamper Authorizations in the `json` file.  
   Run the `security gencert` command with the following parameters from the Product Company to generate an unsigned access certificate (`access_certificate.extsign`) in Security Store:  
   - Device part number  
   - Device serial number  
   - Public Certificate Key  
   ```sh  
   commander security gencert --device EFR32MG21B010F1024 --deviceserialno 000000000000000014b457fffe0f77ce  
   --cert-pubkey cert_pubkey.pem --extsign  
   ```  
   ```sh  
   Authorization file written to Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/ certificate_authorizations.json  
   Cert key written to Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/ cert_pubkey.pem  
   Created an unsigned certificate in Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/ access_certificate.extsign  
   DONE  
   ```  
   **Notes**:  
   - The `--extsign` option to create an unsigned access certificate is only available in Simplicity Commander Version 1.11.2 or above.  
   - The unsigned access certificate is generated with the default certificate authorization file (`certificate_authorization.json`) which uses `0x0000003e` for Authorizations and `0xffffffb6` (HSE-SVH device) for Tamper Authorizations.  
   - (Optional) Use `--authorization` option if the customized json file generated in the above optional steps is used.  
   ```sh  
   commander security gencert --device EFR32MG21B010F1024 --authorization certificate_authorizations.json  
   --deviceserialno 000000000000000014b457fffe0f77ce --cert-pubkey cert_pubkey.pem –extsign –outfile access_certificate.extsign  
   ```
4. The signing of the access certificate can be done by passing an unsigned access certificate to a Hardware Security Module (HSM) containing the Private Command Key.  
   In this example, the OpenSSL is used to sign the access certificate (`access_certificate.extsign`) in Security Store with the Private Command Key (`command_key.pem`). The access certificate signature is in the `cert_signature.bin` file.  
   ```sh  
   openssl dgst -sha256 -binary -sign command_key.pem -out cert_signature.bin access_certificate.extsign  
   ```  
   Run the `util signcert` command with the following parameters to verify the signature and generate the signed access certificate (`access_certificate.bin`):  
   - Unsigned access certificate  
   - Access certificate signature  
   - Public Command Key  
   ```sh  
   commander util signcert access_certificate.extsign --cert-type access --signature cert_signature.bin  
   --verify command_pubkey.pem --outfile access_certificate.bin  
   ```  
   ```sh  
   R = 76CDC5BA18E5248FDA5418002F250F149B449829A005D6F0726268016CC53ED4  
   S = E4B8ABA2CF742B0E6CC5BA2C1023D76BEEF3C4A11DA97CC4D23459F32237A206  
   Successfully verified signature  
   Successfully signed certificate  
   DONE  
   ```  
   **Notes**:  
   - Put the required files in the same folder to run the command.  
   - The `util signcert` command for access certificate is only available in Simplicity Commander Version 1.11.2 or above.  
   - The access certificate signature can be in a Raw or Distinguished Encoding Rules (DER) format.
5. The access certificate is passed to the Product Company. The purpose of the access certificate is to grant overall debug access capabilities to the Product Company and authorize them to allow third parties to debug the device. The Product Company can now use the access certificate to generate the Disable Tamper Token. The same access certificate can be used to generate as many Disable Tamper Tokens as necessary without having to ever go back to the Direct Customer.
6. To create the Disable Tamper Token, a debug session must be started with the device and the challenge value (which is a random number `Challenge 1` in this example) should be read out to generate the challenge response.  
   Run the `security gencommand` command to generate the challenge response without disable tamper command signature and store it in a file (`command_unsign.bin`).  
   ```sh  
   commander security gencommand --action disable-tamper --disable-param 0x00fa0000 -o command_unsign.bin  
   --nostore --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   Unsigned command file written to:  
   command_unsign.bin  
   DONE  
   ```  
   **Notes**:  
   - The tamper disable mask (`0x00fa0000`) is based on the Tamper platform example on EFR32xG21B devices (See readme.md in the Platform sample).  
   - If the `--disable-param` option is not provided, it will restore all tamper sources (`0xffffffb6`) by default.
7. The challenge response is then cryptographically hashed (SHA-256) to create a digest. The digest is then signed by the Private Certificate Key to generate the disable tamper command signature.  
   The signing of the challenge response can be done by passing an unsigned challenge response to a Hardware Security Module (HSM) containing the Private Certificate Key.  
   In this example, the OpenSSL is used to sign the challenge response (`command_unsign.bin`) with the Private Certificate Key (`cert_key.pem`). The disable tamper command signature is in the `command_signature.bin` file.  
   ```sh  
   openssl dgst -sha256 -binary -sign cert_key.pem -out command_signature.bin command_unsign.bin  
   ```
8. Run the `security disabletamper` command with the access certificate (`access_certificate.bin`) from Direct Customer and disable tamper command signature (`command_signature.bin`) in step 7 to generate the Disable Tamper Token.  
   ```sh  
   commander security disabletamper --disable-param 0x00fa0000 --cert access_certificate.bin  
   --command-signature command_signature.bin EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   Certificate written to Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/ device_000000000000000014b457fffe0f77ce/access_certificate.bin  
   R = A70834D97640A92510D151765F0EED6C6A05CB8BE81E06E905C230ED24E71659  
   S = 9B69C113C2B7DEE60BF0BC7D72719F7F9465840D68EADBBB4F9BCE7A1267B936  
   Command signature is valid  
   Tamper successfully disabled.  
   Command disable tamper payload was stored in Security Store  
   DONE  
   ```  
   **Notes**:  
   - Put the required files in the same folder to run the command.  
   - The disable tamper command signature can be in a Raw or Distinguished Encoding Rules (DER) format.  
   - Simplicity Commander Version 1.11.2 or above is required to support signature in DER format.
9. (Alternative) Key protection is not required if the Private Certificate Key is ephemeral. Steps 6 to 8 can be implemented by running the `security disabletamper` command with the access certificate (`access_certificate.bin`) from the Direct Customer and Private Certificate Key (`cert_key.pem`) to generate the Disable Tamper Token.  
   ```sh  
   commander security disabletamper --disable-param 0x00fa0000 --cert access_certificate.bin --cert-privkey  
   cert_key.pem --device EFR32MG21B010F1024 --serialno 440030580  
   ```  
   ```sh  
   Certificate written to Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/access_certificate.bin  
   Cert key written to Security Store:  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/cert_pubkey.pem  
   Created unsigned disable tamper command  
   Signed disable tamper command using  
   C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/cert_key.pem  
   Tamper successfully disabled.  
   Command disable tamper payload was stored in Security Store  
   DONE  
   ```
10. The Disable Tamper Token (aka `Command disable tamper payload`) file (`tamper_payload_111110100000000000000000.bin`, where `111110100000000000000000` is `0x00fa0000` for tamper disable mask) is stored in the Security Store. The location in Windows is `C:\Users\<PC user name>\AppData\Local\SiliconLabs\commander\SecurityStore\device_<Serial number>\challenge_<Challenge value>`.  
    ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image71.jpg)  
    Users can also use the `security getpath` command to get the path of the Security Store or a specified device.  
    ```sh  
    commander security getpath  
    ```  
    ```sh  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore  
    DONE  
    ```  
    ```sh  
    commander security getpath --deviceserialno 0000000000000000588e81fffe70350d  
    ```  
    ```sh  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_0000000000000000588e81fffe70350d  
    DONE  
    ```
11. The Disable Tamper Token and the device are now delivered to the Debug 3rd Party.  
    Run the `security gencommand` command to create the Security Store to place the Disable Tamper Token file.  
    ```sh  
    commander security gencommand --action disable-tamper --disable-param 0x00fa0000  
    --device EFR32MG21B010F1024 --serialno 440030580  
    ```  
    ```sh  
    Unsigned command file written to Security Store:  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/challenge_8e7f73e6322edda06b62997155334f29/ disable_tamper_command_to_be_signed09_08_2021.bin  
    DONE  
    ```  
    Copy the Disable Tamper Token file (`tamper_payload_111110100000000000000000.bin`) from Product Company to the Windows Security Store `challenge_<Challenge value>` folder located in `C:\Users\<PC user name>\AppData\Local\SiliconLabs\commander\SecurityStore\device_<Serial number>\challenge_<Challenge value>`.
12. The device compares the Disable Tamper Token contents with its internal serial number, challenge value, and Public Command Key to determine the token’s authenticity. If authentic, it will execute the disable tamper command to restore the default levels on the tamper disable mask (`0xfa000000`); otherwise, it will ignore the command.  
    Run the `security disabletamper` command to disable the tamper.  
    ```sh  
    commander security disabletamper --disable-param 0x00fa0000 --device EFR32MG21B010F1024  
    --serialno 440030580  
    ```  
    ```sh  
    Disabling tamper with tamper payload:  
    C:/Users/<username>/AppData/Local/SiliconLabs/commander/SecurityStore/device_000000000000000014b457fffe0f77ce/challenge_8e7f73e6322edda06b62997155334f29/ tamper_payload_111110100000000000000000.bin  
    Tamper successfully disabled.  
    DONE  
    ```  
    > **Note**: Users can verify the Disable Tamper Token by following steps 4 to 6 in [Tamper Disable](08-tamper-disable) if the EFR32xG21B device is running in the Normal mode of the SE Manager Tamper platform example.
13. The Debug 3rd Party can now use this same Disable Tamper Token to disable the tamper (step 12), over and over again after each power-on or pin reset, until they have finished debugging the device.
14. Once the Debug 3rd Party has finished debugging, they will send the device back to the Product Company.
15. Once the Product Company receives the device, they will immediately start a debug session to roll the challenge (from `Challenge 1` to `Challenge 2` in this example). Rolling the challenge will effectively invalidate any Disable Tamper Token that has been previously given to any third party.  
    Run the `security rollchallenge` command and reset the device to invalidate the current Disable Tamper Token. The challenge cannot be rolled before it has been used at least once; that is, by running the `security disabletamper` or `security unlock` command.  
    ```sh  
    commander security rollchallenge --device EFR32MG21B010F1024 --serialno 440030580  
    ```  
    ```sh  
    Challenge was rolled successfully.  
    DONE  
    ```  
    The unlock token is invalidated after rolling the challenge because any previously issued Disable Tamper Token now contains a different challenge value (`Challenge 1`) than the challenge value currently in the device (`Challenge 2`).  
    The validation process of any previously issued Disable Tamper Token will always fail until a new Disable Tamper Token is issued with a current matching challenge value (`Challenge 2`).  
    > **Note**: Direct Customer can directly use the Private Command Key on the connected chip to generate the Disable Tamper Token in Security Store. But it has a high risk (cannot use HSM) to leak the Private Command Key to a 3rd party when using this approach.  
    ```sh  
    commander security disabletamper --disable-param 0x00fa0000 --command-key command_key.pem  
    --device EFR32MG21B010F1024 --serialno 440030580  
    ```

#### Appendix A: Examples with Simplicity Studio

##### Overview

The security operations are performed in the Security Settings of Simplicity Studio. This application note uses Simplicity Studio v5.4.0.0. The procedures and pictures may be different on the other version of Simplicity Studio 5.

1. Right-click the selected debug adapter **RB (ID:J-Link serial number)** to display the context menu.  
   ![Debug Adapters Context Menu](/efr32-secure-vault-tamper/0.3/images/sld715-image72.jpg)
2. Click **Device configuration...** to open the **Configuration of device: J-Link Silicon Labs (serial number)** dialog box. Click the **Security Settings** tab to get the selected device configuration.  
   ![Configuration on Selected Device](/efr32-secure-vault-tamper/0.3/images/sld715-image73.png)

##### Provision Public Command Key and Tamper Configuration

This example focuses on provisioning the Public Command Key and tamper configuration. It skips the procedures for provisioning of the Public Sign Key and Secure Boot Enabling.

1. Run the `util keytotoken` command to convert the Public Command Key file (PEM format) into a text file (`command_pubkey.txt`).  
   ```sh  
   commander util keytotoken command_pubkey.pem --outfile command_pubkey.txt  
   ```  
   ```sh  
   Writing EC tokens to command_pubkey.txt...  
   DONE  
   ```
2. Open the **Security Settings** of the selected device as described in [Using Simplicity Studio](09-examples#using-simplicity-commander).
3. Click [**Start Provisioning Wizard...**] in the upper right corner to display the **Secure Initialization** dialog box.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image74.jpg)
4. Click [**Edit**] to open the **Tamper Source Configuration** dialog box. Use the dropdown menus to modify the default tamper responses to the desired configuration. Click [**OK**] to exit.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image75.png)
5. Click [**Next >**]. The **Security Keys** dialog box is displayed.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image76.jpg)
6. Using a text editor, open the `command_pubkey.txt` file generated in step 1.  
   ```sh  
   MFG_SIGNED_BOOTLOADER_KEY_X : B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4  
   MFG_SIGNED_BOOTLOADER_KEY_Y : 7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63  
   ```
7. Check **Enable Writing Command Key**. Copy the Public Command Key (X-point `B1BC...` first, then Y-point `7C04...`) to the **Key:** box under **Command Key:**.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image77.jpg)  
   > **Note**: This example does not enable the secure boot (not checking **Enable Writing Sign Key** option).
8. Click [**Next >**]. The **Secure Locks** dialog box is displayed. The **Debug locks** are set by default. Uncheck **Enable secure debug unlock** and **Enable debug lock**.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image78.jpg)
9. Click [**Next >**] to display the **Summary** dialog box. Verify the tamper configuration and Public Command Key in the **Provisioning Summary** are correct.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image79.png)
10. If the information displayed is correct, click [**Provision**]. Click [**Yes**] to confirm.  
    ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image80.png)  
    > **Note**: The Public Command Key and tamper configuration cannot be changed once written.
11. The **Provisioning Status** is displayed in the **Summary** dialog box.  
    ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image81.png)
12. Click [**Done**] to exit the provisioning process. The device configuration is updated.  
    ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image82.png)

##### Tamper Disable and Roll Challenge

1. Open **Security Settings** of the selected device as described in [Using Simplicity Studio](09-examples#using-simplicity-studio).
2. Click [**Roll Challenge**] to generate a new challenge value to invalidate the Disable Tamper Token for tamper disable. Click [**OK**] to exit.  
   ![screenshot](/efr32-secure-vault-tamper/0.3/images/sld715-image83.jpg)

#### Appendix B: Platform Examples

##### Overview

Simplicity Studio 5 includes the [SE Manager platform examples](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-getting-started/start-a-project#examples) for Secure Tamper. Refer to the corresponding readme file for details about the SE Manager example. This file also includes the procedures to create the project and run the example.

<table>
    <thead>
        <tr>
            <th>Category</th>
            <th>SE Manager Platform Example</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Tamper provisioning and runtime operations</td>
            <td>SoC SE Manager Tamper</td>
            <td>
                Sample application to:
                <ul>
                    <li>provision tamper settings</li>
                    <li>temporarily disable tamper and roll challenge</li>
                    <li>Implement an interrupt handler for a filtered tamper source</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

##### Adapting PRS Tamper for Custom Hardware

The platform examples are designed to work with Silicon Labs development kits. To adapt the code to work with custom hardware a few steps are required as follows. In the sample application these steps are found in `init_tamper_prs` of the `app_se_manager_tamper.c` source file:

1. Set up the GPIO pin as an input. The sample application demonstrates calls to set up the GPIO. It is recommended to install the ‘simple button’ software component to ensure that the necessary drivers are installed.
2. Set up an unused PRS channel as a producer. The sample application uses PRS channels 6, 7 and 8. Refer to the reference manual for your device to determine the source and signal for GPIO. The sample application demonstrates API calls for Series 2 and Series 3 devices.
3. Connect the PRS channel chosen in the previous step to the desired tamper signal. Tamper signals are named `CONSUMER_SETAMPER_TAMPERSR\<bit\>`, where bit is the bit position of the PRS tamper signal. Refer to [Tamper Sources](05-tamper-sources) for the bit positions of PRS tamper signals in the EFR32xG21B and [Appendix C: Tamper Sources Reference](12-appendix-c-tamper-sources-reference) for the bit positions of PRS tamper signals in other devices. The sample application demonstrates calls to perform this task.

#### Appendix C: Tamper Sources Reference

This section provides the tamper sources for devices other than EFR32xG21B.

##### Tamper Sources on Other Series 2 HSE-SVH Devices

|**Type**|**Number**|**Name**|**Description**|**Default Level**|
|---|---|---|---|---|
|SE Hardware|0|Reserved|—|—|
|"|1|Filter counter|Filter counter reached the configured threshold value|0 (Ignore)|
|"|2|SE watchdog|Internal SE watchdog expired|4 (Reset)|
|"|3|Reserved|—|—|
|"|4|SE RAM ECC2|A 2-bit, non-correctable error in the SE RAM has occurred.|4 (Reset)|
|"|5|SE hard fault|The SE core has encountered a hard fault exception indicating that an invalid memory access was attempted.|4 (Reset)|
|"|6|Reserved|—|—|
|SE Software|7|SE software assertion|SE firmware has triggered an assertion, indicating that one of several sanity checks has failed and that normal operation cannot continue without a reset.|4 (Reset)|
|"|8|SE secure boot|Secure boot of SE firmware failed|4 (Reset)|
|"|9|User secure boot|Secure boot of host firmware failed|0 (Ignore)|
|"|10|Mailbox authorization|Unauthorized command received over the Mailbox interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|11|DCI authorization|Unauthorized command received over the DCI interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|12|OTP read|OTP or flash content could not be properly authenticated|4 (Reset)|
|"|13|Reserved|—|—|
|"|14|Self test|A check of the integrity of the SE's internal storage failed during boot up.|4 (Reset)|
|"|15|TRNG monitor|The TRNG monitor performs a number of tests on the collected entropy data. If any of these tests fail, this tamper source is triggered.|0 (Ignore)|
|Hardware|16|Secure lock|This tamper source indicates that the guarding mechanism (comparing the locks with their logical complement) of the debug port locks has failed.|4 (Reset)|
|"|17|Digital glitch|Digital Glitch detector detected an event|0 (Ignore)|
|"|18|Voltage glitch|Voltage Glitch Detector detected an event|0 (Ignore)|
|"|19|SE ICACHE|The SE's instruction cache uses a checksum to verify the integrity of the data. This tamper source is triggered if the checksum is invalid.|4 (Reset)|

|**Type**|**Number**|**Name**|**Description**|**Default Level**|
|---|---|---|---|---|
|"|20|SE RAM ECC1|SE RAM 1-bit ECC error occurred|0 (Ignore)|
|"|21|BOD [1]|Brown-Out-Detector threshold alert|4 (Reset)|
|"|22|Temperature sensor [1]|SE temperature is monitored to be within 5 degrees C of the limits for the device. If the limit is exceeded, this tamper source will be triggered.|0 (Ignore)|
|"|23|DPLL fall|DPLL lock failed low|0 (Ignore)|
|"|24|DPLL rise|DPLL lock failed high|0 (Ignore)|
|"|25|PRS0 or ETAMPDET|PRS consumer for SE Tamper 25 or ETAMPDET asserted|0 (Ignore)|
|"|26 - 31|PRS1 - 6 or PRS0 - 5 [1]|PRS consumer for SE Tamper 26 - 31 asserted|0 (Ignore)|

**Notes**:

- [1] These tamper sources are available down to EM2. Other sources are available in EM1 and above.
- On EFR32xG23B and later devices, the default behavior is to detect tamper events only when the SE core is active. To detect tamper events when the SE is not performing operations, call `sl_se_enter_active_mode()`. This prevents the SE from sleeping and will result in higher current draw.
- In other HSE-SVH devices, tamper sources 25 to 31 are used for External Tamper Detect (ETAMPDET) if present and PRS consumers. Devices with ETAMPDET (e.g. EFR32xG25B) will have 6 PRS consumers (26 to 31) and devices without ETAMPDET will have 7 PRS consumers (25 to 31).
- The **ETAMPDET** source gets triggered when any of the ETAMPDET channels are asserted.

##### Tamper Sources on SixG301 Devices

|**Type**|**Number**|**Name**|**Description**|**Default Level**|
|---|---|---|---|---|
|SE Hardware|0|Reserved|—|—|
|"|1|Filter counter|Filter counter reached the configured threshold value|0 (Ignore)|
|"|2|SE watchdog|Internal SE watchdog expired|4 (Reset)|
|"|3|Crypto error|HostSymCrypto (1)|4 (Reset)|
|"|4|SE RAM ECC2|A 2-bit, non-correctable error in the SE RAM has occurred.|4 (Reset)|
|"|5|Reserved|--|-|
|"|6|SE major fault|SE major fault detected(2)|4 (Reset)|
|SE Software|7|L2 ICACHE|L2 instruction cache error|4 (Reset)|
|"|8|Reserved|--|-|
|"|9|User secure boot|Secure boot of host firmware failed|0 (Ignore)|
|"|10|Mailbox authorization|Unauthorized command received over the Mailbox interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|11|DCI authorization|Unauthorized command received over the DCI interface. This can be triggered by either (1) an incorrectly signed debug unlock or tamper disable token or (2) attempting to export a non-exportable key.|0 (Ignore)|
|"|12|SE Software Assert|SE software triggers an assert|4 (Reset)|
|"|13|Reserved|—|—|
|"|14|Self test|A check of the integrity of the SE's internal storage failed during boot up.|4 (Reset)|
|"|15|TRNG monitor|The TRNG monitor performs a number of tests on the collected entropy data. If any of these tests fail, this tamper source is triggered.|0 (Ignore)|
|Hardware|16|Secure lock|This tamper source indicates that the guarding mechanism (comparing the locks with their logical complement) of the debug port locks has failed.|4 (Reset)|
|"|17|Glitch Detector|Any tamper detection|0 (Ignore)|
|"|18|OTP Alarm|OTP alarm triggered(3)|4 (Reset)|
|"|19|SE ICACHE|The SE's instruction cache uses a checksum to verify the integrity of the data. This tamper source is triggered if the checksum is invalid.|4 (Reset)|
|“|20|SE RAM ECC 1|SE RAM 1-bit ECC error|0 (Ignore)|
| |21|Brownout detect|Brown-out-detector threshold alert|4 (Reset)|
| |22|Temperature sensor|On-device temperature sensor|0 (Ignore)|
| |23|DPLL Lock|DPLL lock failure|0 (Ignore)|
| |24|SoC PLL|SoC PLL failure|0 (Ignore)|
| |25|eTamper detect|External tamper detect|0 (Ignore)|
| |26|KSU ECC 1|KSU ECC 1-bit error|0 (Ignore)|
| |27|KSU ECC 2|KSU ECC 2-bit error|4 (Reset)|
| |28|QSPI Reseed|QSPI reseed error|4 (Reset)|
| |29|PRS0|PRS channel 0 asserted|0 (Ignore)|
| |30|PRS1|PRS channel 1 asserted|0 (Ignore)|
| |31|PRS2|PRS channel 2 asserted|0 (Ignore)|

**Notes**:

1. HOSTSYMCRYPTO is the host cryptographic accelerator referred to as SYMCRYPTO in SixG301 reference manual.
2. The SE Major fault is triggered by any unrecoverable error in the SE code.
3. The OTP alarm is triggered if the OTP data cannot be read and verified.

### Authenticating Silicon Labs Devices using Device Certificates

#### Authenticating Silicon Labs Devices Using Device Certificates

> **Note: This section replaces _AN1268: Authenticating Silicon Labs Devices Using Device Certificates_. Further updates to this application note will be provided here**.

This application note describes how to authenticate a device as a genuine Silicon Labs product at any time during its life. The digital certificates for secure identity are stored in the device and the Silicon Labs Server. This secure identity feature is only available on Secure Vault High devices.

##### Key Points

- Secure identity on Secure Vault High devices
- Device certificate options
- Entity Attestation Token (EAT)
- Remote authentication process
- Examples for certificate chain verification and remote authentication

#### Introduction

One of the biggest challenges for connected devices is post-deployment authentication. Silicon Labs’ factory trust provisioning service with optional secure programming provides a secure device identity certificate, analogous to a birth certificate, for each individual silicon die during integrated circuit (IC) manufacturing. This enables post-deployment security, authenticity, and attestation-based health checks. The device certificate can be used to verify the authenticity of the device for its lifetime. When the certificate is checked, a digital signature confirms that the certificate received has not been tampered with.

The digital signature and certificates are major cryptographic tools to verify the device is authentic. These tools are described in the following sections.

##### Digital Signature

The digital signature is used to protect integrity and authenticity of an electronic message.

###### Digital Signature Example

Alice wants to give data to Bob, and Bob wants to make sure that the data came from Alice and has not been tampered with. Alice has a private/public key pair, and has previously given Bob her public key.

![Digital Signature](/authenticating-devices-using-device-certificates/0.2/images/sld790-digital-signature.png)

1. Alice  generates the hash (for example SHA256) of the data.
2. Alice's private key is used to sign the hash to create a signature. The hash is signed instead of the data itself because the signing operation is slow. Therefore it is more efficient to sign the hash instead of the arbitrarily large data.
3. The signature is attached to the end of the data.
4. The data and signature are given to Bob.
5. Bob independently generates the hash of the data.
6. The signature is verified with the hash and Alice’s public key, which results in a true or false outcome indicating if the data is valid.

> **Note**: This scheme requires distribution of Alice's public key.

##### Digital Certificates and Chain of Trust

In [Digital Signature Example](#digital-signature), Bob already had access to Alice’s public key, which he trusted. However, it is not always feasible to pre-share a public key with everyone for secure identity verification, and no mechanism exists to revoke or inactivate the public key in case it gets stolen.

A digital certificate is simply a small, verifiable data file that contains identity credentials and a public key. That data is then signed either with the corresponding private key, or a different private key. The digital certificate can be used to prove the ownership of a public key.

- If it is signed using the corresponding private key, it is called a self-signed certificate.
- If it is signed by another private key, the owner of that private key is acting as a Certificate Authority (CA).
- A Certificate Authority (CA) is a trusted third party by both the owner and party relying on the certificate.

Concatenation of digital certificates builds a chain of trust.

- At the root of the chain is a self-signed certificate called a root certificate or a CA certificate.
- The root or CA certificate can be used to sign another certificate.

![Digital Certificates and Chain of Trust](/authenticating-devices-using-device-certificates/0.2/images/sld790-digital-certificates-and-chain-of-trust.png)

> **Note**: The private key is never included as part of the certificate – it must be stored separately and kept private. The security of the scheme relies on protecting the private keys.

##### Digital Certificates Verification

This section illustrates the process shown in [Digital Signature Example](#digital-signature), but using digital certificates.

###### Digital Certificates Verification Example

Alice wants to give data to Bob, signed with her private key. Alice has a digital certificate signed by a trusted third party (CA) in addition to her private key. Bob has a certificate from the trusted CA but nothing else is previously shared.

![Digital Certificate Verification](/authenticating-devices-using-device-certificates/0.2/images/sld790-digital-certificate-verification.png)

1. Alice uses her private key to sign the data.
2. Alice gives the data, signature, and her certificate to Bob.
3. Bob first verifies that Alice's certificate is valid, to prove Alice is the owner of the certificate's public key. This is done by verifying that Alice's certificate contains a valid signature created by the CA.
4. Bob then verifies the signature of the data using the public key in Alice's certificate.

> **Note**: The hash process in [Digital Signature Example](#digital-signature-example) is skipped in this example.

#### Secure Identification using MCU Device Certificates on Series 2 and Series 3 Devices

The goal of secure identification is to prove the ownership of a device's unique public key to an external service. It enables the external service to identify the device as legitimate and to authenticate device-generated data or messages.

##### Chain of Trust

A certificate chain of trust establishes a verifiable link between a device and a trusted authority by organizing certificates in a hierarchical structure. At the top of the certificate chain is a root certificate authority (CA), which is implicitly trusted by the system verifying the device. The factory and batch certificates, are used to delegate trust while limiting exposure of the root private key. At the end of the chain is the MCU device certificate, which uniquely identifies a device and is cryptographically bound to a private device certificate key securely stored on the device. During authentication, each certificate in the chain is validated by verifying its signature against the issuing certificate, allowing a remote party to confirm that the device identity ultimately traces back to a trusted root authority.

The chain of trust on Silicon Labs Series 2 and 3 devices is illustrated in the following figure. All certificates are in standard X.509 format, conform to [RFC-3280](https://datatracker.ietf.org/doc/html/rfc3280), TLS compliant with standard endpoint authentication methods, and use the signature algorithm ECDSA-prime256v1 with SHA256. A certificate can be revoked if required, for example when a private key is compromised or a security issue is identified. When revocation occurs, the certificate’s identifier is added to the Certificate Revocation List (CRL) stored on the Silicon Labs server. During certificate validation, remote devices or services consult the CRL, and any certificate listed as revoked is considered invalid and is no longer trusted for authentication or secure communication.

![Chain of Trust](/authenticating-devices-using-device-certificates/0.2/images/sld790-chain-of-trust.png)

###### Storage of the Certificates in the Chain of Trust

The certificates that make up the certificate chain are stored either in a server or the embedded device. Their storage location depends on the certificate’s purpose and the specific security feature subset enabled on the device. Refer to the table below for more details.

|Certificate|Issuer|Storage|Notes|
|---|---|---|---|
|Root Certificate|Root CA|Silicon Labs Server|Silicon Labs is a Certificate Authority.|
|Factory Certificate|Root CA|Silicon Labs Server|The factory certificate is static per factory.|
|Batch Certificate|Factory CA|Certificate stored on Device (location varies per device, see table below), Private Key stored in Silicon Labs HSM|The batch certificate is rolled per production batch.|
|MCU Device Certificate|Batch CA|Stored on Device (location varies per device, see table below)|The MCU device certificate is a unique cryptographic identity.|

###### Storage of the Batch and MCU Device Certificates on Series 2 and 3 Devices (heading level 7)

|Device Security Level|Batch and MCU Device Certificate Location|Availability|
|---|---|---|
|Series 2 Secure Vault High (HSE)|Both Certs stored in SE OTP|Programmed by default|
|Series 2 Secure Vault Mid (VSE and HSE)|Both Certs are injected in device flash|Only available through CPMS certificate injection|
|Series 3 Secure Vault (SixG301)|Both Certs are injected in device flash|Only available through CPMS certificate injection|

**Note**: For more information on CPMS, refer to the [CPMS User's Guide](https://docs.silabs.com/iot-security/latest/iot-security-cpms/).

##### Device Certificate

The device certificate is an X.509 certificate encoded in DER format, with an approximate size of 0.5 kB. This certificate is programmed into the device during manufacturing, either by default or custom-ordered through CPMS, and is stored in SE OTP or Flash, respectively. Because OTP memory cannot be altered after programming, the device certificate is immutable on HSE Secure Vault High devices, which prevents tampering or replacement after the device leaves the factory, ensuring a unique device identity.

Each device certificate uniquely identifies a device. The certificate’s Common Name (CN) field encodes the device’s 64-bit unique identifier (EUI), cryptographically binding the certificate to that specific device. In addition, the Issuer Common Name includes a batch number that identifies the factory and manufacturing batch in which the device was produced, enabling traceability and auditability across production runs. These fields can be customized via CPMS for further identification of individual products or manufacturers.

The device certificate has a validity period of 100 years starting from the device manufacture date. This extended validity is intentional and aligns with the expected lifetime of long-lived embedded devices, eliminating the need for certificate renewal in the field while still maintaining a unique device identity.

An example device certificate for a Series 2 device is shown in the following figure. The boxes in the image below highlight the following fields, in order they appear from the beginning of the certificate:

- The issuer of the device certificate (in this case, the Batch CA)
- The validity period
- The Common Name and device's EUI number
- The public key stored in the device certificate
- The certificate signature

![Device Certificate Example](/authenticating-devices-using-device-certificates/0.2/images/sld790-device-certificate-example.png)

The device certificate contains a device-specific public key, while the corresponding private key is generated and stored in different locations depending on security feature support of the device. See the table listed below for more details.

###### Storage of the Private Device Certificate Key

Protecting the device certificate private key is fundamental to maintaining a secure device identity. The device certificate private key is the cryptographic secret that proves ownership of the device certificate; if it is exposed, copied, or misused, the device identity can be cloned or impersonated, undermining authentication. As a result, the strength of the overall identity is directly tied to how well this private key is protected throughout the device lifecycle—from manufacturing and provisioning to deployment and field operation. This section describes methods available to protect the device certificate private key on Series 2 and Series 3 devices.

|Device Family|Device Certificate Private Key Storage Location|Protections Available|Notes|
|---|---|---|---|
|Series 2 HSE - SVH|Stored securely within SE OTP|Private key never leaves SE OTP|Standard on all Series 2 HSE - SVH devices|
|Series 2 HSE - SVM|Stored in Flash|Wrap the private key using TrustZone|Provisioned to user-defined location in flash via CPMS|
|Series 2 VSE - SVM|Stored in Flash|Wrap the private key using TrustZone|Provisioned to user-defined location in flash via CPMS|
|Series 3 Secure Vault|Stored in Flash|Wrap the private key using Secure Key Storage Feature|Provisioned to user-defined location in flash via CPMS|

##### Secure Identity Signatures and Verification

###### Signing and Verification Process

The signing and verification processes for the certificate chain are shown in the figures below.

The certificate signing process is done during the manufacturing process in order to establish the certificate chain of trust. The root of trust is the self-signed root certificate. The root certificate private key is used to sign the factory certificate, the factory certificate private key is used to sign the batch certificate, and so on. Once signed, the device certificate and batch certificates are stored on the device, either in flash or the SE depending on device security level, forming the chain that can later be presented during attestation.

![Signing for Certificates](/authenticating-devices-using-device-certificates/0.2/images/sld790-signing-for-certificates.png)

The certificate chain verification process is done as the first part of the remote authentication process in order to validate the certificate chain of trust. The verification process begins by verifying the device certificate signature with the batch certificate public key, then the batch certificate signature is verified with the factory certificate public key, and so on. Once validated, this proves the device certificate issued is authentic by a trusted root. The rest of the remote authentication process is covered in detail in ([Remote Authentication Process](06-r-remoteauthenticationprocess)).

![Verification for Certificates](/authenticating-devices-using-device-certificates/0.2/images/sld790-verification-for-certificates.png)

#### Device Certificate Options

The HSE-SVH devices are each programmed with a MCU device certificate during IC production. The device certificate is signed with the private batch key allowing the device certificate to be validated against the Silicon Labs certificate chain [Verification for Certificates](03-r-secureidentity#signing-and-verification) and [Certificate Chain Verification](08-r-examples#certificate-chain-verification).

The device certificate private key never leaves the Secure Key Storage on the HSE-SVH device.
Three device certificate options (standard, modified, and external) are provided to meet different requirements. Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://www.silabs.com/developers/custom-part-manufacturing-service) to program custom certificates at Silicon Labs factories. For more information about CPMS, see [Custom Part Manufacturing Service User's Guide](https://docs.silabs.com/iot-security/1.0.0/iot-security-cpms/).

##### Standard MCU Device Certificate

- Comes standard with Series 2 HSE-SVH devices.  
  - Can be injected into other Series 2 (HSE or VSE SVM devices) and Series 3 devices using CPMS.
- Cryptographically proves the device is an authentic Silicon Labs device.
- Does not protect against overproduction or counterfeit products that are built with authentic Silicon Labs devices.
- Signed to a Silicon Labs Certificate Authority (CA).
- The device can prove that it possesses the private key associated with the public key in its certificate by signing the response to a given challenge ([Remote Authentication Process](06-r-remoteauthenticationprocess) and [Certificate Chain Verification and Remote Authentication](08-r-examples#certificate-chain-verification-and-remote-authentication)).

![Standard Device Certificate](/authenticating-devices-using-device-certificates/0.2/images/sld790-standard.png)

##### Modified MCU Device Certificate

- Available as a customization service via CPMS on Series 2 and Series 3 devices.
- Cryptographically proves the device is an authentic Silicon Labs device that was produced for a specific OEM.
- Protects against overproduction by Contract Manufacturer (CM).
- Device Certificate X.509 fields can be customized, with some restrictions. See the [CPMS User's Guide](https://docs.silabs.com/iot-security/latest/iot-security-cpms/custom-certificates) for more details.
- Signed to a Silicon Labs Certificate Authority (CA).

![Modified Device Certificate](/authenticating-devices-using-device-certificates/0.2/images/sld790-modified.png)

##### External Chain - MCU Device Certificate

- Available as a customization service via CPMS on Series 2 and Series 3 devices.
- Cryptographically proves the device is an authentic Silicon Labs device that was produced for a specific OEM.
- Protects against overproduction by Contract Manufacturer (CM).
- Factory Certificate is custom for each OEM.
- Device Certificate and Factory Certificate X.509 fields can be customized, with some restrictions. See the [CPMS User's Guide](https://docs.silabs.com/iot-security/latest/iot-security-cpms/custom-certificates) for more details.
- Signed to a OEM Certificate Authority (CA).
- Root Certificate Authority is OEM-specified.
- Electronic delivery of all batch and device certificates signed under this OEM factory certificate is supported.

![External Device Certificate](/authenticating-devices-using-device-certificates/0.2/images/sld790-external.png)

#### Entity Attestation Tokens

In addition to the MCU Device Certificate identity, some Silicon Labs devices support both MCU device certificates and Secure Engine (SE) device certificates. The SE certificate is signed into the same batch certificate as the MCU device certificate, and is unique per device.

See table below for details on device support:

|Device Security Level|SE Device Certificate and Private Key Location|Availability|
|---|---|---|
|Series 2 Secure Vault High|Stored in SE OTP|Programmed by default|
|Series 2 Secure Vault Mid (VSE and HSE)|Not programmed on SVM devices|Unsupported on SVM|
|Series 3 Secure Vault (SixG301)|Stored in SE OTP|Programmed by default|

MCU device certificates are intended for application-level identity authentication through challenge-response authentication.

SE device certificates are intended for PSA-compliant attestation. PSA Entity Attestation Tokens (EAT) must be signed using the SE attestation private key, stored within the SE, to ensure claims are rooted in hardware-enforced security mechanisms. This token can either be a PSA Initial Attestation Token (IAT) or a Silicon Labs Security Configuration Token. Each of these tokens can be used to authenticate different claims of the SE or other security features of the device. These tokens can be used in additon to the MCU Device identity for many use cases, including secure provisioning of assets in an untrusted environment.

##### PSA EAT

An Entity Attestation Token (EAT) is a mini-report that is cryptographically signed. An EAT is encoded in either one of two standardized data formats: a Concise Binary Object Representation ([CBOR](https://www.rfc-editor.org/info/rfc7049)) or in the text-based format JSON. A digital signature is then used to protect its content. The technical specification defining the content of the EAT, which are claims about the hardware and the software running on a device, is specified by the Internet Engineering Task Force ([IETF](https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat-11#ref-RATS.Architecture)).

An EAT is a collection of Key ID-Value pairs relating to device pedigree or any other information one wants the device to attest. Collected data can originate from the Root of Trust (RoT), any protected area, or non-protected areas.

The EAT must be signed following the structure of the CBOR Object Signing and Encryption ([COSE](https://www.rfc-editor.org/info/rfc8152)) specification. For asymmetric key algorithms, the signature structure must be COSE-Sign1. A COSE-Sign1 is a CBOR encoded, self-secured data blob that contains headers, a payload, and a signature.

The primary need for EAT verification is to check correct formatting and verify signatures as for any token. In addition, though, the verifier can operate a policy where values of some of the claims in this profile can be compared to reference values, registered with the verifier for a given deployment, to confirm that the device is endorsed by the manufacturer supply chain.

###### PSA IAT

The following tables describe EAT claims that are used in the [PSA IAT](https://www.ietf.org/archive/id/draft-tschofenig-rats-psa-token-08.txt).

> **Note**: The actual claims returned from the tokens are SE firmware version dependent.

<table>
    <caption>Claims of PSA Initial Attestation Token</caption>
    <thead>
        <tr>
            <th>Key ID</th>
            <th>Claim</th>
            <th>Description</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>-75000</p>
            </td>
            <td>
                <p>Profile definition</p>
            </td>
            <td>
                <p>Name of a document that describes the profile of the report.</p>
            </td>
            <td>
                <p>PSA_IOT_PROFILE_1</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75001</p>
            </td>
            <td>
                <p>Client ID</p>
            </td>
            <td>
                <p>Represents the Partition ID of the caller.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75002</p>
            </td>
            <td>
                <p>Security lifecycle</p>
            </td>
            <td>
                <p>Represents the current life cycle stage of the PSA RoT.</p>
            </td>
            <td>
                <p>Device dependent</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75003</p>
            </td>
            <td>
                <p>Implementation ID</p>
            </td>
            <td>
                <p>Uniquely identifies the underlying immutable PSA RoT.</p>
            </td>
            <td>
                <p>Device dependent (32 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75004</p>
            </td>
            <td>
                <p>Boot seed</p>
            </td>
            <td>
                <p>Represents a random value created at system boot time.</p>
            </td>
            <td>
                <p>Random bytes (32 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75006</p>
            </td>
            <td>
                <p>Software components</p>
            </td>
            <td>
                <p>A list of Software components represents all the software loaded by PSA RoT.</p>
            </td>
            <td>
                <p>See the software components table below.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75008</p>
            </td>
            <td>
                <p>Auth challenge</p>
            </td>
            <td>
                <p>Input object from the caller. For example, this can be a cryptographic nonce or a hash of locally attested data. The length must be 32, 48, or 64 bytes.</p>
            </td>
            <td>
                <p>Random bytes or hash (32/48/64 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75009</p>
            </td>
            <td>
                <p>Instance ID</p>
            </td>
            <td>
                <p>Unique identifier of the instance.</p>
            </td>
            <td>
                <p>Device EUI-64 unique ID with type byte 0x06 (9 bytes)</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**:
> 
> - Key ID 75001: Client ID if present. Otherwise the value 1 for a token requested by a secure bus master and -1 for a non-secure master.
> - Key ID 75002 (For the definitions of these lifecycle states, please refer to the ARM [Platform Security Model](https://developer.arm.com/documentation/den0128/0101b/?lang=en)):
>   - UNKNOWN (`0x0000`)
>   - ASSEMBLY_AND_TEST (`0x1000`)
>   - PSA_ROT_PROVISIONING (`0x2000`)
>   - SECURED (`0x3000`)
>   - NON_PSA_ROT_DEBUG (`0x4000`)
>   - RECOVERABLE_PSA_ROT_DEBUG (`0x5000`)
>   - DECOMMISSIONED (`0x6000`)
> - Key ID 75003:
>   - Word[0]: Die revision
>   - Word[1]: HSE OTP version
>   - Word[2]: Bit indicating it is an HSE-SVH device
>   - Word[3]: Production version
>   - Word[4:7]: Reserved (zeros)

<table>
    <caption>Software Components</caption>
    <thead>
        <tr>
            <th>Key ID</th>
            <th>Type</th>
            <th>Description</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>1</p>
            </td>
            <td>
                <p>Measurement type</p>
            </td>
            <td>
                <p>A short string represents the role of this software component.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2</p>
            </td>
            <td>
                <p>Measurement value</p>
            </td>
            <td>
                <p>Represents a hash of the invariant software component in memory at startup time.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>4</p>
            </td>
            <td>
                <p>Version</p>
            </td>
            <td>
                <p>The issued software version is in the form of a text string.</p>
            </td>
            <td>
                <p>See note below</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- Key ID 1:  
  - HSE always exists — **PRoT**  
  - If secure booted Gecko Bootloader exists at flash starting address — **BL**  
  - If secure booted application exists at flash starting address — **ARoT**
- Key ID 2: SHA-256 hash (32 bytes) of the firmware (HSE, Gecko Bootloader, or application)
- Key ID 4: Version of the firmware (HSE, Gecko Bootloader, or application)

##### Security Configuration Token

The following tables describe EAT claims that are used in the Security Configuration Token.

<table>
    <caption>Claims of Security Configuration Token</caption>
    <thead>
        <tr>
            <th>Key ID</th>
            <th>Claim</th>
            <th>Description</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>-75000</p>
            </td>
            <td>
                <p>Profile definition</p>
            </td>
            <td>
                <p>Name of a document that describes the profile of the report.</p>
            </td>
            <td>
                <p>SILABS_1</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75008</p>
            </td>
            <td>
                <p>Auth challenge</p>
            </td>
            <td>
                <p>Input object from the caller. For example, this can be a cryptographic nonce or a hash of locally attested data. The length must be 32 bytes.</p>
            </td>
            <td>
                <p>Random bytes or hash (32 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-75009</p>
            </td>
            <td>
                <p>Instance ID</p>
            </td>
            <td>
                <p>Unique identifier of the instance.</p>
            </td>
            <td>
                <p>Device EUI-64 unique ID with type byte 0x06 (9 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-76000</p>
            </td>
            <td>
                <p>SE status</p>
            </td>
            <td>
                <p>Device HSE status.</p>
            </td>
            <td>
                <p>Device dependent (36 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-76001</p>
            </td>
            <td>
                <p>OTP configuration</p>
            </td>
            <td>
                <p>Device HSE OTP configuration if provisioned.</p>
            </td>
            <td>
                <p>Device dependent (24 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-76002</p>
            </td>
            <td>
                <p>Sign Key</p>
            </td>
            <td>
                <p>Public Sign Key in HSE OTP if provisioned.</p>
            </td>
            <td>
                <p>Device dependent (64 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-76003</p>
            </td>
            <td>
                <p>Command Key</p>
            </td>
            <td>
                <p>Public Command Key in HSE OTP if provisioned.</p>
            </td>
            <td>
                <p>Device dependent (64 bytes)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>-76004</p>
            </td>
            <td>
                <p>Tamper settings</p>
            </td>
            <td>
                <p>Current applied tamper settings.</p>
            </td>
            <td>
                <p>Device dependent (16 bytes)</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- All custom Silicon Labs claims will have a base of 76000.
- Key ID 76000: Refer to the _Get Status_ section in [Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/05-se-command-list#get-status) for the description (HSE-SVH) of the value.
- Key ID 76001: Refer to the _Read User Configuration_ section in [Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/05-se-command-list#read-user-configuration) for the description (HSE-SVH) of the value.
- Key ID 76002 and 76003: Refer to Key Reference for Public Sign Key and Public Command Key.
- Key ID 76004: One nibble per tamper source. Refer to the _Anti-Tamper Configuration_ section in [Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)](https://docs.silabs.com/iot-security/latest/efr32-dci-swd-programming/05-se-command-list#anti-tamper-configuration) for the description of the value.

#### Remote Authentication Process

Remote authentication is used to manage attestation by requesting that the device sign a challenge or [PSA EAT](05-r-entityattestationtoken). The remote device requests a challenge (random nonce) that is either signed directly, if using the MCU identity, or packaged into one of the EAT Tokens, if using the SE identity for authentication. The MCU Device Certificate Private Key is used to sign a challenge for authentication, the SE Device Certificate Private Key is used to sign a EAT (either the PSA IAT or security config token)

![Remote Authentication Process](/authenticating-devices-using-device-certificates/0.2/images/sld790-remote-authentication-process.png)

1. The remote device requests the SE or MCU device certificate and batch certificate from the Silicon Labs device.
2. The remote device looks up the factory certificate and root certificate from the Silicon Labs Server.
3. The remote device validates each certificate in the chain using the public key of each Issuer ([Verification for Certificates](03-r-secureidentity#signing-and-verification-signing-and-verification)).
4. The remote device then sends an attestation request to the device. The device uses the MCU Device Certificate Private Key on the chip to sign the challenge or the SE Device Certificate Private key to sign the EAT and sends the signature of challenge or EAT to the remote device.
5. The remote device requires a small library to validate the signature of challenge or EAT using the Device Certificate Public Key  in the device certificate.

#### Secure Engine Manager

The Secure Engine Manager provides thread-safe APIs for the SE's mailbox interface. The following table lists the SE Manager APIs related to secure identity. The SE Manager API document can be found at [https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager).

For the SE's mailbox interface, see section _Secure Engine Subsystem_ in [Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/03-r-secureelement).

<table>
    <caption>SE Manager API for Security Identity</caption>
    <thead>
        <tr>
            <th>SE Manager API</th>
            <th>Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_read_pubkey</p>
            </td>
            <td>
                <p>Read stored Public Device Key in the HSE-SVH device.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_cert</p>
            </td>
            <td>
                <p>Read stored certificates (DER format) in the HSE-SVH device.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_read_cert_size</p>
            </td>
            <td>
                <p>Read the size of stored certificates in the HSE-SVH device.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_attestation_get_psa_iat_token</p>
            </td>
            <td>
                <p>Get the PSA attestation token from the HSE with the given nonce.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_attestation_get_psa_iat_token_size</p>
            </td>
            <td>
                <p>Get the size of a PSA attestation token with the given nonce.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_attestation_get_config_token</p>
            </td>
            <td>
                <p>Get the security configuration token from the HSE with the given nonce.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_attestation_get_config_token_size</p>
            </td>
            <td>
                <p>Get the size of a security configuration token with the given nonce.</p>
            </td>
        </tr>
    </tbody>
</table>

#### Examples

##### Overview

The secure device authentication examples in this section are demonstrated using the following device and SE FW versions.

<table>
    <caption>Secure Attestation/Identity Examples</caption>
    <thead>
        <tr>
            <th>Example</th>
            <th>Device (Radio Board)</th>
            <th>HSE Firmware</th>
            <th>Tool</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Certificate chain verification using MCU Device Identity</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>Simplicity Commander and OpenSSL</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Certificate chain verification using MCU Device Identity</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>Simplicity Commander</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Certificate chain verification using MCU Device Identity</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>Simplicity Studio 5</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Certificate chain verification &amp; Remote authentication</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>SE Manager and MBedTLS</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Entity Attestation Token (EAT)</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>SE Manager</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Entity Attestation Token (EAT)</p>
            </td>
            <td>
                <p>EFR32MG21B010F1024IM32 (BRD4195A)</p>
            </td>
            <td>
                <p>Version 1.2.16</p>
            </td>
            <td>
                <p>Simplicity Commander</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: Unless specified in the example, these examples can apply to other HSE-SVH devices.

###### Root and Factory Certificates for Verification

Users can download the device root certificate (`Device-Root-CA-chain.pem`) and factory certificate (`Factory-chain.pem`) from [https://www.silabs.com/certificate-authority](https://www.silabs.com/certificate-authority).

![Cert Server](/authenticating-devices-using-device-certificates/0.2/images/sld790-cert-server.png)

For Simplicity Studio v5.3.0.0 and higher, the device root certificate (`device-root-prod.pem`) and factory certificate (`factory-prod.pem`) can be found in the Windows folder below.

C:\SiliconLabs\SimplicityStudio\v5\offline\common\certificates

###### Using Simplicity Commander

1. This application note uses Simplicity Commander v1.23.0. The procedures and console output may be different on the other versions of Simplicity Commander. The latest version of Simplicity Commander can be downloaded from [https://www.silabs.com/developers/mcu-programming-options](https://www.silabs.com/developers/mcu-programming-options).  
   ```sh  
   commander --version  
   ```  
   ```sh  
   Simplicity Commander 1v23p0b1960  
     
   JLink DLL version: 8.94  
   Qt 5.15.2 Copyright (C) 2017 The Qt Company Ltd.  
   EMDLL Version: 0v20p6b826  
   mbed TLS version: 2.16.6  
     
   DONE  
     
   ```
2. The Simplicity Commander's Command Line Interface (CLI) is invoked by `commander.exe` in the Simplicity Commander folder. The location for Simplicity Studio 5 in Windows is `C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\commander`. For ease of use, it is highly recommended to add the path of `commander.exe` to the system `PATH` in Windows.
3. If more than one Wireless Starter Kit (WSTK) is connected via USB, the target WSTK must be specified using the `--serialno \<J-Link serial number>` option.
4. If the WSTK is in debug mode OUT, the target device must be specified using the `--device \<device name>` option.

For more information about Simplicity Commander, see [Simplicity Commander Reference Guide](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/).

###### Using an External Tool

The certificate chain verification with MCU device identity example below uses OpenSSL to validate the certificate chain. The Windows version of OpenSSL can be downloaded from [https://slproweb.com/products/Win32OpenSSL.html](https://slproweb.com/products/Win32OpenSSL.html). This application note uses OpenSSL Version 1.1.1h (Win64).

```sh
openssl version
```

```sh
OpenSSL 1.1.1h  22 Sep 2020
```

The OpenSSL's Command Line Interface (CLI) is invoked by `openssl.exe` in the OpenSSL folder. The location in Windows (Win64) is `C:\Program Files\OpenSSL-Win64\bin`. For ease of use, it is highly recommended to add the path of `openssl.exe` to the system `PATH` in Windows.

###### Using Platform Examples

Simplicity Studio 5 includes the [SE Manager platform examples](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-getting-started/start-a-project#examples) for secure identity and attestation. This application note uses platform example of GSDK v3.2.3. The console output may be different on the other versions of GSDK.

Refer to the corresponding `readme.html` file for details about each SE Manager platform example. This file also includes the procedures to create the project and run the example.

##### Certificate Chain Verification with MCU Device Identity

Certificate chain verification is the process of making sure a given certificate chain is well-formed, valid, properly signed, and trustworthy. The certificate signature is verified using the public key in the issuer certificate ([Verification for Certificates](03-r-secureidentity#signing-and-verification)).

**Note**: The commands below will only verify the MCU Device Identity Certificate on devices with the MCU Device Certificate stored in SE OTP (Series 2 SVH).

###### Using Simplicity Commander and OpenSSL to verify the MCU Device Certificate

1. Run the `security readcert` command to save the batch certificate in PEM format.  
   ```sh  
   commander security readcert batch -o batch.pem --serialno 440030580  
   ```  
   ```sh  
   Writing certificate to batch.pem...  
   DONE  
   ```
2. Run the `security readcert` command to save the device certificate in PEM format.  
   ```sh  
   commander security readcert mcu -o device.pem --serialno 440030580  
   ```  
   ```sh  
   Writing certificate to device.pem...  
   DONE  
   ```
3. Get the root certificate (`device-root-prod.pem`) and factory certificate (`factory-prod.pem`) from the certificate folder in [Simplicity Studio](08-r-examples#root-and-factory-certificates-for-verification).
4. Use OpenSSL to display the certificate information (e.g., `device.pem`).  
   ```sh  
   openssl x509 -in device.pem -text -noout  
   ```  
   ```sh  
   Certificate:  
       Data:  
           Version: 3 (0x2)  
           Serial Number:  
               66:f8:5a:e6:b4:ef:6e:49:d3:36:95:63:c9:c3:99:13:e4:71:93:f6  
           Signature Algorithm: ecdsa-with-SHA256  
           Issuer: CN = Batch 1001317, O = Silicon Labs Inc., C = US  
           Validity  
               Not Before: Nov 19 15:10:33 2019 GMT  
               Not After : Nov 19 15:10:33 2119 GMT  
           Subject: C = US, O = Silicon Labs Inc., CN = EUI:14B457FFFE0F77CE DMS:086AEC3C645836BFB04D312F S:SE0 ID:MCU  
           Subject Public Key Info:  
               Public Key Algorithm: id-ecPublicKey  
                   Public-Key: (256 bit)  
                   pub:  
                       04:5c:4b:c9:b0:b3:ff:fa:99:81:c5:99:be:ff:ae:  
                       77:74:1a:f4:30:f1:1e:0e:2d:df:96:4b:ff:d2:46:  
                       fa:fa:e7:23:4b:79:cb:0a:c7:71:13:fa:7c:39:5f:  
                       e2:18:9e:4e:06:43:88:a7:9c:65:53:f3:a3:a1:06:  
                       81:e6:06:f2:11  
                   ASN1 OID: prime256v1  
                   NIST CURVE: P-256  
           X509v3 extensions:  
               X509v3 Basic Constraints: critical  
                   CA:FALSE  
               X509v3 Key Usage: critical  
                   Digital Signature, Non Repudiation, Key Encipherment  
               X509v3 Extended Key Usage: critical  
                   TLS Web Client Authentication  
       Signature Algorithm: ecdsa-with-SHA256  
           30:44:02:20:57:12:a4:84:d8:37:b8:c0:44:8f:16:ac:c1:a3:  
           be:a9:f1:16:38:9f:b9:a2:57:e6:12:49:bf:96:a9:a9:d2:b8:  
           02:20:5f:ae:22:f5:00:05:49:b1:da:ee:4a:84:48:70:27:97:  
           1c:40:2d:85:5f:f2:12:b3:8b:4a:d7:9a:ee:60:81:7c  
   ```
5. Use OpenSSL to verify the certificate chain from steps 1 to 3.

```sh
openssl verify -show_chain -CAfile device-root-prod.pem -untrusted factory-prod.pem -untrusted batch.pem device.pem
```

```sh
device.pem: OKChain:
depth=0: C = US, O = Silicon Labs Inc., CN = EUI:14B457FFFE0F7777 DMS:086AEC3CE650543EE73568DA S:SE0 ID:MCU (untrusted)
depth=1: CN = Batch 1001317, O = Silicon Labs Inc., C = US (untrusted)
depth=2: CN = Factory, O = Silicon Labs Inc., C = US (untrusted)
depth=3: CN = Device Root CA, O = Silicon Labs Inc., C = US
```

###### Using Simplicity Commander to Verify the MCU Device Certificate and Batch Certificate

Run the `security readcert` command to display the key information about the on-chip certificates (e.g., mcu, batch).

```sh
commander security readcert mcu --serialno 440030580
```

```sh
cert. version     : 3
serial number     : 87:30:83:3C:C9:60:E2:E4:1A:05:0D:17:1F:F0:38:47:7F:29:C4:46
issuer name       : CN=Batch 1172331, O=Silicon Labs Inc., C=US
subject name      : C=US, O=Silicon Labs Inc., CN=EUI:B43522FFFE950215 DMS:086AEC3CBCC884B8D38D896A S:SE0 ID:MCU
issued  on        : 2022-09-15 23:00:53
expires on        : 2122-09-15 23:00:53
signed using      : ECDSA with SHA256
EC key size       : 256 bits
basic constraints : CA=false
key usage         : Digital Signature, Non Repudiation, Key Encipherment
ext key usage     : TLS Web Client Authentication

DONE
```

```sh
commander security readcert batch --serialno 440030580
```

```sh
cert. version     : 3
serial number     : 26:88:29:A3:A7:3D:34:59
issuer name       : CN=Factory, O=Silicon Labs Inc., C=US
subject name      : CN=Batch 1172331, O=Silicon Labs Inc., C=US
issued  on        : 2022-08-23 15:57:18
expires on        : 2118-09-16 17:32:00
signed using      : ECDSA with SHA256
EC key size       : 256 bits
basic constraints : CA=true, max_pathlen=0
key usage         : Digital Signature, Key Cert Sign

DONE
```

###### Using Simplicity Studio v5 to Verify the MCU Device Certificate

This application note uses Simplicity Studio v5.2.1.1. The procedures and pictures may be different on the other versions of Simplicity Studio 5.

1. Right-click the selected debug adapter **RB (ID:J-Link serial number)** to display the context menu.  
   ![Device Config](/authenticating-devices-using-device-certificates/0.2/images/sld790-device-config.png)
2. Click **Device configuration...** to open the **Configuration of device: J-Link Silicon Labs (serial number)** dialog box. Click the **Security Settings** tab to get the selected device configuration.
3. The **MCU Certificate:** will display **Validated Successfully** if it passed the certificate chain verification process.  
   ![Cert Studio](/authenticating-devices-using-device-certificates/0.2/images/sld790-cert-studio.png)
4. Click **Certificate Details...** to browse the details of different certificates (e.g., Device MCU Certificate in the figure below).

![Device Cert](/authenticating-devices-using-device-certificates/0.2/images/sld790-device-cert.png)

##### Using SE Manager Examples for Certificate Chain Verification and Remote Authentication

The SE Manager Secure Identity platform example uses APIs in [SE Manager](07-r-secureenginemanager) and MBedTLS to emulate the processes in [Remote Authentication Process](06-r-remoteauthenticationprocess).

Click the `View Project Documentation` link to open the `readme.html` file.

![Si Example](/authenticating-devices-using-device-certificates/0.2/images/sld790-si-example.png)

The device simulates the operations in the remote device to eliminate the communications between different parties in this example. The factory certificate and root certificate are hard-coded in the `app_mbedtls_x509.c` file.

The MCU Device Certificate Private Key in the Secure Key Storage on the chip is used to sign the challenge from the remote device. Therefore this example can only run as-is on a chip with the [Standard MCU Device Certificate](04-r-devicecertoptions). It must be modified to be used on devices with an injected MCU Device Certificate, such as Series 2 SVM and Series 3 Secure Vault devices.

###### Step 1 in the Remote Authentication Process

```sh
SE Manager Secure Identity Example - Core running at 38000 kHz.
  . SE manager initialization... SL_STATUS_OK (cycles: 6 time: 0 us)

  . Secure Vault High device:
  + Read size of on-chip certificates... SL_STATUS_OK (cycles: 5296 time: 139 us)
  + Read on-chip device certificate... SL_STATUS_OK (cycles: 5138 time: 135 us)
  + Parse the device certificate (DER format)... SL_STATUS_OK (cycles: 167043 time: 4395 us)
  + Get the public device key in device certificate... OK
  + Read on-chip batch certificate... SL_STATUS_OK (cycles: 5080 time: 133 us)
  + Parse the batch certificate (DER format)... SL_STATUS_OK (cycles: 173151 time: 4556 us)
```

###### Steps 2 and 3 in the Remote Authentication Process (certificate chain printout is disabled)

```sh
. Remote device:
  + Parse the factory certificate (PEM format)... SL_STATUS_OK (cycles: 5373122 time: 141 ms)
  + Parse the root certificate (PEM format)... SL_STATUS_OK (cycles: 5448802 time: 143 ms)
  + Verify the certificate chain with root certificate... SL_STATUS_OK (cycles: 958730 time: 25229 us)
```

###### Steps 2 and 3 in the Remote Authentication Process (certificate chain printout is enabled)

```sh
. Remote device:
  + Parse the factory certificate (PEM format)... SL_STATUS_OK (cycles: 5373935 time: 141 ms)
  + Parse the root certificate (PEM format)... SL_STATUS_OK (cycles: 5449622 time: 143 ms)
  + Verify requested for (Depth 3) ... OK
      cert. version     : 3
      serial number     : 12:E6:A2:A5:9C:AA:27:F9
      issuer name       : CN=Device Root CA, O=Silicon Labs Inc., C=USsubject name      : CN=Device Root CA, O=Silicon Labs Inc., C=US
      issued  on        : 2018-10-10 17:32:00
      expires on        : 2118-09-16 17:32:00
      signed using      : ECDSA with SHA256
      EC key size       : 256 bits
      basic constraints : CA=true, max_pathlen=2
      key usage         : Digital Signature, Key Cert Sign, CRL Sign
  + Verify requested for (Depth 2) ... OK
      cert. version     : 3
      serial number     : 24:DC:7B:40:0C:32:9C:0A
      issuer name       : CN=Device Root CA, O=Silicon Labs Inc., C=USsubject name      : CN=Factory, O=Silicon Labs Inc., C=US
      issued  on        : 2018-10-10 17:33:00
      expires on        : 2118-09-16 17:32:00
      signed using      : ECDSA with SHA256
      EC key size       : 256 bits
      basic constraints : CA=true, max_pathlen=1
      key usage         : Digital Signature, Key Cert Sign, CRL Sign
  + Verify requested for (Depth 1) ... OK
      cert. version     : 3
      serial number     : 23:09:DA:39:B4:78:05:AA
      issuer name       : CN=Factory, O=Silicon Labs Inc., C=USsubject name      : CN=Batch 1001317, O=Silicon Labs Inc., C=US
      issued  on        : 2019-10-17 21:20:20
      expires on        : 2118-09-16 17:32:00
      signed using      : ECDSA with SHA256
      EC key size       : 256 bits
      basic constraints : CA=true, max_pathlen=0
      key usage         : Digital Signature, Key Cert Sign
  + Verify requested for (Depth 0) ... OK
      cert. version     : 3
      serial number     : 66:F8:5A:E6:B4:EF:6E:49:D3:36:95:63:C9:C3:99:13:E4:71:93:F6
      issuer name       : CN=Batch 1001317, O=Silicon Labs Inc., C=USsubject name      : C=US, O=Silicon Labs Inc., CN=EUI:14B457FFFE0F77CE DMS:086AEC3C645836BFB04D312F S:SE0 ID:MCU
      issued  on        : 2019-11-19 15:10:33
      expires on        : 2119-11-19 15:10:33
      signed using      : ECDSA with SHA256
      EC key size       : 256 bits
      basic constraints : CA=false
      key usage         : Digital Signature, Non Repudiation, Key Encipherment
      ext key usage     : TLS Web Client Authentication
  + Verify the certificate chain with root certificate... SL_STATUS_OK (cycles: 9703861 time: 255 ms)
```

> **Note**: The longer processing time (255 ms) is due to the certificate chain printout.

###### Steps 4 and 5 (signature of a challenge) in the Remote Authentication Process

```sh
. Remote authentication:
  + Create a 16 bytes challenge (random number) in remote device for signing... SL_STATUS_OK (cycles: 3700 time: 97 us)
  + Sign challenge with private device key in Secure Vault High device... SL_STATUS_OK (cycles: 221983 time: 5841 us)
  + Get public device key in Secure Vault High device... SL_STATUS_OK (cycles: 199788 time: 5257 us)
  + Verify signature with public device key in Secure Vault High device... SL_STATUS_OK (cycles: 229054 time: 6027 us)
  + Verify signature with public device key in remote device... SL_STATUS_OK (cycles: 230442 time: 6064 us)

  . SE manager deinitialization... SL_STATUS_OK (cycles: 6 time: 0 us)
```

##### Using SE Manager Examples to Generate Entity Attestation Tokens (EAT)

These examples demonstrate how to retrieve the [EAT tokens](05-r-entityattestationtoken) from the Series 2 SVH or Series 3 Secure Vault device.

###### SE Manager - Attestation Platform Example

The SE Manager Attestation platform example uses APIs in [SE Manager](07-r-secureenginemanager) to retrieve the PSA initial attestation token and security configuration token from the SE. This example is only available on devices with an SE Device Certificate programmed, which includes Series 2 SVH and Series 3 Secure Vault (SixG301) devices.

Click the `View Project Documentation` link to open the `readme.html` file.

![Att Example](/authenticating-devices-using-device-certificates/0.2/images/sld790-att-example.png)

Press `SPACE` to cycle the challenge size for the PSA attestation token. Press `ENTER` to make a selection and run the program.

```sh
SE Manager Attestation Example - Core running at 38000 kHz.
Initializing SE Manager...
SL_STATUS_OK (cycles: 10 time: 0 us)

Select nonce size for the IAT token (32, 48 or 64 bytes).
Press SPACE to cycle through the options.
Press ENTER to make a selection.
    Current nonce size:  32
    Selected nonce size: 32
Calling sl_se_attestation_get_psa_iat_token...

SL_STATUS_OK (cycles: 661072 time: 17396 us)
```

**PSA Initial Attestation Token** (Refer to [Entity Attestation Token (EAT)](05-r-entityattestationtoken) for additional details)

```sh
PSA IAT token
=============
-------------------------------------------------------------------
Raw token:
d28443a10126a058e4a83a000124ff58204ca14d0bc8601cad2e511de1964e93
9338b6fc20f8231aa178ca79519b0ffae73a000124f7715053415f494f545f50
524f46494c455f313a00012500490614b457fffe0f77ce3a000124f8013a0001
24f91920003a000124fa5820011c00010600000001000000f2030f0000000000
0000000000000000000000003a000124fb58204922b7bbd31c0c81c9b0485ccf
b5396ec24ffa877ece441e11c947b791218cf83a000124fd81a3016450526f54
046830303031303230390258206d39caedba129297062b820ba6d85b3e432c44
3c8a8a31d3c6232be6906d38dc584030f9d61523204793965fc9eb2be788db9d
2b02692d877673c86ebffbfb6769984515d2f1a287a92d2c134c1024f20f018d
be952a2ccae7ed2980a9f242d02c9c

COSE_Sign1 structure:
d2    ; tag(18)
  84    ; array(4)
    43    ; byte_str(3)
      a10126
    a0    ; map(0)
    58    ; byte_str(228)
      a83a000124ff58204ca14d0bc8601cad2e511de1964e939338b6fc20f8231aa1
    78ca79519b0ffae73a000124f7715053415f494f545f50524f46494c455f313a
    00012500490614b457fffe0f77ce3a000124f8013a000124f91920003a000124
    fa5820011c00010600000001000000f2030f0000000000000000000000000000
    0000003a000124fb58204922b7bbd31c0c81c9b0485ccfb5396ec24ffa877ece
    441e11c947b791218cf83a000124fd81a3016450526f54046830303031303230
    390258206d39caedba129297062b820ba6d85b3e432c443c8a8a31d3c6232be6
    906d38dc
    58    ; byte_str(64)
      30f9d61523204793965fc9eb2be788db9d2b02692d877673c86ebffbfb676998
    4515d2f1a287a92d2c134c1024f20f018dbe952a2ccae7ed2980a9f242d02c9c
-------------------------------------------------------------------
Token claims:
a8    ; map(8)
  3a    ; int(-75008)
  58    ; byte_str(32)
    4ca14d0bc8601cad2e511de1964e939338b6fc20f8231aa178ca79519b0ffae7
  3a    ; int(-75000)
  71    ; text_str(17)
    "PSA_IOT_PROFILE_1"
  3a    ; int(-75009)
  49    ; byte_str(9)
    0614b457fffe0f77ce
  3a    ; int(-75001)
  01    ; int(1)
  3a    ; int(-75002)
  19    ; int(8192)
  3a    ; int(-75003)
  58    ; byte_str(32)
    011c00010600000001000000f2030f0000000000000000000000000000000000
  3a    ; int(-75004)
  58    ; byte_str(32)
    4922b7bbd31c0c81c9b0485ccfb5396ec24ffa877ece441e11c947b791218cf8
  3a    ; int(-75006)
  81    ; array(1)
    a3    ; map(3)
      01    ; int(1)
      64    ; text_str(4)
        "PRoT"
      04    ; int(4)
      68    ; text_str(8)
        "00010209"
      02    ; int(2)
      58    ; byte_str(32)
        6d39caedba129297062b820ba6d85b3e432c443c8a8a31d3c6232be6906d38dc

List of claims printed with human-friendly names:
  ARM PSA Nonce, Claim ID: -75008
  58    ; byte_str(32)
    4ca14d0bc8601cad2e511de1964e939338b6fc20f8231aa178ca79519b0ffae7

  ARM PSA Profile ID, Claim ID: -75000
  71    ; text_str(17)
    "PSA_IOT_PROFILE_1"

  ARM PSA / IETF EAT UEID, Claim ID: -75009
  49    ; byte_str(9)
    0614b457fffe0f77ce

  ARM PSA Partition ID, Claim ID: -75001
  01    ; int(1)

  ARM PSA Lifecycle, Claim ID: -75002
  19    ; int(8192)

  ARM PSA Implementation ID, Claim ID: -75003
  58    ; byte_str(32)
    011c00010600000001000000f2030f0000000000000000000000000000000000

  ARM PSA Boot seed, Claim ID: -75004
  58    ; byte_str(32)
    4922b7bbd31c0c81c9b0485ccfb5396ec24ffa877ece441e11c947b791218cf8

  ARM PSA Software components, Claim ID: -75006
  81    ; array(1)
    a3    ; map(3)
      01    ; int(1)
      64    ; text_str(4)
        "PRoT"
      04    ; int(4)
      68    ; text_str(8)
        "00010209"
      02    ; int(2)
      58    ; byte_str(32)
        6d39caedba129297062b820ba6d85b3e432c443c8a8a31d3c6232be6906d38dc
```

**Security Configuration Token** (Refer to [Entity Attestation Token (EAT)](05-r-entityattestationtoken) for additional details)

```sh
-------------------------------------------------------------------

Calling sl_se_attestation_get_config_token...
SL_STATUS_OK (cycles: 541281 time: 14244 us)

Config token
============
-------------------------------------------------------------------
Raw token:
d28443a10126a0590133a83a000124ff5820c3e3664dcc47711bf81734bc95f0
87d81dd841d73fc805fc9237c7b3dfa25c503a000124f76853494c4142535f31
3a00012500490614b457fffe0f77ce3a000128df582400000001000000000000
0000000000000000002000010209ffffffff00000025000000003a000128e058
1800000000100444400401041411224477242204420a0600053a000128e15840
c4af4ac69aab9512db50f7a26ae5b4801183d85417e729a56da974f4e08a562c
de6019dea9411332dc1a743372d170b436238a34597c410ea177024de20fc819
3a000128e25840b1bc6f6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc0
8440f0a4e1dca47c04119ed6a1be31b7707e5f9d001a659a051003e95e1b936f
05c37ea793ad633a000128e350150444400401041411224477142204425840b7
47d98be9cef8a91af0292a479a3fa499527018b97ac1188ddefb0fa6fcb9b3d1
d4159240a8663c8803a2ef7cebdf7644fa3394cf1057d612e1b3977d9de92d

COSE_Sign1 structure:
d2    ; tag(18)
  84    ; array(4)
    43    ; byte_str(3)
      a10126
    a0    ; map(0)
    59    ; byte_str(307)
    a83a000124ff5820c3e3664dcc47711bf81734bc95f087d81dd841d73fc805fc
    9237c7b3dfa25c503a000124f76853494c4142535f313a00012500490614b457
    fffe0f77ce3a000128df58240000000100000000000000000000000000000020
    00010209ffffffff00000025000000003a000128e05818000000001004444004
    01041411224477242204420a0600053a000128e15840c4af4ac69aab9512db50
    f7a26ae5b4801183d85417e729a56da974f4e08a562cde6019dea9411332dc1a
    743372d170b436238a34597c410ea177024de20fc8193a000128e25840b1bc6f
    6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc08440f0a4e1dca47c0411
    9ed6a1be31b7707e5f9d001a659a051003e95e1b936f05c37ea793ad633a0001
    28e35015044440040104141122447714220442
    58    ; byte_str(64)
    b747d98be9cef8a91af0292a479a3fa499527018b97ac1188ddefb0fa6fcb9b3
    d1d4159240a8663c8803a2ef7cebdf7644fa3394cf1057d612e1b3977d9de92d
-------------------------------------------------------------------
Token claims:
a8    ; map(8)
  3a    ; int(-75008)
  58    ; byte_str(32)
    c3e3664dcc47711bf81734bc95f087d81dd841d73fc805fc9237c7b3dfa25c50
  3a    ; int(-75000)
  68    ; text_str(8)
    "SILABS_1"
  3a    ; int(-75009)
  49    ; byte_str(9)
    0614b457fffe0f77ce
  3a    ; int(-76000)
  58    ; byte_str(36)
    000000010000000000000000000000000000002000010209ffffffff0000002500000000
  3a    ; int(-76001)
  58    ; byte_str(24)
    00000000100444400401041411224477242204420a060005
  3a    ; int(-76002)
  58    ; byte_str(64)
    c4af4ac69aab9512db50f7a26ae5b4801183d85417e729a56da974f4e08a562c
  de6019dea9411332dc1a743372d170b436238a34597c410ea177024de20fc819
  3a    ; int(-76003)
  58    ; byte_str(64)
    b1bc6f6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc08440f0a4e1dca4
  7c04119ed6a1be31b7707e5f9d001a659a051003e95e1b936f05c37ea793ad63
  3a    ; int(-76004)
  50    ; byte_str(16)
    15044440040104141122447714220442

List of claims printed with human-friendly names:
  ARM PSA Nonce, Claim ID: -75008
  58    ; byte_str(32)
    c3e3664dcc47711bf81734bc95f087d81dd841d73fc805fc9237c7b3dfa25c50

  ARM PSA Profile ID, Claim ID: -75000
  68    ; text_str(8)
    "SILABS_1"

  ARM PSA / IETF EAT UEID, Claim ID: -75009
  49    ; byte_str(9)
    0614b457fffe0f77ce

  SE Status, Claim ID: -76000
  58    ; byte_str(36)
    000000010000000000000000000000000000002000010209ffffffff0000002500000000

  OTP Configuration, Claim ID: -76001
  58    ; byte_str(24)
    00000000100444400401041411224477242204420a060005

  OTP MCU Boot key, Claim ID: -76002
  58    ; byte_str(64)
    c4af4ac69aab9512db50f7a26ae5b4801183d85417e729a56da974f4e08a562c
  de6019dea9411332dc1a743372d170b436238a34597c410ea177024de20fc819

  OTP MCU Auth key, Claim ID: -76003
  58    ; byte_str(64)
    b1bc6f6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc08440f0a4e1dca4
  7c04119ed6a1be31b7707e5f9d001a659a051003e95e1b936f05c37ea793ad63

  Current applied tamper settings, Claim ID: -76004
  50    ; byte_str(16)
    15044440040104141122447714220442
-------------------------------------------------------------------

Exiting...
SL_STATUS_OK (cycles: 8 time: 0 us)
```

> **Note**: The reserved tamper source in ID 76004 returns a value of 0 or 5.

###### Using Simplicity Commander to Verify the SE Device Certificate

The SE Device certificate can be read from the device using the readcert command.

```sh
commander security readcert se --serialno 440030580
```

```sh
cert. version     : 3
serial number     : B0:38:8C:E3:41:FB:B8:CD:DB:0D:A8:6A:BA:2A:81:88:AA:01:47:81
issuer name       : CN=Batch 1172331, O=Silicon Labs Inc., C=US
subject name      : C=US, O=Silicon Labs Inc., CN=EUI:B43522FFFE950215 DMS:086AEC3C122247BA83B66768 S:SE0 ID:SE
issued  on        : 2022-09-15 23:00:53
expires on        : 2122-09-15 23:00:53
signed using      : ECDSA with SHA256
EC key size       : 256 bits
basic constraints : CA=false
key usage         : Digital Signature, Non Repudiation, Key Encipherment
ext key usage     : TLS Web Client Authentication

DONE
```

Run the `security attestation` command to retrieve and validate the security configuration token from the SE. This command is currently supported only on Series 2 Secure Vault High devices.

```sh
commander security attestation --serialno 440030580
```

```sh
Certificate chain successfully validated up to Silicon Labs device root certificate.

-75008 ARM PSA nonce                   : e2d87794046ad3e752164dd8ecea63f27f0ee82af1112e13bc3ac2537ff366a2
-75000 ARM PSA Profile ID              : SILABS_1
-75009 ARM PSA/IETF EAT UEID           : 06b43522fffe950215
-76000 SE status                       : 000000000000000000000000000000020000002000010210000000000000000200000000
-76001 OTP configuration               : 00000000100444400401041411224477242204420a060005
-76003 MCU command key                 : b1bc6f6fa56640ed522b2ee0f5b3cf7e5d48f60be8148f0dc08440f0a4e1dca47c04119ed6a1be31b7707e5f9d001a659a051003e95e1b936f05c37ea793ad63
-76004 Current applied tamper settings : 15044440040104141122447714220442

Successfully validated signature of attestation token.
DONE
```

> **Note**: The reserved tamper source in ID 76004 returns a value of 0 or 5.

### Secure Key Storage

#### Secure Key Storage

> **Note: This section replaces _AN1271: Secure Key Storage_. Further updates to this application note will be provided here**.

Secure Key Storage is a feature in  High devices that allows for the protection of cryptographic keys by key wrapping. User keys are encrypted by the device's root key for non-volatile storage for later usage. This prevents the need for a key to be stored in plaintext format on the device, preventing attackers from gaining access to the keys through traditional flash-extraction or application attacks, and allowing for a potentially unlimited number of keys to be securely stored in any available storage.

Series 2 devices can use TrustZone to implement Secure Key Storage, so this feature is now also available on  Mid devices.

This document describes the operation and usage of this feature, and provides comparisons with other key storage methods.

##### Key Points

- Keys are encrypted or 'wrapped' with a  root key
- root key is not stored on the device, instead it is generated on each reset
- Wrapped keys are confidential to the , and can be stored in non-volatile memory safely
- Wrapped keys can be cached into  for usage at a later time
- TrustZone Secure Key Storage

#### Series 2 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

<table>
    <thead>
        <tr>
            <th>Level (1)</th>
            <th>SE Support</th>
            <th>Part (2)</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Secure Vault High (SVH)</p>
            </td>
            <td>
                <p>HSE only (HSE-SVH)</p>
            </td>
            <td>
                <p>Refer to <a href="https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/">IoT Endpoint Security Fundamentals</a> for details on supporting devices.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Vault Mid (SVM)</p>
            </td>
            <td>
                <p>HSE (HSE-SVM)</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>"</p>
            </td>
            <td>
                <p>VSE (VSE-SVM)</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Vault Base (SVB)</p>
            </td>
            <td>
                <p>N/A</p>
            </td>
            <td>
                <p>"</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security).
2. [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/).

Secure Vault Mid consists of two core security functions:

- Secure Boot: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- Secure Debug access control: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- Secure Key Storage: Protects cryptographic keys by "wrapping" or encrypting the keys using a root key known only to the HSE-SVH.
- Anti-Tamper protection: A configurable module to protect the device against tamper attacks.
- Device authentication: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th>Document</th>
            <th>Summary</th>
            <th>Applicability</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Secure Key Storage (this application note)</p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1504: Series 3 Security Overview</p>
            </td>
            <td>
                <p>High level overview of the security features included in Series 3 devices</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AN1509: Series 3 AXiP</p>
            </td>
            <td>
                <p>How to encrypt and authenticate memory contents</p>
            </td>
            <td>
                <p>Series 3</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

<table>
    <thead>
        <tr>
            <th>Key Name</th>
            <th>Customer Programmed</th>
            <th>Purpose</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Public Sign key (Sign Key Public)</p>
            </td>
            <td>
                <p>Yes</p>
            </td>
            <td>
                <p>Secure Boot binary authentication and/or OTA upgrade payload authentication</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Public Command key (Command Key Public)</p>
            </td>
            <td>
                <p>Yes</p>
            </td>
            <td>
                <p>Secure Debug Unlock or Disable Tamper command authentication</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>OTA Decryption key (GBL Decryption key) aka AES-128 Key</p>
            </td>
            <td>
                <p>Yes</p>
            </td>
            <td>
                <p>Decrypting GBL payloads used for firmware upgrades</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Attestation key aka Private Device Key</p>
            </td>
            <td>
                <p>No</p>
            </td>
            <td>
                <p>Device authentication for secure identity</p>
            </td>
        </tr>
    </tbody>
</table>

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 and Series 3 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 and Series 3 devices and modules.

#### Introduction

The HSE isolates cryptographic functions and data from the host Cortex-M33 core. It is used to accelerate cryptographic operations as well as to provide a method to securely store keys. This application note will cover the Secure Key Storage feature of the HSE-SVH devices.

The HSE contains one-time programmable memory (OTP) key storage slots for three specific keys:

1. The Public Sign Key, used for Secure Boot and Secure Upgrades
2. The Public Command Key, used for Secure Debug unlock and tamper disable
3. The Symmetric OTA Decryption Key, used for Over-The-Air updates

These keys are one-time programmable, and, after programming, are persistent for the lifetime of the device.

HSE-SVH devices also contain four volatile storage slots for any other user keys. These slots are not persistent through a reset. In the case where a key needs persistent storage, the key must be stored outside of the HSE in non-volatile storage. After a device reset, the key can be loaded into the HSE volatile key storage for usage by index, or used in-place (passed to the HSE on every requested operation). Without any secure key storage mechanism, the user key stored in non-volatile storage is opened to storage-extraction attacks (such as gaining access to and downloading device flash), as well as application-level attacks (i.e., taking control of the user application or privileges in a manner that allows access to the keys).

With Secure Key Storage, a user can only access a key from the HSE in a 'wrapped' format. In this format, the key is encrypted by a device-unique root key, only available to the HSE. This allows a user to store a key confidentially in non-volatile storage to provide key persistence. Using Secure Key Storage, the plaintext key is never stored in non-volatile memory, preventing storage-extraction attacks from obtaining the key. After a device reset, the wrapped key can be loaded into the HSE for usage without ever exposing the plaintext key to the application, which also prevents application-level attacks from exposing the key.

SVM devices can only support Secure Key Storage through the use of [TrustZone](04-r-storagecomparisons-trustzone). GSDK v4.2.2 is the first version to support TrustZone software development on Series 2 devices.

Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://www.silabs.com/developers/custom-part-manufacturing-service) to inject custom secret keys on the chips during manufacturing. For more information about CPMS, see the [Custom Part Manufacturing Service User's Guide](https://docs.silabs.com/iot-security/latest/iot-security-cpms/).

#### HSE Secure Key Storage

The following sections demonstrate three methods for key storage: ARM® TrustZone®, plaintext, and Secure Key Storage.

> **Note**: In the following examples, AES key usage is demonstrated. However, any other key types supported by the device can also be used for key storage.

##### Key Generation and Usage

In HSE-SVH devices, cryptographic functions are performed by the HSE. In order to perform these functions, the HSE must have access to any user keys needed. Keys can be generated and used by the HSE in multiple ways:

1. External storage, in-place usage:  
   1. A user generates a plaintext key and stores it in device memory.  
   2. The user provides a key descriptor to the HSE that points to this key for a specific cryptographic operation.  
   3. The HSE performs the cryptographic operation using this key, but does not store it in any HSE volatile storage slot.
2. External storage with HSE import:  
   1. A user generates a plaintext key and stores it in device memory.  
   2. The user provides a key descriptor to the HSE that points to this key, as well as a slot number to store the key.  
   3. The HSE imports this key into a volatile key storage slot or can optionally save it in wrapped form in device memory.  
   4. The user requests that the HSE performs a cryptographic function by providing the index of the storage slot or a pointer to the wrapped key in device memory.
3. Internal HSE key generation:  
   1. The user commands the HSE to generate a new key within one of the HSE's volatile key slots or can optionally save it in wrapped form in device memory.  
   2. The user requests that the HSE performs a cryptographic function by providing the index of the storage slot or a pointer to the wrapped key in device memory.

**Notes**:

- In each case, to provide persistent storage for the key, the key must be stored in non-volatile memory.
- [Plain Key Storage](#plaintext-key-storage) and [Secure Key Storage](#secure-key-storage) provide details on key generation and usage with HSE-SVH device.

##### Plaintext Key Storage

###### Plaintext Key Import

The simplest manner to store a key is to save it in plaintext form. The steps to store and use a key stored in plaintext form are as follows:

1. A user key is generated and imported into device memory. For persistent storage, this must be non-volatile storage, such as device flash.
2. After a device reset, the HSE volatile key storage will be empty. The plaintext key is imported ([method 2](#key-generation-and-usage)) into a slot for usage. Alternatively, the key could be used in place ([method 1](#key-generation-and-usage)) from non-volatile storage on a per-operation basis.  
   ![Plaintext Key Import](/efr32-secure-key-storage/0.2/images/sld791-plaintext-key-import.png)

###### Plaintext Key Usage

In order to use the key for a cryptographic operation, the following procedure is used.

1. The user passes data to be processed (in this specific example, AES encrypted data) to the HSE.
2. The user requests that a cryptographic operation be performed on this data using one of the keys stored in the HSE volatile key storage slots ([method 2](#key-generation-and-usage)). Alternatively, the key can be passed to the HSE directly for a singular cryptographic operation ([method 1](#key-generation-and-usage)).
3. The HSE performs the cryptographic operation.
4. The output of the cryptographic operation is passed back to the user for processing.  
   ![Plaintext Key Usage](/efr32-secure-key-storage/0.2/images/sld791-plaintext-key-usage.png)

This method exposes the keys to two major vulnerabilities:

1. Access to device storage gives access to the keys. In this case, an attack that gains access to the flash contents will expose the user key.
2. Since the application has access to the keys, compromising the application or device privileges can compromise the keys. Such an attack might not directly access device memory, but take control of the application in a way that causes the application to expose the key to an attacker.

##### Secure Key Storage

With Secure Key Storage, the user key, using the HSE, can be accessed in an encrypted, or 'wrapped' form. Only the HSE has access to the HSE root key used to decrypt, or 'unwrap', the wrapped key. This HSE root key is not stored on the device during power-down, but rather reconstructed after each reset. Key wrapping allows a user to securely store a key in non-volatile memory, limiting the number of keys that can be stored only by the amount of storage the user has available.

> **Note**: The reconstructed root key after each reset is IDENTICAL and UNIQUE on each HSE-SVH device.

###### Wrap an External Key

To wrap an externally-generated key:

1. After power-on, the device's unique root key is reconstructed with output from the Physically Unclonable Function (PUF).
2. A user key is generated and imported into device memory. In this example, the key is imported into RAM for easy deletion, and the added security that, if device power is removed, the key will be lost.
3. The user key is passed to the HSE, where it is encrypted with the HSE's root key.
4. The wrapped key is passed back to the user application for storage in non-volatile memory (in this case, device flash).
5. The plaintext key can now be deleted from the device. From this point forward, only the HSE will have access to the plaintext key.  
   ![External Key Import, Wrapping, and Storage](/efr32-secure-key-storage/0.2/images/sld791-external-key-import-wrapping-and-storage.png)

###### Generate an Internal Wrapped Key

Instead of importing an external key, the HSE can generate a new key directly into one of its volatile key storage slots. This key can then be exported in wrapped form for secure persistent storage.

1. The user requests that the HSE generates a new key into one of its storage slots using the True Random Number Generator (TRNG).
2. The key is encrypted with the HSE's root key.
3. The wrapped key is passed back to the user application for non-volatile storage (flash, in this case).  
   ![Internally Generated Key Wrapping and Storage](/efr32-secure-key-storage/0.2/images/sld791-internally-generated-key-wrapping-and-storage.png)

###### Wrapped Key Import

In order to import a wrapped key into the HSE for usage:

1. The wrapped key is passed to the HSE.
2. The wrapped key is decrypted ("unwrapped") with the HSE's root key.
3. The plaintext key is stored in a volatile key storage slot.  
   ![Wrapped Key Import](/efr32-secure-key-storage/0.2/images/sld791-wrapped-key-import.png)

###### Wrapped Key Usage

In order to use the key for a cryptographic operation, the same steps are followed as when using a plaintext key that has been imported into the HSE:

1. The user passes data to be processed (in this specific example, AES encrypted data) to the HSE.
2. The user requests that a cryptographic operation be performed on this data using one of the keys stored in the HSE volatile key storage slots. Alternatively, the wrapped key can be passed to the HSE directly for a singular cryptographic operation. In this case, the key will be unwrapped before being used, but will not be stored for future operations.
3. The HSE performs the cryptographic operation.
4. The output of the cryptographic operation is passed back to the user for processing.  
   ![Wrapped Key Usage](/efr32-secure-key-storage/0.2/images/sld791-wrapped-key-usage.png)

##### Secure Key Storage Advantages

Secure Key Storage confers the following benefits over other key storage methods:

1. Access to device memory does not expose user keys.
2. Compromising the user application does not expose user keys, since the user application itself does not have access to the plaintext keys.
3. The number of user keys that can be securely stored is only limited by the amount of storage available to the user, including external storage.

##### Operation Details

###### Root Key Generation

Secure Key Storage depends on the HSE to encrypt / decrypt (wrap / unwrap) user keys with its own symmetric root key. The symmetric key used for this wrapping and unwrapping must be highly secure as it can expose all other key material in the system. The HSE key Management system uses a Physically Unclonable Function (PUF) to generate a persistent device-unique seed on power up to dynamically reconstruct this critical root key. The key is only visible to the AES encryption engine, and it is not retained when the device loses power.

###### Access a Wrapped Key

By default, a key in an HSE storage slot can be exported to the application as a plaintext key. To prevent this, the user can use the key descriptor to set a user key to [non-exportable](05-r-securekeystorageimplementation#secure-key-storage-implementations). This option prevents any request to export the wrapped key in plaintext from HSE, so the user application can only access the key encrypted by the HSE's root key. The HSE also tags the key with information to identify the wrapped key. Since only the HSE can access the root key to unwrap the user key, the plaintext key is non-accessible to the user application.

> **Note**: Wrapped keys are slightly larger than the equivalent plaintext key, as some additional metadata is required to identify the wrapped key to the HSE.

###### Wrapped Key Storage and Usage

Once a key has been wrapped, it can be safely stored anywhere - device flash, RAM, external storage, etc. The number of keys that can be securely stored is only limited by the available storage space. A wrapped key can later be imported into a HSE volatile storage slot for usage, or used in-place. Once the key is wrapped and stored, the plaintext key available to the application can be deleted. From here, only the HSE will have the ability to unwrap and use the key.

With access to the wrapped key, the HSE can use this key in one of two ways:

1. A user can request that a cryptographic operation be performed using the key stored in memory. In this case, the HSE will import the key, unwrap it, and then perform the cryptographic operation. The key will not be stored within the HSE.
2. A user can import the wrapped key into a HSE volatile storage slot. In this case, the key is unwrapped by the HSE and stored in plaintext in a volatile slot. The user can then later request that a cryptographic function be performed by the HSE by referencing the volatile slot index. This provides a performance increase over using wrapped keys in place, as the HSE does not need to import and unwrap the key on each requested operation.

###### Password Protection

When defining a key descriptor for a new key, or when importing an existing key into HSE, the user can choose to require a password to allow use of the key. The password field in the key descriptor structure is eight bytes in length. If unspecified, the key will use the default password of all zeros.

After importing a key with a password, failing to provide the correct password when performing a cryptographic operation will result in HSE returning an invalid credentials error, and no operation will be performed.

#### TrustZone Secure Key Storage

In Series 2 devices, key management can be handled by a feature called TrustZone. TrustZone divides the device memory map into a Secure Processing Environment (SPE) and a Non-secure Processing Environment (NSPE). User code is executed from the NSPE, which cannot access any part of the SPE. The SPE is used to store cryptographic keys securely and to control other Secure operations.

The following sections describe using TrustZone on Series 2 devices for Secure Key Storage. Refer to [Series 2 TrustZone](https://docs.silabs.com/mcu-bootloader/latest/series2-trustzone/) for details about TrustZone implementation on Series 2 devices.

##### TrustZone Root Key Generation (HSE and VSE)

![Wrapped TRK](/efr32-secure-key-storage/0.2/images/sld791-wrapped-trk.png)

1. The TrustZone Root Key (TRK) is generated by the True Random Number Generator (TRNG) in Series 2 devices.
2. The PUF-derived key (HSE and xG27 VSE devices) or padded unique device serial number (xG22 VSE devices) is used to wrap (AES-GCM) the TRK.
3. The wrapped TRK is stored in the SE Non-volatile memory (NVM), and the TRK in RAM is deleted.  
   - The wrapped TRK already existed if the shipped Series 2 device with SE firmware version supports this key.  
   - The wrapped TRK will be generated when upgrading from a SE firmware version that did not support this key to the one that does.  
   - The wrapped TRK will be renewed after performing a Device Erase.

> **Note**: The Physically Unclonable Function (PUF) is not retained when the device loses power, so the TRK wrapped by the PUF-derived key is not vulnerable to a storage-extraction attack.

##### TrustZone Root Key Usage (HSE)

![HSE Unwrapped TRK](/efr32-secure-key-storage/0.2/images/sld791-hse-unwrapped-trk.png)

1. The Secure application in the host uses a non-exportable built-in key to access the wrapped TRK in HSE NVM for cryptographic operations.
2. The PUF-derived key is used to decrypt (AES-GCM) the wrapped TRK in HSE NVM.
3. The unwrapped TRK in the HSE is the master key of a Key Derivation Function (KDF).
4. The encryption key in SPE for Secure Key Storage is derived from the KDF CMAC.

**Notes**:

- All cryptographic operations are performed by the HSE (security co-processor).
- Only the HSE can access the unwrapped TRK for KDF, so this key will not expose the Secure application in the host.

##### TrustZone Root Key Usage (VSE)

![VSE Unwrapped TRK](/efr32-secure-key-storage/0.2/images/sld791-vse-unwrapped-trk.png)

1. The wrapped TRK in VSE NVM is accessed by the VSE Root mode firmware.
2. The PUF-derived key (xG27) or padded unique device serial number (xG22) is used to decrypt (AES-GCM) the wrapped TRK in VSE NVM.
3. Unwrapped TRK is transferred to the shared RAM when switching from VSE Root mode to User mode. The VSE user mode Secure application stores this key to the Secure RAM in SPE and deletes this key in the shared RAM.
4. The unwrapped TRK in the Secure RAM is the master key of a Key Derivation Function (KDF).
5. The encryption key in SPE for Secure Key Storage is derived from the KDF CMAC.

> **Note**: On VSE devices, all cryptographic operations are performed by the Cryptographic Accelerator (CRYPTOACC) peripheral.

For more information about the HSE and VSE, refer to the section _Secure Engine Subsystem_ in [Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/03-r-secureelement).

##### TrustZone Secure Key Storage (HSE and VSE)

The TRK allows a user to securely store a key in the Non-secure flash, limiting the number of keys that can be saved only by the amount of Non-secure storage. The following figure describes using the TRK to encrypt a plaintext key and store it in Non-secure NVM.![TZ SKS](/efr32-secure-key-storage/0.2/images/sld791-tz-sks.png)

1. After power-on, the device's TRK (wrapped in HSE NVM and unwrapped in VSE Secure RAM) is available for the SPE.
2. A user key is generated and imported into the device's Non-secure memory. In this example, the key is imported into Non-secure RAM for easy deletion, and the key is lost if device power is removed.
3. Call the PSA Crypto API (`psa_import_key()` or `psa_generate_key()`) through the Secure Gateway (SG) in Non-secure Callable (NSC) memory to generate a key for crypto operations.
4. The plaintext key is passed in the PSA Crypto API to the SPE, where it is encrypted (AES-GCM) with the encryption key derived (KDF CMAC) from the TRK.
5. The encrypted key is stored to the NVM region in the NSPE through the PSA Internal Trusted Storage (ITS) and [NVM3](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3) drivers.
6. The plaintext key can now be deleted from the Non-secure RAM.
7. Only the PSA Crypto API in the SPE can retrieve the encrypted key from NVM in the NSPE and decrypt it for crypto operations in the SPE.

> **Note**: Ignore steps 2 and 6 if the plaintext key is randomly generated by the PSA Crypto.

#### Secure Key Storage Implementations

Users can use Secure Engine Manager (SE Manager) or PSA Crypto in the following figure to access the secure key storage on HSE-SVH devices. SE Manager APIs for secure key storage and crypto are usually not considered external APIs. PSA Crypto API abstracts the entropy sources, crypto primitives, and even advanced security features like secure key storage from the calling functions.

Silicon Labs recommends using PSA Crypto API for secure key storage and cryptography whenever possible. It makes the solution more portable and hardware agnostic. In some cases, however, setting up tamper and initializing the secure boot can only be implemented by the SE Manager APIs.

![Secure Engine Manager and PSA Crypto](/efr32-secure-key-storage/0.2/images/sld791-secure-engine-manager-and-psa-crypto.png)

<table>
    <thead>
        <tr>
            <th>Component</th>
            <th>Functionality</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>EMLIB (em_se.c)</p>
            </td>
            <td>
                <p>Abstracts the mailbox interface: how to construct, send and receive low-level HSE mailbox commands.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE Manager</p>
            </td>
            <td>
                <p>On top of EMLIB, it abstracts the HSE command set: translates function calls into mailbox messages. The SE Manager also provides thread synchronization.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Accelerator Drivers</p>
            </td>
            <td>
                <p>A translation layer to map the PSA Crypto HSE interface and crypto acceleration calls to SE Manager calls.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto API</p>
            </td>
            <td>
                <p>Platform independent cryptographic hardware acceleration support by implementing standardized APIs.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA ITS Driver</p>
            </td>
            <td>
                <p>The key management functionality in PSA Crypto needs access to non-volatile memory for persistent storage of plaintext or wrapped keys. NVM3 gets wrapped by this translation layer, mapping the PSA ITS (Internal Trusted Storage) interface to NVM3 calls.</p>
            </td>
        </tr>
    </tbody>
</table>

For the SE's mailbox interface, see section _Secure Engine Subsystem_ in [Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/03-r-secureelement).

For more information about NVM3, see [https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3).

For more information about PSA Crypto, see [Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS](https://docs.silabs.com/iot-security/latest/mbedtls-psa-crypto-porting-guide/).

##### SE Manager API

The following table lists the SE Manager APIs related to Secure Key Storage operations. The SE Manager API document can be found at [https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager).

<table>
    <thead>
        <tr>
            <th>SE Manager API</th>
            <th>Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>sl_se_generate_key</p>
            </td>
            <td>
                <p>Generate a new key and store it either in a volatile HSE storage slot or as a wrapped key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_import_key</p>
            </td>
            <td>
                <p>Import a plaintext key and store it either in a volatile HSE storage slot or as a wrapped key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_export_key</p>
            </td>
            <td>
                <p>Export a volatile or wrapped key back to plaintext if allowed. It will fail for a key that has been flagged as SL_SE_KEY_FLAG_NON_EXPORTABLE.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_transfer_key</p>
            </td>
            <td>
                <p>Transfer a volatile or wrapped key to another storage option (volatile HSE storage slot or a wrapped key) if allowed.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>sl_se_delete_key</p>
            </td>
            <td>
                <p>Delete a key from a volatile HSE storage slot.</p>
            </td>
        </tr>
    </tbody>
</table>

##### PSA Crypto API

The following table lists the PSA Crypto APIs related to Secure Key Storage operations. The PSA Crypto API document can be found at [https://docs.silabs.com/mbed-tls/latest/](https://docs.silabs.com/mbed-tls/latest/).

For more information about PSA Crypto APIs on Secure Key Storage, see [Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS](https://docs.silabs.com/iot-security/latest/mbedtls-psa-crypto-porting-guide/).

<table>
    <thead>
        <tr>
            <th>PSA Crypto API</th>
            <th>Usage</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>psa_generate_key</p>
            </td>
            <td>
                <p>Generate a new plaintext or wrapped key and store it either in volatile or non-volatile memory.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>psa_import_key</p>
            </td>
            <td>
                <p>Import a plaintext key and save it in plaintext or wrapped form. It can store either in volatile or non-volatile memory.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>psa_export_key</p>
            </td>
            <td>
                <p>Export a key back to plaintext if allowed. The policy on the key must have the usage flag<code>PSA_KEY_USAGE_EXPORT</code>set.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>psa_copy_key</p>
            </td>
            <td>
                <p>Copy key material from one location to another, which may have a different lifetime (e.g., volatile to non-volatile).</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>psa_destroy_key</p>
            </td>
            <td>
                <p>Destroy a key from both volatile memory and, if applicable, non-volatile storage.</p>
            </td>
        </tr>
    </tbody>
</table>

##### SE Manager API Versus PSA Crypto API

The following table compares the SE Manager APIs with PSA Crypto APIs on Secure Key Storage.

<table>
    <thead>
        <tr>
            <th>Item</th>
            <th>SE Manager API</th>
            <th>PSA Crypto API</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Availability</p>
            </td>
            <td>
                <p>Only on HSE devices</p>
            </td>
            <td>
                <p>Platform independent</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>API</p>
            </td>
            <td>
                <p>Silicon Labs proprietary</p>
            </td>
            <td>
                <p>Standardized by ARM®</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Key Storage</p>
            </td>
            <td>
                <p>Volatile (RAM) memory only</p>
            </td>
            <td>
                <p>Volatile (RAM) or non-volatile (flash) memory</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Wrapped Key Cache</p>
            </td>
            <td>
                <p>Can use a volatile HSE storage slot</p>
            </td>
            <td>
                <p>Not yet implemented</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Password Protection</p>
            </td>
            <td>
                <p>Can define in a key descriptor</p>
            </td>
            <td>
                <p>Not yet defined in PSA Crypto</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Custom ECC Curve</p>
            </td>
            <td>
                <p>Can define in a key descriptor</p>
            </td>
            <td>
                <p>Not yet defined in PSA Crypto</p>
            </td>
        </tr>
    </tbody>
</table>

##### PSA Crypto Key Types with TrustZone Secure Key Storage

The following tables describes the storage differences between key storage with and without TrustZone on SVM and SVH devices.

**Table: TrustZone Secure Key Storage (SKS) on SVM Devices**

<table>
    <thead>
        <tr>
            <th>Key Type</th>
            <th>Storage without TrustZone SKS</th>
            <th>Storage with TrustZone SKS</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Volatile Plaintext</p>
            </td>
            <td>
                <p>RAM</p>
            </td>
            <td>
                <p>Secure RAM (2)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Plaintext</p>
            </td>
            <td>
                <p>NVM</p>
            </td>
            <td>
                <p>Encrypted in NS NVM (2)</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Volatile Wrapped</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Wrapped</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
            <td>
                <p>Not supported</p>
            </td>
        </tr>
    </tbody>
</table>

**Table: TrustZone Secure Key Storage (SKS) on SVH Devices**

<table>
    <thead>
        <tr>
            <th>Key Type</th>
            <th>Storage without TrustZone SKS</th>
            <th>Storage with TrustZone SKS</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Volatile Plaintext</p>
            </td>
            <td>
                <p>Plaintext key in RAM</p>
            </td>
            <td>
                <p>Plaintext key in Secure RAM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Plaintext</p>
            </td>
            <td>
                <p>Plaintext key in NVM</p>
            </td>
            <td>
                <p>Encrypted plaintext key in NS NVM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Volatile Wrapped</p>
            </td>
            <td>
                <p>Wrapped key in RAM (1)</p>
            </td>
            <td>
                <p>Wrapped key in Secure RAM</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Persistent Wrapped</p>
            </td>
            <td>
                <p>Wrapped key in NVM (1)</p>
            </td>
            <td>
                <p>Encrypted wrapped key in NS NVM</p>
            </td>
        </tr>
    </tbody>
</table>

**Notes**:

- The NVM or NS NVM is at the last part of the main flash.
- It is possible to replace the wrapped key solution on the SVH device (1) with TrustZone Secure Key Storage on the SVM device (2), but this is a less secure approach.

#### Examples

Simplicity Studio 5 includes the [SE Manager and PSA Crypto platform examples](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-getting-started/start-a-project#examples) for Secure Key Storage. Refer to the corresponding `readme` file for details about each SE Manager and PSA Crypto platform example. This file also includes the procedures to create the project and run the example.

**Table: Platform Examples for Secure Key Storage**

<table>
    <thead>
        <tr>
            <th>Category</th>
            <th>SE Manager Platform Example</th>
            <th>PSA Crypto Platform Example</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td rowspan="2">
                <p>Key Handling</p>
            </td>
            <td>
                <p>SE Manager Symmetric Key Handling</p>
            </td>
            <td>
                <p>PSA Crypto Symmetric Key</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE Manager Asymmetric Key Handling</p>
            </td>
            <td>
                <p>PSA Crypto Asymmetric Key</p>
            </td>
        </tr>
        <tr>
            <td rowspan="4">
                <p>Symmetric Key Usage</p>
            </td>
            <td rowspan="4">
                <p>SE Manager Block Cipher</p>
            </td>
            <td>
                <p>PSA Crypto AEAD</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto Cipher</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto KDF</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PSA Crypto MAC</p>
            </td>
        </tr>
        <tr>
            <td rowspan="2">
                <p>Asymmetric Key Usage</p>
            </td>
            <td>
                <p>SE Manager Digital Signature (ECDSA and EdDSA)</p>
            </td>
            <td>
                <p>PSA Crypto DSA</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SE Manager Key Agreement (ECDH)</p>
            </td>
            <td>
                <p>PSA Crypto ECDH</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>X.509 Certificate</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>PSA Crypto X.509</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>TrustZone Secure Key Storage</p>
            </td>
            <td>
                <p>-</p>
            </td>
            <td>
                <p>tz_psa_crypto_ecdh_ws</p>
            </td>
        </tr>
    </tbody>
</table>

### Programming Series 2 Devices Using DCI and SWD

#### Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)

> **Note: This section replaces _AN1303: Programming Series 2 Devices using the Debug Challenge Interface (DCI) and Serial Wire Debug (SWD)_. Further updates to this Quick-Start Guide will be provided here**.

This application note describes how to provision and configure Series 2 devices through the dedicated Debug Challenge Interface (DCI). The process to use the Serial Wire Debug (SWD) interface for programming the internal flash memory of Series 2 devices is also included.

For details on how to use the SWD interface to program devices, see [AN0062: Programming Internal Flash over the Serial Wire Debug Interface](https://www.silabs.com/documents/public/application-notes/an0062.pdf).

##### Key Points

- DCI overview
- SWD interface overview
- DCI programming examples to provision and configure Series 2 devices
- SWD programming examples to program Series 2 devices
- How to add a new Series 2 device to the programmer

#### Series 2 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level (1)**|**SE Support**|**Part (2)**|
|---|---|---|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|Refer to _IoT Endpoint Security Fundamentals_ for details on supporting devices.|
|Secure Vault Mid (SVM)|HSE (HSE-SVM)|"|
|"|VSE (VSE-SVM)|"|
|Secure Vault Base (SVB)|N/A|"|

Notes:

1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security).
2. [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/).

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug access control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper protection**: A configurable module to protect the device against tamper attacks.
- **Device authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.
- Advanced cryptographic acceleration (i.e., ChaCha20/Poly1305)

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th><strong>Document</strong></th>
            <th><strong>Summary</strong></th>
            <th><strong>Applicability</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/mbedtls-psa-crypto-porting-guide/">Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS</a></p>
            </td>
            <td>
                <p>How to port firmware from the Mbed TLS cryptographic library to PSA Crypto</p>
            </td>
            <td>
                <p>Secure Vault Mid and High</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-trustzone/">Series 2 TrustZone</a></p>
            </td>
            <td>
                <p>How to TrustZone to separate trusted and non-trusted firmware.</p>
            </td>
            <td>
                <p>Secure Vault Mid and High</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 devices and modules.

#### Introduction

The latest SE firmware image (`.seu` and `.hex`) and release notes can be found in the Windows folder below. For GSDK v3.2 and lower:

`C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION>\util\se_release\public`

For GSDK v4.0 and higher:

`C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public`

Silicon Labs provides [Custom Part Manufacturing Service (CPMS)](https://www.silabs.com/developers/custom-part-manufacturing-service) to customize the users' security features and settings.

The Debug Challenge Interface (DCI) is used to configure the security features of the Series 2 devices, whereas the Serial Wire Debug (SWD) interface is used to program the flash memory of Series 2 devices. A general overview of the DCI and SWD programming steps is described in the following sections.

#### Debug Challenge Interface (DCI)

Interaction with the SE is performed over a command interface that is available through a dedicated Debug Challenge Interface (DCI). The DCI is intended to be used for various [SE commands](05-se-command-list#se-command-list). The DCI is open while the SE is running.

##### DCI Connection

The DCI is made available through a connection on the Serial Wire Debug (SWD) port. The steps involved in connecting the DCI through the SWD port are as follows.

1. Send the JTAG-to-SWD switching sequence.
2. Read the IDCODE register (SWD DP register 0) to retrieve an identification value. On the Series 2 devices with a Cortex-M33 core, this value is `0x6BA02477`.
3. Use the ABORT register (SWD DP register 0 = `0x0000001E`) to clear the error and sticky flag conditions.
4. Use the STAT register (SWD DP register 1 = `0x50000000`) to generate a system and debug domain power-up request.
5. Use the SELECT register (SWD DP register 2 = `0x01000000`) to set the SWD interface in the chip to communicate with the DCI.
6. Use the CSW register (SWD AP register 0 = `0x22000002`) to set the transfer size to 32-bit.

See [AN0062: Programming Internal Flash over the Serial Wire Debug Interface](https://www.silabs.com/documents/public/application-notes/an0062.pdf) for more information about the SWD port registers.

![CI Connection Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-dci-connection-flowchart.png)

##### DCI Registers

The following table lists three registers to interact with the DCI through the SWD interface.

**DCI Register**

|**Register**|**Description**|**Fields**|**Address**|**Remarks**|
|---|---|---|---|---|
|DCI_WDATA|Write data to the DCI|WDATA [31:0]|0x1000|Command|
|DCI_RDATA|Read data from the DCI|RDATA [31:0]|0x1004|Response|
|DCI_STATUS|Status of DCI accesses|Bit 0 = WPENDING|0x1008|Write Request to the DCI is pending. Additional writes to DCI_WDATA are discarded when this bit is asserted.|
|"|"|Bit 8 = RDATAVALID|"|Response from the DCI is valid when this bit is asserted. Cleared on a read of DCI_RDATA.|

##### DCI Calls

###### Command

All DCI calls start by writing a 32-bit word containing the length of the DCI data followed by the 32-bit Command ID into the DCI. The length includes the length word itself, so the minimum value is 8 (4 bytes of length and 4 byes of Command ID). Then a variable length command payload (if applicable) is transferred into the DCI.

**DCI Command**

|**Command Word**|**Description**|
|---|---|
|Word 0|Length of packet in bytes (including word 0)|
|Word 1|Command ID|
|Words 2 – N|Command payload if applicable|

###### Response

On completion, a 32-bit word consisting of the response length [15:0] in bytes and response code [31:16] is read from the DCI followed by the response payload, if present.

**DCI Response**

|**Response Word**|**Description**|
|---|---|
|Word 0|Total response length (including word 0) and response code: [15:0] – Total length in bytes; [31:16] – Response code|
|Words 1 – N|Response payload if applicable|

All executed commands return a response code that classifies the result of the operation. The basic meaning of these response codes is given in the following table.

**DCI Response Codes**

|**Response Code**|**Status**|**Description**|
|---|---|---|
|0|SE_RESPONSE_OK|Command executed successfully or signature was successfully validated.|
|1|SE_RESPONSE_INVALID_COMMAND|Command was not recognized as a valid command, or is not allowed in the current context.|
|2|SE_RESPONSE_AUTHORIZATION_ERROR|User did not provide the required credentials to be allowed to execute the command.|
|3|SE_RESPONSE_INVALID_SIGNATURE|Signature validation command failed to verify the given signature as being correct.|
|4|SE_RESPONSE_BUS_ERROR|A command started in non-secure mode is trying to access secure memory.|
|5|SE_RESPONSE_INTERNAL_ERROR|Internal SE error.|
|6|SE_RESPONSE_CRYPTO_ERROR|Error in crypto operation.|
|7|SE_RESPONSE_INVALID_PARAMETER|One of the passed parameters is deemed invalid (for example, out of bounds), or the number of parameters is incorrect.|
|8|SE_RESPONSE_INTEGRITY_ERROR|Operation cannot be completed due to the SE having an invalid internal state.|
|9|SE_RESPONSE_SECUREBOOT_ERROR|The host application failed secure boot check.|
|10|SE_RESPONSE_SELFTEST_ERROR|Failure during self-test.|
|11|SE_RESPONSE_NOT_INITIALIZED|Feature or item is not present or not initialized.|

##### DCI Operation

###### DCI Write

The user can write the DCI_WDATA register to pass command to the SE. The steps involved in writing a command to DCI are as follows.

1. Connect to DCI according to [DCI Connection Flowchart](#dci-connection).
2. For each word in the command, follow these steps in sequence:  
   1. Set the DCI to read from [DCI_STATUS](#dci-calls) by setting SWD AP register 1 to 0x1008.  
   2. Read DCI_STATUS by reading from SWD AP register 3.  
   3. If [WPENDING](#dci-calls) is high, go back to step (a). If WPENDING is low, continue. If [RDATAVALID](#dci-registers) is high, then the SE has started issuing a reply and the current command needs to be aborted.  
   4. Set the DCI to write to [DCI_WDATA](#dci-registers) by setting SWD AP register 1 to 0x1000.  
   5. Write the command word to SWD AP register 3.  
   ![DCI Write Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-dci-write-flowchart.png)

###### DCI Read

The user can read the DCI_RDATA register to retrieve responses from the SE to a previously written command. If a user has sent a command according to [DCI Write Flowchart on page 8](#dci-write), the steps to read the response from the DCI are as follows.

1. Set the DCI to read from [DCI_STATUS](#dci-registers) by setting SWD AP register 1 to 0x1008.
2. Read DCI_STATUS by reading from SWD AP register 3.
3. If [RDATAVALID](#dci-registers) is high, a response word is available to be read from DCI_RDATA. If RDATAVALID is low, go back to step (2) because the SE has not begun to reply.
4. Set the DCI to read from [DCI_RDATA](#dci-registers) by setting SWD AP register 1 to 0x1004.
5. Read the first response word from the command to SWD AP register 3.
6. Total length of the response (including the first word) is in the lower 16 bits of that word. If this is larger than 4, for each response word:  
   a. Set the DCI to read from DCI_STATUS by setting SWD AP register 1 to 0x1008.  
   b. Read DCI_STATUS by reading from SWD AP register 3.  
   c. If RDATAVALID is high, a response word is available to be read from DCI_RDATA. If RDATAVALID is low, go back to step (a) because the process is polling faster than the SE can send data.  
   d. Set the DCI to read from DCI_RDATA by setting SWD AP register 1 to 0x1004.  
   e. Read the sequential response word to SWD AP register 3.

![DCI Read Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-dci-read-flowchart.png)

#### Serial Wire Debug (SWD) Interface

The flash memory on Series 2 devices is divided into two blocks: the main block and the information block. Program code is normally written to the main block. The information block is available for special user data. Throughout this document, the flash or main flash is referred to as the main block and user data is referred to as the information block.

Program the Series 2 flash memory by writing directly to the device's Memory System Controller (MSC) registers over the Serial Wire Debug (SWD) interface. This method is simple and easy to upgrade to support new Series 2 devices.

The program must set the MSC bit in the CMU CLKEN1 register (if available) to enable the clock source for the Memory System Controller (MSC).

Series 2 devices with a Cortex-M33 core return the value `0x84770001` when reading the AP Identification Register (IDR) through SWD.

See [AN0062: Programming Internal Flash over the Serial Wire Debug Interface](https://www.silabs.com/documents/public/application-notes/an0062.pdf) for more information on how to access the SWD interface of the target device and how to use this interface to program devices.

##### Flash Erase

There are two ways to erase the flash of the target device through SWD interface:

###### Page Erase

A page erase can be initiated from software using the ERASEPAGE bit in the MSC WRITECMD register. The page erase operations require that the address of main flash or user data is written into the MSC ADDRB register. To reduce the time needed for the flash erase process, the program should avoid erasing the target main flash page by page, especially for devices with larger flash memories.

###### Mass Erase

A mass erase can be initiated from software using the ERASEMAIN0 bit in the MSC WRITECMD register. This erases the entire flash (excluding the user data).

![Flash-Erase-Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-flash-erase-flowchart.png)

The flash base address of the Series 2 device is either `0x00000000` or `0x08000000.` The timing for page erase or mass erase on each Series 2 device might vary. Refer to the device-specific datasheets for details.

##### Flash Write

The write operation requires that the address be written into the MSC ADDRB register. After each 32-bit word is written, the internal address register is incremented automatically by 4. When a word is written to the MSC WDATA register, the WDATAREADY bit of the MSC STATUS register is cleared. When this status bit is set, software can write the next word.

The flash program time (32-bit word) of each Series 2 device might vary. Refer to the device-specific datasheets for details.

To reduce the time for the flash write process, the program can omit polling the WDATAREADY bit in the MSC STATUS register after writing each 32-bit word, because the register read process is time consuming. The alternative is to add a fixed microseconds delay between each write to make sure the maximum write time can be met.

![Flash-Write-Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-flash-write-flowchart.png)

###### Flash Verify

The program verifies the target flash contents with a buffer to make sure that no errors occurred during the programming process. The autoincrement of the Transfer Address Register (TAR) is for burst reads within the TAR wraparound boundary. The TAR must be initialized at every TAR wraparound boundary to set up the next flash read address.

![Flash Verify Flowchart](/efr32-dci-swd-programming/0.1/images/sld815-flash-verify-flowchart.png)

#### SE Command List

This application note does not include a complete list of commands for DCI. The following sections contain information about each command's operation and arguments for DCI production programming. The [command](03-debug-challenge-interface-dci#command) and [response](03-debug-challenge-interface-dci#response) payload may be device-specific (e.g., Initialize OTP and Get Status).

For more information about secure boot, see [Series 2 Secure Boot with RTSL](https://docs.silabs.com/iot-security/latest/series2-secure-boot-with-rtsl/). For more information about debug lock and secure debug, see [Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

##### SE Image Check

This command can be used to check the SE image before starting the upgrade process, in order to be able to abort early if the image is invalid or inapplicable.

> **Note**: This command is only available on SE firmware version ≥ v1.2.2 (xG21 or xG22 devices).

**SE Image Check Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x4302|0x00|0x00|Address in internal flash where the SE upgrade image is stored - 4 bytes:|None|

##### SE Image Apply

This command can be used to perform an upgrade of the SE firmware where the existing firmware will be overwritten with the one stored in the internal flash if the upgrade image is valid and applicable. The system is restarted and no [response code](03-debug-challenge-interface-dci) is returned if the SE image is successfully upgraded.

> **Note**: This command is only available on SE firmware version ≥ v1.2.2 (xG21 or xG22 devices).

**SE Image Apply Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x4303|0x00|0x00|Address in internal flash where the SE upgrade image is stored - 4 bytes:|None|

##### Apply Lock

This command enables the debug lock for the part.

**Apply Lock Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x430C|0x00|0x00|None|None|

##### Enable Secure Debug

This command enables the secure debug functionality. This command must be used before the debug port is locked and will fail if executed after locking debug access.

**Enable Secure Debug Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x430D|0x00|0x00|None|None|

##### Disable Secure Debug

This command disables the secure debug functionality and is available even after the debug port has been locked.

**Disable Secure Debug Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x430E|0x00|0x00|None|None|

##### Erase Device

This command performs a device mass erase and resets the debug configuration to its initial unlocked state. It is only available if the [Disable Device Erase](#disable-device-erase) command has not been executed.

This command clears and verifies the main flash and RAM of the system, excluding the user data and one-time programmable (OTP) commissioning information in the SE.

**Erase Device Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x430F|0x00|0x00|None|None|

##### Disable Device Erase

This command disables the [Erase Device](#erase-device) command. This command does not lock the debug interface to the part, but it is a permanent action for the part. This is a one-time command.

**Disable Device Erase Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x4310|0x00|0x00|None|None|

##### Read Serial Number

This command is used to read the Silicon Labs-provisioned serial number of the device.

**Read Serial Number Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFE00|0x00|0x00|None|16 bytes serial number|

##### Get Status

This command is used to read out the status information from the SE.

**Get Status Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFE01|0x00|0x00|None|Varies by SE type, see following.|

**VSE-SVM - total 20 bytes:**

- Boot status - 4 bytes
- VSE firmware version - 4 bytes
- MCU firmware version - 4 bytes
- Debug lock status - 4 bytes
- Secure boot configuration - 4 bytes

**HSE-SVM or HSE-SVH - total 36 bytes**:

- 16 bytes for HSE-SVM: Reserved
- 16 bytes for HSE-SVH:  
  - Tamper status - 4 bytes  
  - Tamper time stamp - 4 bytes  
  - Tamper raw status - 4 bytes  
  - Time stamp - 4 bytes
- Boot status - 4 bytes
- HSE firmware version - 4 bytes
- MCU firmware version - 4 bytes
- Debug lock status - 4 bytes
- Secure boot configuration - 4 bytes

> **Note**:
> 
> - Tamper status is a set of 32 flags that indicate which tamper events have occurred.
> - Tamper time stamp is a HSE timer counter value for the last tamper event.
> - Tamper raw status is encoded the same as tamper status but is an immediate value of the tamper event sources.
> - The time stamp is a HSE timer counter value.
> - Boot status:
> - Bit [7:0] - 0x20 if boot is successful.
> - Bit [:] (for xG21 or xG22 devices only) - The [response code](03-debug-challenge-interface-dci) if SE firmware version ≥ v1.2.0
> - VSE or HSE firmware version:
> - Bit [7:0] - Patch version
> - Bit [15:8] - Minor version
> - Bit [23:16] - Major version
> - Bit [31:24] - Series 2 device family (0 for xG21, 1 for xG22, 2 for xG23, etc.)
> - MCU firmware version: Bit [31:0] - The MCU firmware version is not available if all set to 1 (0xFFFFFFFF)
> - Debug lock status:
> - Bit [0] - Debug lock (configuration status) is enabled if set.
> - Bit [1] - Device erase is enabled if set.
> - Bit [2] - Secure debug is enabled if set.
> - Bit [5] - Debug lock (hardware status) is enabled if set.
> - Secure boot configuration:
> - Bit [31:0] - SE OTP is not yet configured if all set to 1 (0xFFFFFFFF)
> - Bit [31:0] - SE OTP has been configured if Bit [31:1] are 0, secure boot is enabled if Bit [0] is set

##### Read User Configuration

This command is used to read non-reconfigurable user settings on the SE OTP for secure boot and tamper response.

> **Note**: This command is only available on SE firmware versions ≥ v1.2.2 (xG21 or xG22 devices).

**Read User Configuration Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFE04|0x00|0x00|None|Varies by SE type, see following.|

**VSE-SVM - total 4 bytes**:

- [MCU flags](#mcu-flags) - 4 bytes

**HSE-SVM - total 24 bytes**:

- [MCU flags](#mcu-flags) - 4 bytes
- Reserved - 20 bytes

**HSE-SVH - total 24 bytes**:

- [MCU flags](#mcu-flags) - 4 bytes
- [Tamper response levels]() (2 signals per byte) - 16 bytes
- [Filter reset period]() - 1 byte
- [Filter trigger threshold]() - 1 byte
- [Tamper flags]() - 1 byte
- [Tamper reset threshold]() - 1 byte

##### Initialize OTP

This command is used during factory initialization, to upload device-specific settings to the SE OTP. This is a one-time command.

**Initialize OTP Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFF00|0x00|0x01|Varies by SE type, see following.|None|

**VSE-SVM - total 12 bytes**:

1. Parity (equal to item 3) - 4 bytes
2. Length of the following content - 4 bytes
3. [MCU flags](#mcu-flags) - 4 bytes

**HSE-SVM - total 32 bytes**:

1. Parity (the XOR of 32-bit words from item 3 and 4) - 4 bytes
2. Length of the following content - 4 bytes
3. [MCU flags](#mcu-flags) - 4 bytes
4. Reserved - 20 bytes

**HSE-SVH - total 32 bytes**:

1. Parity (the XOR of 32-bit words from item 3 to 8) - 4 bytes
2. Length of the following content - 4 bytes
3. [MCU flags](#mcu-flags) - 4 bytes
4. [Tamper response levels]() (2 signals per byte) - 16 bytes
5. [Filter reset period]() - 1 byte
6. [Filter trigger threshold]() - 1 byte
7. [Tamper flags]() - 1 byte
8. [Tamper reset threshold]() - 1 byte

###### MCU Flags

The parameters of the MCU flags are described in the following tables.

**Parameters of MCU Flags**

|**Fields**|**Description**|
|---|---|
|Bit [15:0]|Reserved|
|Bit [16]|SECURE_BOOT_ENABLE|
|Bit [17]|SECURE_BOOT_VERIFY_CERTIFICATE|
|Bit [18]|SECURE_BOOT_ANTI_ROLLBACK|
|Bit [19]|SECURE_BOOT_PAGE_LOCK_NARROW|
|Bit [20]|SECURE_BOOT_PAGE_LOCK_FULL|
|Bit [31:21]|Reserved|

**MCU Flags for Series 2 Devices**

|**Name**|**Description**|
|---|---|
|SECURE_BOOT_ENABLE|If set, verifies the image on the Cortex-M33 before releasing the Cortex-M33 from reset.|
|SECURE_BOOT_VERIFY_CERTIFICATE|If set, requires certificate-based signing of the host application.|
|SECURE_BOOT_ANTI_ROLLBACK|If set, prevents secure upgrading to a host image with a lower version than the image that is currently stored in flash.|
|SECURE_BOOT_PAGE_LOCK_NARROW|If set, locks flash pages that have been validated by the secure boot process to prevent re-flashing by means other than through the SE.|
|"|Write/erase locks pages from 0 through the page where the secure boot signature of the application is located, not including the last page if the signature is not on a page boundary.|
|SECURE_BOOT_PAGE_LOCK_FULL|If set, locks flash pages that have been validated by the secure boot process to prevent re-flashing by means other than through the SE.|
|"|Write/erase locks pages from 0 through the page where the secure boot signature of the application is located, including the last page if the signature is not on a page boundary.|

###### Anti-Tamper Configuration

The 16 bytes of tamper response levels on HSE-SVH devices are described in the following tables.

**Tamper Source Response Level on HSE-SVH (xG21B) Devices**

![Tamper Source Response Level on HSE-SVH (xG21B) Devices](/efr32-dci-swd-programming/0.1/images/sld815-tamper-source-response-level-on-hse-svh-xg21b-devices.png)

**Tamper Source Response Level on Other HSE-SVH Devices**

![Tamper Source Response Level on Other HSE-SVH Devices](/efr32-dci-swd-programming/0.1/images/sld815-tamper-source-response-level-on-other-hse-svh-devices.png)

##### Initialize Public Key

This command is used to initialize the user public key(s) to the SE OTP. This is a one-time command.

**Initialize Public Key Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFF07|Key type, see following|0x01|See following|None|

**Key type:**

- 0x01 - Public Sign Key
- 0x02 - Public Command Key

**Command payload - total 68 bytes**:

1. Parity (the XOR of 32-bit words from item 2) - 4 bytes
2. Public key in option 1 - 64 bytes

##### Read Public Key

This command can be used to read out one of the public keys that are permanently stored in SE OTP.

**Read Public Key Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFF08|Key type, see following|0x01|None|64 bytes: public key in option 1|

**Key type:**

- 0x01 - Public Sign Key
- 0x02 - Public Command Key

##### Initialize AES Key

This command is used to initialize a 128-bit symmetric key to the SE OTP. This is a one-time command.

> **Note**: This command is only available on HSE devices.

**Initialize AES Key Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0xFF0B|Key type, see following|0x01|See following|None|

**Key type:**

- 0x05 - AES-128 key

**Command payload - total 20 bytes**:

1. Parity (the XOR of 32-bit words from item 2) - 4 bytes
2. Symmetric key in option 1 - 16 bytes

##### Set Debug Restrictions

This command is used to set the restrictions for the debug port.

**Set Debug Restrictions Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x4312|0x00|0x00|See following|None|

Command Payload – total 4 bytes. Debug restriction bit mask is defined in the table below.

**Debug Port Restriction Bits**

<table>
    <thead>
        <tr>
            <th><strong>Bit</strong></th>
            <th><strong>Name</strong></th>
            <th><strong>Description</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>0</p>
            </td>
            <td>
                <p>DBGLOCK</p>
            </td>
            <td>
                <p>Non-secure, invasive debug lock.<br>
                    If this bit is set, it is not possible to debug the non-secure state in a way that is intrusive to program execution.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>1</p>
            </td>
            <td>
                <p>NIDLOCK</p>
            </td>
            <td>
                <p>Non-secure, non-invasive debug lock.<br>
                    If this bit is set, it is not possible to observe the non-secure state of the M33 using trace.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>2</p>
            </td>
            <td>
                <p>SPIDLOCK</p>
            </td>
            <td>
                <p>Secure, invasive debug lock.<br>
                    If this bit is set, it is not possible to debug the secure state in a way that is intrusive to program execution.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>3</p>
            </td>
            <td>
                <p>SPNIDLOCK</p>
            </td>
            <td>
                <p>Secure, non-invasive debug lock.<br>
                    If this bit is set, it is not possible to observe the secure state of the M33 using trace.<br>
                    (If SPIDLOCK is open, SPNIDLOCK will also remain open.)</p>
            </td>
        </tr>
    </tbody>
</table>

##### Read Lock Status

This command is used to read the lock status of the debug port.

**Read Lock Status Command**

|**ID [31:16]**|**Option 1 [15:8]**|**Option 2 [7:0]**|**Command payload**|**Response payload**|
|---|---|---|---|---|
|0x4311|0x00|0x00|See following|None|

Debug port lock status – total 4 bytes:

- Bit [0] - Debug lock (configuration status) is enabled if set
- Bit [1] - Device erase enabled is enabled if set
- Bit [2] – Secure debug lock enabled is enabled if set
- Bit [3:4] – Reserved
- Bit [5] – Debug lock hardware status is enabled if set
- Bit [6] – Invasive debug lock is enabled if set
- Bit [7] – Non-invasive debug lock is enabled if set
- Bit [8] - Secure invasive debug lock is enabled if set
- Bit [9] - Secure non-invasive debug lock is enabled if set

#### Series 2 DCI and SWD Programming Examples

The programming examples in this application note use the [Series 2 DCI and SWD Programming](#software-overview) platform example of GSDK v4.0.1. The hardware and software implementation may be different on other versions of the GSDK.

For more information about production programming steps, see section "_Overview_" in [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/).

##### Hardware Overview

The Wireless Starter Kit (WSTK) with the [BRD4182A Radio Board](https://www.silabs.com/documents/public/user-guides/ug430-brd4182a-user-guide.pdf) (EFR32MG22C224F512IM40) is used as the hardware platform of the DCI and SWD programmer.

The programmer uses GPIO to emulate the DCI and SWD to program the target device. The UART interface handles the user interface. The VCOM_TX and VCOM_RX are routed to the WSTK virtual COM port by setting the VCOM_ENABLE line high.

![Block Diagram of DCI and SWD Programmer](/efr32-dci-swd-programming/0.1/images/sld815-block-diagram-of-dci-and-swd-programmer.png)

**Resources of BRD4182A Used by Programmer**

|**GPIO (SoC Peripheral)**|**WSTK Peripheral**|**Function**|**EXP Header Connection**|
|---|---|---|---|
|PA01 (DBG_SWCLK)|DBG_TCK_SWCLK|Programmer debug SWCLK|—|
|PA02 (DBG_SWDIO)|DBG_TCK_SWDIO|Programmer debug SWDIO|—|
|PA05 (US1_TX)|VCOM_TX|WSTK Virtual COM port TX|Pin 12|
|PA06 (US1_RX)|VCOM_RX|WSTK Virtual COM port RX|Pin 14|
|PB04|VCOM_ENABLE|WSTK Virtual COM port enable|—|
|PC03|—|Target device RESETn|Pin 10|
|PD02|UIF_LED0|Target device SWCLK (shared with WSTK LED0)|Pin 11|
|PD03|UIF_LED1|Target device SWDIO (shared with WSTK LED1)|Pin 13|

The following figure shows the interconnection between programmer and target device. The programmer is the WSTK with the BRD4182A Radio Board and the target device is the WSTK with one of the Series 2 radio boards below.

- EFR32MG21A — BRD4181A (J101 P16 for SWCLK)
- EFR32MG21B — BRD4181C (J101 P16 for SWCLK)
- EFR32MG22 — BRD4182A (J101 P16 for SWCLK)
- EFR32FG23A — BRD4263B (J101 P20 for SWCLK)
- EFR32FG23B — BRD4263C (J101 P20 for SWCLK)

![Programmer Connection Diagram](/efr32-dci-swd-programming/0.1/images/sld815-programmer-connection-diagra.png)

The programmer powers the target device on the Series 2 radio board through VMCU. Therefore power switch (SW700) of the target device WSTK should be in the BAT position.

**Programmer Connection Diagram**

The programmer can work on other Series 2 radio boards or kits. However, the following limitations may apply.

- Some firmware images (`xg2*_app_image[] and xg2*_signed_imag[]`) in [Hard-coded Firmware Images](#firmware-images) are hardware-dependent (GPIOs for LEDs, push buttons, and UART). Therefore, they may not function properly on other radio boards or kits.
- The SWCLK and SWDIO of the target radio boards or kits may be on different pins or connectors. Therefore, the connection diagram above may not apply (refer to the board-specific schematics for details).

##### Software Overview

Users must select the BRD4182A radio board to access the `Series 2 DCI and SWD Programming` platform example in Simplicity Studio 5. Click the `View Project Documentation` link to open the `readme` file. This file includes the procedures to create the project and run the example.

![View Project Documentation](/efr32-dci-swd-programming/0.1/images/sld815-image19.jpg)

###### Bit-Bang

The main overhead on writing directly to MSC registers is to emulate the [SWCLK and SWDIO](#hardware-overview) signals by bit-banging GPIO pins. The programmer must use the GPIOs in the same port group (0-7 or 8-15) for SWCLK and SWDIO to speed up this emulation process. The software writes to the entire port at once when bit-banging the SWCLK and SWDIO signals. Therefore, the programmer cannot use the spare pins of this port for other purposes.

###### Security Keys

The following table describes the security keys (hard-coded in `app_dci_task.c`) used in the programming examples. Users can modify these keys to adapt to the application requirements. The files (`.prv` and `.pem`) of security keys can be found in the Windows folder `C:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\secmgr\scripts\offline.`

**Hard-Coded Security Keys**

|**Array**|**Usage**|**Source**|
|---|---|---|
|aes_key[]|Decrypt GBL payloads|A 16 bytes AES-128 key in encrypt-unsafe-key.prv (binary file).|
|public_sign_key[]|Secure boot|A 64 bytes Public Sign Key, the corresponding Private Sign Key in root-sign-unsafe-privkey.pem.|
|public_command_key[]|Secure debug unlock and Disable tamper|A 64 bytes Public Command Key, the corresponding Private Command Key in cmd-unsafe-privkey.pem.|

The public key can be derived from the private key by using [OpenSSL](https://slproweb.com/products/Win32OpenSSL.html).

```sh
openssl ec -in rootsign-unsafe-privkey.pem -pubout -text > public_sign_key.txt
```

```sh
openssl ec -in cmd-unsafe-privkey.pem -pubout -text > public_command_key.txt
```

###### OTP Settings

The following table describes the OTP settings (hard-coded in `app_dci_task.c`) used in the programming examples. Users can modify these values to adapt to the application requirements.

**Hard-Coded OTP Settings**

|**Array**|**OTP Settings**|**Value**|
|---|---|---|
|vse_svm_conf[]|VSE-SVM|MCU flags: Secure boot enable and Secure boot anti-rollback (0x00050000)|
|hse_svm_conf[]|HSE-SVM|MCU flags: Secure boot enable and Secure boot anti-rollback (0x00050000)|
|"|"|Reserved: 0x00000000, 0x00000000, 0x00000000, 0x00000000|
|hse_svh_xg21b_conf[]|HSE-SVH (xG21B)|MCU flags: Secure boot enable and Secure boot anti-rollback (0x00050000)|
|"|"|Tamper source levels: 0x40440410, 0x14040104, 0x77442211, 0x42042224|
|"|"|Filter reset period: 10|
|"|"|Filter trigger threshold: 6|
|"|"|Tamper flags: 0|
|"|"|Tamper reset threshold: 5|
|hse_svh_other_conf[]|HSE-SVH (others)|MCU flags: Secure boot enable and Secure boot anti-rollback (0x00050000)|
|"|"|Tamper source levels: 0x40440410, 0x14040104, 0x22414224, 0x74422112|
|"|"|Filter reset period: 10|
|"|"|Filter trigger threshold: 6|
|"|"|Tamper flags: 0|
|"|"|Tamper reset threshold: 5|

> **Note**: Refer to the tables below for details about OTP settings.

- [Parameters of MCU Flags](05-se-command-list#mcu-flags)
- [Tamper Source Response Level on HSE-SVH (xG21B) Devices](05-se-command-list#anti-tamper-configuration)
- [Tamper Source Response Level on Other HSE-SVH Devices](05-se-command-list#anti-tamper-configuration)
- [Anti-Tamper Configuration Settings](05-se-command-list#anti-tamper-configuration)

###### Firmware images

The following table describes the firmware images (hard-coded in `app_firmware_image.c`) used in the programming examples. Users can modify these images to adapt to the application requirements.

**Hard-Coded Firmware Images**

|**Array**|**Size (Bytes)**|**Usage**|
|---|---|---|
|xg21_hse_image[]|41125|The xG21 HSE upgrade firmware image (v1.2.9)|
|xg21_app_image[]|9212|The xG21 application firmware image (Blink Bare-metal platform example)|
|xg21_signed_image[]|11192|A signed xG21 UART XMODEM Bootloader image (v1.12.0)|
|erase_xg21_userdata[]|3068|Application firmware image to erase xG21 user data|
|write_xg21_userdata[]|4228|Application firmware image to program xG21 user data|
|prog_xg21_hse_upgrade[]|6956|Application firmware image to upgrade xG21 HSE firmware|
|xg22_vse_image[]|16549|The xG22 VSE upgrade firmware image (v1.2.7)|
|xg22_app_image[]|10756|The xG22 application firmware image (Blink Bare-metal platform example)|
|xg22_signed_image[]|14128|A signed xG22 UART XMODEM Bootloader image (v1.12.0)|
|prog_xg22_vse_upgrade[]|9320|Application firmware image to upgrade xG22 VSE firmware|
|xg23_hse_image[]|88221|The xG23 HSE upgrade firmware image (v2.1.4)|
|xg23_app_image[]|13560|The xG23 application firmware image (Blink Bare-metal platform example)|
|xg23_signed_image[]|16248|A signed xG23 UART XMODEM Bootloader image (v1.12.0)|
|prog_xg23_hse_upgrade[]|11696|Application firmware image to upgrade xG23 HSE firmware|

> **Note**:
> 
> - The HSE or VSE upgrade firmware image must be stored to the device's internal flash in [.seu](02-introduction#introduction) format.
> - The firmware image (`.seu` format) can be converted to a C source file using the SEGGER free utility [`Bin2C.exe`](https://www.segger.com/free-utilities/bin2c/). The last **NULL** (`0x00`) character in the converted firmware image array should be discarded.
> 
> ![Bin2C.exe](/efr32-dci-swd-programming/0.1/images/sld815-image20.png)
> 
> - The programmer uses the bootloader image signed by the Private Sign Key ([rootsign-unsafe-privkey.pem](#security-keys)) to recover a secure boot failure device.
> - Refer to [Add a New Series Device to the Programmer](07-add-a-new-series-2-device-to-the-programmer#add-a-new-series-2-device-to-the-programmer) for instructions on adding firmware images for newer devices.

###### Compile Options

The following tables describe the compile options in header files to set up the software and hardware environment for the programming examples.

**Compile Options in app_dci_swd.h**

|**Parameter**|**Usage**|**Default Setting**|
|---|---|---|
|RESET_PULSE|Pin reset pulse width in microseconds|1000 µs (1 ms)|
|RESET_DELAY|Delay in microseconds after issuing a soft or pin reset|50000 µs (50 ms)|
|DCI_RETRY_COUNT|Number of times to retry a DCI read or write operation. It must be high enough to receive a response from the SE command.|1001000|
|SWCLK_PORT|GPIO port for SWCLK|3 (Port D)|
|SWCLK_PIN|GPIO pin for SWCLK|2 (PD02)|
|SWDIO_PORT|GPIO port for SWDIO|3 (Port D)|
|SWDIO_PIN|GPIO pin for SWDIO|3 (PD03)|
|RESET_PORT|GPIO port for RESETn|2 (Port C)|
|RESET_PIN|GPIO pin for RESETn|3 (PC03)|

**Compile Options in app_firmware_image.h**

|**Parameter**|**Usage**|**Default Setting**|
|---|---|---|
|SE_START_ADDR|SE upgrade firmware image start address (aligned with 8 kB flash page size)|0x00060000|
|SE_UPGRADE_DELAY|Delay in microseconds after issuing a command to upgrade the SE firmware|2500000 µs (2.5 s)|
|USER_DATA_DELAY|Delay in microseconds after issuing a soft reset to run the application to erase or write the user data on xG21 devices|1000000 µs (1 s)|

> **Note**: Make sure the device has enough flash space to accommodate the SE firmware image when setting the SE_START_ADDR.

**Compile Options in app_swd_task.h**

|**Parameter**|**Usage**|**Default Setting**|
|---|---|---|
|ERASE_DELAY|Delay in microseconds after a flash page erase or mass erase|12000 µs (12 ms)|
|ERASE_LOOPCNT|It must be high enough to cover the page erase or mass erase time|1000|
|SKIP_POLLING|Skip polling WDATAREADY bit in the MSC STATUS register after writing 32-bit word to target device flash|1 (Skip)|
|WRITE_DELAY|Fix delay in microseconds after writing a 32-bit word to target device flash (if SKIP_POLLING = 1)|11 µs|

> **Note**:
> 
> - Refer to [Flash Erase](04-serial-wire-debug-swd-interface#flash-erase) for details about page erase and mass erase.
> - Refer to [Flash Write](04-serial-wire-debug-swd-interface#flash-write) for details about `SKIP_POLLING` and `WRITE_DELAY`.

##### Menu Operation

The `SPACE` and `ENTER` presses from the terminal program are used to manipulate the menu of the programmer.

###### Interface Menu

```sh
Series 2 DCI and SWD Programming Examples - Core running at 80000 kHz.
 . Current interface selection is DEBUG CHALLENGE INTERFACE (DCI).
 + Press SPACE to pick an interface (DCI/SWD), press ENTER to select the task of the chosen interface.
```

**DCI Menu**

```sh
. Current DCI task is GET SE STATUS.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 + Current DCI task is READ SE OTP CONFIGURATION.
 + Current DCI task is READ SERIAL NUMBER.
 + Current DCI task is READ PUBLIC SIGN KEY.
 + Current DCI task is READ PUBLIC COMMAND KEY.
 + Current DCI task is READ LOCK STATUS.
 + Current DCI task is SET DEBUG RESTRICTIONS.
 + Current DCI task is ENABLE SECURE DEBUG.
 + Current DCI task is DISABLE SECURE DEBUG.
 + Current DCI task is LOCK DEVICE.
 + Current DCI task is ERASE DEVICE (UNLOCK).
 + Current DCI task is RECOVER SECURE BOOT FAILURE DEVICE.
 + Current DCI task is UPGRADE SE FIRMWARE THROUGH DCI.
 + Current DCI task is INITIALIZE AES-128 KEY (HSE).
 + Current DCI task is INITIALIZE PUBLIC SIGN KEY.
 + Current DCI task is INITIALIZE PUBLIC COMMAND KEY.
 + Current DCI task is INITIALIZE SE OTP.
 + Current DCI task is DISABLE DEVICE ERASE.
```

From task `ENABLE SECURE DEBUG` to task `UPGRADE SE FIRMWARE THROUGH DCI`:

```sh
 + Current DCI task is ENABLE SECURE DEBUG.
 + Press ENTER to confirm or press SPACE to abort.
```

From task `INITIALIZE AES-128 KEY (HSE)` to task `DISABLE DEVICE ERASE`:

```sh
+ Current DCI task is DISABLE DEVICE ERASE.
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
```

**SWD Interface Menu**

```sh
Series 2 DCI and SWD Programming Examples - Core running at 80000 kHz.
 . Current interface selection is DEBUG CHALLENGE INTERFACE (DCI).
 + Press SPACE to pick an interface (DCI/SWD), press ENTER to select the task of the chosen interface.
 + Current interface selection is SERIAL WIRE DEBUG (SWD) INTERFACE.

 . Current SWD task is ERASE MAIN FLASH.
 + Press SPACE to cycle through the SWD tasks, press ENTER to run the selected SWD task.
 + Current SWD task is PROGRAM MAIN FLASH.
 + Current SWD task is ERASE USER DATA.
 + Current SWD task is PROGRAM USER DATA.
 + Current SWD task is UPGRADE SE FIRMWARE THROUGH APPLICATION FIRMWARE.
```

```sh
 + Current SWD task is ERASE MAIN FLASH.
 + Press ENTER to confirm or press SPACE to abort.
```

**Error Handling**

```sh
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

###### DCI Programming Examples

The following DCI programming examples are based on EFR32MG21B (BRD4181C) as the target device [Programmer Connection Diagram on page 23](#hardware-overview). Software is compiled with -O2 optimization in Simplicity IDE of Simplicity Studio 5.

**Get SE Status**

- To get the current [SE status](05-se-command-list#get-status).

```sh
 . Current DCI task is GET SE STATUS.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

###### Read SE OTP Configuration

- To read the current [SE OTP configuration](05-se-command-list#read-user-configuration).  
  ```sh  
  . Current DCI task is READ SE OTP CONFIGURATION.  
  + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.  
    
  . Read target device user (SE OTP) configuration... OK  
  + Secure boot : Disabled  
  + Secure boot verify certificate : Disabled  
  + Secure boot anti-rollback : Disabled  
  + Secure boot page lock narrow : Disabled  
  + Secure boot page lock full : Disabled  
  + Tamper source level  
  Filter counter : 1  
  SE watchdog : 4  
  SE RAM CRC : 4  
  SE hard fault : 4  
  SE software assertion : 4  
  SE secure boot : 4  
  User secure boot : 0  
  Mailbox authorization : 1  
  DCI authorization : 0  
  OTP read : 4  
  Self test : 4  
  TRNG monitor : 1  
  PRS0 : 1  
  PRS1 : 1  
  PRS2 : 2  
  PRS3 : 2  
  PRS4 : 4  
  PRS5 : 4  
  PRS6 : 7  
  PRS7 : 7  
  Decouple BOD : 4  
  Temperature sensor : 2  
  Voltage glitch falling : 2  
  Voltage glitch rising : 2  
  Secure lock : 4  
  SE debug : 0  
  Digital glitch : 2  
  SE ICACHE : 4  
  + Reset period for the tamper filter counter: ~32 ms x 1024  
  + Activation threshold for the tamper filter: 4  
  + Digital glitch detector always on: Disabled  
  + Tamper reset threshold: 5  
  ```
- SE will return the [SE_RESPONSE_INVALID_COMMAND](03-debug-challenge-interface-dci#response) code if the SE OTP data has not been initialized or SE firmware version is less than v1.2.2 (xG21 or xG22 devices).

```sh
 . Read target device user (SE OTP) configuration... Failed - Unsupported command.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Read Serial Number**

- To read the [serial number](05-se-command-list#read-serial-number) of the Series 2 device.

```sh
 . Current DCI task is READ SERIAL NUMBER.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 . Read target device serial number... OK
 + The serial number (16 bytes): 000000000000000014B457FFFE0F77CE
```

###### Read Public Sign Key

- To read the [Public Sign Key](05-se-command-list#read-public-key) in SE OTP.

```sh
 . Current DCI task is READ PUBLIC COMMAND KEY.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 . Read target device public command key... OK
 + The public command key (64 bytes): B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4
 7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63
```

- SE will return the [SE_RESPONSE_INTERNAL_ERROR](03-debug-challenge-interface-dci#response) code if the Public Sign Key has not been provisioned.

```sh
 . Read target device public command key... Failed - Internal SE error.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Read Public Command Key**

- To read the [Public Command Key](05-se-command-list#read-public-key) in SE OTP.

```sh
 . Current DCI task is READ PUBLIC COMMAND KEY.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 . Read target device public command key... OK
 + The public command key (64 bytes): B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4
 7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63
```

- SE will return the [SE_RESPONSE_INTERNAL_ERROR](03-debug-challenge-interface-dci#response) code if the Public Command Key has not been provisioned.

```sh
 . Read target device public command key... Failed - Internal SE error.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Read Lock Status**

- To read the lock state of the debug port.

```sh
+ Current DCI task is READ LOCK STATUS.
 . Debug port lock state
 + Debug Locked, config status : Disabled.
 + Device erase : Enabled.
 + Secure debug unlock : Enabled.
 + Debug port : Unlocked.
 + Invasive Debug Lock : Unlocked.
 + Non-invasive Debug Lock : Unlocked.
 + Secure Invasive Debug Lock : Unlocked.
 + Secure Non-invasive Debug Lock : Unlocked.
```

**Set Debug Restrictions**

- To set debug restrictions.

```sh
 + Setting the lockbit for Secure, Non-Invasive Debug
 . Set the debug restriction bits of the target device... OK
 . Read target device SE status... OK
 + SE firmware version : 0001020E
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Enabled
 + Secure boot : Disabled and SE OTP is not configured
 + Boot status : 0x20 - Command successful.
Series 2 DCI and SWD Programming Examples - Core running at 80000 kHz.
 . Current interface selection is DEBUG CHALLENGE INTERFACE (DCI).
 + Press SPACE to pick an interface (DCI/SWD), press ENTER to select the task of the chosen interface.
```

###### Enable Secure Debug

- To [enable](05-se-command-list#enable-secure-debug) the secure debug functionality.

```sh
 + Current DCI task is ENABLE SECURE DEBUG.
 + Press ENTER to confirm or press SPACE to abort.
 . Enable secure debug of the target device... OK
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Enabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if the Public Command Key has not been provisioned.

```sh
 . Enable secure debug of the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

- SE will return the [SE_RESPONSE_INVALID_COMMAND](03-debug-challenge-interface-dci#response) code if the secure debug has already enabled.

```sh
 . Enable secure debug of the target device... Failed - Unsupported command.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Disable Secure Debug**

- To [disable](05-se-command-list#disable-secure-debug) the secure debug functionality.

```sh
 + Current DCI task is DISABLE SECURE DEBUG.
 + Press ENTER to confirm or press SPACE to abort.
 . Disable secure debug of the target device... OK
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

**Lock Device**

- To enable the [debug lock](05-se-command-list#apply-lock) of the Series 2 device.

```sh
 + Current DCI task is LOCK DEVICE.
 + Press ENTER to confirm or press SPACE to abort.
 . Lock target device... OK
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Enabled
 + Debug lock state : True
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

**Erase Device (Unlock)**

- To perform a device mass erase and [unlock](05-se-command-list#erase-device) the standard debug lock of the Series 2 device.

```sh
 + Current DCI task is ERASE DEVICE (UNLOCK).
 + Press ENTER to confirm or press SPACE to abort.
 . Erase (unlock) target device... OK
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

- SE will return the [SE_RESPONSE_INVALID_COMMAND](03-debug-challenge-interface-dci#erase-device) code if the [Device Erase](05-se-command-list#disable-device-erase) is disabled.

```sh
 . Erase (unlock) target device... Failed - Unsupported command.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Recover Secure Boot Failure Device**

- To get the current [SE status](05-se-command-list#get-status).

```sh
 . Current DCI task is GET SE STATUS.
 + Press SPACE to cycle through the DCI tasks, press ENTER to run the selected DCI task.
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Enabled
 + Boot status : 0x14 - Failure while checking the host for secure boot.
```

- Issue a [device erase](05-se-command-list#erase-device) to unlock the target device through DCI.

```sh
 + Current DCI task is RECOVER SECURE BOOT FAILURE DEVICE.
 + Press ENTER to confirm or press SPACE to abort.

 . Issue a device erase through DCI.
 + Erase target device... OK
```

- A correctly-signed firmware image [xg21_signed_image[]](#firmware-images) is programmed to the target device main flash through the SWD interface to recover a secure boot failure device.

```sh
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x14B457FFFE0F7762
 . Program a correctly-signed image to recover device.
 + The xG21 signed firmware image size is 11192 bytes and start address is 0x00000000.
 + Erase-Program-Verify the xG21 main flash for signed firmware image... OK (cycles: 13616519 time: 170 ms)
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : 010C0000
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Enabled
 + Boot status : 0x20 - Command successful.
```

- The device cannot be recovered if the image is not correctly-signed.

```sh
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : 010C0000
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Enabled
 + Boot status : 0x12 - Failure while checking the host for secure boot.
```

**Upgrade SE Firmware Through DCI**

- A SE upgrade firmware image [xg21_hse_image[]](#firmware-images) is programmed to the target device main flash at [SE_START_ADDR](#compile-options) through the SWD interface. It will overwrite the data from `SE_START_ADDR` to `SE_START_ADDR` + the size of `xg21_hse_image[]`.

```sh
 + Current DCI task is UPGRADE SE FIRMWARE THROUGH DCI.
 + Press ENTER to confirm or press SPACE to abort.
 . Program a SE firmware image to the target device.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x588E81FFFE7034E5
 + The xG21 HSE firmware image version: 00010209
 + The xG21 HSE firmware image size is 41125 bytes and start address is 0x00060000.
 + Erase-Program-Verify the xG21 main flash for HSE firmware image... OK (cycles: 52365323 time: 654 ms)
```

- [Validate](05-se-command-list#se-image-check) the SE upgrade firmware image and start the [upgrade](05-se-command-list#se-image-apply) process if the image is valid.

```sh
 . Validate SE firmware image in the target device... OK
 . Upgrade SE firmware image, delay few seconds to check SE status... Done
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if the SE upgrade firmware image is invalid.

```sh
 . Validate SE firmware image in the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

- SE will return the [SE_RESPONSE_INVALID_COMMAND](03-debug-challenge-interface-dci#response) code if the current SE firmware version is less than v1.2.2 (xG21 or xG22 devices).

```sh
 . Validate SE firmware image in the target device... Failed - Unsupported command.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.

```

###### Initialize AES-128 Key (HSE)

- To [initialize](05-se-command-list#initialize-aes-key) the [aes_key[]](#security-keys) to HSE OTP.

```sh
 + Current DCI task is INITIALIZE AES-128 KEY (HSE).
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
 . Initialize AES-128 key of the target device... OK
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if the AES-128 key has already been initialized.

```sh
 . Initialize AES-128 key of the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Initialize Public Sign Key**

- To [initialize](05-se-command-list#initialize-public-key) the [public_sign_key[]](#security-keys) to SE OTP.

```sh
 + Current DCI task is INITIALIZE PUBLIC SIGN KEY.
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
 . Initialize public sign key of the target device... OK
 . Read target device public sign key... OK
 + The public sign key (64 bytes): C4AF4AC69AAB9512DB50F7A26AE5B4801183D85417E729A56DA974F4E08A562C
 DE6019DEA9411332DC1A743372D170B436238A34597C410EA177024DE20FC819
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if the Public Sign Key has already been initialized.

```sh
 . Initialize public sign key of the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Initialize Public Command Key**

- To [initialize](05-se-command-list#initialize-public-key) the [public_command_key[]](#security-keys) to SE OTP.

```sh
 + Current DCI task is INITIALIZE PUBLIC COMMAND KEY.
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
 . Initialize public command key of the target device... OK
 . Read target device public command key... OK
 + The public command key (64 bytes): B1BC6F6FA56640ED522B2EE0F5B3CF7E5D48F60BE8148F0DC08440F0A4E1DCA4
 7C04119ED6A1BE31B7707E5F9D001A659A051003E95E1B936F05C37EA793AD63
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if the Public Command Key has already been initialized.

```sh
 . Initialize public command key of the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

###### Initialize SE OTP

- To [initialize](05-se-command-list#initialize-otp) the [hse_svh_xg21b_conf[]](#otp-settings) to the HSE OTP.

```sh
 + Current DCI task is INITIALIZE SE OTP.
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
 . Initialize SE OTP of the target device... OK
 . Read target device user (SE OTP) configuration... OK
 + Secure boot : Enabled
 + Secure boot verify certificate : Disabled
 + Secure boot anti-rollback : Enabled
 + Secure boot page lock narrow : Disabled
 + Secure boot page lock full : Disabled
 + Tamper source level
 Filter counter : 1
 SE watchdog : 4
 SE RAM CRC : 4
 SE hard fault : 4
 SE software assertion : 4
 SE secure boot : 4
 User secure boot : 0
 Mailbox authorization : 1
 DCI authorization : 0
 OTP read : 4
 Self test : 4
 TRNG monitor : 1
 PRS0 : 1
 PRS1 : 1
 PRS2 : 2
 PRS3 : 2
 PRS4 : 4
 PRS5 : 4
 PRS6 : 7
 PRS7 : 7
 Decouple BOD : 4
 Temperature sensor : 2
 Voltage glitch falling : 2
 Voltage glitch rising : 2
 Secure lock : 4
 SE debug : 0
 Digital glitch : 2
 SE ICACHE : 4
 + Reset period for the tamper filter counter: ~32 ms x 1024
 + Activation threshold for the tamper filter: 4
 + Digital glitch detector always on: Disabled
 + Tamper reset threshold: 5
```

- SE will return the [SE_RESPONSE_INVALID_COMMAND](03-debug-challenge-interface-dci#response) code if the SE OTP has already programmed.

```sh
 . Initialize SE OTP of the target device... Failed - Unsupported command.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

- SE will return the [SE_RESPONSE_INVALID_PARAMETER](03-debug-challenge-interface-dci#response) code if secure boot option is enabled and the Public Sign Key has not been provisioned.

```sh
 . Initialize SE OTP of the target device... Failed - Parameters are invalid or buffer is too small.
 + Press ENTER to issue a pin reset to the target, press SPACE to skip.
```

**Disable Device Erase**

- To [disable](05-se-command-list#disable-device-erase) the [Erase Device](05-se-command-list#erase-device) command.

```sh
 + Current DCI task is DISABLE DEVICE ERASE.
 + Warning: This is a ONE-TIME command and the operation is IRREVERSIBLE!
 + Press ENTER to confirm or press SPACE to abort.
 . Disable device erase of the target device... OK
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Disabled
 + Secure debug : Enabled
 + Secure boot : Disabled
 + Boot status : 0x20 - Command successful.
```

##### SWD Programming Examples

The following SWD programming examples are based on EFR32MG21B (BRD4181C) and EFR32MG22 (BRD4182A) as target devices ([Programmer Connection Diagram](#hardware-overview)). Software is compiled with -O2 optimization in the Simplicity IDE of Simplicity Studio 5.

If the secure boot option is enabled in the SE OTP or bootloader, the application firmware must be signed.

Some operations are implemented by the SE Manager APIs in an application firmware that is programmed to the target device.

- For more information about SE Manager, see [Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).
- The SE Manager is available in Gecko SDK Suite 3.0.0 or later.
- The SE Manager APIs are fully described in the Silicon Labs online documentation located at [https://docs.silabs.com/gecko-plat-](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager) [form/latest/service/api/group-sl-se-manager](https://docs.silabs.com/gecko-platform/latest/service/api/group-sl-se-manager).

**Erase Main Flash**

- This example demonstrates the [mass erase](04-serial-wire-debug-swd-interface#flash-erase) operation through the SWD interface.

```sh
 + Current SWD task is ERASE MAIN FLASH.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x14B457FFFE0F77CE
 . Erase main flash of the target device... OK (cycles: 1511120 time: 18889 us)
```

**Program Main Flash**

- This example demonstrates the [flash erase](04-serial-wire-debug-swd-interface#flash-erase), [flash write](04-serial-wire-debug-swd-interface#flash-write), and [flash verify](04-serial-wire-debug-swd-interface) operations through the SWD interface. In this example, an application firmware image [xg21_app_image[]](#firmware-images) is programmed to the target device main flash.

```sh
 + Current SWD task is PROGRAM MAIN FLASH.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x14B457FFFE0F77CE
 . Program an application firmware image to the target device.
 + The xG21 application firmware image size is 9212 bytes and start address is 0x00000000.
 + Erase-Program-Verify the xG21 main flash for application firmware image... OK (cycles: 11388469 time: 142 ms)
 + Issue a soft reset to run the application firmware... OK
```

**Erase User Data (xG21 Devices)**

- For xG21 devices (BRD4181C), the user data can only be erased by issuing a command to the HSE through the SE Manager API.
- In this example, an application firmware image [erase_xg21_userdata[]](#firmware-images) (see source code below) is programmed to the target device main flash.

```sh
#include "em_chip.h"
#include "em_cmu.h"
#include "sl_se_manager.h"
#include "sl_se_manager_util.h"
/***************************************************************************//**
 * Main function
 ******************************************************************************/
int main(void)
{
 // Command context
 sl_se_command_context_t cmd_ctx;
 // Switch SYSCLK to 38 MHz HFRCO
 CMU_HFRCODPLLBandSet(cmuHFRCODPLLFreq_38M0Hz);
 // Initialize SE Manager
 sl_se_init();
 // Erase user page
 sl_se_erase_user_data(&cmd_ctx);
 
 while (1) ;
}
```

- The original application firmware image on the application start address will be overwritten.
- Issue a soft reset to run the application above to erase the user data.

```sh
 + Current SWD task is ERASE USER DATA.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x14B457FFFE0F77CE
 . Erase xG21 user data through application firmware.
 + The xG21 application firmware image size is 3068 bytes and start address is 0x00000000.
 + Erase-Program-Verify the xG21 main flash for application firmware image... OK (cycles: 4473314 time: 55916 us)
 + Issue a soft reset to run the application firmware to erase the xG21 user data... OK
```

**Erase User Data (non xG21 Devices)**

- For non xG21 devices (BRD4182A), the user data can be erased the same way as any page in the main flash.

```sh
 + Current SWD task is ERASE USER DATA.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG22C224F512 and unique ID is 0x680AE2FFFE287808
 . Erase xG22 user data... OK (cycles: 2027306 time: 25341 us)
```

**Program User Data (xG21 Devices)**

- For xG21 devices (BRD4181C), the user data can only be written by issuing a command to the HSE through the SE Manager API.
- In this example, an application firmware image write_xg21_userdata[] (see source code below) is programmed to the target device  
  main flash.

```sh
#include "em_chip.h"
#include "em_cmu.h"
#include "sl_se_manager.h"
#include "sl_se_manager_util.h"
// User data
SL_ALIGN(4) static const uint32_t user_data[256] SL_ATTRIBUTE_ALIGN(4) = {
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55, 0x55AA55AA, 0xAA55AA55,
};
/***************************************************************************//**
 * Main function
 ******************************************************************************/
int main(void)
{
 // Command context
 sl_se_command_context_t cmd_ctx;
 // Switch SYSCLK to 38 MHz HFRCO
 CMU_HFRCODPLLBandSet(cmuHFRCODPLLFreq_38M0Hz);
 // Initialize SE Manager
 sl_se_init();
 // Erase user data
 sl_se_erase_user_data(&cmd_ctx);
 
 // Write user data
 sl_se_write_user_data(&cmd_ctx, 0, (uint32_t *)user_data, sizeof(user_data));
 while (1) ;
}
```

- The original application firmware image on the application start address will be overwritten.
- Issue a soft reset to run the application above to write the user data.

```sh
 + Current SWD task is PROGRAM USER DATA.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x14B457FFFE0F77CE
 . Program xG21 user data through application firmware.
 + The xG21 application firmware image size is 4228 bytes and start address is 0x00000000.
 + Erase-Program-Verify the xG21 main flash for application firmware image... OK (cycles: 5777749 time: 72221 us)
 + Issue a soft reset to run the application firmware to program the xG21 user data... OK
```

**Program User Data (non xG21 Devices)**

- For non xG21 devices (BRD4182A), the user data can be written the same way as any page in the main flash.

```sh
 + Current SWD task is PROGRAM USER DATA.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG22C224F512 and unique ID is 0x680AE2FFFE287808
 . Program xG22 user data.
 + User data size is 1024 bytes and start address is 0x0FE00000.
 + Erase-Program-Verify the xG22 user data... OK (cycles: 2179418 time: 27242 us)
```

**Upgrade SE Firmware Through Application Firmware**

- For xG21 or xG22 target devices, the SE firmware can only be upgraded by issuing a command to the SE through the SE Manager API if the SE firmware version is less than v1.2.2.
- Connect to the target device through the SWD interface.
- An application firmware image [prog_xg21_hse_upgrade[]](#firmware-images) (see source code below) is programmed to the target device main flash.

```sh
#include "em_chip.h" #include "em_cmu.h" #include "sl_se_manager.h"

#include "sl_se_manager_util.h"

// SE firmware image start address

#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG) \ && (_SILICON_LABS_32B_SERIES_2_CONFIG \< 3)

#define SE_START_ADDR (**0x00060000UL**)

#else

#define SE_START_ADDR (**0x08060000UL**)

#endif

// Current SE firmware version static uint32_t current_version;

// Upgrade SE firmware version

static volatile uint32_t upgrade_version;

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*//\*\*

\* Main function

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ int main(void)

{

// Command context sl_se_command_context_t cmd_ctx;

// Switch SYSCLK to 38 MHz HFRCO CMU_HFRCODPLLBandSet(cmuHFRCODPLLFreq_38M0Hz);

// Initialize SE Manager sl_se_init();

// Get current SE firmware version

if (sl_se_get_se_version(&cmd_ctx, &current_version) != 0) { goto exit;

}

// Get upgrade SE firmware version

upgrade_version = \*((uint32_t \*)SE_START_ADDR + 3);

// Check if upgrade version \> current version if (upgrade_version \<= current_version) {

goto exit;

}

#if !defined(CRYPTOACC_PRESENT)

// Validate the SE firmware image

if (sl_se_check_se_image(&cmd_ctx, (uint32_t \*)SE_START_ADDR) != 0) { goto exit;

}

#endif

// Upgrade the SE firmware image sl_se_apply_se_image(&cmd_ctx, (uint32_t \*)SE_START_ADDR);

exit:

while (1) ;

}
```

- The original application firmware image on the application start address will be overwritten.

```sh
 + Current SWD task is UPGRADE SE FIRMWARE THROUGH APPLICATION FIRMWARE.
 + Press ENTER to confirm or press SPACE to abort.
 . Connect to the target device through the SWD interface.
 + Initialize DP... OK - IDCODE = 0x6BA02477
 + Read AP... OK - IDR = 0x84770001
 + Set up AHB-AP and halt target... OK
 + Get device information... OK - Target device is EFR32MG21B010F1024 and unique ID is 0x60A423FFFEA0773C
 . Program an application firmware image to the target device to upgrade the SE firmware.
 + The xG21 HSE upgrade application firmware image size is 6956 bytes and start address is 0x00000000.
 + Erase-Program-Verify the xG21 main flash for application to upgrade
 HSE firmware... OK (cycles: 8840993 time: 110 ms)
```

- A SE upgrade firmware image [xg21_hse_image[]](#firmware-images) is programmed to the target device main flash at [SE_START_ADDR](#compile-options). The application start address cannot overlap with `SE_START_ADDR`. This means the `SE_START_ADDR` must be greater than the application start address plus the size [6956 bytes](#firmware-images) of the application firmware image (`prog_xg21_hse_upgrade[]`).

```sh
 . Program a SE firmware image to the target device.
 + The xG21 HSE firmware image version: 00010209
 + The xG21 HSE firmware image size is 41125 bytes and start address is 0x00060000.
 + Erase-Program-Verify the xG21 main flash for HSE firmware image... OK (cycles: 52363897 time: 654 ms)
```

- Issue a pin reset to run the application firmware in `prog_xg21_hse_upgrade[]`.
- Check the SE firmware version after a few seconds to verify the SE firmware has been upgraded.

```sh
 + Issue a pin reset to run the application to upgrade the SE firmware.
 + Delay few seconds to check SE status... Done
 . Read target device SE status... OK
 + SE firmware version : 00010209
 + MCU firmware version : NA
 + Debug lock : Disabled
 + Debug lock state : False
 + Device Erase : Enabled
 + Secure debug : Disabled
 + Secure boot : Disabled and SE OTP is not configured
 + Boot status : 0x20 - Command successful.
```

- The SE firmware cannot be downgraded so the upgrade will be ignored if SE firmware with the same or a lower version is applied to the device.

##### Benchmark

The application firmware in [Hard-coded Firmware Images on page 26](#firmware-images) is replaced by a 256 kB image for benchmarking. The test results in the following table are based on the conditions below.

- [Series 2 DCI and SWD Programming](#software-overview) platform example of GSDK v4.0.1
- Erase, program, and verify the main flash
- [Compile options](#compile-options) are set to default values
- Software is compiled with -O2 in Simplicity IDE (GNU ARM v10.2.1) of Simplicity Studio 5
- The programmer (EFR32MG22C224F512IM40) is running at 80 MHz

**Erase-Program-Verify Time for Different Target Devices**

|**Target Device**|**Application Firmware Image Size**|**Erase-Program-Verify Time**|
|---|---|---|
|EFR32MG21B (BRD4181C)|256 kB (xg21_app_image[])|3.68 s|
|EFR32MG22 (BRD4182A)|256 kB (xg22_app_image[])|3.68 s|
|EFR32FG23B (BRD4263C)|256 kB (xg23_app_image[])|3.74 s|

> **Note**: The following section describes how to add firmware images for newer devices. Users requiring performance data for devices not listed here can add their own 256 kb image to perform the test.

#### Add a New Series 2 Device to the Programmer

The programmer in this application note uses EFR32MG22C224F512IM40 as a host controller. The defines in the following table for EFR32MG22C224F512 should usually apply to the new Series 2 devices.

**Defines for EFR32MG22C224F512**

|**Item**|**Define**|**Value**|
|---|---|---|
|Main flash base address|FLASH_MEM_BASE in efr32mg22c224f512im40.h|0x00000000|
|User data base address|USERDATA_BASE in efr32mg22c224f512im40.h|0x0FE00000|
|MSC base address|MSC_BASE in efr32mg22c224f512im40.h|0x40030000|
|Offset and bitfields of MSC registers|MSC Register Map in xG22 reference manual|—|
|DEVINFO base address|DEVINFO_BASE in efr32mg22c224f512im40.h|0x0FE08000|
|Offset and bitfields of DEVINFO registers|DEVINFO Register Map in xG22 reference manual|—|
|CMU base address|CMU_BASE in efr32mg22c224f512im40.h|0x40008000|
|Offset of CMU_CLKEN1_SET register|CMU Register Map in xG22 reference manual|0x00001068|
|Bitmask to enable MSC clock|CMU_CLKEN1_MSC in efr32mg22_cmu.h|0x00020000|
|AP IDR (Cortex-M33)|S2_AHBAP_ID in app_dci_swd.h|0x84770001|
|TAR wrap mask (Cortex-M33)|TAR_WRAP_1K in app_swd_task.h|0x3FF|

Users need to define new items if any defines in the table above do not match the new Series 2 device. And users may require tuning the settings in [Compile Options](06-series-2-dci-and-swd-programming-examples#compile-options) for the new Series 2 device.

The following procedures describe how to add the xG23 device to the programmer.

1. Add `XG23_FAMILY` (`0x17` for 23) to `app_swd_task.h.` It is `0x15` for xG21, `0x16` for xG22, `0x17` for xG23, etc.  
   ```sh  
   /// Device family of xG23  
   #define XG23_FAMILY (0x00170000UL)  
   ```
2. The  items  below  are  different  from  the  EFR32MG22C224F512  after  checking  the  xG23  header  files  (e.g., efr32fg23b010f512im48.h) and reference manual.  
   - Main [flash base address](04-serial-wire-debug-swd-interface#flash-erase) — Add `FLASH_BASE_XG23` to `app_swd_task.h.`  
   ```sh  
   /// Flash start address of xG23  
   #define FLASH_BASE_XG23 (0x08000000UL)  
   ```  
   - Bitmask to enable MSC clock — Add `CLKEN1_MSC_XG23` to `app_swd_task.h.`  
   ```sh  
   /// MSC bit of xG23 CMU_CLKEN1_SET  
   #define CLKEN1_MSC_XG23 (0x00010000UL)  
   ```
3. Add code to `app_swd_task.c` to enable [MSC clock](04-serial-wire-debug-swd-interface#serial-wire-debug-swd-interface) and set flash base address.  
   ```sh  
   // Enable MSC clock if device is xG23  
   if (buf0 == XG23_FAMILY) {  
   write_mem((uint32_t)&(CMU->CLKEN1_SET), CLKEN1_MSC_XG23);  
   // Check UDLOCKBIT on xG23  
   if (read_mem((uint32_t)&(MSC->MISCLOCKWORD)) & MSC_MISCLOCKWORD_UDLOCKBIT) {  
   RAISE(SWD_ERROR_USERDATA_LOCK);  
   }  
   // Flash start address for xG23  
   flash_start_addr = FLASH_BASE_XG23;  
   }  
   ```
4. Add `DEVICE_XG23` (ASCII code of character "3") to `app_process.h.` It is "1" for xG21, "2" for xG22, "3" for xG23, etc.  
   ```sh  
   /// xG23 device  
   #define DEVICE_XG23 (0x33)  
   ```
5. The [hse_svm_conf[]](06-series-2-dci-and-swd-programming-examples#otp-settings) can apply to xG23A (HSE-SVM) devices. Add || `defined(DEVICE_XG23)` to `hse_svm_conf[]` in `app_dci_ta sk.c.`  
   ```sh  
   #if defined(DEVICE_XG21) || defined(DEVICE_XG23)  
   /// HSE-SVM user configuration  
   static const uint32_t hse_svm_conf[HSE_USER_CONF_SIZE] = {  
   0x00000018, // 24 bytes data below  
   SECURE_BOOT_ENABLE_MASK + ANTI_ROLLBACK_MASK, // MCU settings  
   0x00000000, // 20 bytes reserved data  
   0x00000000,  
   0x00000000,  
   0x00000000,  
   0x00000000  
   };  
   #endif  
   ```
6. The [hse_svh_xg21b_conf[]](06-series-2-dci-and-swd-programming-examples#otp-settings) cannot apply to xG23B (HSE-SVH) devices. Add [hse_svh_other_conf[]](06-series-2-dci-and-swd-programming-examples#otp-settings) to `app_dci_task.c.`  
   ```sh  
   #if defined(DEVICE_XG23)  
   /// Other HSE-SVH user configuration  
   static const uint32_t hse_svh_other_conf[HSE_USER_CONF_SIZE] = {  
   0x00000018, // 24 bytes data below  
   SECURE_BOOT_ENABLE_MASK + ANTI_ROLLBACK_MASK, // MCU settings  
   0x40440410, // Tamper settings  
   0x14040104,  
   0x22414224,  
   0x74422112,  
   0x0500060A  
   };  
   #endif  
   ```
7. Add code (based on `case DEVICE_XG21:`, replace `hse_svh_xg21b_conf` with `hse_svh_other_conf`) to `app_dci_task.c` to set up a command buffer for [OTP configuration](05-se-command-list#initialize-otp).  
   ```sh  
   #if defined(DEVICE_XG23)  
   case DEVICE_XG23:  
   // Check SVM or SVH  
   if (*(cmd_buf + 2) == 'A') {  
   *cmd_buf = INIT_HSE_OTP_LENGTH;  
   *(++cmd_buf) = COMMAND_INIT_OTP;  
   // Calculate parity of OTP configuration  
   *(++cmd_buf) = 0;  
   for (i = 1; i < HSE_USER_CONF_SIZE; i++) {  
   *cmd_buf ^= hse_svm_conf[i];  
   }  
   // Copy OTP configuration to buffer  
   memcpy((uint32_t *)(++cmd_buf), (uint32_t *)hse_svm_conf,  
   INIT_HSE_OTP_LENGTH);  
   } else if (*(cmd_buf + 2) == 'B') {  
   *cmd_buf = INIT_HSE_OTP_LENGTH;  
   *(++cmd_buf) = COMMAND_INIT_OTP;  
   // Calculate parity of OTP configuration  
   *(++cmd_buf) = 0;  
   for (i = 1; i < HSE_USER_CONF_SIZE; i++) {  
   *cmd_buf ^= hse_svh_other_conf[i];  
   }  
   // Copy OTP configuration to buffer  
   memcpy((uint32_t *)(++cmd_buf), (uint32_t *)hse_svh_other_conf,  
   INIT_HSE_OTP_LENGTH);  
   } else {  
   RAISE(SWD_ERROR_UNKNOWN_DEVICE);  
   }  
   break;  
   #endif  
   ```
8. Add [firmware images](06-series-2-dci-and-swd-programming-examples#firmware-images) to `app_firmware_image.c` and `app_firmware_image.h.`  
   ![Add firmware image](/efr32-dci-swd-programming/0.1/images/sld815-image21.png)
9. Add functions to `app_firmware_image.c` and `app_firmware_image.h` to get the address and size of firmware images.  
   ![Add functions](/efr32-dci-swd-programming/0.1/images/sld815-image22.png)
10. The `tamper_source_xg21b[]` cannot be applied to xG23B (HSE-SVH) devices. Add `tamper_source_other[]` to `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    /// Strings for tamper sources of other HSE-SVH devices  
    static const char *tamper_source_other[TAMPER_SIGNAL_NUM] = {  
    NULL,  
    "Filter counter : ",  
    "SE watchdog : ",  
    NULL,  
    "SE RAM ECC 2 : ",  
    "SE hard fault : ",  
    NULL,  
    "SE software assertion : ",  
    "SE secure boot : ",  
    "User secure boot : ",  
    "Mailbox authorization : ",  
    "DCI authorization : ",  
    "OTP Read : ",  
    NULL,  
    "Self test : ",  
    "TRNG monitor : ",  
    "Secure lock : ",  
    "Digital glitch : ",  
    "Voltage glitch : ",  
    "SE ICACHE : ",  
    "SE RAM ECC 1 : ",  
    "BOD : ",  
    "Temperature sensor : ",  
    "DPLL lock fail low : ",  
    "DPLL lock fail high : ",  
    "PRS0 : ",  
    "PRS1 : ",  
    "PRS2 : ",  
    "PRS3 : ",  
    "PRS4 : ",  
    "PRS5 : ",  
    "PRS6 : "  
    };  
    #endif  
    ```
11. Add  || `defined(DEVICE_XG23)` and  code  (based  on  `case DEVICE_XG21:`,  replace  `tamper_source_xg21b` with `tamper_source_other`) to function `print_otp_conf()` in `app_process.c` to print out the [tamper configuration](05-se-command-list#anti-tamper-configuration).  
    ```sh  
    #if defined(DEVICE_XG21) || defined(DEVICE_XG23)  
    uint32_t i;  
    uint32_t j;  
    uint32_t k;  
    #endif  
    ...  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    for (i = 0, j = 0, k = 2; i < TAMPER_SIGNAL_NUM; i++, j += 4) {  
    if (j == 32) {  
    j = 0;  
    k++;  
    }  
    cmd_resp_buf[8] = (cmd_resp_buf[k] >> j) & 0x0f;  
    if (tamper_source_other[i] != NULL) {  
    printf(" %s %lu\n", tamper_source_other[i], cmd_resp_buf[8]);  
    }  
    }  
    break;  
    #endif  
    ...  
    #if defined(DEVICE_XG21) || defined(DEVICE_XG23)  
    // Common tamper parameters  
    printf(" + Reset period for the tamper filter counter: ~32 ms x %u\n",  
    1 << (cmd_resp_buf[6] & COUNTER_PERIOD_MASK));  
    printf(" + Activation threshold for the tamper filter: %d\n",  
    256 / (1 << ((cmd_resp_buf[6] & COUNTER_THRESHOLD_MASK) >> COUNTER_THRESHOLD_SHIFT)));  
    if (cmd_resp_buf[6] & GLITCH_DETECTOR_MASK) {  
    printf(" + Digital glitch detector always on: Enabled\n");  
    } else {  
    printf(" + Digital glitch detector always on: Disabled\n");  
    }  
    if (device_name[DEVICE_INDEX] > DEVICE_XG22) {  
    if (cmd_resp_buf[6] & SLEEP_ALIVE_MASK) {  
    printf(" + Keep tamper alive during sleep: Enabled\n");  
    } else {  
    printf(" + Keep tamper alive during sleep: Disabled\n");  
    }  
    }  
    printf(" + Tamper reset threshold: %lu\n", cmd_resp_buf[6] >> TAMPER_RESET_SHIFT);  
    #endif  
    ```
12. Add code (take `case DEVICE_XG21:` as reference) to function `prog_main_flash_app()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf(" + The xG23 application firmware image size is %lu bytes "  
    "and start address is 0x%08lX.\n", get_xg23_app_size(),  
    get_flash_start_addr());  
    printf(" + Erase-Program-Verify the xG23 main flash for "  
    "application firmware image... ");  
    cmd_resp_buf[0] = prog_flash(get_flash_start_addr(),  
    get_xg23_app_size(),  
    (uint32_t *)get_xg23_app_addr());  
    print_cycle_time();  
    break;  
    #endif  
    ```
13. Add code (take `case DEVICE_XG21:` as reference) to function `prog_main_flash_se()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf(" + The xG23 HSE firmware image version: %08lX\n",  
    *((uint32_t *)get_xg23_hse_addr() + 3));  
    printf(" + The xG23 HSE firmware image size is %lu bytes and start "  
    "address is 0x%08lX.\n", get_xg23_hse_size(),  
    SE_START_ADDR + get_flash_start_addr());  
    printf(" + Erase-Program-Verify the xG23 main flash for HSE "  
    "firmware image... ");  
    cmd_resp_buf[0] = prog_flash(SE_START_ADDR + get_flash_start_addr(),  
    get_xg23_hse_size(),  
    (uint32_t *)get_xg23_hse_addr());  
    print_cycle_time();  
    break;  
    #endif  
    ```
14. Add code (take `case DEVICE_XG21:` as reference) to function `prog_main_flash_se_app()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf(" + The xG23 HSE upgrade application firmware image size is "  
    "%lu bytes and start address is 0x%08lX.\n",  
    get_xg23_hse_upgrade_app_size(), get_flash_start_addr());  
    printf(" + Erase-Program-Verify the xG23 main flash for "  
    "application to upgrade \n");  
    printf(" HSE firmware... ");  
    cmd_resp_buf[0] = prog_flash(get_flash_start_addr(),  
    get_xg23_hse_upgrade_app_size(),  
    (uint32_t *)get_xg23_hse_upgrade_app_addr());  
    print_cycle_time();  
    break;  
    #endif  
    ```
15. Add code (take `case DEVICE_XG21:` as reference) to function `prog_main_flash_signed()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf(" + The xG23 signed firmware image size is %lu bytes "  
    "and start address is 0x%08lX.\n",  
    get_xg23_signed_size(),  
    get_flash_start_addr());  
    printf(" + Erase-Program-Verify the xG23 main flash for "  
    "signed firmware image... ");  
    cmd_resp_buf[0] = prog_flash(get_flash_start_addr(),  
    get_xg23_signed_size(),  
    (uint32_t *)get_xg23_signed_addr());  
    print_cycle_time();  
    break;  
    #endif  
    ```
16. For xG23 devices, the user data can be erased the same way as any page in the main flash. Add code (take `case DEVICE_XG22:` as reference) to function `erase_user_data()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf("\n . Erase xG23 user data... ");  
    cmd_resp_buf[0] = erase_flash(true);  
    print_cycle_time();  
    hard_reset_target();  
    break;  
    #endif  
    ```
17. For xG23 devices, the user data can be written the same way as any page in the main flash. Add code (take `case DEVICE_XG22:` as reference) to function `prog_user_data()` in `app_process.c.`  
    ```sh  
    #if defined(DEVICE_XG23)  
    case DEVICE_XG23:  
    printf("\n . Program xG23 user data.\n");  
    printf(" + User data size is %lu bytes and start address is 0x%08lX.\n",  
    get_userdata_size(), USERDATA_BASE);  
    printf(" + Erase-Program-Verify the xG23 user data... ");  
    cmd_resp_buf[0] = prog_flash(USERDATA_BASE,  
    get_userdata_size(),  
    (uint32_t *)get_userdata_addr());  
    print_cycle_time();  
    hard_reset_target();  
    break;  
    #endif  
    ```
18. There is no need to change the default settings in [Compile Options](06-series-2-dci-and-swd-programming-examples#compile-options) for xG23 devices.  
    > **Note**: The 512 kB flash of EFR32MG22C224F512 is not enough to store the [firmware images](06-series-2-dci-and-swd-programming-examples#firmware-images) when the programmer needs to support more Series 2 devices. Users can selectively comment out the defines in `app_process.h` to save memory for the required Series 2 devices.  
    ```sh  
    /// xG21 device  
    #define DEVICE_XG21 (0x31)  
      
    /// xG22 device  
    define DEVICE_XG22 (0x32)  
      
    /// xG23 device  
    #define DEVICE_XG23 (0x33)  
      
    ```

#### Use J-Link Commander to Run DCI Command

J-Link Commander from [Segger](https://www.segger.com/downloads/jlink/) is a command line-based utility that supports simple commands to verify and communicate with the target connection. There are two ways to run the DCI command through the J-Link Commander.

1. [J-Link Command File](https://wiki.segger.com/J-Link_Commander#Using_J-Link_Command_Files) (*.jlink)
2. [J-Link Script File](https://wiki.segger.com/J-Link_script_files#Using_J-Link_script_files) (*.JLinkScript)

This application note uses J-Link Commander v7.66g. The J-Link Commander's command line interface is invoked by JLink.exe located in `C:\Program Files\SEGGER\JLink_V766g` (Windows).

##### J-Link Command File

The J-Link Command file below is an example to invoke the J-Link Commander in batch processing mode for the [Erase Device](05-se-command-list) operation. The delay (`sleep 500`) in milliseconds after writing the command word is device dependent. It may be shorter or longer.

```sh
connect
swdwritedp 2 0x01000000 ; Select DCI AP
swdwriteap 1 0x1008 ; DCI STATUS
swdreadap 3 
swdreaddp 3 ; Poll till DCI_STATUS.WPENDING (bit 0) is low
swdwriteap 1 0x1000 ; DCI WDATA
swdwriteap 3 0x08 ; Command word 0
sleep 500 ; Delay if necessary
swdwriteap 1 0x1008 ; DCI STATUS
swdreadap 3 
swdreaddp 3 ; Poll till DCI_STATUS.WPENDING (bit 0) is low
swdwriteap 1 0x1000 ; DCI WDATA
swdwriteap 3 0x430F0000 ; command word 1 (Erase Device)
sleep 500 ; Delay if necessary
swdwriteap 1 0x1008 ; DCI STATUS
swdreadap 3 
swdreaddp 3 ; Poll till DCI_STATUS.RDATAVALID (bit 8) is high
swdwriteap 1 0x1004 ; DCI RDATA
swdreadap 3 ; First word
swdreaddp 3 ; Status code is upper 16 bits, total length is lower 16 bits
exit
```

The example below is to run the J-Link Command file (assume `EraseDevice.jlink` is in the J-Link Commander folder) via the Windows DOS command prompt. The target device is EFR32MG21A, and the target interface is 1000 kHz SWD. The SWD speed is hardware dependent; for example, the length of the wires between the programmer and the device debug pins. The speed (frequency) can be higher for shorter wires and lower for longer wires.

```sh
JLink.exe -device EFR32MG21AXXXF1024 -if SWD -speed 1000 -CommandFile EraseDevice.jlink
```

```sh
SEGGER J-Link Commander V7.66g (Compiled Jul 7 2022 10:44:29)
DLL version V7.66g, compiled Jul 7 2022 10:42:43
J-Link Command File read successfully.
Processing script file...
J-Link>connect
J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: Silicon Labs J-Link Pro OB compiled Sep 16 2020 17:10:58
Hardware version: V4.00
S/N: 440048205
License(s): RDI, FlashBP
IP-Addr: DHCP (no addr. received yet)
VTref=3.326V
Device "EFR32MG21AXXXF1024" selected.
Connecting to target via SWD
Found SW-DP with ID 0x6BA02477
DPv0 detected
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[3]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x84770001)
AP[1]: APB-AP (IDR: 0x54770002)
AP[2]: AHB-AP (IDR: 0x84770001)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FE000
CPUID register: 0x410FD213. Implementer code: 0x41 (ARM)
Feature set: Mainline
Found Cortex-M33 r0p3, Little endian.
FPUnit: 8 code (BP) slots and 0 literal slots
Security extension: implemented
Secure debug: enabled
CoreSight components:
ROMTbl[0] @ E00FE000
[0][0]: E00FF000 CID B105100D PID 000BB4C9 ROM Table
ROMTbl[1] @ E00FF000
[1][0]: E000E000 CID B105900D PID 000BBD21 DEVARCH 47702A04 DEVTYPE 00 Cortex-M33
[1][1]: E0001000 CID B105900D PID 000BBD21 DEVARCH 47701A02 DEVTYPE 00 DWT
[1][2]: E0002000 CID B105900D PID 000BBD21 DEVARCH 47701A03 DEVTYPE 00 FPB
[1][3]: E0000000 CID B105900D PID 000BBD21 DEVARCH 47701A01 DEVTYPE 43 ITM
[1][5]: E0041000 CID B105900D PID 002BBD21 DEVARCH 47724A13 DEVTYPE 13 ETM
[1][6]: E0042000 CID B105900D PID 000BBD21 DEVARCH 47701A14 DEVTYPE 14 CSS600-CTI
[0][1]: E0040000 CID B105900D PID 000BBD21 DEVARCH 00000000 DEVTYPE 11 Cortex-M33
[0][2]: E00FD000 CID B105F00D PID 001BB101 TSG
Cortex-M33 identified.
J-Link>swdwritedp 2 0x01000000 ; Select DCI AP
Write DP register 2 = 0x01000000
J-Link>swdwriteap 1 0x1008 ; DCI STATUS
Write AP register 1 = 0x00001008
J-Link>swdreadap 3
Read AP register 3 = 0x000000B1
J-Link>swdreaddp 3 ; Poll till DCI_STATUS.WPENDING (bit 0) is low
Read DP register 3 = 0x00000000
J-Link>swdwriteap 1 0x1000 ; DCI WDATA
Write AP register 1 = 0x00001000
J-Link>swdwriteap 3 0x08 ; Command word 0
Write AP register 3 = 0x00000008
J-Link>sleep 500 ; Delay if necessary
Sleep(500)
J-Link>swdwriteap 1 0x1008 ; DCI STATUS
Write AP register 1 = 0x00001008
J-Link>swdreadap 3
Read AP register 3 = 0x00000000
J-Link>swdreaddp 3 ; Poll till DCI_STATUS.WPENDING (bit 0) is low
Read DP register 3 = 0x00000000
J-Link>swdwriteap 1 0x1000 ; DCI WDATA
Write AP register 1 = 0x00001000
J-Link>swdwriteap 3 0x430F0000 ; command word 1 (Erase Device)
Write AP register 3 = 0x430F0000
J-Link>sleep 500 ; Delay if necessary
Sleep(500)
J-Link>swdwriteap 1 0x1008 ; DCI STATUS
Write AP register 1 = 0x00001008
J-Link>swdreadap 3
Read AP register 3 = 0x00000000
J-Link>swdreaddp 3 ; Poll till DCI_STATUS.RDATAVALID (bit 8) is high
Read DP register 3 = 0x00000100
J-Link>swdwriteap 1 0x1004 ; DCI RDATA
Write AP register 1 = 0x00001004
J-Link>swdreadap 3 ; First word
Read AP register 3 = 0x00000100
J-Link>swdreaddp 3 ; Status code is upper 16 bits, total length is lower 16 bits
Read DP register 3 = 0x00000004
J-Link>exit
Script processing completed.
```

###### J-Link Script File

The J-Link Script file below is an example to customize some actions performed by the J-Link Commander for the [Read Serial Number](05-se-command-list#read-serial-number) operation.

```sh
// Function to select DCI AP register bank 0
int SelectDciAp(void)
{
 int stat;
 int value;
 JLINK_SYS_Report("- Select DCI AP register bank 0\n");
 value = 0x01000000; 
 stat = JLINK_CORESIGHT_WriteDP(2, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- DP 2 write failed: ", value);
 }
 return stat;
}
// Function to write command to DCI_WDATA (0x1000) 
int WriteCommandWord(int command)
{
 int stat;
 int value;
 // Poll DCI_STATUS (0x1008) WPENDING bit (bit 0)
 do {
 value = 0x00001008;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
 }
 JLINK_CORESIGHT_ReadAP(3);
 value = JLINK_CORESIGHT_ReadDP(3);
 if (value == -1) {
 JLINK_SYS_Report("- DP 3 read failed");
 return value;
 }
 if ((value & 0x0100) != 0) {
 JLINK_SYS_Report("- RDATAVALID is high, command aborted");
 return -1;
 } 
 } while ((value & 0x01) != 0);
 
 // Write command
 value = 0x00001000;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
 }
 value = command;
 stat = JLINK_CORESIGHT_WriteAP(3, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 3 write failed: ", value);
 return stat;
 }
 JLINK_SYS_Report1("- Write command word ", command); 
 return stat;
}
// Function to read response from DCI_RDATA (0x1004)
int ReadResponse(void)
{
 int stat;
 int value;
 int count;
// Poll DCI_STATUS (0x1008) RDATAVALID bit (bit 8) 
 do {
 value = 0x00001008;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
 }
 JLINK_CORESIGHT_ReadAP(3);
 value = JLINK_CORESIGHT_ReadDP(3);
 if (value == -1) {
 JLINK_SYS_Report("- DP 3 read failed");
 return value;
 }
 } while ((value & 0x0100) != 0x0100);
 
 // Read first 32-bit response word 
 value = 0x00001004;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
 }
 JLINK_CORESIGHT_ReadAP(3);
 value = JLINK_CORESIGHT_ReadDP(3);
 if (value == -1) {
 JLINK_SYS_Report("- DP 3 read failed");
 return value;
 }
 // Get response count
 count = value & 0x00FF; 
 count = count >> 2;
 JLINK_SYS_Report1("- Number of 32-bit response word: ", count);
 // Get response code
 JLINK_SYS_Report1("- Response: ", value);
 stat = value >>16; 
 if (stat != 0) {
 JLINK_SYS_Report1("- Command error: ", stat);
 return -1;
 }
 
 // Read following 32-bit response word
 count = count - 1;
 while (count != 0) {
 // Poll DCI_STATUS (0x1008) RDATAVALID bit (bit 8) 
 do {
 value = 0x00001008;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
 }
 JLINK_CORESIGHT_ReadAP(3);
 value = JLINK_CORESIGHT_ReadDP(3);
 if (value == -1) {
 JLINK_SYS_Report("- DP 3 read failed");
 return value;
 }
 } while ((value & 0x0100) != 0x0100);
 
 // Read 32-bit response word 
 value = 0x00001004;
 stat = JLINK_CORESIGHT_WriteAP(1, value);
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 1 write failed: ", value);
 return stat;
  }
 JLINK_CORESIGHT_ReadAP(3);
 value = JLINK_CORESIGHT_ReadDP(3);
 if (value == -1) {
 JLINK_SYS_Report("- DP 3 read failed");
 return value;
 }
 JLINK_SYS_Report1("- Response: ", value);
 count = count - 1;
 }
 return 0;
}
// Function to connect DCI
int ConnectDci(void)
{ 
 int stat;
 int value;
 
 JLINK_SYS_Report("\n******************************************************");
 JLINK_SYS_Report("Connect to Series 2 Device DCI\n");
 JLINK_SYS_Report("- Select SWD by sending SWD switching sequence\n");
 stat = JLINK_CORESIGHT_Configure(""); 
 if (stat < 0) {
 JLINK_SYS_Report("- SWD connection failed");
 return stat;
 }
 // Manually select debug interface 
 JLINK_SYS_Report("- Clear sticky error flags\n");
 value = 0x0000001E; 
 stat = JLINK_CORESIGHT_WriteDP(0, value); 
 if (stat < 0) {
 JLINK_SYS_Report1("- DP 0 write failed: ", value);
 return stat;
 }
 JLINK_SYS_Report("- Power up system and debug\n");
 value = 0x50000000; 
 stat = JLINK_CORESIGHT_WriteDP(1, value); 
 if (stat < 0) {
 JLINK_SYS_Report1("- DP 1 write failed: ", value);
 return stat;
 }
 
 value = JLINK_CORESIGHT_ReadDP(0); 
 if (value != 0x6BA02477) {
 JLINK_SYS_Report1("- The connected device does not have a Secure Element (ID Code): ", value);
 return -1;
 }
 JLINK_SYS_Report1("- Read SWD-DP ID code: ", value);
 JLINK_SYS_Report("- Select DCI AP register bank 0\n");
 value = 0x01000000; 
 stat = JLINK_CORESIGHT_WriteDP(2, value); 
 if (stat < 0) {
 JLINK_SYS_Report1("- DP 2 write failed: ", value);
 return stat;
 }
 
 JLINK_SYS_Report("- Set up AP defaults\n");
 value = 0x22000002; 
 stat = JLINK_CORESIGHT_WriteAP(0, value); 
 if (stat < 0) {
 JLINK_SYS_Report1("- AP 0 write failed: ", value); 
 return stat;
 }
 JLINK_SYS_Report("Connect to Series 2 Device DCI OK\n");
 JLINK_SYS_Report("******************************************************");
 return 0;
}
// Function to run DCI command
void RunDciCommand(void)
{
 JLINK_SYS_Report("\n******************************************************");
 JLINK_SYS_Report("Read Serial Number\n");
 if (SelectDciAp() == -1) {
 JLINK_SYS_Report("- Select DCI AP failed\n");
 JLINK_SYS_Report("******************************************************\n\n");
 return;
 }
 if (WriteCommandWord(0x00000008) == -1) {
 JLINK_SYS_Report("- Write DCI command (length) failed\n");
 JLINK_SYS_Report("******************************************************\n\n");
 return;
 }
 if (WriteCommandWord(0xFE000000) == -1) {
 JLINK_SYS_Report("- Write DCI command (ID) failed\n");
 JLINK_SYS_Report("******************************************************\n\n");
 return;
 }
 if (ReadResponse() == -1) {
 JLINK_SYS_Report("- Read DCI command response failed\n");
 JLINK_SYS_Report("******************************************************\n\n");
 return;
 }
 JLINK_SYS_Report("Read Serial Number Done\n");
 JLINK_SYS_Report("******************************************************\n\n");
}
// Replace ConfigTargetSettings() in J-Link DLL
void ConfigTargetSettings(void)
{
 if (ConnectDci() == -1) {
 JLINK_SYS_Report("- Connect to DCI failed\n");
 JLINK_SYS_Report("******************************************************\n\n");
 return;
 }
 RunDciCommand();
}
```

The example below is to run the J-Link Script file (assume `ReadSerialNo.JLinkScript` is in the J-Link Commander folder) via the Windows DOS command prompt. The target device is EFR32MG21A, and the target interface is 1000 kHz SWD. The SWD speed is hardware dependent; for example, the length of the wires between the programmer and the device debug pins. It can be higher for shorter wires and lower for longer wires.

```sh
JLink -device EFR32MG21AXXXF1024 -if SWD -speed 1000 -autoConnect 1 -JLinkScriptFile ReadSerialNo.JlinkScript

```

```sh
SEGGER J-Link Commander V7.66g (Compiled Jul 7 2022 10:44:29)
DLL version V7.66g, compiled Jul 7 2022 10:42:43
Connecting to J-Link via USB...O.K.
Firmware: Silicon Labs J-Link Pro OB compiled Sep 16 2020 17:10:58
Hardware version: V4.00
S/N: 440048205
License(s): RDI, FlashBP
IP-Addr: DHCP (no addr. received yet)
VTref=3.328V
Device "EFR32MG21AXXXF1024" selected.
Connecting to target via SWD
ConfigTargetSettings() start
******************************************************
Connect to Series 2 Device DCI
- Select SWD by sending SWD switching sequence
- Clear sticky error flags
- Power up system and debug
- Read SWD-DP ID code: 0x6BA02477
- Select DCI AP register bank 0
- Set up AP defaults
```

```sh
Connect to Series 2 Device DCI OK
******************************************************
******************************************************
Read Serial Number
- Select DCI AP register bank 0
- Write command word 0x00000008
- Write command word 0xFE000000
- Number of 32-bit response word: 0x00000005
- Response: 0x00000014
- Response: 0x00000000
- Response: 0x00000000
- Response: 0xFF818E58
- Response: 0xE53470FE
Read Serial Number Done
******************************************************
ConfigTargetSettings() end
```

### Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS

#### Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS

> **Note: This section replaces _AN1311: Integrating Crypto Functionality Using PSA Crypto Compared to Mbed TLS_. Further updates to this application note will be provided here**.

This application note describes how to integrate crypto functionality into applications using PSA Crypto compared to Mbed TLS. It includes a guide to migrating existing Mbed TLS implementations to PSA Crypto.

This document focuses on the Silicon Labs PSA Crypto implementations that support the RNG, symmetric and asymmetric keys, message digests, MAC, unauthenticated ciphers, AEAD, KDF, DSA, and ECDH.

This document assumes familiarity with the crypto algorithms discussed.

##### Key Points

- Overview of Mbed TLS and PSA Crypto
- Key management in PSA Crypto
- Migration guide
- PSA Crypto platform examples

#### Series 2 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs’ security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

On Series 1 devices, the security features are implemented by the TRNG (if available) and CRYPTO peripherals.

On Series 2 devices, the security features are implemented by the Secure Engine and CRYPTOACC (if available). The Secure Engine may be hardware-based, or virtual (software-based). Throughout this document, the following abbreviations are used:

- HSE - Hardware Secure Engine
- VSE - Virtual Secure Engine
- SE - Secure Engine (either HSE or VSE)

Additional security features are provided by Secure Vault. Three levels of Secure Vault feature support are available, depending on the part and SE implementation, as reflected in the following table:

|**Level (1)**|**SE Support**|**Part (2)**|
|---|---|---|
|Secure Vault High (SVH)|HSE only (HSE-SVH)|Refer to _IoT Endpoint Security Fundamentals_ for details on supporting devices.|
|Secure Vault Mid (SVM)|HSE (HSE-SVM)|"|
|"|VSE (VSE-SVM)|"|
|Secure Vault Base (SVB)|N/A|"|

> **Notes**:
> 
> 1. The features of different Secure Vault levels can be found in [https://www.silabs.com/security](https://www.silabs.com/security).
> 2. [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/).

Secure Vault Mid consists of two core security functions:

- **Secure Boot**: Process where the initial boot phase is executed from an immutable memory (such as ROM) and where code is authenticated before being authorized for execution.
- **Secure Debug access control**: The ability to lock access to the debug ports for operational security, and to securely unlock them when access is required by an authorized entity.

Secure Vault High offers additional security options:

- **Secure Key Storage**: Protects cryptographic keys by “wrapping” or encrypting the keys using a root key known only to the HSE-SVH.
- **Anti-Tamper protection**: A configurable module to protect the device against tamper attacks.
- **Device authentication**: Functionality that uses a secure device identity certificate along with digital signatures to verify the source or target of device communications.

A Secure Engine Manager and other tools allow users to configure and control their devices both in-house during testing and manufacturing, and after the device is in the field.

##### User Assistance

In support of these products Silicon Labs offers whitepapers, webinars, and documentation. The following table summarizes the key security documents:

<table>
    <thead>
        <tr>
            <th><strong>Document</strong></th>
            <th><strong>Summary</strong></th>
            <th><strong>Applicability</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/series2-secure-debug/">Series 2 and Series 3 Secure Debug</a></p>
            </td>
            <td>
                <p>How to lock and unlock Series 2 and Series 3 debug access, including background information about the SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/">Series 2 and Series 3 Secure Boot with RTSL</a></p>
            </td>
            <td>
                <p>Describes the secure boot process on Series 2 and Series 3 devices using SE</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/">Anti-Tamper Protection Configuration and Use</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure the anti-tamper module</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/">Authenticating Silicon Labs Devices using Device Certificates</a></p>
            </td>
            <td>
                <p>How to authenticate a device using secure device certificates and signatures, at any time during the life of the product</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/">Secure Key Storage</a></p>
            </td>
            <td>
                <p>How to securely "wrap" keys so they can be stored in non-volatile storage.</p>
            </td>
            <td>
                <p>Secure Vault High, and Series 3 devices</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><a href="https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/">Production Programming of Series 2 and Series 3 Devices</a></p>
            </td>
            <td>
                <p>How to program, provision, and configure security information using SE during device production</p>
            </td>
            <td>
                <p>Secure Vault Mid, High, and Series 3 devices</p>
            </td>
        </tr>
    </tbody>
</table>

##### Key Reference

Public/Private keypairs along with other keys are used throughout Silicon Labs security implementations. Because terminology can sometimes be confusing, the following table lists the key names, their applicability, and the documentation where they are used.

|**Key Name**|**Customer Programmed**|**Purpose**|
|---|---|---|
|Public Sign key (Sign Key Public)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|
|Public Command key (Command Key Public)|Yes|Secure Debug Unlock or Disable Tamper command authentication|
|OTA Decryption key (GBL Decryption key) aka AES-128 Key|Yes|Decrypting GBL payloads used for firmware upgrades|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|

##### SE Firmware

Silicon Labs strongly recommends installing the latest SE firmware on Series 2 devices to support the required security features. Refer to [Production Programming of Series 2 and Series 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/) for the procedure to upgrade the SE firmware and [IoT Endpoint Security Fundamentals](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 2 devices and modules.

#### Device Capability

The following table lists the hardware related to cryptography hardware acceleration features on Series 1 and Series 2 devices (MCU and Wireless SoC).

|**Feature**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|
|---|---|---|---|
|TRNG|TRNG peripheral (1)|CRYPTOACC peripheral|HSE|
|Crypto Engine (2)|CRYPTO peripheral|CRYPTOACC peripheral|HSE|
|Advanced Crypto (3)|—|—|HSE-SVH|
|Secure Key Storage (4)|—|—|HSE-SVH|

> **Notes**:
> 
> 1. See [Table Entropy Source on Series 1 and Series 2 Devices](06-migration-guide#initialization-and-random-number-generation-rng) for details of TRNG (True Random Number Generator) on Series 1 devices.
> 2. Crypto engine supports up to 256-bit ciphers and elliptic curves.
> 3. Advanced crypto supports up to 512-bit ciphers and 521-bit elliptic curves.
> 4. See [Table PSA Crypto Key Lifetime Support on Series 1 and Series 2 Devices](04-key-management-in-psa-crypto#key-lifetimes) for details of Secure Key Storage support on HSE-SVH devices.

#### Overview

##### Mbed TLS

Mbed TLS is a C library that implements cryptographic primitives, X.509 certificate manipulation, and the SSL/TLS and DTLS protocols.

ARM developed Mbed TLS, which was formerly known as PolarSSL. Mbed TLS has been handed over to [Trusted Firmware](https://www.trustedfirmware.org/projects/mbed-tls/) under open governance since March 2020.

For the time being, Trusted Firmware Mbed TLS is the project containing a reference implementation of the PSA Crypto API and the TLS portion of Mbed TLS. The following table lists different Mbed TLS versions supported in Simplicity Studio and Gecko SDK (GSDK) suites.

|**Mbed TLS**|**Gecko SDK Suite**|**PSA Crypto**|**Location in Windows**|
|---|---|---|---|
|v3.2.1|v4.3.x (Simplicity Studio 5)|Y|C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\mbedtls|
|v3.2.1|v4.2.x (Simplicity Studio 5)|Y|C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\mbedtls|
|v3.1.0|v4.1.x (Simplicity Studio 5)|Y|C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\mbedtls|
|v3.0.0|v4.0.x (Simplicity Studio 5)|Y|C:\Users\<PC USER NAME>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\mbedtls|
|v2.26.0|v3.2.x (Simplicity Studio 5)|Y|C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.2\util\third_party\crypto\mbedtls|
|v2.24.0|v3.1.x (Simplicity Studio 5)|Y|C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.1\util\third_party\crypto\mbedtls|
|v2.16.6|v3.0.x (Simplicity Studio 5)|—|C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.0\util\third_party\mbedtls|
|v2.7.12|v2.7.8 (Simplicity Studio 4)|—|C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.7\util\third_party\mbedtls|

##### PSA Crypto

**Platform Security Architecture (PSA)**

The [Platform Security Architecture](https://developer.arm.com/architectures/security-architectures/platform-security-architecture) (PSA) is made up of four key stages:

- Threat modeling
- Predefined architectural choices
- Standardized implementation
- Certification

The PSA Crypto API is one of the standardized implementation features and is discussed in the following sections.

**PSA Root of Trust (PSA-RoT)**

For an IoT product to achieve its security goals, it must meet the requirements of one of the pillars known as Root of Trust. The following figure shows the four PSA-Certified key elements that make up the Root of Trust.

![Key Requirements of PSA-RoT](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image8.png)

The PSA Root of Trust (PSA-RoT) is a source of confidentiality (for example, crypto keys) and integrity. The PSA-RoT defines what it takes for a hardware or software system to be trusted.

The [Trusted Firmware-M](https://www.trustedfirmware.org/projects/tf-m/) (TF-M) offers an open-source firmware reference implementation and APIs. These resources provide developers with a trusted codebase that complies with PSA specifications and APIs that create a consistent interface to underlying Root of Trust hardware.

**PSA Functional APIs**

[PSA Certified](https://www.psacertified.org/) defines a set of PSA Functional APIs (which are implemented as part of TF-M) to access the Root of Trust features. The PSA Functional APIs provide a standardized set of vetted APIs to ensure portability and promote adherence to best practices.

- PSA Crypto APIs
- PSA Attestation APIs
- PSA Secure Storage (Internal Trusted Storage and Protected Storage) APIs

Since the Trusted boot (aka Secure boot) shown in [Figure Key Requirements of PSA-RoT](#psa-crypto) is used when booting up the device and is not used after the system is up and running, there is no need for a Trusted boot API.

The three APIs provide software developers with access to security functions to ensure interoperability across different hardware implementations of the Root of Trust. It means another hardware platform can reuse the applications in the following figure, because these APIs are standardized across various security hardware.

![PSA Functional APIs](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image9.png)

[PSA Functional API Certification](https://www.psacertified.org/getting-certified/functional-api-certification/) is part of [PSA Certified](https://www.psacertified.org/), and demonstrates that software is compatible with the PSA Functional API specification. PSA Functional API Certified does not imply that a device has a security capability or is robust. Only PSA Certified Levels 1–3 can achieve this.

This application note only focuses on the PSA Crypto API.

**PSA Crypto API**

The PSA Crypto API is a low-level cryptographic API optimized for MCU and Wireless SoC. It provides APIs related to [Random Number Generation](06-migration-guide#initialization-and-random-number-generation-rng) (RNG), cryptographic algorithm usage, and [key handling](06-migration-guide#key-handling) (symmetric and asymmetric).

The PSA Crypto API provides developers with an easy-to-use and easy-to-learn interface to crypto primitives. It is designed for usability and flexibility and is based on the idea of a key store. The store can isolate the keys from the rest of the applications, which means keys remain opaque in [storage](04-key-management-in-psa-crypto#key-lifetimes) and only accessible for usage through crypto primitives.

#### Key Management in PSA Crypto

Key attributes are managed in a `psa_key_attributes_t` object. These are used when a key is created, after which the key attributes are impossible to change.

The actual key material is not considered an attribute of a key. Key attributes do not contain information that is generally considered highly confidential. The individual attributes ([Key Types](#key-types), [Key Lifetimes](#key-lifetimes), [Key Identifiers](#key-identifiers), and [Key Policies](#key-policies)) are described in the following sections.

The `crypto_values.h` in the Windows folder below includes the defines for macros of key attributes.

For GSDK v3.1.x and v3.2.x: `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION\>\util\third_party\crypto\mbedtls\include\psa`

For GSDK v4.0.0 and higher: `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\mbedtls\include\psa`

##### Key Types

This attribute consists of information about the key: the type, and the size used by this type. The key type and size are encoded in

`psa_key_type_t` and `psa_key_bits_t` objects. The following table describes the type and size in symmetric and asymmetric keys.

<table>
    <thead>
        <tr>
            <th><strong>Category</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Size in Bits</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td rowspan="4">Symmetric Keys</td>
            <td>HMAC key<br>• <code>PSA_KEY_TYPE_HMAC</code></td>
            <td>Non-zero multiple of 8</td>
        </tr>
        <tr>
            <td>Key derivation<br>• <code>PSA_KEY_TYPE_DERIVE</code></td>
            <td>Non-zero multiple of 8</td>
        </tr>
        <tr>
            <td>Cipher/AEAD/MAC key<br>• <code>PSA_KEY_TYPE_AES</code></td>
            <td>
                <ul>
                    <li>128 (16-byte)</li>
                    <li>192 (24-byte)</li>
                    <li>256 (32-byte)</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>ChaCha20/ChaCha20-Poly1305 AEAD key<br>• <code>PSA_KEY_TYPE_CHACHA20</code></td>
            <td>256 (32-byte)</td>
        </tr>
        <tr>
            <td rowspan="4">Elliptic Curve Cryptography (ECC) Keys</td>
            <td>SEC random curves over prime fields<br>• <code>PSA_ECC_FAMILY_SECP_R1</code></td>
            <td>
                <ul>
                    <li>secp192r1 : 192</li>
                    <li>secp224r1 : 224</li>
                    <li>secp256r1 : 256</li>
                    <li>secp384r1 : 384</li>
                    <li>secp521r1 : 521</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>SEC Koblitz curve over prime fields<br>• <code>PSA_ECC_FAMILY_SECP_K1</code></td>
            <td>secp256k1 : 256</td>
        </tr>
        <tr>
            <td>Montgomery curves<br>• <code>PSA_ECC_FAMILY_MONTGOMERY</code></td>
            <td>
                <ul>
                    <li>Curve25519 : 255</li>
                    <li>Curve448 : 448</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>Twisted Edwards curve<br>• <code>PSA_ECC_FAMILY_TWISTED_EDWARDS</code></td>
            <td>Edwards25519 : 255</td>
        </tr>
    </tbody>
</table>

##### Key Lifetimes

The lifetime is encoded in the `psa_key_lifetime_t` object (`[31:0]`). This object consists of a persistence level (`psa_key_persistence_t`) and a location indicator (`psa_key_location_t`). The persistent level indicates whether the key is volatile, persistent, or read-only. The location indicator indicates where the key is stored and where operations on the key are performed.

|**Type**|**Persistence Level [7:0]**|**Location Indicator [31:8]**|**Storage**|
|---|---|---|---|
|Volatile Plain Key|PSA_KEY_PERSISTENCE_VOLATILE|Local (0x0)|RAM|
|Persistent Plain Key|PSA_KEY_PERSISTENCE_DEFAULT|Local (0x0)|Flash (2)|
|Volatile Wrapped Key|PSA_KEY_PERSISTENCE_VOLATILE|Secure (0x1) (1)|RAM|
|Persistent Wrapped Key|PSA_KEY_PERSISTENCE_DEFAULT|Secure (0x1) (1)|Flash (2)|
|Public Sign Key|PSA_KEY_PERSISTENCE_READ_ONLY|Secure (0x1)|SE OTP|
|Public Command Key|PSA_KEY_PERSISTENCE_READ_ONLY|Secure (0x1)|SE OTP|
|AES-128 Key|PSA_KEY_PERSISTENCE_READ_ONLY|Secure (0x1)|SE OTP|
|Private Device Key|PSA_KEY_PERSISTENCE_READ_ONLY|Secure (0x1)|SE OTP|
|PUF-derived Hardware Unique Key|PSA_KEY_PERSISTENCE_READ_ONLY|Secure (0x1)|PUF Module|

> **Notes**:
> 
> 1. If the key cannot be stored persistently inside the SE, it must be stored in a [wrapped form](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/) in RAM or flash such that only the SE can access the key material in plaintext.
> 2. Persistent storage in flash memory is implemented by the [NVM3 driver](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3).

|**Type**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|
|---|---|---|---|
|Volatile Plain Key|Y|Y|Y|
|Persistent Plain Key|Y|Y|Y|
|Volatile Wrapped Key|—|—|HSE-SVH|
|Persistent Wrapped Key|—|—|HSE-SVH|
|Public Sign Key|—|— (1)|Y (2)|
|Public Command Key|—|— (1)|Y (2)|
|AES-128 Key|—|—|Y (3)|
|Private Device Key|—|—|HSE-SVH (2)|
|PUF-derived Hardware Unique Key|—|Y (4)|—|

> **Notes**:
> 
> 1. The PSA Crypto cannot access the Public Sign Key and Public Command Key in the VSE-SVM OTP.
> 2. These keys can only be used for ECDSA (SECP256R1) precomputed hash operations.
> 3. This key can only be used for AES cipher operations. The `SL_SE_BUILTIN_KEY_AES128_ALG` in `sli_se_opaque_types.h` or `sl_psa_values.h` in the Windows folder below defines the default AES cipher algorithm (AES CTR) for this key.
> 
> For GSDK v3.1.x and v3.2.x (`sli_se_opaque_types.h`): `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION>\util\third_party\crypto\sl_component\sl_psa_driver\inc`
> 
> For GSDK v4.0.x (`sli_se_opaque_types.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\sl_component\sl_psa_driver\inc`
> 
> For GSDK v4.1.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\sl_component\sl_psa_driver\inc\public`
> 
> For GSDK v4.2.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\platform\security\sl_component\sl_psa_driver\inc\public`
> 
> For GSDK v4.3.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\platform\security\sl_component\sl_mbedtls_support\inc`
> 
> 1. The PUF-derived Hardware Unique Key is only available on VSE-SVM devices with a built-in PUF module (e.g., EFR32xG27C). This key can only be used by the [CRYPTOACC](02-device-capability#device-capability) peripheral for [Message Authentication Codes (MAC)](06-migration-guide#message-authentication-codes-mac) and [Key Derivation](06-migration-guide#key-derivation).
> 
> The `SL_CRYPTOACC_BUILTIN_KEY_PUF_ALG` in `sl_psa_values.h` in the Windows folder below defines the default algorithm (PBKDF2 CMAC) for this key.
> 
> For GSDK v4.3.x and higher: `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\platform\security\sl_compon ent\sl_mbedtls_support\inc`

##### Key Identifiers

A key identifier can be a permanent name for a persistent key, or a transient reference to a volatile key. Key identifiers are encoded in a

`psa_key_id_t` object. The identifier and [lifetime](#key-lifetimes) of a key indicate the location of the key in storage.

The `sli_se_opaque_types.h` or `sl_psa_values.h` in the Windows folder below includes the defines for SE key identifier macros.

For GSDK v3.1.x and v3.2.x (`sli_se_opaque_types.h`): `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\\<GSDK VERSION\>\util\third_party\crypto\sl_component\sl_psa_driver\inc`

For GSDK v4.0.x (`sli_se_opaque_types.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\ crypto\sl_component\sl_psa_driver\inc`

For GSDK v4.1.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\third_party\crypto\sl_component\sl_psa_driver\inc\public`

For GSDK v4.2.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\platform\security\sl_component\sl_psa_driver\inc\public`

For GSDK v4.3.x (`sl_psa_values.h`): `C:\Users\\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\platform\security\sl_component\sl_mbedtls_support\inc`

|**Type**|**Key Identifier (Key ID)**|**SE Key Identifier**|
|---|---|---|
|Volatile Plain Key|0 (Assigned by the PSA Crypto)|—|
|Persistent Plain Key|PSA_KEY_ID_USER_MIN to PSA_KEY_ID_USER_MAX|—|
|Volatile Wrapped Key|0 (Assigned by the PSA Crypto)|—|
|Persistent Wrapped Key|PSA_KEY_ID_USER_MIN to PSA_KEY_ID_USER_MAX|—|
|Public Sign Key|PSA_KEY_ID_VENDOR_MIN to PSA_KEY_ID_VENDOR_MAX|SL_SE_BUILTIN_KEY_SECUREBOOT_ID|
|Public Command Key|PSA_KEY_ID_VENDOR_MIN to PSA_KEY_ID_VENDOR_MAX|SL_SE_BUILTIN_KEY_SECUREDEBUG_ID|
|AES-128 Key|PSA_KEY_ID_VENDOR_MIN to PSA_KEY_ID_VENDOR_MAX|SL_SE_BUILTIN_KEY_AES128_ID|
|Private Device Key|PSA_KEY_ID_VENDOR_MIN to PSA_KEY_ID_VENDOR_MAX|SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID|
|PUF-derived Hardware Unique Key|PSA_KEY_ID_VENDOR_MIN to PSA_KEY_ID_VENDOR_MAX|SL_CRYPTOACC_BUILTIN_KEY_PUF_ID (GSDK ≥ v4.3.0)|

If users are about to use the PSA Crypto for persistent key storage in their application, adhere to the identifier (Key ID) allocation below. The value 0 is reserved as an invalid key identifier.

![image-10](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image10.png)

##### Key Policies

This attribute consists of usage flags and a specification of the permitted algorithm. The `psa_key_usage_t` encodes the usage flags in a bit-mask. The following table describes three kinds of usage flag in the PSA Crypto.

<table>
    <thead>
        <tr>
            <th><strong>Flag</strong></th>
            <th><strong>Bit-mask</strong></th>
            <th><strong>Description</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Extractable</td>
            <td>PSA_KEY_USAGE_EXPORT</td>
            <td>Permission to export the key.</td>
        </tr>
        <tr>
            <td>Copyable</td>
            <td>PSA_KEY_USAGE_COPY</td>
            <td>Permission to copy the key.</td>
        </tr>
        <tr>
            <td>Other usage</td>
            <td>PSA_KEY_USAGE_ENCRYPT</td>
            <td>Permission for a symmetric encryption operation, for an AEAD encryption-and-authentication operation, or for an asymmetric encryption operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_DECRYPT</td>
            <td>Permission for a symmetric decryption operation, for an AEAD decryption-and-verification operation, or for an asymmetric decryption operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_SIGN_MESSAGE</td>
            <td>Permission for a MAC calculation operation or for an asymmetric message signature operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_VERIFY_MESSAGE</td>
            <td>Permission for a MAC verification operation or for an asymmetric message signature verification operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_SIGN_HASH</td>
            <td>Permission to sign a message hash as part of an asymmetric signature operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_VERIFY_HASH</td>
            <td>Permission to verify a message hash as part of an asymmetric signature verification operation.</td>
        </tr>
        <tr>
            <td>#</td>
            <td>PSA_KEY_USAGE_DERIVE</td>
            <td>Permission to derive other keys from this key.</td>
        </tr>
    </tbody>
</table>

> **Note**: Users can always export a public key or the public part of a key pair regardless of the value of the `PSA_KEY_USAGE_EXPORT` ﬂag.

The `psa_algorithm_t` encodes the permitted algorithm with the key. The [Symmetric Cryptographic Operation](06-migration-guide#symmetric-cryptographic-operation) and [Asymmetric Cryptographic Operation](06-migration-guide#asymmetric-cryptographic-operation) describe which algorithms can apply to the corresponding cryptographic operations.

The application must supply the algorithm to use for the operation. This algorithm is checked against the permitted algorithm policy of the key.

##### Summary

The `psa_key_attributes_t` object specifies the attributes for the new key during the creation process. The attributes are immutable once the key has been created.

The key identifier and lifetime in the attributes determine the location of the key in storage. The application must set the key type and size, key algorithm policy, and the appropriate key usage flags in the attributes for the key to be used in any cryptographic operations.

The key material can be copied into a new key, which can have a different lifetime or a more restrictive usage policy.

If the key creation succeeds, the PSA Crypto will return an identifier for the newly created key. The PSA Crypto can destroy a key from volatile memory and non-volatile storage [NVM3 object](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3). The destroying process makes the key identifier invalid, and the key identifier must not be used again by the application until it is allocated to a newly created key.

If not necessary, the extractable usage flag (`PSA_KEY_USAGE_EXPORT`) should not be set to allow the key to export in binary format.

#### Key Attributes API

The following table lists the PSA Crypto API for the [key attributes](04-key-management-in-psa-crypto#key-management-in-psa-crypto).

<table>
    <thead>
        <tr>
            <th><strong>API</strong></th>
            <th><strong>Description</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p><code>psa_key_attributes_init(…)</code></p>
            </td>
            <td>
                <p>Initialize the key attributes (<code>psa_key_attributes_t</code>) before calling any function.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_attributes(…)</code></p>
            </td>
            <td>
                <p>Retrieve the key attributes (<code>psa_key_attributes_t</code>) of a key if successful.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_reset_key_attributes(…)</code></p>
            </td>
            <td>
                <p>Reset the key attributes (<code>psa_key_attributes_t</code>) to an initialized state.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_type(…)</code></p>
            </td>
            <td>
                <p>Declare the key type (<code>psa_key_type_t</code>) of a key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_type(…)</code></p>
            </td>
            <td>
                <p>Retrieve the key type (<code>psa_key_type_t</code>) from key attributes.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_bits(…)</code></p>
            </td>
            <td>
                <p>Declare the key size (<code>psa_key_bits_t</code>) of a key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_bits(…)</code></p>
            </td>
            <td>
                <p>Retrieve the key size (<code>size_t</code>) from key attributes.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_usage_flags(…)</code></p>
            </td>
            <td>
                <p>Declare the usage flags (<code>psa_key_usage_t</code>) for a key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_usage_flags(…)</code></p>
            </td>
            <td>
                <p>Retrieve the usage flags (<code>psa_key_usage_t</code>) from key attributes.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_algorithm(…)</code></p>
            </td>
            <td>
                <p>Declare the permitted algorithm policy (<code>psa_algorithm_t</code>) for a key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_algorithm(…)</code></p>
            </td>
            <td>
                <p>Retrieve the algorithm policy (<code>psa_algorithm_t</code>) from key attributes.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_id(…)</code></p>
            </td>
            <td>
                <p>Declare a key as persistent and set its key identifier (<code>psa_key_id_t</code>).</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_id(…)</code></p>
            </td>
            <td>
                <p>Retrieve the key identifier (<code>psa_key_id_t</code>) from key attributes.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_set_key_lifetime(…)</code></p>
            </td>
            <td>
                <p>Set the location (<code>psa_key_lifetime_t</code>) of a persistent key.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>psa_get_key_lifetime(…)</code></p>
            </td>
            <td>
                <p>Retrieve the lifetime (<code>psa_key_lifetime_t</code>) from key attributes.</p>
            </td>
        </tr>
    </tbody>
</table>

The following sections describe how to use the key attributes API to set up the [storage](04-key-management-in-psa-crypto) for a key. Refer to the quick reference examples in [Symmetric Key](06-migration-guide#symmetric-key) and [Asymmetric Key](06-migration-guide#asymmetric-key) for more details.

**Volatile Plain Key**

<table>
    <thead>
        <tr>
            <th><strong>Key ID</strong></th>
            <th><strong>Persistence Level</strong></th>
            <th><strong>Location Indicator</strong></th>
            <th><strong>API Flow</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>= 0</td>
            <td><code>PSA_KEY_PERSISTENCE_VOLATILE</code></td>
            <td>Local (0x0)</td>
            <td>
                It is the default setting after calling <code>psa_key_attributes_init()</code>.
                No need to call <code>psa_set_key_id()</code> and <code>psa_set_key_lifetime()</code>.
            </td>
        </tr>
    </tbody>
</table>

**Example**:

```sh
psa_key_attributes_t key_attr;
key_attr = psa_key_attributes_init();
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&key_attr, 256);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);
```

**Persistent Plain Key**

<table>
    <thead>
        <tr>
            <th><strong>Key ID</strong></th>
            <th><strong>Persistence Level</strong></th>
            <th><strong>Location Indicator</strong></th>
            <th><strong>API Flow</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>&gt; 0</td>
            <td><code>PSA_KEY_PERSISTENCE_DEFAULT</code></td>
            <td>Local (0x0)</td>
            <td>
                A non-zero key ID in <code>psa_set_key_id()</code> will change the persistence level from <code>PSA_KEY_PERSISTENCE_VOLATILE</code> to <code>PSA_KEY_PERSISTENCE_DEFAULT</code>.
            </td>
        </tr>
    </tbody>
</table>

**Example**:

```sh
psa_key_attributes_t key_attr;
key_attr = psa_key_attributes_init();
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&key_attr, 256);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);
psa_set_key_id(&key_attr, 0x02);
```

**Volatile Wrapped Key**

<table>
    <thead>
        <tr>
            <th><strong>Key ID</strong></th>
            <th><strong>Persistence Level</strong></th>
            <th><strong>Location Indicator</strong></th>
            <th><strong>API Flow</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>= 0</p>
            </td>
            <td>
                <p><code>PSA_KEY_PERSISTENCE_VOLATILE</code></p>
            </td>
            <td>
                <p>Secure (0x1)</p>
            </td>
            <td>
                <p>Use the <code>psa_set_key_lifetime()</code> to change the location indicator from Local to Secure (0x01).</p>
            </td>
        </tr>
    </tbody>
</table>

**Example**:

```sh
psa_key_attributes_t key_attr;
key_attr = psa_key_attributes_init();
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&key_attr, 256);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);
psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_VOLATILE, 0x01));
```

**Persistent Wrapped Key**

<table>
    <thead>
        <tr>
            <th><strong>Key ID</strong></th>
            <th><strong>Persistence Level</strong></th>
            <th><strong>Location Indicator</strong></th>
            <th><strong>API Flow</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>&gt; 0</p>
            </td>
            <td>
                <p><code>PSA_KEY_PERSISTENCE_DEFAULT</code></p>
            </td>
            <td>
                <p>Local (0x0)</p>
            </td>
            <td>
                <p>A non-zero key ID in <code>psa_set_key_id()</code> will change the persistence level from <code>PSA_KEY_PERSISTENCE_VOLATILE</code> to <code>PSA_KEY_PERSISTENCE_DEFAULT</code>.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>&gt; 0</p>
            </td>
            <td>
                <p><code>PSA_KEY_PERSISTENCE_DEFAULT</code></p>
            </td>
            <td>
                <p>Secure (0x1)</p>
            </td>
            <td>
                <p>Use the <code>psa_set_key_lifetime()</code> to change the location indicator from Local to Secure (0x01).</p>
            </td>
        </tr>
    </tbody>
</table>

**Example**:

```sh
psa_key_attributes_t key_attr;
key_attr = psa_key_attributes_init();
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&key_attr, 256);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);
psa_set_key_id(&key_attr, 0x02);
psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0x01));
```

> **Note**:
> 
> - The `PSA_KEY_PERSISTENCE_DEFAULT` is equal to `PSA_KEY_LIFETIME_PERSISTENT`.
> - Refer to [Key Identifiers](04-key-management-in-psa-crypto#key-identifiers) for details about the Key ID.

#### Migration Guide

##### System Requirements and Document

1. Simplicity Studio 5
2. GSDK v3.1.1 (Mbed TLS v2.24.0) or later
3. The latest SE Firmware image and release note can be found in the Windows folder below.  
   - For GSDK v3.1.x and v3.2.x: `C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\<GSDK VERSION\>\util\se_release\public`  
   - For GSDK v4.0.0 and higher: `C:\Users\<PC USER NAME\>\SimplicityStudio\SDKs\gecko_sdk\util\se_release\public`
4. PSA Crypto API (aka PSA Cryptography API) document: [ARM](https://arm-software.github.io/psa-api/crypto/)

##### Mbed TLS Versus PSA Crypto API

<table>
    <thead>
        <tr>
            <th><strong>Item</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto API</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Key input</p>
            </td>
            <td>
                <p>APIs take key input directly.</p>
            </td>
            <td>
                <p>
                    • APIs do not take key input directly.<br>
                    • Key (identifier) needs to be created or imported before use.<br>
                    • APIs take an identifier if a key is required.
                </p>
            </td>
        </tr>
        <tr>
            <td rowspan="3">
                <p>Symmetric cryptographic operation</p>
            </td>
            <td>
                <p>Individual API (one-shot and streaming) for algorithm-specific functions.</p>
            </td>
            <td>
                <p>
                    • APIs are grouped by algorithm category for one-shot and streaming modes.<br>
                    • The exact algorithm is a parameter (<code>psa_algorithm_t</code>) to the function, not an individual API.
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Except for AEAD (encrypt and decrypt), a one-shot function is not in a pair.</p>
            </td>
            <td>
                <p>Single-part (one-shot) functions are in a pair. For example, compute and verify, or encrypt and decrypt.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Initialization and free a context are required.</p>
            </td>
            <td>
                <p>Initialization and abort an operation are only required in multi-part (streaming) operations.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Error code</p>
            </td>
            <td>
                <p>APIs always return an integer.</p>
            </td>
            <td>
                <p>APIs always return <code>psa_status_t</code>.</p>
            </td>
        </tr>
    </tbody>
</table>

##### Migration

In [Key Handling](#key-handling), [Symmetric Cryptographic Operation](#symmetric-cryptographic-operation), [Asymmetric Cryptographic Operation](#asymmetric-cryptographic-operation) the following items will be considered when migrating from Mbed TLS to PSA Crypto.

1. The algorithms that can be used in a cryptographic operation.
2. The [key attributes](04-key-management-in-psa-crypto#key-management-in-psa-crypto) [type](04-key-management-in-psa-crypto#key-types) and [usage flags](04-key-management-in-psa-crypto#key-policies) for specific [algorithms](04-key-management-in-psa-crypto#key-policies) in the PSA Crypto.
3. Security Software Components.
4. The functions (APIs) for the Mbed TLS and PSA Crypto. For each type of [symmetric cryptographic operation](#symmetric-cryptographic-operation), the functions include:  
   - A pair of single-part (one-shot) functions  
   - A series of functions that implement multi-part (streaming) operations
5. Quick Reference Examples. These examples do not have error checking, but the user should always check the return code ([psa_status_t](https://docs.silabs.com/gecko-platform/latest/service/api/group-error) = `PSA_SUCCESS` or `PSA_ERROR_XXX`) from PSA Crypto to determine whether to use the output parameters in the application.

##### Platform Examples

Simplicity Studio 5 includes the PSA Crypto platform examples to evaluate the performance on [key handling](#key-handling), [symmetric](#symmetric-cryptographic-operation) and [asymmetric cryptographic operations](#asymmetric-cryptographic-operation), and [X.509 certificate](#x509-certificate).

- Refer to the corresponding `readme` file for details about each PSA Crypto platform example. This file also includes the procedures to create the project and run the example.
- Unless specified in the example, the PSA Crypto platform examples will use the software fallback feature in Mbed TLS if the [cryptography hardware accelerator](02-device-capability#device-capability) of the selected device does not support the corresponding ECC key or algorithm.

The figures in the following sections are based on GSDK v4.1.0. These figures may be different on other versions of the GSDK.

##### Security Software Components

The `slcp` file for each PSA Crypto platform example defines the software components installed in the project. The following figure shows the installed security software components (under the **Platform → Security** category) in the PSA Crypto ECDH example (`psa_crypto_ecdh.slcp`) on an HSE-SVH device.

![Installed Security Software Components](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image12.png)

The Simplicity IDE uses the installed security software components to automatically generate the configuration files for Mbed TLS (`mbedtls_config_autogen.h`) and PSA Crypto (`psa_crypto_config_autogen.h`) in the `autogen` folder when creating the project.

![Mbed TLS and PSA Crypto Configuration Files](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image13.png)

The user can browse the available security software components (under the **Platform → Security** category) on the target MCU or Wireless SoC if the [**Installed Components**] checkbox is unchecked.

![Available Security Software Components on the Target Device](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image14.png)

The Mbed TLS and PSA Crypto configuration files automatically regenerates when the user installs or uninstalls a security software component in the project.

![Install a Security Software Component](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image15.png)

![Uninstall a Security Software Component](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image16.png)

For a new project (like `empty.slcp`), the required security software components will be automatically added to the project after installing any cryptographic operation in PSA Crypto (like `GCM`) from the user. The `SE Manager` component is only for the HSE devices.

![Security Software Components for PSA Crypt](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image17.png)

If users are about to use the PSA Crypto for persistent key storage (either plain or wrapped) in their application, make sure to add the `PSA Persistent Storage Support (ITS)` component to the project.

![Security Software Component for Persistent Key Storage](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image18.png)

##### PSA Crypto Configuration

Click **Configuration** in **Installed Components**. Click [**Configure**] to open the Configuration Wizard in Context Menu.

![image19](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image19.png)

Enter the desired values in **PSA User Maximum Open Keys Count** (`SL_PSA_KEY_USER_SLOT_COUNT`) and **PSA Maximum User Persistent Keys Count** (`SL_PSA_ITS_USER_MAX_FILES`) to replace the default values. Click [**X**] to exit.

The default value of **PSA User Maximum Open Keys Count** is equal to 0 if the project installed any Wireless Stack before.

![image20](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image20.png)

The PSA Crypto configuration file (`psa_crypto_config_autogen.h`) in the `autogen` folder [Figure Mbed TLS and PSA Crypto Configuration Files](#security-software-components) includes the definitions for PSA key slot count and maximum PSA ITS files.

```sh
#define MBEDTLS_PSA_KEY_SLOT_COUNT (2 + 1 + SL_PSA_KEY_USER_SLOT_COUNT)
#define SL_PSA_ITS_MAX_FILES (1 + SL_PSA_ITS_USER_MAX_FILES)
```

The first digit in `MBEDTLS_PSA_KEY_SLOT_COUNT` is Wireless Stack (if installed) dependent. The second digit should be 1 for the PSA Crypto.

The first digit in `SL_PSA_ITS_MAX_FILES` is equal to 1 if the project installed the `PSA persistent storage support (ITS)` component [Figure Security Software Component for Persistent Key Storage](#security-software-components) before.

##### Initialization and Random Number Generation (RNG)

In PSA Crypto, applications must call `psa_crypto_init()` to initialize the library before using any other function. The PSA Crypto initialization includes seeding the pseudo-random generator (CTR-DRBG) with a hardware entropy source during the execution of `psa_crypto_init()`.

<table>
    <thead>
        <tr>
            <th><strong>Item</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Initialization</p>
            </td>
            <td>
                <p>
                    Initialize CTR-DRBG<br>
                    • <code>void mbedtls_entropy_init(…)</code><br>
                    • <code>void mbedtls_ctr_drbg_init(…)</code><br>
                    • <code>int mbedtls_entropy_add_source(…)</code><br>
                    Seed and set up the CTR-DRBG entropy<br>
                    • <code>int mbedtls_ctr_drbg_seed(…)</code>
                </p>
            </td>
            <td>
                <p>
                    Initialize PSA Crypto<br>
                    • <code>psa_status_t psa_crypto_init(void)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Generate random bytes</p>
            </td>
            <td>
                <p><code>int mbedtls_ctr_drbg_random(…)</code></p>
            </td>
            <td>
                <p><code>psa_status_t psa_generate_random(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Free resources</p>
            </td>
            <td>
                <p>
                    • <code>void mbedtls_ctr_drbg_free(…)</code><br>
                    • <code>void mbedtls_entropy_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>void mbedtls_psa_crypto_free(void)</code></p>
            </td>
        </tr>
    </tbody>
</table>

If a device includes a True Random Number Generator (TRNG) hardware module, the example will use the TRNG as an entropy source to seed the CTR-DRBG. If the device does not incorporate a TRNG, the example will use [RAIL](https://docs.silabs.com/rail/latest/), Non-volatile (NV) seed (requires [NVM3 driver](https://docs.silabs.com/gecko-platform/latest/driver/api/group-nvm3)), or ADC as the entropy source.

|**Device**|**Entropy Source**|
|---|---|
|MCU Series 1 - EFM32JG1, EFM32PG1|NV seed (default) or ADC|
|MCU Series 1 - EFM32JG12, EFM32PG12, EFM32GG11, EFM32GG12, EFM32TG11|TRNG|
|Wireless SoC Series 1 - EFR32xG1, EFR32xG14|RAIL|
|Wireless SoC Series 1 - EFR32xG12, EFR32xG13 (Revision D or later)|TRNG|
|All MCU Series 2 and Wireless SoC Series 2 devices|TRNG|

**Quick Reference Examples**

**PSA Crypto Initialization and Random Number Generation**

```c++
#include "psa/crypto.h"
void app_process_action(void)
{
  uint8_t rand_buf[32];
  psa_status_t ret;

  // Initialize the PSA Crypto and generate random numbers
  ret = psa_crypto_init();
  ret = psa_generate_random(rand_buf, sizeof(rand_buf));
}
```

##### Key Handling

The following table describes the main differences in key handling between Mbed TLS and PSA Crypto.

|**Item**|**Mbed TLS**|**PSA Crypto**|
|---|---|---|
|Random Number Generation (RNG)|It requires application code to keep track of RNG.|The core keeps track of RNG.|
|Buffer|It requires dedicated key buffers.|The core manages the key.|
|Key export|The key is exportable.|The usage flag manages this option.|
|Lifetime|It is volatile.|It can be volatile or persistent.|
|Location|Local|Local or Secure|

##### Symmetric Key

A symmetric key can be used with a block cipher or a stream cipher.

**Algorithms**

Refer to the [Symmetric Cryptographic Operation](#symmetric-cryptographic-operation) section.

**Key Attributes in PSA Crypto**

Refer to the [Symmetric Cryptographic Operation](#symmetric-cryptographic-operation) section.

**Security Software Components**

Refer to the [Symmetric Cryptographic Operation](#symmetric-cryptographic-operation) section.

**Functions**

<table>
    <thead>
        <tr>
            <th><strong>Item</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Create a random key</p>
            </td>
            <td>
                <p>
                    Generate random numbers to a buffer<br>
                    • <code>int mbedtls_ctr_drbg_random(…)</code><br>
                    Set up a key from a buffer (API is algorithm dependent)<br>
                    • <code>int mbedtls_aes_setkey_enc(…)</code><br>
                    • <code>int mbedtls_aes_setkey_dec(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    • <code>int mbedtls_ccm_setkey(…)</code><br>
                    • <code>int mbedtls_gcm_setkey(…)</code><br>
                    • <code>int mbedtls_chacha20_setkey(…)</code><br>
                    • <code>int mbedtls_chachapoly_setkey(…)</code>
                </p>
            </td>
            <td>
                <p>
                    Create a key from randomly generated data<br>
                    • <code>psa_status_t psa_generate_key(…)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Import a key from a buffer</p>
            </td>
            <td>
                <p>
                    API is algorithm dependent<br>
                    • <code>int mbedtls_aes_setkey_enc(…)</code><br>
                    • <code>int mbedtls_aes_setkey_dec(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    • <code>int mbedtls_ccm_setkey(…)</code><br>
                    • <code>int mbedtls_gcm_setkey(…)</code><br>
                    • <code>int mbedtls_chacha20_setkey(…)</code><br>
                    • <code>int mbedtls_chachapoly_setkey(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_import_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Copy a key</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_copy_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Export a key to a buffer</p>
            </td>
            <td>
                <p>The key is always in a buffer.</p>
            </td>
            <td>
                <p><code>psa_status_t psa_export_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Destroy a key</p>
            </td>
            <td>
                <p>Zero the key buffer.</p>
            </td>
            <td>
                <p><code>psa_status_t psa_destroy_key(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The `psa_export_key()` can export a symmetric key in plaintext if the [PSA_KEY_USAGE_EXPORT](04-key-management-in-psa-crypto#key-policies) usage flag is set.

**Quick Reference Examples**

**Symmetric Plain Key Creation and Import**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t aes_ecb_key[16] = {0};

  psa_status_t ret;
  psa_key_id_t generate_key_id;
  psa_key_id_t import_key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a AES ECB key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, 128);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);

  // Generate a random volatile plain key for AES ECB
  ret = psa_generate_key(&key_attr, &generate_key_id);

  // Import a volatile plain key for AES ECB
  ret = psa_import_key(&key_attr, aes_ecb_key, sizeof(aes_ecb_key), &import_key_id);

  // Destroy the volatile plain keys for AES ECB
  ret = psa_destroy_key(generate_key_id);
  ret = psa_destroy_key(import_key_id);

  // Generate a random persistent plain key for AES ECB (ID = 0x02)
  psa_set_key_id(&key_attr, 0x02);
  ret = psa_generate_key(&key_attr, &generate_key_id);

  // Import a persistent plain key for AES ECB (ID = 0x03)
  psa_set_key_id(&key_attr, 0x03);
  ret = psa_import_key(&key_attr, aes_ecb_key, sizeof(aes_ecb_key), &import_key_id);

  // Destroy the persistent plain keys for AES ECB
  ret = psa_destroy_key(generate_key_id);
  ret = psa_destroy_key(import_key_id);
}
```

**Symmetric Wrapped Key Creation and Import (HSE-SVH only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t aes_ecb_key[16] = {0};

  psa_status_t ret;
  psa_key_id_t generate_key_id;
  psa_key_id_t import_key_id;
  psa_key_attributes_t key_attr;
  ret = psa_crypto_init();

  // Set up attributes for a AES ECB key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, 128);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
  psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_VOLATILE, 0x01));

  // Generate a random volatile wrapped key for AES ECB
  ret = psa_generate_key(&key_attr, &generate_key_id);

  // Import a volatile wrapped key for AES ECB
  ret = psa_import_key(&key_attr, aes_ecb_key, sizeof(aes_ecb_key), &import_key_id);

  // Destroy the volatile wrapped keys for AES ECB
  ret = psa_destroy_key(generate_key_id);
  ret = psa_destroy_key(import_key_id);

  // Generate a random persistent wrapped key for AES ECB (ID = 0x02)
  psa_set_key_id(&key_attr, 0x02);
  psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0x01));
  ret = psa_generate_key(&key_attr, &generate_key_id);

  // Import a persistent wrapped key for AES ECB (ID = 0x03)
  psa_set_key_id(&key_attr, 0x03);
  psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0x01));
  ret = psa_import_key(&key_attr, aes_ecb_key, sizeof(aes_ecb_key), &import_key_id);

  // Destroy the persistent wrapped keys for AES ECB
  ret = psa_destroy_key(generate_key_id);
  ret = psa_destroy_key(import_key_id);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image21](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image21.png)

The following table describes the implementation status of the PSA Crypto symmetric key platform example.

|**Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|Extractable|Y|Y|Y|—|
|Copyable|Y|Y|Y|The PSA_KEY_USAGE_COPY usage flag does not apply to the wrapped key.|
|Wrapped|—|—|Y|Only on HSE-SVH devices.|
|128-bit|Y|Y|Y|—|
|192-bit|Y|Y|Y|—|
|256-bit|Y|Y|Y|—|

##### Asymmetric Key

An asymmetric key pair consists of a (secret) private key and a public key (not secret). A public key cryptographic algorithm can be used for key distribution and digital signatures.

**Algorithms**

Refer to the [Asymmetric Cryptographic Operation](#asymmetric-cryptographic-operation) section.

**Key Attributes in PSA Crypto**

Refer to the [Asymmetric Cryptographic Operation](#asymmetric-cryptographic-operation) section.

**Security Software Components**

Refer to the [Asymmetric Cryptographic Operation](#asymmetric-cryptographic-operation) section.

**Functions**

<table>
    <thead>
        <tr>
            <th><strong>Item</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Create a random key</p>
            </td>
            <td>
                <p>
                    ECDH<br>
                    • <code>void mbedtls_ecdh_init(…)</code><br>
                    • <code>int mbedtls_ecp_group_load(…)</code><br>
                    • <code>int mbedtls_ecdh_gen_public(…)</code><br>
                    ECDSA<br>
                    • <code>void mbedtls_ecdsa_init(…)</code><br>
                    • <code>int mbedtls_ecdsa_genkey(…)</code>
                </p>
            </td>
            <td>
                <p>
                    Create a key from randomly generated data<br>
                    • <code>psa_status_t psa_generate_key(…)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Import a private or public key from a buffer</p>
            </td>
            <td>
                <p>
                    • <code>int mbedtls_ecp_point_read_binary(…)</code><br>
                    • <code>int mbedtls_mpi_read_binary(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_import_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Copy a key</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_copy_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Export a private key to a buffer</p>
            </td>
            <td>
                <p>
                    • <code>int mbedtls_ecp_point_write_binary(…)</code><br>
                    • <code>int mbedtls_mpi_write_binary(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_export_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Export a public key to a buffer</p>
            </td>
            <td>
                <p>
                    • <code>int mbedtls_ecp_point_write_binary(…)</code><br>
                    • <code>int mbedtls_mpi_write_binary(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_export_public_key(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Destroy a key</p>
            </td>
            <td>
                <p>
                    ECDH<br>
                    • <code>void mbedtls_ecdh_free(…)</code><br>
                    ECDSA<br>
                    • <code>void mbedtls_ecdsa_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_destroy_key(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**:
> 
> - The `psa_import_key()` cannot store a public key in [wrapped](04-key-management-in-psa-crypto) form.
> - The `psa_export_key()` can export a private key in plaintext if the [PSA_KEY_USAGE_EXPORT](04-key-management-in-psa-crypto) usage flag is set.

|**ECC Key**|**Private Key Size (Import and Export)**|**Public Key Size (Import and Export)**|
|---|---|---|
|secp192r1|24-byte|49-byte|
|secp224r1|28-byte|57-byte|
|secp256r1|32-byte|65-byte|
|secp384r1|48-byte|97-byte|
|secp521r1|66-byte|133-byte|
|secp256k1|32-byte|65-byte|
|Curve25519|32-byte|32-byte|
|Curve448|56-byte|56-byte|
|Edwards25519|32-byte|32-byte|

> **Note**:
> 
> - The public key of the `secpxxx` curve is stored in an uncompressed format (prefix `0x04` with the X and Y coordinates).
> - EFR32xG21A/B devices do not support hardware acceleration on the secp224r1 curve.
> - Only the VSE-SVM devices support hardware acceleration on the secp256k1 curve.
> - The secp224r1 and secp256k1 with wrapped keys are not supported yet.

**Quick Reference**

**Examples Asymmetric Key Creation and Import**

```c++
#include "psa/crypto.h"
void app_process_action(void)
{
  uint8_t public_key[65];         // Uncompressed point format
  size_t pubkey_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Check if there is already a persistent key with the given identifier (ID = 0x02)
  key_attr = psa_key_attributes_init();
  ret = psa_get_key_attributes(0x02, &key_attr);

  if (ret == PSA_ERROR_INVALID_HANDLE) {
    // Key identifier does not exist, set up attributes for a persistent private wrapped key (secp256r1)
    key_attr = psa_key_attributes_init();
    psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
    psa_set_key_bits(&key_attr, 256);
    psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
    psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);
    psa_set_key_id(&key_attr, 0x02);
    psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0x01));

    // Generate a random persistent private wrapped key (ID = 0x02)
    ret = psa_generate_key(&key_attr, &key_id);

    // Export a public key from a persistent private wrapped key (ID = 0x02)
    ret = psa_export_public_key(0x02, public_key, sizeof(public_key), &pubkey_len);

    // Set up attributes for a public key (secp256r1)
    key_attr = psa_key_attributes_init();
    psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
    psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
    psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);

    // Import a public key
    ret = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);

    // Destroy a persistent private wrapped key (ID = 0x02) and public key
    ret = psa_destroy_key(0x02);
    ret = psa_destroy_key(key_id);
  } else if (ret == PSA_SUCCESS) {
    // Key identifier already exists
    return;
  } else {
      // Unexpected error
    return;
  }
}
```

> **Note**: Remove the code for the `psa_set_key_lifetime()` function to generate a random persistent private plain key on non-HSE-SVH devices.

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image22](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image22.png)

The following table describes the implementation status of the PSA Crypto asymmetric key platform example.

|**ECC Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|Extractable|Y|Y|Y|—|
|Copyable|Y|Y|Y|The PSA_KEY_USAGE_COPY usage flag does not apply to the wrapped key.|
|Wrapped|—|—|Y|Only on HSE-SVH devices.|
|secp192r1|Y|Y|Y|—|
|secp256r1|Y|Y|Y|—|
|secp384r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|secp521r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|Curve25519|Y|Y|Y|Hardware acceleration only on HSE devices.|
|Curve448|—|—|Y|Only on HSE-SVH devices with hardware acceleration.|
|Edwards25519|—|—|Y|Only on HSE devices with hardware acceleration.|

> **Note**:
> 
> - This example does not include secp224r1 and secp256k1.
> - The PSA Crypto does not yet support software fallback on the Curve448 and Edwards25519.
> - The HSE-SVM devices require SE firmware v1.2.11 or higher (EFR32xG21) and v2.1.7 or higher (other HSE devices) to support hardware acceleration on Curve25519 and Edwards25519. This feature also requires GSDK v4.0.1 or higher.

##### Symmetric Cryptographic Operation

###### Message Digests

Message digests are designed to protect the integrity of a piece of data or media to detect changes to any part of a message. They are a type of cryptography utilizing hash values that can warn the receiver of any modifications applied to a message transmitted over an insecure channel.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>SHA-1</p>
            </td>
            <td>
                <p><code>MBEDTLS_MD_SHA1</code></p>
            </td>
            <td>
                <p><code>PSA_ALG_SHA_1</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>SHA-2</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_MD_SHA224</code><br>
                    • <code>MBEDTLS_MD_SHA256</code><br>
                    • <code>MBEDTLS_MD_SHA384</code><br>
                    • <code>MBEDTLS_MD_SHA512</code>
                </p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_SHA_224</code><br>
                    • <code>PSA_ALG_SHA_256</code><br>
                    • <code>PSA_ALG_SHA_384</code><br>
                    • <code>PSA_ALG_SHA_512</code>
                </p>
            </td>
        </tr>
    </tbody>
</table>

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_SHA_1|SHA-1|
|PSA_ALG_SHA_224|SHA-224|
|PSA_ALG_SHA_256|SHA-256|
|PSA_ALG_SHA_384|SHA-384|
|PSA_ALG_SHA_512|SHA-512|

**Single-Part Functions**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_md(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_sha1_ret(…)</code><br>
                    • <code>int mbedtls_sha256_ret(…)</code><br>
                    • <code>int mbedtls_sha512_ret(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_compute(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_compare(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

**Multi-Part Operations**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_md_init(…)</code><br>
                    Algorithm specific<br>
                    • <code>void mbedtls_sha1_init(…)</code><br>
                    • <code>void mbedtls_sha256_init(…)</code><br>
                    • <code>void mbedtls_sha512_init(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_hash_operation_t psa_hash_operation_init(void)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_md_setup(…)</code><br>
                    • <code>int mbedtls_md_starts(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_sha1_starts_ret(…)</code><br>
                    • <code>int mbedtls_sha256_starts_ret(…)</code><br>
                    • <code>int mbedtls_sha512_starts_ret(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_md_update(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_sha1_update_ret(…)</code><br>
                    • <code>int mbedtls_sha256_update_ret(…)</code><br>
                    • <code>int mbedtls_sha512_update_ret(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_update(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_md_finish(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_sha1_finish_ret(…)</code><br>
                    • <code>int mbedtls_sha256_finish_ret(…)</code><br>
                    • <code>int mbedtls_sha512_finish_ret(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_finish(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_verify(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_md_free(…)</code><br>
                    Algorithm specific<br>
                    • <code>void mbedtls_sha1_free(…)</code><br>
                    • <code>void mbedtls_sha256_free(…)</code><br>
                    • <code>void mbedtls_sha512_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_abort(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_md_clone(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_sha1_clone(…)</code><br>
                    • <code>int mbedtls_sha256_clone(…)</code><br>
                    • <code>int mbedtls_sha512_clone(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_hash_clone(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The multi-part operation allows the data to be processed for message digest in fragments instead of all at once.

**Quick Reference Examples**

**SHA-256 (One-shot)**

```c++
#include "psa/crypto.h"
void app_process_action(void)
{
  char test_msg[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"};
  uint8_t expect_sha256_hash[] = {
    0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
    0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
  };

  uint8_t hash_buf[32];
  size_t hash_len;
  psa_status_t ret;

  ret = psa_crypto_init();

  // Calculate the hash of a message
  ret = psa_hash_compute(PSA_ALG_SHA_256,
                        (uint8_t *)test_msg,
                        sizeof(test_msg) - 1,
                        hash_buf,
                        sizeof(hash_buf),
                        &hash_len);

  // Calculate the hash of a message and compare it with a reference value
  ret = psa_hash_compare(PSA_ALG_SHA_256,
                        (uint8_t *)test_msg,
                        sizeof(test_msg) - 1,
                        expect_sha256_hash,
                        sizeof(expect_sha256_hash));
}
```

**SHA-256 (Streaming)**

```c++
#include "psa/crypto.h"
void app_process_action(void)
{
  char test_msg[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"};
  uint8_t hash_buf[32];
  size_t hash_len;
  uint32_t hash_total;
  uint32_t stream_block_size = 16;            // Block size for streaming

  psa_status_t ret;
  psa_hash_operation_t hash_op;
  psa_hash_operation_t verify_op;

  ret = psa_crypto_init();

  hash_op = psa_hash_operation_init();
  ret = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);

  // Streaming block
  hash_total = 0;
  while ((sizeof(test_msg) - 1 - hash_total) > stream_block_size) {
  ret = psa_hash_update(&hash_op, (uint8_t *)(test_msg + hash_total), stream_block_size);
  hash_total += stream_block_size;
  }
  ret = psa_hash_update(&hash_op, (uint8_t *)(test_msg + hash_total), sizeof(test_msg) -1 - hash_total);

  // Generate hash and verify
  // Expected hash:
  // 24 8d 6a 61 d2 06 38 b8 e5 c0 26 93 0c 3e 60 39 a3 3c e4 59 64 ff 21 67 f6 ec ed d4 19 db 06 c1
  verify_op = psa_hash_operation_init();
  ret = psa_hash_clone(&hash_op, &verify_op);
  ret = psa_hash_finish(&hash_op, hash_buf, sizeof(hash_buf), &hash_len);
  ret = psa_hash_verify(&verify_op, hash_buf, hash_len);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image23](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image23.png)

The following table describes the implementation status of the PSA Crypto hash platform example.

|**Algorithm**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|SHA-1|Y|Y|Y|—|
|SHA-224|Y|Y|Y|—|
|SHA-256|Y|Y|Y|—|
|SHA-384|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|SHA-512|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|

##### Message Authentication Codes (MAC)

A Message Authentication Code (MAC), sometimes known as a tag, is a short piece of information used to confirm that the message came from the stated sender (its authenticity) and has not been changed.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>HMAC</p>
            </td>
            <td>
                <p><code>• MBEDTLS_MD_SHA1</code><br><code>• MBEDTLS_MD_SHA224</code><br><code>• MBEDTLS_MD_SHA256</code><br><code>• MBEDTLS_MD_SHA384</code><br><code>• MBEDTLS_MD_SHA512</code></p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_HMAC(PSA_ALG_SHA_1)</code><br>
                    • <code>PSA_ALG_HMAC(PSA_ALG_SHA_224)</code><br>
                    • <code>PSA_ALG_HMAC(PSA_ALG_SHA_256)</code><br>
                    • <code>PSA_ALG_HMAC(PSA_ALG_SHA_384)</code><br>
                    • <code>PSA_ALG_HMAC(PSA_ALG_SHA_512)</code><br>
                    • <code>PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)</code><br>
                    • <code>PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_HMAC(hash_alg))</code><br>
                    • <code>PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(hash_alg), min_mac_length)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>CMAC</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_CIPHER_AES_128_ECB</code><br>
                    • <code>MBEDTLS_CIPHER_AES_192_ECB</code><br>
                    • <code>MBEDTLS_CIPHER_AES_256_ECB</code>
                </p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_CMAC</code><br>
                    • <code>PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, mac_length)</code><br>
                    • <code>PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_CMAC)</code><br>
                    • <code>PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, min_mac_length)</code>
                </p>
            </td>
        </tr>
    </tbody>
</table>

**Key Attributes in PSA Crypto**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Key Size in Bits</strong></th>
            <th><strong>Key Usage Flag</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>•PSA_ALG_HMAC(PSA_ALG_SHA_1)<br><br>
                •PSA_ALG_HMAC(PSA_ALG_SHA_224)<br><br>
                •PSA_ALG_HMAC(PSA_ALG_SHA_256)<br><br>
                •PSA_ALG_HMAC(PSA_ALG_SHA_384)<br><br>
                •PSA_ALG_HMAC(PSA_ALG_SHA_512)<br><br>
                •PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)<br><br>
                •PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_HMAC(hash_alg))<br><br>
                •PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(hash_alg), min_mac_length)
            </td>
            <td>PSA_KEY_TYPE_HMAC</td>
            <td>Multiple of 8</td>
            <td rowspan="2">•PSA_KEY_USAGE_SIGN_MESSAGE<br><br>
                •PSA_KEY_USAGE_VERIFY_MESSAGE
            </td>
        </tr>
        <tr>
            <td>•PSA_ALG_CMAC<br><br>
                •PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, mac_length)<br><br>
                •PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_CMAC)<br><br>
                •PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, min_mac_length)
            </td>
            <td>PSA_KEY_TYPE_AES</td>
            <td>•128 (16-byte)<br><br>
                •192 (24-byte)<br><br>
                •256 (32-byte)
            </td>
        </tr>
    </tbody>
</table>

> **Note**: For GSDK lower than v4.1.0, use usage flag `PSA_KEY_USAGE_SIGN_HASH` and `PSA_KEY_USAGE_VERIFY_HASH` instead of `PSA_KEY_USAGE_SIGN_MESSAGE` and `PSA_KEY_USAGE_VERIFY_MESSAGE`.

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_HMAC(PSA_ALG_SHA_1)|HMAC and SHA-1|
|PSA_ALG_HMAC(PSA_ALG_SHA_224)|HMAC and SHA-224|
|PSA_ALG_HMAC(PSA_ALG_SHA_256)|HMAC and SHA-256|
|PSA_ALG_HMAC(PSA_ALG_SHA_384)|HMAC and SHA-384|
|PSA_ALG_HMAC(PSA_ALG_SHA_512)|HMAC and SHA-512|
|PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)|HMAC and SHA-X|
|PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_HMAC(hash_alg))|HMAC and SHA-X|
|PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(hash_alg), min_mac_length)|HMAC and SHA-X|
|PSA_ALG_CMAC|CMAC|
|PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, mac_length)|CMAC|
|PSA_ALG_FULL_LENGTH_MAC(PSA_ALG_CMAC)|CMAC|
|PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, min_mac_length)|CMAC|

**Single-Part Functions**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>int mbedtls_md_hmac(…)</code><br>
                    CMAC<br>
                    • <code>int mbedtls_cipher_cmac(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_compute(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_verify(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

**Multi-Part Operations**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>void mbedtls_md_init(…)</code><br>
                    • <code>int mbedtls_md_setup(…)</code><br>
                    CMAC<br>
                    • <code>void mbedtls_cipher_init(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_mac_operation_t psa_mac_operation_init(void)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>int mbedtls_md_hmac_starts(…)</code><br>
                    CMAC<br>
                    • <code>int mbedtls_cipher_cmac_starts(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_sign_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_verify_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>int mbedtls_md_hmac_update(…)</code><br>
                    CMAC<br>
                    • <code>int mbedtls_cipher_cmac_update(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_update(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>int mbedtls_md_hmac_finish(…)</code><br>
                    CMAC<br>
                    • <code>int mbedtls_cipher_cmac_finish(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_sign_finish(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_verify_finish(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    HMAC<br>
                    • <code>void mbedtls_md_free(…)</code><br>
                    CMAC<br>
                    • <code>void mbedtls_cipher_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_mac_abort(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The multi-part operation allows the data to be processed for MAC in fragments instead of all at once.

**Quick Reference Examples**

**CMAC (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t cmac_key[] = {
    0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
    0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
  };
  uint8_t cmac_msg[] = {
    0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
    0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
    0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11
  };
  uint8_t mac_buf[16];
  size_t mac_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a CMAC key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CMAC);

  // Import a volatile plain key for CMAC
  ret = psa_import_key(&key_attr, cmac_key, sizeof(cmac_key), &key_id);

  // Calculate the CMAC MAC of a message
  // Expected CMAC MAC: aa f3 d8 f1 de 56 40 c2 32 f5 b1 69 b9 c9 11 e6
  ret = psa_mac_compute(key_id, PSA_ALG_CMAC,
                        cmac_msg, sizeof(cmac_msg),
                        mac_buf, sizeof(mac_buf), &mac_len);

  // Verify the CMAC MAC of a message
  ret = psa_mac_verify(key_id, PSA_ALG_CMAC,
                        cmac_msg, sizeof(cmac_msg),
                        mac_buf, mac_len);

  // Destroy a volatile plain key for CMACss
  ret = psa_destroy_key(key_id);
}
```

> **Note**: There are two ways to change the CMAC MAC length (default 16 bytes).
> 
> 1. Replace all MAC algorithm `PSA_ALG_CMAC` with `PSA_ALG_TRUNCATED_MAC``(PSA_ALG_CMAC, mac_length)` for the desired size (≥ 4) of the MAC in bytes.
> 2. Replace the MAC algorithm `PSA_ALG_CMAC` in the `psa_set_key_algorithm(&key_attr, PSA_ALG_CMAC)` function with `PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, min_mac_length)` to set the minimum MAC length (≥ 4) in bytes. Replace the MAC algorithm `PSA_ALG_CMAC` in `psa_mac_compute()` and `psa_mac_verify()` with `PSA_ALG_TRUNCATED_MAC``(PSA_ALG_CMAC, mac_length)` to set the desired MAC length (≥ `min_mac_length` and ≤ `PSA_MAC_LENGTH``(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC))` in bytes.

**HMAC SHA-256 (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t hmac_key[] = {
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
  };
  uint8_t hmac_msg[] = {
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
  };
  uint8_t mac_buf[32];
  size_t mac_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a HMAC key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_HMAC);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));

  // Import a volatile plain key for HMAC
  ret = psa_import_key(&key_attr, hmac_key, sizeof(hmac_key), &key_id);

  // Calculate the HMAC MAC of a message
  // Expected HMAC MAC:
  // fb 5b 26 22 9c 20 b7 ed 86 67 06 a2 fb fa e6 7e 3f 40 4b b6 ab e7 7f f4 50 63 a4 59 a4 29 24 a4
  ret = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
                        hmac_msg, sizeof(hmac_msg),
                        mac_buf, sizeof(mac_buf), &mac_len);
  // Verify the HMAC MAC of a message
  ret = psa_mac_verify(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
                        hmac_msg, sizeof(hmac_msg),
                        mac_buf, mac_len);

  // Destroy a volatile plain key for HMAC
  ret = psa_destroy_key(key_id);
}
```

> **Notes**: There are two ways to change the HMAC MAC length (default is `hash_alg` dependent).
> 
> 1. Replace all MAC algorithm `PSA_ALG_HMAC(hash_alg)` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg)`, `mac_length`) for the desired size (≥ 4) of the MAC in bytes.
> 2. Replace the MAC algorithm `PSA_ALG_HMAC(hash_alg)` in the `psa_set_key_algorithm(&key_attr, PSA_ALG_HMAC(hash_alg))` function with `PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(hash_alg), min_mac_length)` to set the minimum MAC length (≥ 4) in bytes.
> 
> Replace the MAC algorithm `PSA_ALG_HMAC(hash_alg)` in `psa_mac_compute()` and `psa_mac_verify()` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)` to set the desired MAC length `(≥ min_mac_length` and `≤ PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 256, PSA_ALG_HMAC(hash_alg)))` in bytes.

**CMAC (Streaming)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t cmac_key[] = {
    0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
    0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
  };
  uint8_t cmac_msg[] = {
    0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
    0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
    0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11
  };
  uint8_t mac_buf[16];
  size_t mac_len;
  uint32_t mac_total;
  uint32_t stream_block_size = 8;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_mac_operation_t mac_op;

  ret = psa_crypto_init();

  // Set up attributes for a CMAC key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CMAC);

  // Import a volatile plain key for CMAC
  ret = psa_import_key(&key_attr, cmac_key, sizeof(cmac_key), &key_id);

  // Stream message and calculate the CMAC MAC
  // Expected CMAC MAC: aa f3 d8 f1 de 56 40 c2 32 f5 b1 69 b9 c9 11 e6
  mac_op = psa_mac_operation_init();
  ret = psa_mac_sign_setup(&mac_op, key_id, PSA_ALG_CMAC);
  mac_total = 0;        // Streaming block
  while ((sizeof(cmac_msg) - mac_total) > stream_block_size) {
    ret = psa_mac_update(&mac_op, cmac_msg + mac_total, stream_block_size);
    mac_total += stream_block_size;
  }
  ret = psa_mac_update(&mac_op, cmac_msg + mac_total, sizeof(cmac_msg) - mac_total);
  ret = psa_mac_sign_finish(&mac_op, mac_buf, sizeof(mac_buf), &mac_len);

  // Stream message and verify the CMAC MAC
  mac_op = psa_mac_operation_init();
  ret = psa_mac_verify_setup(&mac_op, key_id, PSA_ALG_CMAC);
  mac_total = 0;        // Streaming block
  while ((sizeof(cmac_msg) - mac_total) > stream_block_size) {
    ret = psa_mac_update(&mac_op, cmac_msg + mac_total, stream_block_size);
    mac_total += stream_block_size;
  }
  ret = psa_mac_update(&mac_op, cmac_msg + mac_total, sizeof(cmac_msg) - mac_total);
  ret = psa_mac_verify_finish(&mac_op, mac_buf, mac_len);

  // Destroy a volatile plain key for CMAC
  ret = psa_destroy_key(key_id);
}
```

> **Notes**: There are two ways to change the CMAC MAC length (default 16 bytes).
> 
> 1. Replace all MAC algorithm `PSA_ALG_CMAC` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, mac_length)` for the desired size (≥ 4) of the MAC in bytes.
> 2. Replace the MAC algorithm `PSA_ALG_CMAC` in the `psa_set_key_algorithm(&key_attr, PSA_ALG_CMAC)` function with `PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, min_mac_length)` to set the minimum MAC length (≥ 4) in bytes.
> 
> Replace the MAC algorithm `PSA_ALG_CMAC` in `psa_mac_sign_setup()` and `psa_mac_verify_setup()` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, mac_length)` to set the desired MAC length `(≥ min_mac_length and ≤ PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC))` in bytes.

**HMAC SHA-256 (Streaming)**

```c++
#include "psa/crypto.h"
void app_process_action(void)
{
  uint8_t hmac_key[] = {
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
  };
  uint8_t hmac_msg[] = {
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
  };
  uint8_t mac_buf[32];
  size_t mac_len;
  uint32_t mac_total;
  uint32_t stream_block_size = 8;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_mac_operation_t mac_op;

  ret = psa_crypto_init();

  // Set up attributes for a HMAC key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_HMAC);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));

  // Import a volatile plain key for HMAC
  ret = psa_import_key(&key_attr, hmac_key, sizeof(hmac_key), &key_id);

  // Stream message and calculate the HMAC MAC
  // Expected HMAC MAC:
  // fb 5b 26 22 9c 20 b7 ed 86 67 06 a2 fb fa e6 7e 3f 40 4b b6 ab e7 7f f4 50 63 a4 59 a4 29 24 a4
  mac_op = psa_mac_operation_init();
  ret = psa_mac_sign_setup(&mac_op, key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256));
  mac_total = 0; // Streaming block
  while ((sizeof(hmac_msg) - mac_total) > stream_block_size) {
    ret = psa_mac_update(&mac_op, hmac_msg + mac_total, stream_block_size);
    mac_total += stream_block_size;
  }
  ret = psa_mac_update(&mac_op, hmac_msg + mac_total, sizeof(hmac_msg) - mac_total);
  ret = psa_mac_sign_finish(&mac_op, mac_buf, sizeof(mac_buf), &mac_len);

  // Stream message and verify the HMAC MAC
  mac_op = psa_mac_operation_init();
  ret = psa_mac_verify_setup(&mac_op, key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256));
  mac_total = 0; // Streaming block
  while ((sizeof(hmac_msg) - mac_total) > stream_block_size) {
    ret = psa_mac_update(&mac_op, hmac_msg + mac_total, stream_block_size);
    mac_total += stream_block_size;
  }
  ret = psa_mac_update(&mac_op, hmac_msg + mac_total, sizeof(hmac_msg) - mac_total);
  ret = psa_mac_verify_finish(&mac_op, mac_buf, mac_len);

  // Destroy a volatile plain key for HMAC
  ret = psa_destroy_key(key_id);
}
```

> **Notes**: There are two ways to change the HMAC MAC length (default is `hash_alg` dependent).
> 
> 1. Replace all MAC algorithm `PSA_ALG_HMAC(hash_alg)` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)` for the desired size (≥ 4) of the MAC in bytes.
> 2. Replace the MAC algorithm `PSA_ALG_HMAC(hash_alg)` in the `psa_set_key_algorithm(&key_attr, PSA_ALG_HMAC(hash_alg))` function with `PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(hash_alg), min_mac_length)` to set the minimum MAC length (≥ 4) in bytes.
> 
> Replace the MAC algorithm `PSA_ALG_HMAC(hash_alg)` in `psa_mac_sign_setup()` and `psa_mac_verify_setup()` with `PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(hash_alg), mac_length)` to set the desired MAC length `(≥ min_mac_length and ≤ PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 256, PSA_ALG_HMAC(hash_alg)))` in bytes.

**PSA Crypto Platform Example**

Click the View Project Documentation link to open the readme file.

![image24](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image24.png)

The following table describes the implementation status of the PSA Crypto MAC platform example.

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Series 1</strong></th>
            <th><strong>Series 2 - VSE</strong></th>
            <th><strong>Series 2 - HSE</strong></th>
            <th>Remark</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>HMAC</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>
                    - Hardware acceleration only on Series 2 devices.<br>
                    - HMAC streaming with wrapped key is not supported yet.
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>CMAC</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Y</p>
            </td>
            <td>
                <p>Series 1 devices do not support a 192-bit key.</p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**:
> 
> - The MAC platform example uses the default MAC length.
> - The single-part MAC functions are only available on GSDK v4.0.0 and higher.

###### Unauthenticated Ciphers

The unauthenticated cipher API is for use cases where the data integrity and authenticity are guaranteed by non-cryptographic means.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>AES ECB</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_CIPHER_AES_128_ECB</code><br>
                    • <code>MBEDTLS_CIPHER_AES_192_ECB</code><br>
                    • <code>MBEDTLS_CIPHER_AES_256_ECB</code>
                </p>
            </td>
            <td>
                <p><code>PSA_ALG_ECB_NO_PADDING</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AES CBC</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_CIPHER_AES_128_CBC</code><br>
                    • <code>MBEDTLS_CIPHER_AES_192_CBC</code><br>
                    • <code>MBEDTLS_CIPHER_AES_256_CBC</code>
                </p>
            </td>
            <td>
                <p><code>PSA_ALG_CBC_NO_PADDING</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AES CFB</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_CIPHER_AES_128_CFB128</code><br>
                    • <code>MBEDTLS_CIPHER_AES_192_CFB128</code><br>
                    • <code>MBEDTLS_CIPHER_AES_256_CFB128</code>
                </p>
            </td>
            <td>
                <p><code>PSA_ALG_CFB</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AES CTR</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_CIPHER_AES_128_CTR</code><br>
                    • <code>MBEDTLS_CIPHER_AES_192_CTR</code><br>
                    • <code>MBEDTLS_CIPHER_AES_256_CTR</code>
                </p>
            </td>
            <td>
                <p><code>PSA_ALG_CTR</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>CHACHA20</p>
            </td>
            <td>
                <p><code>MBEDTLS_CIPHER_CHACHA20</code></p>
            </td>
            <td>
                <p><code>PSA_ALG_STREAM_CIPHER</code></p>
            </td>
        </tr>
    </tbody>
</table>

**Key Attributes in PSA Crypto**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Key Size in Bits</strong></th>
            <th><strong>Key Usage Flag</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>PSA_ALG_ECB_NO_PADDING</code></td>
            <td rowspan="4"><code>PSA_KEY_TYPE_AES</code></td>
            <td rowspan="4">128 (16-byte)<br>192 (24-byte)<br>256 (32-byte)</td>
            <td rowspan="5"><code>PSA_KEY_USAGE_ENCRYPT</code><br><code>PSA_KEY_USAGE_DECRYPT</code></td>
        </tr>
        <tr>
            <td><code>PSA_ALG_CBC_NO_PADDING</code></td>
        </tr>
        <tr>
            <td><code>PSA_ALG_CFB</code></td>
        </tr>
        <tr>
            <td><code>PSA_ALG_CTR</code></td>
        </tr>
        <tr>
            <td><code>PSA_ALG_STREAM_CIPHER</code></td>
            <td><code>PSA_KEY_TYPE_CHACHA20</code></td>
            <td>256 (32-byte)</td>
        </tr>
    </tbody>
</table>

**Security Software Components**

|**Algorithm and Built-in Key**|**Security Software Components**|
|---|---|
|PSA_ALG_ECB_NO_PADDING|ECB Mode|
|PSA_ALG_CBC_NO_PADDING|CBC Mode|
|PSA_ALG_CFB|CFB Mode|
|PSA_ALG_CTR|CTR Mode|
|PSA_ALG_STREAM_CIPHER|Chacha20 Stream Cipher|

|**Built-in Key**|**Security Software Components**|
|---|---|
|secp256r1 keys in SE OTP|Built-In Keys|

**Single-Part Functions**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_crypt(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_aes_crypt_ecb(…)</code><br>
                    • <code>int mbedtls_aes_crypt_cbc(…)</code><br>
                    • <code>int mbedtls_aes_crypt_cfb128(…)</code><br>
                    • <code>int mbedtls_aes_crypt_ctr(…)</code><br>
                    • <code>int mbedtls_chacha20_crypt(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_encrypt(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_crypt(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_aes_crypt_ecb(…)</code><br>
                    • <code>int mbedtls_aes_crypt_cbc(…)</code><br>
                    • <code>int mbedtls_aes_crypt_cfb128(…)</code><br>
                    • <code>int mbedtls_aes_crypt_ctr(…)</code><br>
                    • <code>int mbedtls_chacha20_crypt(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_decrypt(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**:
> 
> - The `psa_cipher_encrypt()` encrypts a message with a random initialization vector (IV). The output of this function is the IV followed by the ciphertext. Use the multi-part operations to manage the IV and ciphertext separately.
> - The input to `psa_cipher_decrypt()` must contain the IV followed by the ciphertext, as output by` psa_cipher_encrypt()`. Use the multi-part operations to decrypt data that is not in the expected input format.

**Multi-Part Operations**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_cipher_init(…)</code><br>
                    Algorithm specific<br>
                    • <code>void mbedtls_chacha20_init(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_cipher_operation_t psa_cipher_operation_init(void)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_setup(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_setkey(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_encrypt_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_set_iv(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_starts(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_generate_iv(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_setup(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_setkey(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_decrypt_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_set_iv(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_starts(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_set_iv(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_update(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_update(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_update(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p><code>int mbedtls_cipher_finish(…)</code></p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_finish(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_cipher_free(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_chacha20_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_cipher_abort(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The following situations require the use of a multi-part operation:
> 
> - Processing messages that cannot be assembled in memory.
> - Using a deterministic initialization vector (IV) for unauthenticated encryption.
> - Providing the IV separately for unauthenticated encryption or decryption.

**Quick Reference Examples**

**AES ECB (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t aes_ecb_key[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  };
  uint8_t plain_msg_buf[] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
  };
  uint8_t cipher_buf[16];
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_cipher_operation_t cipher_op;

  ret = psa_crypto_init();

  // Set up attributes for a AES ECB key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);

  // Import a volatile plain key for AES ECB
  ret = psa_import_key(&key_attr, aes_ecb_key, sizeof(aes_ecb_key), &key_id);
  
  // AES ECB encryption and decryption
  // Expected ciphertext: 69 c4 e0 d8 6a 7b 04 30 d8 cd b7 80 70 b4 c5 5a
  // Single-part
  ret = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_decrypt(key_id, PSA_ALG_ECB_NO_PADDING,
                          cipher_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);

  // Multi-part
  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_encrypt_setup(&cipher_op, key_id, PSA_ALG_ECB_NO_PADDING);
  ret = psa_cipher_update(&cipher_op, plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_finish(&cipher_op,
                          cipher_buf + out_len,
                          sizeof(cipher_buf) - out_len,
                          &out_len);

  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_decrypt_setup(&cipher_op, key_id, PSA_ALG_ECB_NO_PADDING);
  ret = psa_cipher_update(&cipher_op, cipher_buf, sizeof(cipher_buf),
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);

  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_len,
                          sizeof(plain_msg_buf) - out_len,
                          &out_len);

  // Destroy a volatile plain key for AES ECB
  ret = psa_destroy_key(key_id);
}
```

**AES CFB (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t aes_cbc_key[] = {
    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
  };
  uint8_t iv_buf[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  };
  uint8_t plain_msg_buf[] = {
    0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
  };
  uint8_t cipher_buf[32]; // Random IV + Ciphertext for single-part
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_cipher_operation_t cipher_op;

  ret = psa_crypto_init();

  // Set up attributes for a AES CBC key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CBC_NO_PADDING);

  // Import a volatile plain key for AES CBC
  ret = psa_import_key(&key_attr, aes_cbc_key, sizeof(aes_cbc_key), &key_id);

  // AES CBC encryption and decryption
  // Single-part - Random IV generated during encryption is embedded in the ciphertext buffer
  ret = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING,
                          cipher_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);

  // Multi-part
  // Expected ciphertext: 76 49 ab ac 81 19 b2 46 ce e9 8e 9b 12 e9 19 7d
  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_encrypt_setup(&cipher_op, key_id, PSA_ALG_CBC_NO_PADDING);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          cipher_buf + out_len,
                          sizeof(cipher_buf) - out_len,
                          &out_len);

  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_decrypt_setup(&cipher_op, key_id, PSA_ALG_CBC_NO_PADDING);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          cipher_buf, sizeof(plain_msg_buf),
                          plain_msg_buf, sizeof(plain_msg_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_len,
                          sizeof(plain_msg_buf) - out_len,
                          &out_len);

  // Destroy a volatile plain key for AES CBC
  ret = psa_destroy_key(key_id);
}
```

> **Note**: The multi-part operations provide the IV separately for AES CFB encryption or decryption.

**AES CTR (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t aes_ctr_key[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  };
  uint8_t iv_buf[] = {
    0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70
  };
  uint8_t plain_msg_buf[] = {
    0xd8, 0x65, 0xc9, 0xcd, 0xea, 0x33, 0x56, 0xc5, 0x48, 0x8e, 0x7b, 0xa1, 0x5e, 0x84, 0xf4, 0xeb,
    0xa3, 0xb8, 0x25, 0x9c, 0x05, 0x3f, 0x24, 0xce, 0x29, 0x67, 0x22, 0x1c, 0x00, 0x38, 0x84, 0xd7,
    0x9d, 0x4c, 0xa4, 0x87, 0x7f, 0xfa, 0x4b, 0xc6, 0x87, 0xc6, 0x67, 0xe5, 0x49, 0x5b, 0xcf, 0xec,
    0x12, 0xf4, 0x87, 0x17, 0x32, 0xaa, 0xe4, 0x5a, 0x11, 0x06, 0x76, 0x11, 0x3d, 0xf9, 0xe7, 0xda
  };
  uint8_t cipher_buf[80]; // Random IV + Ciphertext for single-part
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_cipher_operation_t cipher_op;

  ret = psa_crypto_init();

  // Set up attributes for a AES CTR key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Import a volatile plain key for AES CTR
  ret = psa_import_key(&key_attr, aes_ctr_key, sizeof(aes_ctr_key), &key_id);

  // AES CTR encryption and decryption
  // Single-part - Random IV generated during encryption is embedded in the ciphertext buffer
  ret = psa_cipher_encrypt(key_id, PSA_ALG_CTR,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_decrypt(key_id, PSA_ALG_CTR,
                          cipher_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);
  // Multi-part
  // Expected ciphertext:
  // b6 72 f2 af 6a cc 20 ae ee 1a d8 14 12 8c 31 8b 95 5b be 80 5b 38 92 49 89 76 00 f5 20 74 54 32
  // 7d 6d 0f b4 ac 0a 94 f3 7c a0 9e 45 05 33 98 fe a8 9c 20 0a d3 58 12 6d 9e 89 a4 05 26 5c 96 e7
  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_encrypt_setup(&cipher_op, key_id, PSA_ALG_CTR);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          cipher_buf + out_len,
                          sizeof(cipher_buf) - out_len,
                          &out_len);

  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_decrypt_setup(&cipher_op, key_id, PSA_ALG_CTR);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          cipher_buf, sizeof(plain_msg_buf),
                          plain_msg_buf, sizeof(plain_msg_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_len,
                          sizeof(plain_msg_buf) - out_len,
                          &out_len);
  // Destroy a volatile plain key for AES CTR
  ret = psa_destroy_key(key_id);
}
```

> **Note**: The multi-part operations provide the IV separately for AES CTR encryption or decryption.

**CHACHA20 (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t chacha20_key[32] = {0};
  uint8_t iv_buf[12] = {0};
  uint8_t plain_msg_buf[64] = {0};
  uint8_t cipher_buf[76];         // Random IV + Ciphertext for single-part
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_cipher_operation_t cipher_op;

  ret = psa_crypto_init();

  // Set up attributes for a CHACHA20 key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_CHACHA20);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_STREAM_CIPHER);

  // Import a volatile plain key for CHACHA20
  ret = psa_import_key(&key_attr, chacha20_key, sizeof(chacha20_key), &key_id);

  // CHACHA20 encryption and decryption
  // Single-part - Random IV generated during encryption is embedded in the ciphertext buffer
  ret = psa_cipher_encrypt(key_id, PSA_ALG_STREAM_CIPHER,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_decrypt(key_id, PSA_ALG_STREAM_CIPHER,
                          cipher_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);

  // Multi-part
  // Expected ciphertext:
  // 76 b8 e0 ad a0 f1 3d 90 40 5d 6a e5 53 86 bd 28 bd d2 19 b8 a0 8d ed 1a a8 36 ef cc 8b 77 0d c7
  // da 41 59 7c 51 57 48 8d 77 24 e0 3f b8 d8 4a 37 6a 43 b8 f4 15 18 a1 1c c3 87 b6 69 b2 ee 65 86
  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_encrypt_setup(&cipher_op, key_id, PSA_ALG_STREAM_CIPHER);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          cipher_buf + out_len,
                          sizeof(cipher_buf) - out_len,
                          &out_len);

  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_decrypt_setup(&cipher_op, key_id, PSA_ALG_STREAM_CIPHER);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          cipher_buf, sizeof(plain_msg_buf),
                          plain_msg_buf, sizeof(plain_msg_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_len,
                          sizeof(plain_msg_buf) - out_len,
                          &out_len);

  // Destroy a volatile plain key for CHACHA20
  ret = psa_destroy_key(key_id);
}
```

> **Note**: The multi-part operations provide the IV separately for CHACHA20 encryption or decryption.

**AES CTR (Streaming)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
 uint8_t aes_ctr_key[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 uint8_t iv_buf[] = {
   0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70, 0x22, 0x22, 0x1a, 0x70
 };
 uint8_t plain_msg_buf[] = {
  0xd8, 0x65, 0xc9, 0xcd, 0xea, 0x33, 0x56, 0xc5, 0x48, 0x8e, 0x7b, 0xa1, 0x5e, 0x84, 0xf4, 0xeb,
  0xa3, 0xb8, 0x25, 0x9c, 0x05, 0x3f, 0x24, 0xce, 0x29, 0x67, 0x22, 0x1c, 0x00, 0x38, 0x84, 0xd7,
  0x9d, 0x4c, 0xa4, 0x87, 0x7f, 0xfa, 0x4b, 0xc6, 0x87, 0xc6, 0x67, 0xe5, 0x49, 0x5b, 0xcf, 0xec,
  0x12, 0xf4, 0x87, 0x17, 0x32, 0xaa, 0xe4, 0x5a, 0x11, 0x06, 0x76, 0x11, 0x3d, 0xf9, 0xe7, 0xda
 };
 uint8_t cipher_buf[64];
 size_t out_len;
 uint32_t out_total;
 uint32_t stream_block_size = 14;                 // Block size for streaming

 psa_status_t ret;
 psa_key_id_t key_id;
 psa_key_attributes_t key_attr;
 psa_cipher_operation_t cipher_op;

 ret = psa_crypto_init();

 // Set up attributes for a AES CTR key
 key_attr = psa_key_attributes_init();
 psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
 psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

 // Import a volatile plain key for AES CTR
 ret = psa_import_key(&key_attr, aes_ctr_key, sizeof(aes_ctr_key), &key_id);

 // AES CTR stream encryption and decryption
 // Expected ciphertext:
 // b6 72 f2 af 6a cc 20 ae ee 1a d8 14 12 8c 31 8b 95 5b be 80 5b 38 92 49 89 76 00 f5 20 74 54 32
 // 7d 6d 0f b4 ac 0a 94 f3 7c a0 9e 45 05 33 98 fe a8 9c 20 0a d3 58 12 6d 9e 89 a4 05 26 5c 96 e7
 cipher_op = psa_cipher_operation_init();
 ret = psa_cipher_encrypt_setup(&cipher_op, key_id, PSA_ALG_CTR);
 ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));

 out_total = 0; // Streaming block
 while ((sizeof(plain_msg_buf) - out_total) > stream_block_size) {
   ret = psa_cipher_update(&cipher_op,
                            plain_msg_buf + out_total, stream_block_size,
                            cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                            &out_len);
  out_total += out_len;
 }
  ret = psa_cipher_update(&cipher_op, // Last block
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          &out_len);
  out_total += out_len;

 ret = psa_cipher_finish(&cipher_op,
                        cipher_buf + out_total,
                        sizeof(cipher_buf) - out_total,
                        &out_len);

 cipher_op = psa_cipher_operation_init();
 ret = psa_cipher_decrypt_setup(&cipher_op, key_id, PSA_ALG_CTR);
 ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));

 out_total = 0; // Streaming block
 while ((sizeof(cipher_buf) - out_total) > stream_block_size) {
  ret = psa_cipher_update(&cipher_op,
                          cipher_buf + out_total, stream_block_size,
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len);
  out_total += out_len;
 }

  ret = psa_cipher_update(&cipher_op, // Last block
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len);
  out_total += out_len;

  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_total,
                          sizeof(plain_msg_buf) - out_total,
                          &out_len);

 // Destroy a volatile plain key for AES CTR
 ret = psa_destroy_key(key_id);
}
```

**AES CTR with Built-in AES-128 Key (HSE only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t iv_buf[16] = {0};
  uint8_t plain_msg_buf[16] = {0};
  uint8_t cipher_buf[32]; // Random IV + Ciphertext for single-part
  size_t out_len;

  psa_status_t ret;
  psa_cipher_operation_t cipher_op;

  ret = psa_crypto_init();

  // AES CTR encryption and decryption with built-in AES-128 key
  // ret = -140 (PSA_ERROR_DOES_NOT_EXIST) if the AES-128 key has not been provisioned
  // Single-part - Random IV generated during encryption is embedded in the ciphertext buffer
  ret = psa_cipher_encrypt(SL_SE_BUILTIN_KEY_AES128_ID, PSA_ALG_CTR,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf), &out_len);

  ret = psa_cipher_decrypt(SL_SE_BUILTIN_KEY_AES128_ID, PSA_ALG_CTR,
                          cipher_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf), &out_len);

  // Multi-part
  // Built-in AES-128 key: 81 a5 e2 1f a1 52 86 f1 df 44 5c 2c c1 20 fa 3f
  // Expected ciphertext: 66 d2 0f 99 65 3e a8 d0 83 05 a6 39 d4 4e 98 a6
  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_encrypt_setup(&cipher_op, SL_SE_BUILTIN_KEY_AES128_ID, PSA_ALG_CTR);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_buf, sizeof(cipher_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          cipher_buf + out_len,
                          sizeof(cipher_buf) - out_len,
                          &out_len);

  cipher_op = psa_cipher_operation_init();
  ret = psa_cipher_decrypt_setup(&cipher_op, SL_SE_BUILTIN_KEY_AES128_ID, PSA_ALG_CTR);
  ret = psa_cipher_set_iv(&cipher_op, iv_buf, sizeof(iv_buf));
  ret = psa_cipher_update(&cipher_op,
                          cipher_buf, sizeof(plain_msg_buf),
                          plain_msg_buf, sizeof(plain_msg_buf),
                          &out_len);
  ret = psa_cipher_finish(&cipher_op,
                          plain_msg_buf + out_len,
                          sizeof(plain_msg_buf) - out_len,
                          &out_len);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image25](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image25.png)

The following table describes the implementation status of the PSA Crypto cipher platform example.

|**Algorithm/Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|AES ECB|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|AES CBC|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|AES CFB|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|AES CTR|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|CHACHA20|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|AES-128 Key|—|—|Y|—|

> **Note**: The single-part unauthenticated cipher functions are only available on GSDK v4.0.0 and higher.

###### Authenticated Encryption with Associated Data (AEAD)

The authenticated encryption with associated data (AEAD) is a form of encryption that simultaneously assures the confidentiality and authenticity of data.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>AES GCM</p>
            </td>
            <td>
                <p>
                    • MBEDTLS_CIPHER_AES_128_GCM<br>
                    • MBEDTLS_CIPHER_AES_192_GCM<br>
                    • MBEDTLS_CIPHER_AES_256_GCM
                </p>
            </td>
            <td>
                <p>
                    • PSA_ALG_GCM<br>
                    • PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_length)<br>
                    • PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(PSA_ALG_GCM)<br>
                    • PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_GCM, min_tag_length)
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>AES CCM</p>
            </td>
            <td>
                <p>
                    • MBEDTLS_CIPHER_AES_128_CCM<br>
                    • MBEDTLS_CIPHER_AES_192_CCM<br>
                    • MBEDTLS_CIPHER_AES_256_CCM
                </p>
            </td>
            <td>
                <p>
                    • PSA_ALG_CCM<br>
                    • PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length)<br>
                    • PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(PSA_ALG_CCM)<br>
                    • PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, min_tag_length)
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>CHACHA20_POLY1305</p>
            </td>
            <td>
                <p>MBEDTLS_CIPHER_CHACHA20_POLY1305</p>
            </td>
            <td>
                <p>PSA_ALG_CHACHA20_POLY1305</p>
            </td>
        </tr>
    </tbody>
</table>

|**Algorithm**|**Nonce Length (Bytes)**|**Authentication Tag Length (Bytes)**|
|---|---|---|
|AES GCM|1 - 16 (Default 12)|4, 8, 12, 13, 14, 15, and 16 (Default)|
|AES CCM|7 - 13|4, 6, 8, 10, 12, 14, and 16 (Default)|
|CHACHA20_POLY1305|12|16|

**Key Attributes in PSA Crypto**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Key Size in Bits</strong></th>
            <th><strong>Key Usage Flag</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <code>PSA_ALG_GCM</code> or<br>
                <code>PSA_ALG_AEAD_WITH_*(PSA_ALG_GCM…)</code>
            </td>
            <td rowspan="2"><code>PSA_KEY_TYPE_AES</code></td>
            <td>128 (16-byte)<br>192 (24-byte)<br>256 (32-byte)</td>
            <td rowspan="3">
                <code>PSA_KEY_USAGE_ENCRYPT</code><br>
                <code>PSA_KEY_USAGE_DECRYPT</code>
            </td>
        </tr>
        <tr>
            <td>
                <code>PSA_ALG_CCM</code> or<br>
                <code>PSA_ALG_AEAD_WITH_*(PSA_ALG_CCM…)</code>
            </td>
        </tr>
        <tr>
            <td><code>PSA_ALG_CHACHA20_POLY1305</code></td>
            <td><code>PSA_KEY_TYPE_CHACHA20</code></td>
            <td>256 (32-byte)</td>
        </tr>
    </tbody>
</table>

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_GCM or PSA_ALG_AEAD_WITH_*(PSA_ALG_GCM…)|GCM (12-byte IV) or GCM with Non-Recommended IV Lengths|
|PSA_ALG_CCM or PSA_ALG_AEAD_WITH_*(PSA_ALG_CCM…)|CCM Mode|
|PSA_ALG_CHACHA20_POLY1305|ChachaPoly|

**Single-Part Functions**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_auth_encrypt(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_ccm_encrypt_and_tag(…)</code><br>
                    • <code>int mbedtls_gcm_crypt_and_tag(…)</code><br>
                    • <code>int mbedtls_chachapoly_encrypt_and_tag(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_encrypt(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_auth_decrypt(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_ccm_auth_decrypt(…)</code><br>
                    • <code>int mbedtls_gcm_auth_decrypt(…)</code><br>
                    • <code>int mbedtls_chachapoly_auth_decrypt(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_decrypt(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The single-part functions use one buffer for the ciphertext and AEAD authentication tag.

**Multi-Part Operations**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_cipher_init(…)</code><br>
                    Algorithm specific<br>
                    • <code>void mbedtls_gcm_init(…)</code><br>
                    • <code>void mbedtls_chachapoly_init(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_aead_operation_t psa_aead_operation_init(void)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_setup(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_setkey(…)</code><br>
                    • <code>int mbedtls_chachapoly_setkey(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_encrypt_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_set_iv(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_starts(…)</code><br>
                    • <code>int mbedtls_chachapoly_starts(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_generate_nonce(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_set_lengths(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_setup(…)</code><br>
                    • <code>int mbedtls_cipher_setkey(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_setkey(…)</code><br>
                    • <code>int mbedtls_chachapoly_setkey(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_decrypt_setup(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_set_iv(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_starts(…)</code><br>
                    • <code>int mbedtls_chachapoly_starts(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_set_nonce(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_update_ad(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_starts(…)</code><br>
                    • <code>int mbedtls_chachapoly_update_aad(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_update_ad(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_update(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_update(…)</code><br>
                    • <code>int mbedtls_chachapoly_update(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_update(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>int mbedtls_cipher_finish(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_finish(…)</code><br>
                    • <code>int mbedtls_chachapoly_finish(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_finish(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_verify(…)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>
                    Generic<br>
                    • <code>void mbedtls_cipher_free(…)</code><br>
                    Algorithm specific<br>
                    • <code>int mbedtls_gcm_free(…)</code><br>
                    • <code>int mbedtls_chachapoly_free(…)</code>
                </p>
            </td>
            <td>
                <p><code>psa_status_t psa_aead_abort(…)</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**:
> 
> - For `PSA_ALG_CCM`, calling` psa_aead_set_lengths()` is required.
> - For the other AEAD algorithms, calling `psa_aead_set_lengths()` is not required.
> - The following situations require the use of a multi-part operation:
> - Processing messages that cannot be assembled in memory.
> - Separating the AEAD authentication tag from the ciphertext.

**Quick Reference Examples**

**AES CCM (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t key_buf[] = {
    0xea, 0x4f, 0x6f, 0x3c, 0x2f, 0xed, 0x2b, 0x9d, 0xd9, 0x70, 0x8c, 0x2e, 0x72, 0x1a, 0xe0, 0x0f
  };
  uint8_t nonce_buf[] = {0xf9, 0x75, 0x80, 0x9d, 0xdb, 0x51, 0x72, 0x38, 0x27, 0x45, 0x63, 0x4f};
  uint8_t ad_buf[] = {0x5c, 0x65, 0xd4, 0xf2, 0x61, 0xd2, 0xc5, 0x4f, 0xfe, 0x6a};
  uint8_t plain_msg_buf[] = {0x8d, 0x6c, 0x08, 0x44, 0x6c, 0xb1, 0x0d, 0x9a, 0x20, 0x75};
  uint8_t cipher_tag_buf[32];       // Ciphertext + Tag
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a AES CCM key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CCM);

  // Import a volatile plain key for AES CCM
  ret = psa_import_key(&key_attr, key_buf, sizeof(key_buf), &key_id);

  // AES CCM encryption and descryption
  // Expected ciphertext: e2 2f 37 3b eb f6 4a 3e 9b 87
  // Expected tag: 75 2b f9 db 34 dc 4d 43 3f 00 f5 5c 3f 53 0c 89
  ret = psa_aead_encrypt(key_id, PSA_ALG_CCM,
                        nonce_buf, sizeof(nonce_buf),
                        ad_buf, sizeof(ad_buf),
                        plain_msg_buf, sizeof(plain_msg_buf),
                        cipher_tag_buf, sizeof(cipher_tag_buf),
                        &out_len);
  ret = psa_aead_decrypt(key_id, PSA_ALG_CCM,
                        nonce_buf, sizeof(nonce_buf),
                        ad_buf, sizeof(ad_buf),
                        cipher_tag_buf, out_len,
                        plain_msg_buf, sizeof(plain_msg_buf),
                        &out_len);

  // Destroy a volatile plain key for AES CCM
  ret = psa_destroy_key(key_id);
}
```

> **Notes**:
> 
> - There are two ways to change the CCM authentication tag length (default 16 bytes).
>   1. Replace all AEAD algorithm `PSA_ALG_CCM` with `PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length)` for the desired size of the authentication tag in bytes.
>   2. Replace the AEAD algorithm `PSA_ALG_CCM` in the `psa_set_key_algorithm(&key_attr, PSA_ALG_CCM)` function with `PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, min_tag_length)` to set the minimum authentication tag length in bytes. Replace the AEAD algorithm `PSA_ALG_CCM in psa_aead_encrypt()` and `psa_aead_decrypt()` with `PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length)` to set the desired tag length `(≥ min_tag_length and ≤ PSA_AEAD_TAG_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CCM))` in bytes.

**AES GCM (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t key_buf[] = {
    0xea, 0x4f, 0x6f, 0x3c, 0x2f, 0xed, 0x2b, 0x9d, 0xd9, 0x70, 0x8c, 0x2e, 0x72, 0x1a, 0xe0, 0x0f
  };
  uint8_t nonce_buf[] = {0xf9, 0x75, 0x80, 0x9d, 0xdb, 0x51, 0x72, 0x38, 0x27, 0x45, 0x63, 0x4f};
  uint8_t ad_buf[] = {0x5c, 0x65, 0xd4, 0xf2, 0x61, 0xd2, 0xc5, 0x4f, 0xfe, 0x6a};
  uint8_t plain_msg_buf[] = {0x8d, 0x6c, 0x08, 0x44, 0x6c, 0xb1, 0x0d, 0x9a, 0x20, 0x75};
  uint8_t cipher_tag_buf[32]; // Ciphertext + Tag
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a AES GCM key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_GCM);

  // Import a volatile plain key for AES GCM
  ret = psa_import_key(&key_attr, key_buf, sizeof(key_buf), &key_id);

  // AES GCM encryption and decryption
  // Expected ciphertext: 0f 51 f7 a8 3c 5b 5a a7 96 b9
  // Expected tag: 70 25 9c dd fe 8f 9a 15 a5 c5 eb 48 5a f5 78 fb
  ret = psa_aead_encrypt(key_id, PSA_ALG_GCM,
                          nonce_buf, sizeof(nonce_buf),
                          ad_buf, sizeof(ad_buf),
                          plain_msg_buf, sizeof(plain_msg_buf),
                          cipher_tag_buf, sizeof(cipher_tag_buf),
                          &out_len);

  ret = psa_aead_decrypt(key_id, PSA_ALG_GCM,
                          nonce_buf, sizeof(nonce_buf),
                          ad_buf, sizeof(ad_buf),
                          cipher_tag_buf, out_len,
                          plain_msg_buf, sizeof(plain_msg_buf),
                          &out_len);
                          
  // Destroy a volatile plain key for AES GCM
  ret = psa_destroy_key(key_id);
}
```

> **Notes**:
> 
> - There are two ways to change the GCM authentication tag length (default 16 bytes).
>   1. Replace all AEAD algorithm `PSA_ALG_GCM` with `PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_length)` for the desired size of the authentication tag in bytes.
>   2. Replace the AEAD algorithm `PSA_ALG_GCM in the psa_set_key_algorithm(&key_attr, PSA_ALG_GCM)` function with `PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_GCM, min_tag_length)` to set the minimum authentication tag length in bytes. Replace the AEAD algorithm `PSA_ALG_GCM in psa_aead_encrypt()` and `psa_aead_decrypt()` with `PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_length)` to set the desired tag length `(≥ min_tag_length and ≤ PSA_AEAD_TAG_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_GCM))` in bytes.

**CHACHA20_POLY1305 (One-shot)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t key_buf[] = {
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
  };
  uint8_t nonce_buf[] = {0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47};
  uint8_t ad_buf[] = {0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7};
  uint8_t plain_msg_buf[] = {
    0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
    0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
    0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
    0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
    0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
    0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
    0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
    0x74, 0x2e
  };
  uint8_t cipher_tag_buf[130]; // Ciphertext + Tag
  size_t out_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  
  ret = psa_crypto_init();

  // Set up attributes for a CHACHA20_POLY1305 key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_CHACHA20);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CHACHA20_POLY1305);

  // Import a volatile plain key for CHACHA20_POLY1305
  ret = psa_import_key(&key_attr, key_buf, sizeof(key_buf), &key_id);

  // CHACHA20_POLY1305 encryption
  // Expected ciphertext:
  // d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2 a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6
  // 3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b 1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36
  // 92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58 fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc
  // 3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b 61 16
  // Expected tag: 1a e1 0b 59 4f 09 e2 6a 7e 90 2e cb d0 60 06 91
  ret = psa_aead_encrypt(key_id,
                        PSA_ALG_CHACHA20_POLY1305,
                        nonce_buf,
                        sizeof(nonce_buf),
                        ad_buf,
                        sizeof(ad_buf),
                        plain_msg_buf,
                        sizeof(plain_msg_buf),
                        cipher_tag_buf,
                        sizeof(cipher_tag_buf),
                        &out_len);

  // CHACHA20_POLY1305 decryption
  ret = psa_aead_decrypt(key_id,
                        PSA_ALG_CHACHA20_POLY1305,
                        nonce_buf,
                        sizeof(nonce_buf),
                        ad_buf,
                        sizeof(ad_buf),
                        cipher_tag_buf,
                        out_len,
                        plain_msg_buf,
                        sizeof(plain_msg_buf),
                        &out_len);

  // Destroy a volatile plain key for CHACHA20_POLY1305
  ret = psa_destroy_key(key_id);
}
```

**AES CCM (Streaming)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t key_buf[] = {
    0x9c, 0xde, 0xba, 0xee, 0xe8, 0x69, 0x0b, 0x68, 0x75, 0x10, 0x70, 0x69, 0x1f, 0x49, 0x59, 0x36,
    0x68, 0xa6, 0xde, 0x12, 0xd3, 0xa9, 0x48, 0xb3, 0x8d, 0xdb, 0xd3, 0xf7, 0x52, 0x18, 0xb2, 0xd4
  };
  uint8_t nonce_buf[] = {0xaf, 0x1a, 0x97, 0xd4, 0x31, 0x51, 0xf5, 0xea, 0x9c, 0x48, 0xad, 0x36, 0xa3};
  uint8_t ad_buf[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13
  };
  uint8_t plain_msg_buf[] = {
    0x3c, 0xbb, 0x08, 0xf1, 0x33, 0x27, 0x0e, 0x44, 0x54, 0xbc, 0xaa, 0xa0, 0xf2, 0x0f, 0x6d, 0x63,
    0xc3, 0x8b, 0x65, 0x72, 0xe7, 0x66
  };
  uint8_t cipher_buf[22];
  uint8_t tag_buf[16];
  size_t tag_len;
  size_t out_len;
  uint32_t out_total;
  uint32_t stream_cnt;
  uint32_t stream_block_size = 14;                      // Block size for streaming

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_aead_operation_t aead_op;

  ret = psa_crypto_init();

  // Set up attributes for a AES CCM key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CCM);

  // Import a volatile plain key for AES CCM
  ret = psa_import_key(&key_attr, key_buf, sizeof(key_buf), &key_id);

  // AES CCM stream encryption and decryption
  // Expected ciphertext:
  // 39 66 93 0a 2a e8 fd d8 f4 0e 70 07 f3 fd e0 bd 6e b4 8a 46 e6 d2
  // Expected tag: 7c 0c 1b a4 bf d2 bd 21 5b 0c d9 21 f0 6a 8f 3b
  aead_op = psa_aead_operation_init();
  ret = psa_aead_encrypt_setup(&aead_op, key_id, PSA_ALG_CCM);
  ret = psa_aead_set_lengths(&aead_op, sizeof(ad_buf), sizeof(plain_msg_buf));
  ret = psa_aead_set_nonce(&aead_op, nonce_buf, sizeof(nonce_buf));
  ret = psa_aead_update_ad(&aead_op, ad_buf, sizeof(ad_buf));

  stream_cnt = 0;                                             // Streaming block
  out_total = 0;
  while ((sizeof(plain_msg_buf) - (stream_cnt * stream_block_size)) > stream_block_size) {
    ret = psa_aead_update(&aead_op,
                          plain_msg_buf + (stream_cnt * stream_block_size), stream_block_size,
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          &out_len);
                          stream_cnt++;
    out_total += out_len;
  }
    ret = psa_aead_update(&aead_op,                         // Last block
                          plain_msg_buf + (stream_cnt * stream_block_size),
                          sizeof(plain_msg_buf) - (stream_cnt * stream_block_size),
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          &out_len);
    out_total += out_len;

    ret = psa_aead_finish(&aead_op,                         // Generate tag
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          &out_len,
                          tag_buf, sizeof(tag_buf),
                          &tag_len);
  out_total += out_len;

  aead_op = psa_aead_operation_init();
  ret = psa_aead_decrypt_setup(&aead_op, key_id, PSA_ALG_CCM);
  ret = psa_aead_set_lengths(&aead_op, sizeof(ad_buf), sizeof(plain_msg_buf));
  ret = psa_aead_set_nonce(&aead_op, nonce_buf, sizeof(nonce_buf));
  ret = psa_aead_update_ad(&aead_op, ad_buf, sizeof(ad_buf));

  stream_cnt = 0;                                           // Streaming block
  out_total = 0;
  while ((sizeof(cipher_buf) - (stream_cnt * stream_block_size)) > stream_block_size) {
    ret = psa_aead_update(&aead_op,
                          cipher_buf + (stream_cnt * stream_block_size), stream_block_size,
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len);
                          stream_cnt++;
    out_total += out_len;
  }

    ret = psa_aead_update(&aead_op,                           // Last block
                        cipher_buf + (stream_cnt * stream_block_size),
                        sizeof(cipher_buf) - (stream_cnt * stream_block_size),
                        plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                        &out_len);
    out_total += out_len;
    ret = psa_aead_verify(&aead_op,                           // Verify tag
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len,
                          tag_buf, sizeof(tag_buf));
    out_total += out_len;

    // Destroy a volatile plain key for AES CCM
    ret = psa_destroy_key(key_id);
}
```

**AES GCM (Streaming)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t key_buf[] = {
    0x5f, 0xe0, 0x1c, 0x4b, 0xaf, 0x01, 0xcb, 0xe0, 0x77, 0x96, 0xd5, 0xaa, 0xef, 0x6e, 0xc1, 0xf4,
    0x51, 0x93, 0xa9, 0x8a, 0x22, 0x35, 0x94, 0xae, 0x4f, 0x0e, 0xf4, 0x95, 0x2e, 0x82, 0xe3, 0x30
  };
  uint8_t nonce_buf[] = {0xbd, 0x58, 0x73, 0x21, 0x56, 0x6c, 0x7f, 0x1a, 0x5d, 0xd8, 0x65, 0x2d};
  uint8_t ad_buf[] = {
    0x90, 0x13, 0x61, 0x78, 0x17, 0xdd, 0xa9, 0x47, 0xe1, 0x35, 0xee, 0x6d, 0xd3, 0x65, 0x33, 0x82
  };
  uint8_t plain_msg_buf[] = {
    0x88, 0x1d, 0xc6, 0xc7, 0xa5, 0xd4, 0x50, 0x9f, 0x3c, 0x4b, 0xd2, 0xda, 0xab, 0x08, 0xf1, 0x65,
    0xdd, 0xc2, 0x04, 0x48, 0x9a, 0xa8, 0x13, 0x45, 0x62, 0xa4, 0xea, 0xc3, 0xd0, 0xbc, 0xad, 0x79,
    0x65, 0x84, 0x7b, 0x10, 0x27, 0x33, 0xbb, 0x63, 0xd1, 0xe5, 0xc5, 0x98, 0xec, 0xe0, 0xc3, 0xe5,
    0xda, 0xdd, 0xdd
  };
  uint8_t cipher_buf[51];
  uint8_t tag_buf[16];
  size_t tag_len;
  size_t out_len;
  uint32_t out_total;
  uint32_t stream_cnt;
  uint32_t stream_block_size = 14;                              // Block size for streaming

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;
  psa_aead_operation_t aead_op;

  ret = psa_crypto_init();

  // Set up attributes for a AES GCM key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_GCM);

  // Import a volatile plain key for AES GCM
  ret = psa_import_key(&key_attr, key_buf, sizeof(key_buf), &key_id);

  // AES GCM stream encryption and decryption
  // Expected ciphertext:
  // 16 e3 75 b4 97 3b 33 9d 3f 74 6c 1c 5a 56 8b c7 52 6e 90 9d df f1 e1 9c 95 c9 4a 6c cf f2 10 c9
  // a4 a4 06 79 de 57 60 c3 96 ac 0e 2c eb 12 34 f9 f5 fe 26
  // Expected tag: ab d3 d2 6d 65 a6 27 5f 7a 4f 56 b4 22 ac ab 49
  aead_op = psa_aead_operation_init();
  ret = psa_aead_encrypt_setup(&aead_op, key_id, PSA_ALG_GCM);
  ret = psa_aead_set_nonce(&aead_op, nonce_buf, sizeof(nonce_buf));
  ret = psa_aead_update_ad(&aead_op, ad_buf, sizeof(ad_buf));

  stream_cnt = 0; // Streaming block
  out_total = 0;
  while ((sizeof(plain_msg_buf) - (stream_cnt * stream_block_size)) > stream_block_size) {
    ret = psa_aead_update(&aead_op,
                          plain_msg_buf + (stream_cnt * stream_block_size), stream_block_size,
                          cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                          &out_len);
                          stream_cnt++;
    out_total += out_len;
    }

    ret = psa_aead_update(&aead_op,                                     // Last block
                        plain_msg_buf + (stream_cnt * stream_block_size),
                        sizeof(plain_msg_buf) - (stream_cnt * stream_block_size),
                        cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                        &out_len);
    out_total += out_len;

    ret = psa_aead_finish(&aead_op,                                       // Generate tag
                        cipher_buf + out_total, sizeof(cipher_buf) - out_total,
                        &out_len,
                        tag_buf, sizeof(tag_buf),
                        &tag_len);
    out_total += out_len;

  aead_op = psa_aead_operation_init();
  ret = psa_aead_decrypt_setup(&aead_op, key_id, PSA_ALG_GCM);
  ret = psa_aead_set_nonce(&aead_op, nonce_buf, sizeof(nonce_buf));
  ret = psa_aead_update_ad(&aead_op, ad_buf, sizeof(ad_buf));

  stream_cnt = 0;                                                       // Streaming block
  out_total = 0;
  while ((sizeof(cipher_buf) - (stream_cnt * stream_block_size)) > stream_block_size) {
    ret = psa_aead_update(&aead_op,
                          cipher_buf + (stream_cnt * stream_block_size), stream_block_size,
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len);
                          stream_cnt++;
    out_total += out_len;
  }

    ret = psa_aead_update(&aead_op,                                         // Last block
                          cipher_buf + (stream_cnt * stream_block_size),
                          sizeof(cipher_buf) - (stream_cnt * stream_block_size),
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len);
    out_total += out_len;

    ret = psa_aead_verify(&aead_op,                                         // Verify tag
                          plain_msg_buf + out_total, sizeof(plain_msg_buf) - out_total,
                          &out_len,
                          tag_buf, sizeof(tag_buf));
    out_total += out_len;

    // Destroy a volatile plain key for AES GCM
    ret = psa_destroy_key(key_id);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image26](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image26.png)

The following table describes the implementation status of the PSA Crypto AEAD platform example.

|**Algorithm**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|AES CCM|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|AES GCM|Y|Y|Y|Series 1 devices do not support a 192-bit key.|
|CHACHA20_POLY1305|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|

> **Notes**:
> 
> - The AEAD platform example uses default nonce (12-byte for GCM) and tag length (16-byte for CCM and GCM).
> - The multi-part AEAD operations are only available on GSDK v4.2.0 and higher.
> - The multi-part AEAD operations for CHACHA20_POLY1305 are not yet implemented.
> - The multi-part AEAD operations for a shortened tag length (AES CCM and GCM) are not yet implemented.
> - The multi-part GCM operations do not support non-12-byte nonce (GCM with Non-Recommended IV Lengths).
> - The AEAD platform example for multi-part AEAD operations is pending for fully-featured multi-part AEAD drivers.

##### Key Derivation

A Key Derivation Function (KDF) derives one or many secret keys from a secret value such as a master key, a password, or a pass-phrase using a pseudo-random function. The typical usage of a key derivation function is to use a secret, such as a password or an ECDH shared secret, and a salt to produce a symmetric key and initialization vector (IV) for use with AES.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>HKDF (SHA-1)</p>
            </td>
            <td>
                <p><code>MBEDTLS_MD_SHA1</code></p>
            </td>
            <td>
                <p><code>PSA_ALG_HKDF(PSA_ALG_SHA_1)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>HKDF (SHA-2)</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_MD_SHA224</code><br>
                    • <code>MBEDTLS_MD_SHA256</code><br>
                    • <code>MBEDTLS_MD_SHA384</code><br>
                    • <code>MBEDTLS_MD_SHA512</code>
                </p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_HKDF(PSA_ALG_SHA_224)</code><br>
                    • <code>PSA_ALG_HKDF(PSA_ALG_SHA_256)</code><br>
                    • <code>PSA_ALG_HKDF(PSA_ALG_SHA_384)</code><br>
                    • <code>PSA_ALG_HKDF(PSA_ALG_SHA_512)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PBKDF2 (SHA-1)</p>
            </td>
            <td>
                <p><code>MBEDTLS_MD_SHA1</code></p>
            </td>
            <td>
                <p><code>PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_1)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PBKDF2 (SHA-2)</p>
            </td>
            <td>
                <p>
                    • <code>MBEDTLS_MD_SHA224</code><br>
                    • <code>MBEDTLS_MD_SHA256</code><br>
                    • <code>MBEDTLS_MD_SHA384</code><br>
                    • <code>MBEDTLS_MD_SHA512</code>
                </p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_224)</code><br>
                    • <code>PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)</code><br>
                    • <code>PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_384)</code><br>
                    • <code>PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_512)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>PBKDF2 CMAC</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_PBKDF2_AES_CMAC_PRF_128</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>ECDH + HKDF</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(hash_alg))</code></p>
            </td>
        </tr>
    </tbody>
</table>

**Key Attributes in PSA Crypto**

|**Algorithm**|**Key Type**|**Key Size in Bits**|**Key Usage Flag**|
|---|---|---|---|
|- PSA_ALG_HKDF(PSA_ALG_SHA_1)|PSA_KEY_TYPE_DERIVE|Multiple of 8|PSA_KEY_USAGE_DERIVE|
|- PSA_ALG_HKDF(PSA_ALG_SHA_224)| | | |
|- PSA_ALG_HKDF(PSA_ALG_SHA_256)| | | |
|- PSA_ALG_HKDF(PSA_ALG_SHA_384)| | | |
|- PSA_ALG_HKDF(PSA_ALG_SHA_512)| | | |
|- PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_1)| | | |
|- PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_224)| | | |
|- PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)| | | |
|- PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_384)| | | |
|- PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_512)| | | |
|PSA_ALG_PBKDF2_AES_CMAC_PRF_128| | | |

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_HKDF(PSA_ALG_SHA_1)|HKDF and SHA-1|
|PSA_ALG_HKDF(PSA_ALG_SHA_224)|HKDF and SHA-224|
|PSA_ALG_HKDF(PSA_ALG_SHA_256)|HKDF and SHA-256|
|PSA_ALG_HKDF(PSA_ALG_SHA_384)|HKDF and SHA-384|
|PSA_ALG_HKDF(PSA_ALG_SHA_512)|HKDF and SHA-512|
|PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_1)|PBKDF2 and SHA-1|
|PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_224)|PBKDF2 and SHA-224|
|PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)|PBKDF2 and SHA-256|
|PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_384)|PBKDF2 and SHA-384|
|PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_512)|PBKDF2 and SHA-512|
|PSA_ALG_PBKDF2_AES_CMAC_PRF_128|PBKDF2|
|PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(hash_alg))|ECDH and HKDF and SHA-X|

> **Note**:
> 
> - It should add the components for the derived key algorithm to implement the HKDF. For example, it requires the `CTR Mode` component if the derived key algorithm is `PSA_ALG_CTR`.
> - Refer to [Key Agreement (ECDH)](#key-agreement-ecdh) to add the ECDH components to derive the shared secret for the ECDH + HKDF algorithm (`PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(hash_alg))`).

**Single-Part Functions**

|**Mbed TLS**|**PSA Crypto**|
|---|---|
|int mbedtls_hkdf(…)|psa_status_t sl_psa_key_derivation_single_shot(…)|
|int mbedtls_pkcs5_pbkdf2_hmac(…)|psa_status_t sl_psa_key_derivation_single_shot(…)|

> **Note**: The `sl_psa_key_derivation_single_shot(…)` is a **Silicon Labs custom API**. It can only use on HSE-SVH devices.

**Multi-Part Operations**

|**Mbed TLS**|**PSA Crypto**|
|---|---|
|—|psa_key_derivation_operation_t psa_key_derivation_operation_init(void)|
|—|psa_status_t psa_key_derivation_setup(…)|
|—|psa_status_t psa_key_derivation_get_capacity(…)|
|—|psa_status_t psa_key_derivation_set_capacity(…)|
|—|psa_status_t psa_key_derivation_input_bytes(…)|
|—|psa_status_t psa_key_derivation_input_key(…)|
|—|psa_status_t psa_key_derivation_output_bytes(…)|
|—|psa_status_t psa_key_derivation_output_key(…)|
|—|psa_status_t psa_key_derivation_abort(…)|

> **Note**: The multi-part operation allows the data to be processed for KDF in fragments instead of all at once.

**Quick Reference Examples HKDF (SHA-256)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t hkdf_ikm[] = {
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
  };
  uint8_t hkdf_salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
  uint8_t hkdf_info[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
  uint8_t key_buf[32];
  size_t key_len;
  psa_status_t ret;
  psa_key_id_t master_key_id;
  psa_key_id_t hkdf_key_id;
  psa_key_attributes_t key_attr;
  psa_key_derivation_operation_t kdf_op;

  ret = psa_crypto_init();

  // Set up attributes for a volatile master plain key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_DERIVE);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_HKDF(PSA_ALG_SHA_256));

  // Import a volatile master plain key
  ret = psa_import_key(&key_attr, hkdf_ikm, sizeof(hkdf_ikm), &master_key_id);

  // Set up attributes for a volatile derived plain key (exportable for verification)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, sizeof(key_buf) * 8);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Derive (HKDF SHA256) a volatile plain key for AES CTR
  #if defined(SEMAILBOX_PRESENT) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)

  // Silicon Labs custom API for Secure Vault High devices
  ret = sl_psa_key_derivation_single_shot(PSA_ALG_HKDF(PSA_ALG_SHA_256), master_key_id,
                                          hkdf_info, sizeof(hkdf_info),
                                          hkdf_salt, sizeof(hkdf_salt),
                                          0, &key_attr, &hkdf_key_id);
  #else
  kdf_op = psa_key_derivation_operation_init();
  ret = psa_key_derivation_setup(&kdf_op, PSA_ALG_HKDF(PSA_ALG_SHA_256));
  ret = psa_key_derivation_set_capacity(&kdf_op, sizeof(key_buf));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_SALT, hkdf_salt, sizeof(hkdf_salt));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_INFO, hkdf_info, sizeof(hkdf_info));
  ret = psa_key_derivation_input_key(&kdf_op, PSA_KEY_DERIVATION_INPUT_SECRET, master_key_id);
  ret = psa_key_derivation_output_key(&key_attr, &kdf_op, &hkdf_key_id);
  ret = psa_key_derivation_abort(&kdf_op);
  #endif

  // Export derived volatile plain key (expected value of HKDF SHA256):
  // 3c b2 5f 25 fa ac d5 7a 90 43 4f 64 d0 36 2f 2a 2d 2d 0a 90 cf 1a 5a 4c 5d b0 2d 56 ec c4 c5 bf
  ret = psa_export_key(hkdf_key_id, key_buf, sizeof(key_buf), &key_len);

  // Destroy the master and derived keys
  ret = psa_destroy_key(master_key_id);
  ret = psa_destroy_key(hkdf_key_id);
}
```

**PBKDF2-HMAC-SHA256 (HSE-SVH only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t pbkdf2_ikm[] = {0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64};
  uint8_t pbkdf2_salt[] = {0x73, 0x61, 0x6c, 0x74};
  uint8_t key_buf[32];
  size_t key_len;
  psa_status_t ret;
  psa_key_id_t master_key_id;
  psa_key_id_t pbkdf2_key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();
  // Set up attributes for a volatile master plain key

  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_DERIVE);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256));

  // Import a volatile master plain key
  ret = psa_import_key(&key_attr, pbkdf2_ikm, sizeof(pbkdf2_ikm), &master_key_id);

  // Set up attributes for a volatile derived plain key (exportable for verification)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, sizeof(key_buf) * 8);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Derive (PBKDF2 SHA256 with 4096 iterations) a volatile plain key for AES CTR
  // Silicon Labs custom API for Secure Vault High devices
  ret = sl_psa_key_derivation_single_shot(PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256), master_key_id,
                                          NULL, 0,
                                          pbkdf2_salt, sizeof(pbkdf2_salt),
                                          4096, &key_attr, &pbkdf2_key_id);

  // Export derived volatile plain key (expected value of PBKDF2 SHA256 with 4096 iterations):
  // c5 e4 78 d5 92 88 c8 41 aa 53 0d b6 84 5c 4c 8d 96 28 93 a0 01 ce 4e 11 a4 96 38 73 aa 98 13 4a
  ret = psa_export_key(pbkdf2_key_id, key_buf, sizeof(key_buf), &key_len);

  // Destroy the master and derived keys
  ret = psa_destroy_key(master_key_id);
  ret = psa_destroy_key(pbkdf2_key_id);
}
```

> **Note**: The PBKDF2-HMAC implementation of PSA Crypto is not yet available.

**PBKDF2-AES-CMAC-PRF-128 (HSE-SVH only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t pbkdf2_ikm[] = {0x4a, 0x30, 0x31, 0x4e, 0x4d, 0x45};
  uint8_t pbkdf2_salt[] = {
    0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x37, 0x33, 0x35, 0x63, 0x38, 0x37, 0x62, 0x34, 0x4f, 0x70,
    0x65, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x44, 0x65, 0x6d, 0x6f
  };
  uint8_t key_buf[16];
  size_t key_len;
  psa_status_t ret;
  psa_key_id_t master_key_id;
  psa_key_id_t pbkdf2_key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile master plain key
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_DERIVE);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_PBKDF2_AES_CMAC_PRF_128);

  // Import a volatile master plain key
  ret = psa_import_key(&key_attr, pbkdf2_ikm, sizeof(pbkdf2_ikm), &master_key_id);

  // Set up attributes for a volatile derived plain key (exportable for verification)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, sizeof(key_buf) * 8);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Derive (PBKDF2 AES_CMAC_PRF_128 with 16384 iterations) a volatile plain key for AES CTR
  // Silicon Labs custom API for Secure Vault High devices
  ret = sl_psa_key_derivation_single_shot(PSA_ALG_PBKDF2_AES_CMAC_PRF_128, master_key_id,
                                          NULL, 0,
                                          pbkdf2_salt, sizeof(pbkdf2_salt),
                                          16384, &key_attr, &pbkdf2_key_id);

  // Export derived volatile plain key (expected value of PBKDF2 AES_CMAC_PRF_128 with 16384 iterations):
  // 8b 27 be ed 7e 7a 4d d6 c5 31 38 c8 79 a8 e3 3c
  
  ret = psa_export_key(pbkdf2_key_id, key_buf, sizeof(key_buf), &key_len);

  // Destroy the master and derived keys
  ret = psa_destroy_key(master_key_id);
  ret = psa_destroy_key(pbkdf2_key_id);
}
```

> **Note**:
> 
> - The PBKDF2-AES-CMAC-PRF-128 implementation of PSA Crypto is not yet available.
> - EFR32xG21B (HSE-SVH) devices do not support PBKDF2-AES-CMAC-PRF-128.

**ECDH and HKDF**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t client_private_key[] = {
    0xc8, 0x8f, 0x01, 0xf5, 0x10, 0xd9, 0xac, 0x3f, 0x70, 0xa2, 0x92, 0xda, 0xa2, 0x31, 0x6d, 0xe5,
    0x44, 0xe9, 0xaa, 0xb8, 0xaf, 0xe8, 0x40, 0x49, 0xc6, 0x2a, 0x9c, 0x57, 0x86, 0x2d, 0x14, 0x33
  };
  uint8_t client_public_key[] = { // Uncompressed point format
    0x04, 0xda, 0xd0, 0xb6, 0x53, 0x94, 0x22, 0x1c, 0xf9, 0xb0, 0x51, 0xe1, 0xfe, 0xca, 0x57, 0x87, 0xd0,
    0x98, 0xdf, 0xe6, 0x37, 0xfc, 0x90, 0xb9, 0xef, 0x94, 0x5d, 0x0c, 0x37, 0x72, 0x58, 0x11, 0x80,
    0x52, 0x71, 0xa0, 0x46, 0x1c, 0xdb, 0x82, 0x52, 0xd6, 0x1f, 0x1c, 0x45, 0x6f, 0xa3, 0xe5, 0x9a,
    0xb1, 0xf4, 0x5b, 0x33, 0xac, 0xcf, 0x5f, 0x58, 0x38, 0x9e, 0x05, 0x77, 0xb8, 0x99, 0x0b, 0xb3
  };
  uint8_t server_private_key[] = {
    0xc6, 0xef, 0x9c, 0x5d, 0x78, 0xae, 0x01, 0x2a, 0x01, 0x11, 0x64, 0xac, 0xb3, 0x97, 0xce, 0x20,
    0x88, 0x68, 0x5d, 0x8f, 0x06, 0xbf, 0x9b, 0xe0, 0xb2, 0x83, 0xab, 0x46, 0x47, 0x6b, 0xee, 0x53
  };
  uint8_t server_public_key[] = { // Uncompressed point format
    0x04, 0xd1, 0x2d, 0xfb, 0x52, 0x89, 0xc8, 0xd4, 0xf8, 0x12, 0x08, 0xb7, 0x02, 0x70, 0x39, 0x8c, 0x34,
    0x22, 0x96, 0x97, 0x0a, 0x0b, 0xcc, 0xb7, 0x4c, 0x73, 0x6f, 0xc7, 0x55, 0x44, 0x94, 0xbf, 0x63,
    0x56, 0xfb, 0xf3, 0xca, 0x36, 0x6c, 0xc2, 0x3e, 0x81, 0x57, 0x85, 0x4c, 0x13, 0xc5, 0x8d, 0x6a,
    0xac, 0x23, 0xf0, 0x46, 0xad, 0xa3, 0x0f, 0x83, 0x53, 0xe7, 0x4f, 0x33, 0x03, 0x98, 0x72, 0xab
  };
  uint8_t hkdf_salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
  uint8_t hkdf_info[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
  uint8_t key_buf[32];
  size_t key_len;

  psa_status_t ret;
  psa_key_id_t master_key_id;
  psa_key_id_t hkdf_key_id;
  psa_key_attributes_t key_attr;
  psa_key_derivation_operation_t kdf_op;

  ret = psa_crypto_init();

  // Set up attributes for a volatile master plain key (algorithm for ECDH and HKDF)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)));

  // Import a volatile master plain key (client private key)
  ret = psa_import_key(&key_attr, client_private_key, sizeof(client_private_key),
  &master_key_id);

  // Set up attributes for a volatile derived plain key (exportable for verification)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, sizeof(key_buf) * 8);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Derive (HKDF SHA256) a volatile plain key from ECDH shared secret (server public key) for AES CTR
  kdf_op = psa_key_derivation_operation_init();
  ret = psa_key_derivation_setup(&kdf_op, PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)));
  ret = psa_key_derivation_set_capacity(&kdf_op, sizeof(key_buf));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_SALT, hkdf_salt, sizeof(hkdf_salt));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_INFO, hkdf_info, sizeof(hkdf_info));
  ret = psa_key_derivation_key_agreement(&kdf_op, PSA_KEY_DERIVATION_INPUT_SECRET, master_key_id, server_public_key,
  sizeof(server_public_key));
  ret = psa_key_derivation_output_key(&key_attr, &kdf_op, &hkdf_key_id);
  ret = psa_key_derivation_abort(&kdf_op);

  // Export derived volatile plain key (client shared secret):
  // B7 CA BD A7 42 60 DE D5 4C 4C 11 FA BC A3 56 4B 77 35 CC 9F 89 E9 BF E8 08 24 8A F3 54 99 B0 55
  ret = psa_export_key(hkdf_key_id, key_buf, sizeof(key_buf), &key_len);

  // Destroy the master and derived keys
  ret = psa_destroy_key(master_key_id);
  ret = psa_destroy_key(hkdf_key_id);

  // Set up attributes for a volatile master plain key (algorithm for ECDH and HKDF)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)));

  // Import a volatile master plain key (server private key)
  ret = psa_import_key(&key_attr, server_private_key, sizeof(server_private_key),
                      &master_key_id);

  // Set up attributes for a volatile derived plain key (exportable for verification)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
  psa_set_key_bits(&key_attr, sizeof(key_buf) * 8);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  psa_set_key_algorithm(&key_attr, PSA_ALG_CTR);

  // Derive (HKDF SHA256) a volatile plain key from ECDH shared secret (client public key) for AES CTR
  kdf_op = psa_key_derivation_operation_init();
  ret = psa_key_derivation_setup(&kdf_op, PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)));
  ret = psa_key_derivation_set_capacity(&kdf_op, sizeof(key_buf));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_SALT, hkdf_salt, sizeof(hkdf_salt));
  ret = psa_key_derivation_input_bytes(&kdf_op, PSA_KEY_DERIVATION_INPUT_INFO, hkdf_info, sizeof(hkdf_info));
  ret = psa_key_derivation_key_agreement(&kdf_op, PSA_KEY_DERIVATION_INPUT_SECRET, master_key_id, client_public_key,
                                        sizeof(client_public_key));
  ret = psa_key_derivation_output_key(&key_attr, &kdf_op, &hkdf_key_id);
  ret = psa_key_derivation_abort(&kdf_op);

  // Export derived volatile plain key (server shared secret):
  // B7 CA BD A7 42 60 DE D5 4C 4C 11 FA BC A3 56 4B 77 35 CC 9F 89 E9 BF E8 08 24 8A F3 54 99 B0 55
  ret = psa_export_key(hkdf_key_id, key_buf, sizeof(key_buf), &key_len);

  // Destroy the master and derived keys
  ret = psa_destroy_key(master_key_id);
  ret = psa_destroy_key(hkdf_key_id);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image27](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image27.png)

The following table describes the implementation status of the PSA Crypto KDF platform example.

|**Algorithm**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|HKDF|Y|Y|Y|Hardware acceleration only on HSE-SVH devices with Silicon Labs custom API.|
|ECDH + HKDF|Y|Y|Y|Hardware acceleration (HKDF) only on HSE-SVH devices with Silicon Labs custom API.|

> **Note**:
> 
> - The PBKDF2 implementation of PSA Crypto is not yet available.
> - The ECDH + HKDF algorithm does not apply to the [wrapped key](04-key-management-in-psa-crypto#key-lifetimes).

##### Asymmetric Cryptographic Operation

###### Asymmetric Signature (ECDSA and EdDSA)

In modern cryptography, the Elliptic-Curve-based signatures (like ECDSA and EdDSA) are widely used because of shorter key lengths, shorter signature lengths, higher security levels (for the same key length), and better performance.

The Elliptic Curve Digital Signature Algorithm (ECDSA) is a cryptographically secure digital signature scheme based on the Elliptic Curve Cryptography (ECC). The Edwards-curve Digital Signature Algorithm (EdDSA) is a fast digital signature algorithm, using elliptic curves in Edwards form (like Ed25519 and Ed448).

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>ECDSA (SHA-1)</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_ECDSA(PSA_ALG_SHA_1)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>ECDSA (SHA-2)</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p>
                    • <code>PSA_ALG_ECDSA(PSA_ALG_SHA_224)</code><br>
                    • <code>PSA_ALG_ECDSA(PSA_ALG_SHA_256)</code><br>
                    • <code>PSA_ALG_ECDSA(PSA_ALG_SHA_384)</code><br>
                    • <code>PSA_ALG_ECDSA(PSA_ALG_SHA_512)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>ECDSA (Any hash algorithm)</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>ECDSA (No hashing)</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_ECDSA_ANY</code></p>
            </td>
        </tr>
        <tr>
            <td>
                <p>EdDSA</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p><code>PSA_ALG_PURE_EDDSA</code></p>
            </td>
        </tr>
    </tbody>
</table>

> **Note**: The hash-and-sign algorithms `(PSA_ALG_ECDSA(hash_alg)` and `PSA_ALG_ECDSA(PSA_ALG_ANY_HASH))` include the hashing step for ECDSA.

**Key Attributes in PSA Crypto**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Key Size in Bits</strong></th>
            <th><strong>Key Usage Flag</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>PSA_ALG_ECDSA_ANY</code></td>
            <td><code>PSA_ECC_FAMILY_SECP_R1</code></td>
            <td>
                secp192r1 : 192<br>
                secp224r1 : 224<br>
                secp256r1 : 256<br>
                secp384r1 : 384<br>
                secp521r1 : 521
            </td>
            <td>
                <code>PSA_KEY_USAGE_SIGN_HASH</code><br>
                <code>PSA_KEY_USAGE_VERIFY_HASH</code>
            </td>
        </tr>
        <tr>
            <td></td>
            <td><code>PSA_ECC_FAMILY_SECP_K1</code></td>
            <td>secp256k1 : 256</td>
            <td></td>
        </tr>
        <tr>
            <td>
                <code>PSA_ALG_ECDSA(PSA_ALG_SHA_1)</code><br>
                <code>PSA_ALG_ECDSA(PSA_ALG_SHA_224)</code><br>
                <code>PSA_ALG_ECDSA(PSA_ALG_SHA_256)</code><br>
                <code>PSA_ALG_ECDSA(PSA_ALG_SHA_384)</code><br>
                <code>PSA_ALG_ECDSA(PSA_ALG_SHA_512)</code><br>
                <code>PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)</code>
            </td>
            <td><code>PSA_ECC_FAMILY_SECP_R1</code></td>
            <td>
                secp192r1 : 192<br>
                secp224r1 : 224<br>
                secp256r1 : 256<br>
                secp384r1 : 384<br>
                secp521r1 : 521
            </td>
            <td>
                <code>PSA_KEY_USAGE_SIGN_MESSAGE</code><br>
                <code>PSA_KEY_USAGE_VERIFY_MESSAGE</code>
            </td>
        </tr>
        <tr>
            <td></td>
            <td><code>PSA_ECC_FAMILY_SECP_K1</code></td>
            <td>secp256k1 : 256</td>
            <td></td>
        </tr>
        <tr>
            <td><code>PSA_ALG_PURE_EDDSA</code></td>
            <td><code>PSA_ECC_FAMILY_TWISTED_EDWARDS</code></td>
            <td>Edwards25519 : 255</td>
            <td>
                <code>PSA_KEY_USAGE_SIGN_MESSAGE</code><br>
                <code>PSA_KEY_USAGE_VERIFY_MESSAGE</code>
            </td>
        </tr>
    </tbody>
</table>

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_ECDSA_ANY|ECDSA|
|PSA_ALG_ECDSA(PSA_ALG_SHA_1)|ECDSA and SHA-1|
|PSA_ALG_ECDSA(PSA_ALG_SHA_224)|ECDSA and SHA-224|
|PSA_ALG_ECDSA(PSA_ALG_SHA_256)|ECDSA and SHA-256|
|PSA_ALG_ECDSA(PSA_ALG_SHA_384)|ECDSA and SHA-384|
|PSA_ALG_ECDSA(PSA_ALG_SHA_512)|ECDSA and SHA-512|
|PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)|ECDSA and SHA-X|

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_PURE_EDDSA|EdDSA|

|**PSA_ECC_FAMILY_SECP_R1**|**Security Software Components**|
|---|---|
|secp192r1|secp192r1|
|secp224r1|secp224r1|
|secp256r1|secp256r1|
|secp384r1|secp384r1|
|secp521r1|secp521r1|

|**PSA_ECC_FAMILY_SECP_K1**|**Security Software Components**|
|---|---|
|secp256k1|secp256k1|

|**PSA_ECC_FAMILY_TWISTED_EDWARDS**|**Security Software Components**|
|---|---|
|Edwards25519|edwards25519|

|**Built-in Key**|**Security Software Components**|
|---|---|
|secp256r1 keys in SE OTP|Built-In Keys|

**Functions**

<table>
    <thead>
        <tr>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>Hash-and-sign<br>—</p>
            </td>
            <td>
                <p>Hash-and-sign<br>
                    <code>psa_status_t psa_sign_message(…)</code><br>
                    <code>psa_status_t psa_verify_message(…)</code>
                </p>
            </td>
        </tr>
        <tr>
            <td>
                <p>Precomputed hash<br>
                    <code>int mbedtls_ecdsa_write_signature(…)</code><br>
                    <code>int mbedtls_ecdsa_read_signature(…)</code>
                </p>
            </td>
            <td>
                <p>Precomputed hash<br>
                    <code>psa_status_t psa_sign_hash(…)</code><br>
                    <code>psa_status_t psa_verify_hash(…)</code>
                </p>
            </td>
        </tr>
    </tbody>
</table>

**Quick Reference Examples**

**ECDSA on secp256r1 (Precomputed Hash)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t hash_data[] = {
    0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
    0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
  };
  uint8_t public_key[65]; // Uncompressed point format
  size_t pubkey_len;
  uint8_t signature_buf[64];
  size_t signature_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile private plain key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_bits(&key_attr, 256);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);

  // Generate a random volatile private plain key
  ret = psa_generate_key(&key_attr, &key_id);

  // Sign a hash with a volatile private plain key
  ret = psa_sign_hash(key_id,
                      PSA_ALG_ECDSA_ANY,
                      hash_data,
                      sizeof(hash_data),
                      signature_buf,
                      sizeof(signature_buf),
                      &signature_len);

  // Verify a signature with a volatile private plain key
  ret = psa_verify_hash(key_id,
                        PSA_ALG_ECDSA_ANY,
                        hash_data,
                        sizeof(hash_data),
                        signature_buf,
                        signature_len);

  // Export a public key from a volatile private plain key and then destroy the private key
  ret = psa_export_public_key(key_id,
                              public_key,
                              sizeof(public_key),
                              &pubkey_len);

  ret = psa_destroy_key(key_id);

  // Set up attributes for a public key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);

  // Import a public key
  ret = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);

  // Verify a signature with a public key and then destroy the public key
  ret = psa_verify_hash(key_id,
                        PSA_ALG_ECDSA_ANY,
                        hash_data,
                        sizeof(hash_data),
                        signature_buf,
                        signature_len);

  ret = psa_destroy_key(key_id);
}
```

**ECDSA on secp256r1 (Hash-and-Sign)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t ecdsa_msg[] = {
    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
    0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
    0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
  };
  uint8_t public_key[65];                                     // Uncompressed point format
  size_t pubkey_len;
  uint8_t signature_buf[64];
  size_t signature_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile private plain key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_bits(&key_attr, 256);
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));

  // Generate a random volatile private plain key
  ret = psa_generate_key(&key_attr, &key_id);

  // Hash-and-Sign (SHA-256) a message with a volatile private plain key
  ret = psa_sign_message(key_id,
                        PSA_ALG_ECDSA(PSA_ALG_SHA_256),
                        ecdsa_msg,
                        sizeof(ecdsa_msg),
                        signature_buf,
                        sizeof(signature_buf),
                        &signature_len);

  // Hash (SHA-256) a message and verify a signature with a volatile private plain key
  ret = psa_verify_message(key_id,
                          PSA_ALG_ECDSA(PSA_ALG_SHA_256),
                          ecdsa_msg,
                          sizeof(ecdsa_msg),
                          signature_buf,
                          signature_len);

  // Export a public key from a volatile private plain key and then destroy the private key
  ret = psa_export_public_key(key_id,
                              public_key,
                              sizeof(public_key),
                              &pubkey_len);

  ret = psa_destroy_key(key_id);

  // Set up attributes for a public key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));

  // Import a public key
  ret = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);

  // Hash (SHA-256) and verify a signature with a public key and then destroy the public key
  ret = psa_verify_message(key_id,
                          PSA_ALG_ECDSA(PSA_ALG_SHA_256),
                          ecdsa_msg,
                          sizeof(ecdsa_msg),
                          signature_buf,
                          signature_len);

  ret = psa_destroy_key(key_id);
}
```

**ECDSA with Built-in Private Device Key (HSE-SVH only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
 uint8_t hash_data[] = {
  0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
  0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
 };
 uint8_t public_key[65];                                  // Uncompressed point format
 size_t pubkey_len;
 uint8_t signature_buf[64];
 size_t signature_len;

 psa_status_t ret;
 psa_key_id_t key_id;
 psa_key_attributes_t key_attr;

 ret = psa_crypto_init();

 // Sign a hash with a built-in private device key
 ret = psa_sign_hash(SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID,
                    PSA_ALG_ECDSA_ANY,
                    hash_data,
                    sizeof(hash_data),
                    signature_buf,
                    sizeof(signature_buf),
                    &signature_len);

 // Verify a signature with a built-in private device key
 ret = psa_verify_hash(SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID,
                      PSA_ALG_ECDSA_ANY,
                      hash_data,
                      sizeof(hash_data),
                      signature_buf,
                      signature_len);

 // Export a built-in public device key
 ret = psa_export_public_key(SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID,
                            public_key,
                            sizeof(public_key),
                            &pubkey_len);

 // Set up attributes for a public device key
 key_attr = psa_key_attributes_init();
 psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
 psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA_ANY);

 // Import a public device key
 ret = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);

 // Verify a signature with a public device key
 ret = psa_verify_hash(key_id,
                      PSA_ALG_ECDSA_ANY,
                      hash_data,
                      sizeof(hash_data),
                      signature_buf,
                      signature_len);

 // Destroy a public device key
 ret = psa_destroy_key(key_id);
#endif
}
```

**EdDSA on Ed25519 (HSE only)**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
#if defined(SEMAILBOX_PRESENT)
  uint8_t eddsa_msg[] = {
    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
    0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
    0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
  };
  uint8_t ed25519_private[] = {
    0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
    0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
  };
  uint8_t ed25519_public[] = {
    0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
    0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
  };
  uint8_t signature_buf[64];
  size_t signature_len;

  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile private plain key (Ed25519)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA);

  // Import a volatile private plain key
  ret = psa_import_key(&key_attr, ed25519_private, sizeof(ed25519_private), &key_id);

  // Hash-and-Sign a message with a volatile private plain key (expected EdDSA signature):
  // dc 2a 44 59 e7 36 96 33 a5 2b 1b f2 77 83 9a 00 20 10 09 a3 ef bf 3e cb 69 be a2 18 6c 26 b5 89
  // 09 35 1f c9 ac 90 b3 ec fd fb c7 c6 64 31 e0 30 3d ca 17 9c 13 8a c1 7a d9 be f1 17 73 31 a7 04
  ret = psa_sign_message(key_id,
                        PSA_ALG_PURE_EDDSA,
                        eddsa_msg,
                        sizeof(eddsa_msg),
                        signature_buf,
                        sizeof(signature_buf),
                        &signature_len);

  // Destroy a volatile private plain key
  ret = psa_destroy_key(key_id);

  // Set up attributes for a public key (Ed25519)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA);

  // Import a public key
  ret = psa_import_key(&key_attr, ed25519_public, sizeof(ed25519_public), &key_id);

  // Hash a message and verify the signature with a public key
  ret = psa_verify_message(key_id,
                          PSA_ALG_PURE_EDDSA,
                          eddsa_msg,
                          sizeof(eddsa_msg),
                          signature_buf,
                          signature_len);

  // Destroy a public key
  ret = psa_destroy_key(key_id);
#endif
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image28](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image28.png)

The following table describes the implementation status of the PSA Crypto DSA platform example.

|**ECC Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|secp192r1|Y|Y|Y|—|
|secp256r1|Y|Y|Y|—|
|secp384r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|secp521r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|Edwards25519|—|—|Y|Only on HSE devices with hardware acceleration.|
|Public Sign Key|—|—|Y|—|
|Public Command Key|—|—|Y|—|
|Private Device Key|—|—|Y|Only on HSE-SVH devices.|

> **Note**:
> 
> - This example does not include secp224r1 and secp256k1. The secp256k1 ECDSA on HSE devices is not yet implemented.
> - The PSA Crypto does not yet support software fallback on the Edwards25519.
> - The HSE-SVM devices require SE firmware v1.2.11 or higher (EFR32xG21) and v2.1.7 or higher (other HSE devices) to support hardware acceleration on Edwards25519. This feature also requires GSDK v4.0.1 or higher.

##### Key Agreement (ECDH)

The Elliptic Curve Diffie-Hellman (ECDH) is an anonymous key agreement protocol that allows two parties, each having an elliptic-curve private-public key pair, to establish a shared secret over an insecure channel.

**Algorithms**

|**Algorithm**|**Mbed TLS**|**PSA Crypto**|
|---|---|---|
|ECDH|—|PSA_ALG_ECDH|
|ECDH and HKDF|—|PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(hash_alg))|

**Key Attributes in PSA Crypto**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Key Type</strong></th>
            <th><strong>Key Size in Bits</strong></th>
            <th><strong>Key Usage Flag</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>PSA_ALG_ECDH</p>
            </td>
            <td>
                <p>PSA_ECC_FAMILY_SECP_R1</p>
            </td>
            <td>
                <p>
                    • secp192r1 : 192<br>
                    • secp224r1 : 224<br>
                    • secp256r1 : 256<br>
                    • secp384r1 : 384<br>
                    • secp521r1 : 521
                </p>
            </td>
            <td>
                <p>PSA_KEY_USAGE_DERIVE</p>
            </td>
        </tr>
        <tr>
            <td></td>
            <td>
                <p>PSA_ECC_FAMILY_SECP_K1</p>
            </td>
            <td>
                <p>secp256k1 : 256</p>
            </td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>
                <p>PSA_ECC_FAMILY_MONTGOMERY</p>
            </td>
            <td>
                <p>
                    • Curve25519 : 255<br>
                    • Curve448 : 448
                </p>
            </td>
            <td></td>
        </tr>
    </tbody>
</table>

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_ECDH|ECDH|

|**PSA_ECC_FAMILY_SECP_R1**|**Security Software Components**|
|---|---|
|secp192r1|secp192r1|
|secp224r1|secp224r1|
|secp256r1|secp256r1|
|secp384r1|secp384r1|
|secp521r1|secp521r1|

|**PSA_ECC_FAMILY_SECP_K1**|**Security Software Components**|
|---|---|
|secp256k1|secp256k1|

|**PSA_ECC_FAMILY_MONTGOMERY**|**Security Software Components**|
|---|---|
|Curve25519|Curve25519|
|Curve448|Curve448|

**Functions**

|**Mbed TLS**|**PSA Crypto**|
|---|---|
|int mbedtls_ecdh_compute_shared(…)|psa_status_t psa_raw_key_agreement(…)|
|—|psa_status_t psa_key_derivation_key_agreement(…)|

> **Note**: For the `psa_key_derivation_key_agreement(…)` function, refer to the PSA Crypto [KDF](#key-derivation) quick reference (ECDH and HKDF) and platform examples for details.

**Quick Reference Examples ECDH on secp256r1**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t client_private_key[] = {
    0xc8, 0x8f, 0x01, 0xf5, 0x10, 0xd9, 0xac, 0x3f, 0x70, 0xa2, 0x92, 0xda, 0xa2, 0x31, 0x6d, 0xe5,
    0x44, 0xe9, 0xaa, 0xb8, 0xaf, 0xe8, 0x40, 0x49, 0xc6, 0x2a, 0x9c, 0x57, 0x86, 0x2d, 0x14, 0x33
  };

  uint8_t client_public_key[] = { // Uncompressed point format
    0x04, 0xda, 0xd0, 0xb6, 0x53, 0x94, 0x22, 0x1c, 0xf9, 0xb0, 0x51, 0xe1, 0xfe, 0xca, 0x57, 0x87, 0xd0,
    0x98, 0xdf, 0xe6, 0x37, 0xfc, 0x90, 0xb9, 0xef, 0x94, 0x5d, 0x0c, 0x37, 0x72, 0x58, 0x11, 0x80,
    0x52, 0x71, 0xa0, 0x46, 0x1c, 0xdb, 0x82, 0x52, 0xd6, 0x1f, 0x1c, 0x45, 0x6f, 0xa3, 0xe5, 0x9a,
    0xb1, 0xf4, 0x5b, 0x33, 0xac, 0xcf, 0x5f, 0x58, 0x38, 0x9e, 0x05, 0x77, 0xb8, 0x99, 0x0b, 0xb3
  };

  uint8_t server_private_key[] = {
    0xc6, 0xef, 0x9c, 0x5d, 0x78, 0xae, 0x01, 0x2a, 0x01, 0x11, 0x64, 0xac, 0xb3, 0x97, 0xce, 0x20,
    0x88, 0x68, 0x5d, 0x8f, 0x06, 0xbf, 0x9b, 0xe0, 0xb2, 0x83, 0xab, 0x46, 0x47, 0x6b, 0xee, 0x53
  };

  uint8_t server_public_key[] = { // Uncompressed point format
    0x04, 0xd1, 0x2d, 0xfb, 0x52, 0x89, 0xc8, 0xd4, 0xf8, 0x12, 0x08, 0xb7, 0x02, 0x70, 0x39, 0x8c, 0x34,
    0x22, 0x96, 0x97, 0x0a, 0x0b, 0xcc, 0xb7, 0x4c, 0x73, 0x6f, 0xc7, 0x55, 0x44, 0x94, 0xbf, 0x63,
    0x56, 0xfb, 0xf3, 0xca, 0x36, 0x6c, 0xc2, 0x3e, 0x81, 0x57, 0x85, 0x4c, 0x13, 0xc5, 0x8d, 0x6a,
    0xac, 0x23, 0xf0, 0x46, 0xad, 0xa3, 0x0f, 0x83, 0x53, 0xe7, 0x4f, 0x33, 0x03, 0x98, 0x72, 0xab
  };

  // Expected shared secret:
  // d6 84 0f 6b 42 f6 ed af d1 31 16 e0 e1 25 65 20 2f ef 8e 9e ce 7d ce 03 81 24 64 d0 4b 94 42 de
  uint8_t shared_secret_buf[32];
  size_t shared_secret_len;
  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile client private plain key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);

  // Import a volatile client private plain key
  ret = psa_import_key(&key_attr, client_private_key, sizeof(client_private_key), &key_id);

  // Perform a key agreement with the server public key and then destroy the client private key
  ret = psa_raw_key_agreement(PSA_ALG_ECDH,
                              key_id,
                              server_public_key,
                              sizeof(server_public_key),
                              shared_secret_buf,
                              sizeof(shared_secret_buf),
                              &shared_secret_len);

  ret = psa_destroy_key(key_id);

  // Set up attributes for a volatile server private plain key (secp256r1)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);

  // Import a volatile server private plain key
  ret = psa_import_key(&key_attr, server_private_key, sizeof(server_private_key), &key_id);

  // Perform a key agreement with the client public key and then destroy the server private key
  ret = psa_raw_key_agreement(PSA_ALG_ECDH,
                              key_id,
                              client_public_key,
                              sizeof(client_public_key),
                              shared_secret_buf,
                              sizeof(shared_secret_buf),
                              &shared_secret_len);

  ret = psa_destroy_key(key_id);
}
```

**ECDH on Curve25519**

```c++
#include "psa/crypto.h"

void app_process_action(void)
{
  uint8_t client_private_key[] = {
    0xB0, 0x76, 0x51, 0xEA, 0x20, 0xF0, 0x28, 0xA8,0x16, 0xEE, 0x01, 0xB0, 0xD1, 0x06, 0x2A, 0x7C,
    0x81, 0x58, 0xE8, 0x84, 0xE9, 0xBC, 0xC6, 0x1C, 0x5D, 0xAB, 0xDB, 0x4E, 0x38, 0x2F, 0x96, 0x69,
  };

  uint8_t client_public_key[] = {
    0x87, 0xD8, 0x6B, 0xDA, 0xAC, 0x38, 0x3C, 0x85, 0xA6, 0xBC, 0xF8, 0xFC, 0xC6, 0x26, 0xD6, 0x14,
    0x36, 0xE4, 0x8F, 0xDB, 0xFA, 0x5A, 0x45, 0xFE, 0x0C, 0x9E, 0xA8, 0x4B, 0x35, 0x3E, 0xF1, 0x37,
  };

  uint8_t server_private_key[] = {
    0x98, 0x2E, 0xB6, 0x7D, 0x0A, 0x01, 0x57, 0x90, 0xE1, 0x45, 0xF3, 0x67, 0xF6, 0xDA, 0xA6, 0x44,
    0x2C, 0x87, 0xC0, 0xED, 0x3C, 0x36, 0x71, 0xA6, 0x89, 0xC7, 0x49, 0xAC, 0x0D, 0xFE, 0x43, 0x6E,
  };

  uint8_t server_public_key[] = {
    0x0C, 0x04, 0x10, 0x5B, 0xE8, 0x7C, 0xAB, 0x37, 0x21, 0x15, 0x7A, 0x8D, 0x49, 0x85, 0x8C, 0x7A,
    0x9F, 0xC1, 0x46, 0xDA, 0xCC, 0x96, 0xEF, 0x6E, 0xD4, 0xDA, 0x71, 0xBF, 0xED, 0x32, 0x0D, 0x76,
  };

  // Expected shared secret:
  // F2 E6 0E 1C B7 64 BC 48 F2 9D BB 12 FB 12 17 31 32 1D 79 AF 0A 9F AB AD 34 05 A2 07 39 9C 5F 15
  uint8_t shared_secret_buf[32];
  size_t shared_secret_len;
  psa_status_t ret;
  psa_key_id_t key_id;
  psa_key_attributes_t key_attr;

  ret = psa_crypto_init();

  // Set up attributes for a volatile client private plain key (Curve25519)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);

  // Import a volatile client private plain key
  ret = psa_import_key(&key_attr, client_private_key, sizeof(client_private_key), &key_id);

  // Perform a key agreement with server public key
  ret = psa_raw_key_agreement(PSA_ALG_ECDH,
                              key_id,
                              server_public_key,
                              sizeof(server_public_key),
                              shared_secret_buf,
                              sizeof(shared_secret_buf),
                              &shared_secret_len);

  // Destroy the client private key
  ret = psa_destroy_key(key_id);

  // Set up attributes for a volatile server private plain key (Curve25519)
  key_attr = psa_key_attributes_init();
  psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY));
  psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_DERIVE);
  psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);

  // Import a volatile server private plain key
  ret = psa_import_key(&key_attr, server_private_key, sizeof(server_private_key), &key_id);

  // Perform a key agreement with client public key
  ret = psa_raw_key_agreement(PSA_ALG_ECDH,
                              key_id,
                              client_public_key,
                              sizeof(client_public_key),
                              shared_secret_buf,
                              sizeof(shared_secret_buf),
                              &shared_secret_len);

  // Destroy the server private key
  ret = psa_destroy_key(key_id);
}
```

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image29](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image29.png)

The following table describes the implementation status of the PSA Crypto ECDH platform example.

|**ECC Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|secp192r1|Y|Y|Y|—|
|secp256r1|Y|Y|Y|—|
|secp384r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|secp521r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|Curve25519|Y|Y|Y|Hardware acceleration only on HSE devices.|
|Curve448|—|—|Y|Only on HSE-SVH devices with hardware acceleration.|

> **Note**:
> 
> - This example does not include secp224r1 and secp256k1. The secp256k1 ECDH on HSE devices is not yet implemented.
> - The PSA Crypto does not yet support software fallback on the Curve448.
> - The HSE-SVM devices require SE firmware v1.2.11 or higher (EFR32xG21) and v2.1.7 or higher (other HSE devices) to support hardware acceleration on Curve25519. This feature also requires GSDK v4.0.1 or higher.

##### X.509 Certificate

An X.509 certificate is a digital certificate that uses the widely accepted international X.509 public key infrastructure (PKI) standard to verify that a public key belongs to the user, computer, or service identity contained within the certificate.

An X.509 certificate contains a public key and an identity (a hostname, an organization, an individual). It is either signed by a certificate authority or self-signed. When a certificate is signed by a trusted certificate authority or validated by other means, someone holding that certificate can rely on the public key it contains to establish secure communications with another party or validate documents digitally signed by the corresponding private key.

**Algorithms**

<table>
    <thead>
        <tr>
            <th><strong>Algorithm</strong></th>
            <th><strong>Mbed TLS</strong></th>
            <th><strong>PSA Crypto</strong></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>ECDSA (SHA-2)</p>
            </td>
            <td>
                <p>—</p>
            </td>
            <td>
                <p>
                    PSA_ALG_ECDSA(PSA_ALG_SHA_224)<br>
                    PSA_ALG_ECDSA(PSA_ALG_SHA_256)<br>
                    PSA_ALG_ECDSA(PSA_ALG_SHA_384)<br>
                    PSA_ALG_ECDSA(PSA_ALG_SHA_512)
                </p>
            </td>
        </tr>
    </tbody>
</table>

**Key Attributes in PSA Crypto**

|**Algorithm**|**Key Type**|**Key Size in Bits**|**Key Usage Flag**|
|---|---|---|---|
|• PSA_ALG_ECDSA(PSA_ALG_SHA_224)|PSA_ECC_FAMILY_SECP_R1|• secp192r1 : 192|• PSA_KEY_USAGE_SIGN_HASH|
|• PSA_ALG_ECDSA(PSA_ALG_SHA_256)| |• secp256r1 : 256|• PSA_KEY_USAGE_VERIFY_HASH|
|• PSA_ALG_ECDSA(PSA_ALG_SHA_384)| |• secp384r1 : 384| |
|• PSA_ALG_ECDSA(PSA_ALG_SHA_512)| |• secp521r1 : 521| |

> **Note**: The key usage flag must use PSA_KEY_USAGE_SIGN_HASH and PSA_KEY_USAGE_VERIFY_HASH.

**Security Software Components**

|**Algorithm**|**Security Software Components**|
|---|---|
|PSA_ALG_ECDSA(PSA_ALG_SHA_224)|ECDSA and SHA-224|
|PSA_ALG_ECDSA(PSA_ALG_SHA_256)|ECDSA amd SHA-256|
|PSA_ALG_ECDSA(PSA_ALG_SHA_384)|ECDSA and SHA-384|
|PSA_ALG_ECDSA(PSA_ALG_SHA_512)|ECDSA and SHA-512|

|**PSA_ECC_FAMILY_SECP_R1**|**Security Software Components**|
|---|---|
|secp192r1|secp192r1|
|secp256r1|secp256r1|
|secp384r1|secp384r1|
|secp521r1|secp521r1|

|**Built-in Key**|**Security Software Components**|
|---|---|
|secp256r1 keys in SE OTP|Built-In Keys|

|**Item**|**Security Software Components**|
|---|---|
|SHA-1 for X.509 certificate|SHA-1|

|**Item**|**Security Software Components**|
|---|---|
|X.509 certificate support|X.509|

**Using Opaque ECDSA Key to Generate Certificate Signing Request (CSR)**

1. Declare (and allocate) an object of type `mbedtls_pk_context` (PK context) and an object of type `psa_key_id_t` (key identifier).
2. Use the key identifier to generate an ECDSA key or load the built-in ECDSA key. Refer to the [Asymmetric Key](#asymmetric-key) for details.
3. Set up the PK context to wrap that PSA key by calling `mbedtls_pk_setup_opaque(mbedtls_pk_context \*ctx, const psa_key_id_t key)`.
4. Configure the pending CSR object to use that key by calling `mbedtls_x509write_csr_set_key(mbedtls_x509write_csr \*ctx, mbedtls_pk_context \*key)` on that PK context.
5. Call any other function that needs to configure and generate the CSR.
6. After generating the CSR, free the PK context using `mbedtls_pk_free(mbedtls_pk_context \*ctx)`. It only frees the PK context itself and leaves the key identifier untouched.
7. Either keep using the key identifier or call `psa_destroy_key()` on it, depending on the application flow.

**PSA Crypto Platform Example**

Click the `View Project Documentation` link to open the `readme` file.

![image30](/mbedtls-psa-crypto-porting-guide/0.1/images/sld817-image30.png)

The following table describes the implementation status of the PSA Crypto X.509 platform example.

|**ECDSA Key**|**Series 1**|**Series 2 - VSE**|**Series 2 - HSE**|**Remark**|
|---|---|---|---|---|
|secp192r1|Y|Y|Y|—|
|secp256r1|Y|Y|Y|—|
|secp384r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|secp521r1|Y|Y|Y|Hardware acceleration only on HSE-SVH devices.|
|Private Device Key|—|—|Y|Only on HSE-SVH devices.|

> **Note**: This example can select the Private Device Key (secp256r1) to generate the root certificate CSR.

### Series 3 Security Overview

#### Series 3 Security Overview

> **Note**: This section replaces _AN1504: Series 3 Security Overview_. Further updates to this application note will be provided here.

This application note provides a high level overview of the security features included in Series 3 devices.

Security features on Series 3 devices described in this document are implemented through the Secure Engine.

##### Key Points

- Basic overview of Series 3 security features
- Authenticated execute in-place (AXiP)
- Mailbox/Debug challenge interface
- Automatic tamper responses
- Secure debug lock/unlock
- Secure boot/RTSL
- Secure key storage
- Secure identity
- Cryptographic hardware acceleration
- DPA/DFA countermeasures

#### Series 3 Device Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help developers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs' security offerings were significantly enhanced by the introduction of the Series 2 products that included a Secure Engine. Series 3 products continue to include and expand upon existing Secure Engine technology. The Secure Engine is a tamper-resistant component used to securely store sensitive data and keys and to execute cryptographic functions and secure services.

##### User Assistance

In support of these products, we offer the following essential documentation:

|Document|Summary|Applicability|
|---|---|---|
|[AN1190: Series 2 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/)|How to lock and unlock Series 2 debug access, including background information about the SE|Series 3|
|[AN1218: Series 2 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)|Describes the secure boot process on Series 2 devices using SE|Series 3|
|[AN1222: Production Programming of Series 2 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/)|How to program, provision, and configure security information using SE during device production|Series 3|
|[AN1247: Anti-Tamper Protection Configuration and Use](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/)|How to program, provision, and configure the anti-tamper module|Series 3|
|[AN1268: Authenticating Silicon Labs Devices using Device Certificates](https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/)|How to authenticate a device using secure device certificates and signatures, at any time during the life of the product|Series 3|
|[AN1271: Secure Key Storage](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/)|How to securely "wrap" keys so they can be stored in non-volatile storage.|Series 3|

> **Note:** Documents in the above table were written for Series 2 devices and will be updated for Series 3.

##### Key Reference

Silicon Labs security implementations use asymmetric key pairs and symmetric keys. The table below clarifies key names, applicability, and relevant documentation.

|Key Name|Customer Programmed|Purpose|Used in|
|---|---|---|---|
|Public Sign key (Public Sign Key)|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|AN1218 (primary), AN1222|
|Public Command key (Public Command Key)|Yes|Secure Debug Unlock or Disable Tamper command authentication|AN1190 (primary), AN1222, AN1247|
|OTA Decryption key (GBL Decryption key)|Yes|Decrypting GBL payloads used for firmware upgrades|AN1222 (primary), UG266/UG489|
|Attestation key (Private Device Key)|No|Device authentication for secure identity|AN1268|
|Authenticated eXecute in Place (AXiP) Key|No|Authentication and encryption/decryption key for AXiP|AN1509|
|Encrypted eXecute in Place (EXiP) key|No|Encryption/Decryption key for EXIP|AN1509|

##### SE Firmware

We strongly recommend installing the latest SE firmware on Series 3 devices to support the required security features. Refer to [Example 3.6](examples#secure-se-firmware-update) for the procedure to upgrade the SE firmware and [UG103.05](https://docs.silabs.com/iot-security/latest/iot-endpoint-security-fundamentals/) for the latest SE Firmware shipped with Series 3 devices and modules.

##### Acronyms Used in this Document

|Acronym|Meaning|
|---|---|
|AXiP|Authenticated execute in-Place|
|DCI|Debug Challenge Interface|
|DFA|Differential Fault Analysis|
|DPA|Differential Power Analysis|
|ECC|Elliptic Curve Cryptography|
|OTP|One-time programmable|
|SE|Secure Engine|

#### Introduction

Attacks include both logical and physical attacks. Logical attacks attempt to exploit software vulnerabilities over some type of communication interface such as a wireless protocol or serial communication interface. Physical attacks require an attacker to have physical access to the device so that they perform attacks such as fault injections and side channel analysis. Defending against these attacks requires implementing a variety of security features. These include:

- Securing the application firmware using secure boot
- Locking access to the debug port using secure debug
- Mitigating fault injections using automatic tamper detection and response
- Mitigating side channel attacks using DPA and DFA countermeasures against cryptographic operations
- Secure key storage

##### Secure Engine Principles

The following is a list of the various security features found in Series 3. This document is intended to provide an overview of each security feature. Refer to the linked documents in each section for details, including examples for implementing each feature.

###### Users and Modes

The SE has a single user -- the product developer. The interfaces to the SE are described in the following section. The SE has two modes, active and inactive. When the Secure Engine is processing a command, it is active, otherwise it is inactive.

##### Mailbox/DCI Interface

The Secure Engine is accessible to a single user through commands that can be issued using:

- SE Mailbox (from host core) via the SE Manager API.
- Debug Challenge Interface (DCI). The Silicon Labs Simplicity Commander tool is the recommended method for using the DCI interface. The Simplicity Commander user guide is available [here](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/). The recommended version of Simplicity Commander for the steps in this application note is v1.17.4, or higher.

These commands provide access to the following features:

- Key provisioning
- Debug port configuration and locking
- Secure boot configuration and status reporting
- Tamper response configuration
- Secure engine (SE) and host firmware updates
- Code/data region configuration for EXiP/AXiP
- Cryptographic operations

###### Secure Engine Manager

The Secure Engine manager provides an interface for users to control all the features mentioned here. Documentation for SE Manager APIs can be found [here](https://docs.silabs.com/gecko-platform/5.2.0/platform-security-api/sl-se-manager). At the time of publication, this document refers to SE Manager API documentation version v5.2.0.

##### Authenticated eXecute in Place (AXiP)

The AXiP feature is used to encrypt and authenticate external flash memory to protect the confidentiality and integrity of code and data.

The AXiP feature is configurable in up to 8 regions, and each region can be either unprotected, encrypted (eXiP), or authenticated and encrypted (AXiP). Each region must be a multiple of 32 KB.

The configuration can be read or changed using either DCI commands or SE manager APIs. The commands are summarized in Table: AXiP Security Parameters. The default configuration is to configure region 0 for 32 KB with AXiP enabled and region 1 for the remainder of flash with AXiP enabled. Unused regions are set to size 0 and start address immediately following the previous region.

###### Users and User-controlled Security Parameters

The user of this feature is the end product developer who configures the feature through the use of the DCI interface or the SE manager APIs mentioned in the _SE Manager APIs for AXiP_ table.

_Table: AXiP Security Parameters._

|Parameter|Configuration Options|Description|
|---|---|---|
|Region Start Address|Start address - Integer|The starting address of one of up to 8 code regions|
|Region Size|Region size - integer, multiple of 32 KB|The size of the current region _(1)_|
|Region Protection Type|Integer indicating the protection type for the region|The protection mode for the code region. One of the following settings is valid. No encryption, encryption only, authentication with encryption|
|Code Region Closed|Boolean|Closing a code region finalizes the message authentication code (MAC) for that region.|

> **Note:**
> 
> 1. Unused regions default to a size of 0.

_Table: SE Manager APIs for AXiP._

|DCI Command (1,2)|SE Manager API|Usage|
|---|---|---|
|Read Region Config|`sl_se_code_region_get_config`|Reads the memory region configuration and reports the region sizes and protection types|
|Close Region|`sl_se_code_region_close`|Finalizes the message authentication tag (MAC) for the memory region|
|Apply Region Config|`sl_se_code_region_apply_config`|Writes the memory region configuration to set the size and protection type for each region. Some regions can have a size of 0.|
|Erase Region|`sl_se_code_region_erase`|Erases a code region|
|Get Region Version|`sl_se_code_region_get_version`|Gets the version of a code region (32bit int)|
|Write Region|`sl_se_code_region_write`|Write code region|
|Write Region|`sl_se_data_region_write`|Write to a data region|
|Erase Region|`sl_se_data_region_erase`|Erase data sectors|
|Get Data Region Location|`sl_se_data_region_get_location`|Get data region location|
|-|`sl_se_flash_pause`|Resume the previously paused long-running flash operation and/or re-enable long-running operations.|
|-|`sl_se_flash_resume`|Resume the previously paused long-running flash operation and/or re-enable long-running operations.|
|-|`sl_se_code_region_set_active_banked`|Check if a long-running operation (page/region erase, bulk write) is currently being executed on the flash|
|-|`sl_se_flash_is_busy`|Pause the ongoing long-running flash operation (and/or inhibit new long-running operations from starting), which frees up the auto-port such that code can run again (unless it tries to access the sector/region being erased, in which case the SE will need to auto-resume).|

> **Notes:**
> 
> 1. Performing these commands over DCI is implemented in Simplicity Commander.
> 2. Not all commands exist as both APIs and DCI commands.

##### Secure Attestation

The secure attestation feature is used to authenticate a device as a genuine Silicon Labs product. Each device is provisioned with one certificate to identify the device and another certificate to identify the batch to which the device belongs. Together with Silicon Labs' root certificate and factory certificate, a chain of trust is formed which can be used to verify the identity of a device, confirming it to be a genuine Silicon Labs product. The private key associated with the public key in the device certificate is securely stored on the device to facilitate signing of random number challenges. Refer to [AN1268](https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/) for more details.

_Table: SE Manager APIs for Secure Attestation._

|DCI Command (1,2)|SE Manager API|Usage|
|---|---|---|
|Vault Device Attestation|`sl_se_attestation_get_psa_iat_token`|Get the PSA attestation token from the SE with the given nonce.|
|Read Device Certificate|`sl_se_read_cert`|Read stored certificates (DER format) in the device.|
|Read Public Key from Device|`sl_se_read_pubkey`|Read stored Public Device Key in the device.|
|-|`sl_se_attestation_get_config_token`|Get the security configuration token from the SE with the given nonce.|
|-|`sl_se_attestation_get_psa_iat_token_size`|Get the size of a PSA attestation token with the given nonce.|
|-|`sl_se_attestation_get_config_token_size`|Get the size of a security configuration token with the given nonce.|
|-|`sl_se_read_cert_size`|Read the size of stored certificates in the device.|

> **Note:**
> 
> 1. Performing these commands over DCI is implemented in Simplicity Commander.
> 2. Not all commands exist as both APIs and DCI commands.

###### Secure Attestation Users and User-controlled Security Parameters

_Table: Secure Attestation Security Parameters._

|Parameter|Configuration options|Description|
|---|---|---|
|SE Device Identity Certificate|None _(1)_|X.509 certificate identifying the specific device|
|SE Batch Certificate|None _(1)_|X.509 certificate identifying the batch of devices|
|SE Device Private Signing Key|None _(1)_|ECC P-256 private key used to sign attestation tokens|

> **Note:**
> 
> 1. This parameter is provisioned in the Silicon Labs production facility and cannot be changed by the user of the product.

##### Secure Debug

Access to the host core's debug port can be securely locked and unlocked. The command public key is stored securely in SE OTP. The associated command private key signs a certificate that includes the device serial number, permitted debug modes, and a public key referred to as the certificate public key. The certificate private key is used to sign an access token consisting of the access command, a debug mode request, and a nonce. The random number challenge is issued by the device and must be correctly signed for the debug port to be unlocked. The debug port is automatically locked again upon reset. The random challenge can be rolled to a new value to prevent previous access tokens from being reused by unauthorized parties.

For a detailed description, see [AN1190](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

###### Secure Debug Users and User-controlled Security Parameters

The user of this feature is the end product developer who configures the feature through the DCI interface or the SE manager APIs mentioned in Table: SE Manager APIs for Secure Debug.

_Table: Secure Debug Security Parameters._

|Parameter|Configuration Options|Description|
|---|---|---|
|Secure Debug Unlock|Boolean -- enable/disable|Enables or disables the ability to securely unlock the debug port using a signed access token|
|Public Command Key|ECC public key|User generated ECC P-256 public key used to verify a signed certificate|
|Device Erase Command|Boolean -- enable/disable|One-time programmable option to disable the device erase command. Disabling this command makes it impossible to reset the secure debug unlock bit or to unlock the debug port by erasing the device.|
|Debug lock|Boolean -- enable/disable|This parameter controls the lock state of the debug port.|
|Non-secure Zone Invasive Debug Restriction|Boolean -- enable/disable|This option enables or disables the ability to perform invasive debugging on the non-secure memory region. Only applies when using TrustZone.|
|Non-secure Zone Non-Invasive Debug Restriction|Boolean -- enable/disable|This option enables or disables the ability to perform non-invasive debugging on the non-secure memory region. Only applies when using TrustZone.|
|Secure Zone Invasive Debug Restriction|Boolean -- enable/disable|This option enables or disables the ability to perform invasive debugging on the secure memory region. Only applies when using TrustZone.|
|Secure Zone Non-Invasive Debug Restriction|Boolean -- enable/disable|This option enables or disables the ability to perform non-invasive debugging on the secure memory region. Only applies when using TrustZone.|
|Device Serial Number|Not configurable by the user|128-bit unique identifier provisioned by Silicon Labs production process.|

_Table: SE Manager APIs for Secure Debug._

|DCI Command (1)|SE Manager API|Usage|
|---|---|---|
|Enable Secure Debug|`sl_se_enable_secure_debug`|Enables the ability to securely unlock the debug port using a signed access token.|
|Disable Secure Debug|`sl_se_disable_secure_debug`|Disables the ability to securely unlock the debug port using a signed access token.|
|Set Debug Options|`sl_se_set_debug_options`|Sets options for restricting invasive/non-invasive debug access in the secure/non-secure memory regions.|
|Disable Device Erase|`sl_se_disable_device_erase`|Disables the device erase SE command. Once enabled, it is impossible to unlock the device through an erase.|
|Apply Lock|`sl_se_apply_debug_lock`|Locks the debug port. Unlocking depends on the secure debug lock and disable device erase settings.|
|- (2)|`sl_se_get_challenge`|Gets a random number challenge from the SE to be signed.|
|Roll Challenge|`sl_se_roll_challenge`|Rolls the random number challenge for unlocking the debug port.|
|Secure Debug Unlock|`sl_se_open_debug`|Unlocks the debug port. Requires a signed certificate.|
|Read Lock Status|`sl_se_get_debug_lock_status`|Returns the current state of the debug port lock.|
|Disable Device Erase|`sl_se_disable_device_erase`|Disables the Erase Device command. This command does not lock the debug interface to the part, but it is an IRREVERSIBLE action for the part.|

> **Notes:**
> 
> 1. Performing these commands over DCI is implemented in Simplicity Commander.
> 2. Device challenge is retrieved through the secure unlock command.

##### Secure Key Storage

The SE isolates cryptographic functions and data from the host core. The SE is used to accelerate cryptographic operations as well as provide a method to securely store keys.

The SE contains OTP key storage slots for three specific keys:

1. The Public Sign Key, used for Secure Boot and Secure Upgrades
2. The Public Command Key, used for Secure Debug unlock and tamper disable
3. The Symmetric OTA Decryption Key, used for Over-The-Air updates

These keys are one-time programmable and are persistent for the lifetime of the device.

###### Secure Key Storage Users and User-controlled Security Parameters

The user of this feature is the end product developer who configures the feature using the SE manager APIs mentioned in Table: SE Manager APIs for Secure Key Storage and DCI commands through Simplicity Commander.

_Table: Security Parameters for Secure Key Storage._

|Parameter|Configuration Options|Description|
|---|---|---|
|Key Size|Integer -- number of bits|Indicates the size of the key in bits|
|Key Type|Integer -- type of key|Indicates the type of key symmetric or asymmetric|
|Key Permissions|Bitfield -- allowed uses for the key|A set of flags indicating the permitted uses for the key, the exportability of the key, and whether the key is in volatile or non-volatile memory|
|Key Storage|Data structure pointing to the physical storage location of the key|A pointer to the physical location of the key material together with a size parameter indicating the size of the key material|
|Key Password|Data structure|An optional 8-byte value which, if set, is required to use the key|
|Key Domain|Data structure|For ECC asymmetric keys, a set of data that indicates the parameters for the curve used|

###### SE Volatile Storage

The SE also contains four volatile storage slots for other user keys. These slots are not persistent through a reset. In the case where a key needs persistent storage, the key must be stored wrapped outside of the SE in non-volatile storage. After a device reset, the key can be loaded into the SE volatile key storage for usage by index or used in-place (passed to the SE on every requested operation).

###### Wrapped Keys

Without any secure key storage mechanism, the user key stored in non-volatile storage is opened to storage-extraction attacks (such as gaining access to and downloading device flash), as well as application-level attacks (i.e., taking control of the user application or privileges in a manner that allows access to the keys). With Secure Key Storage, a user can only access a key from the SE in a "wrapped" format. In this format, the key is encrypted by a device-unique root key, only available to the SE. This allows a user to store a key confidentially in non-volatile storage to provide key persistence. Using Secure Key Storage, the plaintext key is never stored in non-volatile memory, preventing storage-extraction attacks from obtaining the key. After a device reset, the wrapped key can be loaded from non-volatile storage into the SE. The SE then unwraps the key and stores it in one of the key storage slots without ever exposing the plaintext key to the application, which also prevents application-level attacks from exposing the key. To perform cryptographic operations using a wrapped key, the key is referred to by its identifier. Refer to [AN1271](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/) for more details.

###### Key Slot Unit (KSU)

The KSU module provides local key storage for wrapped keys. The SE can unwrap a wrapped key and place it in the KSU for the appropriate AES engine. Each key contains metadata that controls which AES engine may use it. The host cannot read the contents of the KSU slots directly, it can only reference the keys using their slot identifiers. KSU slots are volatile, meaning their contents are not visible when the device is powered off.

> **Note:** DFA countermeasures are only available in the SE cryptographic accelerator, not in the host cryptographic accelerators. Any operations that should be protected against DFA attacks must be restricted to the SE.

_Table: SE Manager APIs for Secure Key Storage._

|SE Manager API|Usage|
|---|---|
|`sl_se_generate_key`|Generate a new key and store it either in a volatile HSE storage slot or as a wrapped key.|
|`sl_se_import_key`|Import a plaintext key and store it either in a volatile HSE storage slot or as a wrapped key.|
|`sl_se_export_key`|Export a volatile or wrapped key back to plaintext if allowed. It will fail for a key that has been flagged as `SL_SE_KEY_FLAG_NON_EXPORTABLE`.|
|`sl_se_transfer_key`|Transfer a volatile or wrapped key to another storage option (volatile HSE storage slot or a wrapped key) if allowed.|
|`sl_se_delete_key`|Delete a key from a volatile SE storage slot.|
|`sl_se_generate_key`|Generate a new key and store it either in a volatile HSE storage slot or as a wrapped key.|
|`sl_se_import_key`|Import a plaintext key and store it either in a volatile HSE storage slot or as a wrapped key.|
|`sl_se_export_key`|Export a volatile or wrapped key back to plaintext if allowed. It will fail for a key that has been flagged as `SL_SE_KEY_FLAG_NON_EXPORTABLE`.|
|`sl_export_public_key`|Export the public part of an ECC keypair.|
|`sl_se_validate_key`|Validates a key descriptor to determine if all of the required properties for that key type have been set.|
|`sl_se_get_storage_size`|Returns the required storage size for the given key.|
|`sl_se_init_otp_key`|Provision a key to SE OTP. Used for symmetric and public keys.|
|`sl_se_read_pubkey`|Read out a public key from SE OTP.|

##### Secure Boot and Root of Trust Secure Loader (RTSL)

One of the most important criteria for a secure product is to ensure that the firmware that defines the behavior of that product is authentic. Secure boot ensures that firmware is authentic by verifying the signature of that firmware using a tamper-resistant public key. The firmware is only allowed to run once it has been verified to be authentic. Another important feature of secure boot is roll-back protection. Firmware rollbacks should be prevented to mitigate an attacker's ability to take advantage of vulnerabilities in previous firmware versions. Refer to [AN1218](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) for more details.

###### Secure Boot Users and User-controlled Security Parameters

The user of this feature is the end product developer who configures the feature through the use of the SE manager APIs and DCI commands mentioned in Table: SE Manager APIs for Secure Boot.

_Table: Secure Boot Security Parameters._

|Parameter|Configuration options|Description|
|---|---|---|
|Secure Boot Enable|Boolean -- enable/disable|OTP flag to indicate whether secure boot is enforced or not|
|Secure Boot Anti-Rollback|Boolean -- enable/disable|OTP flag to indicate whether rollback protection of host firmware is enabled or not|
|Secure Boot Verify Certificate|Boolean -- enable/disable|OTP flag to indicate whether certificate-based signing of host firmware is required or not|
|Secure Boot Public Sign Key|ECC P-256 public key|User-generated ECC P-256 public key. Used to verify either the host firmware certificate when certificate-based secure boot is used, or the host firmware signature itself when certificate-based secure boot is not used|
|Secure Boot Certificate|Proprietary data structure|A certificate containing a version and a public key used to verify host firmware signature. This is injected into the host firmware image binary|
|Host Firmware Signature|ECDSA signature|User-generated signature created with ECDSA on ECC P-256 curve with the user's private signing key. Injected into the host firmware image binary|

_Table: SE Manager APIs for Secure Boot._

|DCI Command (1,2)|SE Manager API|Usage|
|---|---|---|
|Write User Configuration|`sl_se_init_otp`|Provision the configuration settings to OTP. Settings include secure boot enforcement, anti-rollback of host firmware, flash page locking, and tamper response settings. Settings are provisioned as a single word. Therefore, all settings must be set in a single operation|
|Read User Configuration|`sl_se_read_otp`|Read out the OTP settings currently provisioned to the device|
|Get Device Status|`sl_se_get_status`|Read the boot status of the SE. The information retrieved also includes SE firmware version, state of the debug port lock, tamper status, secure debug configuration|
|-|`sl_se_check_se_image`|Validate SE firmware image|
|-|`sl_se_apply_se_image`|Apply SE firmware image|
|-|`sl_se_get_upgrade_status_se_image`|Get upgrade status of SE firmware image|
|-|`sl_se_check_host_image`|Validate Host firmware image|
|-|`sl_se_apply_host_image`|Apply Host firmware image|
|-|`sl_se_get_upgrade_status_host_image`|Get upgrade status of Host firmware image|

> **Note:**
> 
> 1. Performing these commands over DCI is implemented in Simplicity Commander.
> 2. Not all commands exist as both APIs and DCI commands.

###### SE Boot Status

The SE can be queried through the DCI interface to determine the boot status. Refer to [AN1218](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/) section 6 for a full list of the status codes.

##### Cryptographic Acceleration

###### Security Parameters for Cryptographic Acceleration

_Table: Security Parameters for Cryptographic Algorithms._

|Parameter|Configuration Options|Description|
|---|---|---|
|Private Key|Integer -- size depends on algorithm|For ECDSA/EdDDSA algorithms, this is the key used for signing. For key agreement algorithms, this is the key used together with a peer's public key for establishing a shared secret.|
|Public Key|Derived from associated private key and elliptic curve|For ECDSA/EdDDSA algorithms, this is the key used for verification. For key agreement algorithms, this is the key used together with a peer's private key for establishing a shared secret.|
|Elliptic Curve|One of the following: P-192, P-256, Curve25519|A set of parameters that define an elliptic curve. These are used to associate a public key with a private key.|
|Symmetric Key|Key material|128, 192, or 256 bits of key material used for encrypting/decrypting/authentication.|
|Key Size|For symmetric algorithms, 128, 192, or 256 bits|The size of the key to be used in AES operations.|
|Algorithm|One of the following: AES-ECB, AES-CFB8, AES-CFB128, AES-CBC, AES-CTR, AES-CMAC, AES-CCM, AES-GCM, ECDSA, EdDSA, ECDH, SHA1/SHA2/HMAC-AES-MMO, EC-JPAKE, HMAC|The cryptographic algorithm to be performed.|
|Operation|Encrypt or decrypt|This parameter controls the behavior of algorithms that support encryption or decryption through the same API function.|
|Nonce|Data|Initialization value for supported cipher algorithms.|
|Nonce Length|Integer -- allowable values depend on chosen algorithm|The length of the nonce passed to the cryptographic algorithm.|
|Input Data|Data|The data to be processed by the cryptographic algorithm.|
|Associated Data|Data|For supported algorithms, data that is to be used in the generation of an authentication tag but not encrypted or decrypted.|
|Output Data|Storage location|The storage location for the data output by the cryptographic algorithm.|
|Data Length|Integer -- allowable values depend on chosen algorithm|The length of the data to be operated on by the cryptographic algorithm. Configurable for all algorithms except AES-ECB.|
|Authentication Tag|Storage location|Location where an authentication tag such as a CCM or GCM tag is to be stored.|
|Authentication Tag Length|Integer -- allowable values depend on chosen algorithm|The length of authentication tag to be generated or verified by the chosen cryptographic algorithm.|
|Password|Data|Password for EC-JPAKE.|
|Password Length|Integer|Length of the EC-JPAKE password in bytes.|
|Role|Boolean -- client or server|The role for EC-JPAKE. Only values indicating client or server are allowable.|
|Hash Type|Integer|The type of hash to use. Supported hashes are SHA1, SHA2/256/384/512, and HMAC-AES-MMO.|

Refer to [SE Manager API](https://docs.silabs.com/gecko-platform/5.2.0/platform-security-api/sl-se-manager) for more information.

###### Asymmetric Cryptography

Asymmetric cryptographic operations, those that operate on public/private keypairs, are always performed by the SE core. The supported curves and operations are summarized in Table: Supported Curves and Operations.

_Table: Supported Curves and Operations._

|Curve|Supported Operations|
|---|---|
|P-192, P-256|ECDSA, ECDH, EC-JPAKE|
|Curve25519|ECDH, EdDSA|

All operations are available through the mailbox interface. The APIs are summarized in Table: SE Manager APIs for Asymmetric Cryptographic Functions.

_Table: SE Manager APIs for Asymmetric Cryptographic Functions._

|SE Manager API|Usage|
|---|---|
|`sl_se_ecc_sign`|This function computes Elliptic-Curve Cryptography (ECC) digital signatures of a message.|
|`sl_se_ecc_verify`|This function verifies Elliptic-Curve Cryptography (ECC) digital signatures of a message.|
|`sl_se_ecdh_compute_shared_secret`|This function computes the shared secret with Elliptic Curve Diffie Hellman (ECDH) algorithm.|
|`sl_se_ecjpake_check`|Check if an EC J-PAKE context is ready for use.|
|`sl_se_ecjpake_derive_secret`|Derive the shared secret (TLS: Pre-Master Secret).|
|`sl_se_ecjpake_free`|This clears an EC J-PAKE context and frees any embedded data structure.|
|`sl_se_ecjpake_init`|Initialize an EC J-PAKE context.|
|`sl_se_ecjpake_read_round_one`|Read and process the first round message (TLS: contents of the Client/ServerHello extension, excluding extension type and length bytes).|
|`sl_se_ecjpake_read_round_two`|Read and process the second round message (TLS: contents of the Client/ServerKeyExchange).|
|`sl_se_ecjpake_setup`|Set up an EC J-PAKE context for use.|
|`sl_se_ecjpake_write_round_one`|Generate and write the first round message (TLS: contents of the Client/ServerHello extension, excluding extension type and length bytes).|
|`sl_se_ecjpake_write_round_two`|Generate and write the second round message (TLS: contents of the Client/ServerKeyExchange).|

###### Symmetric Cryptography

Symmetric cryptographic operations such as AES and hash operations can be performed by the SE, when high performance on large blocks with high security is desired or by one of the host cryptographic accelerators. The following symmetric cipher modes are supported with key sizes of 128/192/256 bits:

- ECB
- CTR
- CBC
- CFB
- CCM
- GCM
- CBC-MAC

The following hashes are supported:

- SHA-1
- SHA-2/256/384/512
- HMAC-AES-MMO

Operations to be performed by the SE use the mailbox interface. The following user-friendly APIs are provided for these operations.

_Table: SE Manager APIs for Symmetric Cryptographic Functions._

|SE Manager API|Usage|
|---|---|
|`sl_se_aes_crypt_ecb`|AES-ECB block encryption/decryption.|
|`sl_se_aes_crypt_cbc`|AES-CBC buffer encryption/decryption.|
|`sl_se_aes_crypt_cfb128`|AES-CFB128 buffer encryption/decryption.|
|`sl_se_aes_crypt_cfb8`|AES-CFB8 buffer encryption/decryption.|
|`sl_se_aes_crypt_ctr`|AES-CTR buffer encryption/decryption.|
|`sl_se_ccm_encrypt_and_tag`|AES-CCM buffer encryption.|
|`sl_se_ccm_auth_decrypt`|AES-CCM buffer decryption.|
|`sl_se_ccm_multipart_starts`|Prepare a CCM streaming command context object.|
|`sl_se_ccm_multipart_update`|This function feeds an input buffer into an ongoing CCM computation.|
|`sl_se_ccm_multipart_finish`|Finish a CCM streaming operation and return the resulting CCM tag.|
|`sl_se_gcm_crypt_and_tag`|This function performs GCM encryption or decryption of a buffer.|
|`sl_se_gcm_auth_decrypt`|This function performs a GCM authenticated decryption of a buffer.|
|`sl_se_cmac`|This function calculates the full generic CMAC on the input buffer with the provided key.|
|`sl_se_cmac_multipart_starts`|Prepare a CMAC streaming command context object.|
|`sl_se_cmac_multipart_update`|This function feeds an input buffer into an ongoing CMAC computation.|
|`sl_se_cmac_multipart_finish`|Finish a CMAC streaming operation and return the resulting CMAC tag.|
|`sl_se_gcm_multipart_starts`|Prepare a GCM streaming command context object.|
|`sl_se_gcm_multipart_update`|This function feeds an input buffer into an ongoing GCM computation.|
|`sl_se_gcm_multipart_finish`|Finish a GCM streaming operation and return the resulting GCM tag.|
|`sl_se_hmac`|Compute an HMAC on a full message.|
|`sl_se_hmac_multipart_starts`|Prepare an HMAC streaming command context object to be used in subsequent HMAC streaming function calls.|
|`sl_se_hmac_multipart_update`|This function feeds an input buffer into an ongoing HMAC computation.|
|`sl_se_hmac_multipart_finish`|Finish an HMAC streaming operation and return the resulting HMAC.|

##### Countermeasures for Side-channel and Other Physical Attacks

Side channel attacks observe physical quantities such as power consumption to extract information such as secret keys. Physical fault injection can be used to alter program behavior. Refer to the following section for specific types of fault injection.

###### Fault Injection

###### Power Supply Glitching (heading level 7)

Injecting current into the power supply of a victim device can cause applications to misbehave by altering bits in non-volatile memory. This type of attack is mitigated using a brown-out detector (BOD) which triggers a configurable automatic response.

###### Electromagnetic Glitching (heading level 7)

The presence of an electromagnetic pulse can cause applications to misbehave by altering bits in memory. Glitch detection circuits detect these fault injections and trigger a configurable automatic response.

###### Temperature Glitching (heading level 7)

Applications running on devices operating near their temperature limit may misbehave. A temperature sensor monitors the device temperature and can trigger a configurable automatic tamper response when the temperature is above or below the defined limits.

###### Enclosure Opening (heading level 7)

Most attacks in this section require the product's enclosure to be opened as a prerequisite. This can be detected with the External Tamper Detect (ETAMPDET) module.

Refer to [AN1247](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/) for details on automatic tamper responses.

_Table: SE Manager APIs for Secure Tamper Responses._

|DCI Command|SE Manager API|Usage|
|---|---|---|
|Write User Configuration|`sl_se_init_otp`|Initialize SE OTP configuration (including tamper configuration on HSE-SVH devices).|
|Read User Configuration|`sl_se_read_otp`|Read SE OTP configuration (including tamper configuration on HSE-SVH devices).|
|Generate Access Certificate|`sl_se_get_serialnumber`|Read out the serial number (16 bytes) of the HSE device.|
|Roll Challenge|`sl_se_get_challenge`|Read out the current challenge value (16 bytes) for tamper disable.|
|Get Device Status|`sl_se_get_status`|Read the current HSE status (including recorded tamper status on HSE-SVH devices).|
|-|`sl_se_get_tamper_reset_cause`|Read the cached value of the EMU->TAMPERRSTCAUSE register after a tamper reset.|
|-|`sl_se_disable_tamper`|Temporarily disable tamper configuration using the Disable Tamper Token.|
|-|`sl_se_get_reset_cause`|Read the EMU->RSTCAUSE register from HSE devices after a tamper reset.|
|-|`sl_se_get_tamper_reset_cause`|Read the cached value of the EMU->TAMPERRSTCAUSE register after a tamper reset.|
|-|`sl_se_enter_active_mode`|Force the SE to remain active to enable the detection of glitch tamper events on the host Cortex-M33 core.|
|-|`sl_se_exit_active_mode`|Exit active mode and allow the SE to sleep when not performing operations. This will prevent the detection of glitch tamper events when the SE is sleeping. This API should only be used if active mode was entered by calling `sl_se_enter_active_mode`. If active mode is set through a DCI command, it can only be disabled through a DCI command.|

> **Note:**
> 
> 1. Performing these commands over DCI is implemented in Simplicity Commander.
> 2. Not all commands exist as both APIs and DCI commands.

###### Differential Power Analysis (DPA)

Observing the power consumption of a device may leak information. DPA attacks are mitigated by "blinding" the power consumption of the device in a randomized pattern. DPA countermeasures are always on and cannot be disabled.

###### Differential Fault Analysis (DFA)

Injecting faults during cryptographic operations may leak information about the internal state of the cryptographic accelerator. DFA attacks are mitigated by performing the same cryptographic operation more than once to compare the results. DFA countermeasures are always on and cannot be disabled.

###### Secure Tamper Response User-controlled Security Parameters

_Table: Secure Tamper Response Security Parameters._

|Parameter|Configuration options|Description|
|---|---|---|
|Filter Period|Integer between 0 - 7|Determines the filter period. A tamper event is triggered if a number of filtered tamper events equal to or greater than the filter threshold occurs within the time determined by the filter period. Filter period is 32 ms × 2*(n)*|
|Filter Threshold|Integer between 0 -- 31|Determines the number of events required to trigger a filtered tamper. Threshold = 256/2 _(n)_|
|Reset Threshold|Integer between 0 - 255|Determines the number of times the device is reset due to a tamper before entering debug mode. Setting to "0" means never enter debug mode.|
|Active During Sleep|Boolean -- enable/disable|Determines whether tamper detection is active while the device is in sleep mode|
|Digital Glitch Always On|Boolean -- enable/disable|Determines whether glitch detection is always active|
|Crypto Error|One of Reset or erase OTP|Tamper source automatic response|
|DCI Authorization|One of Ignore, filter, interrupt, reset or erase OTP| |
|Decouple Brownout Detect|One of Reset or erase OTP| |
|DPLL Fail|One of Ignore, filter, interrupt, reset or erase OTP| |
|External Tamper Detect|One of Ignore, filter, interrupt, reset or erase OTP| |
|Filter Counter|One of Ignore, filter, interrupt, reset or erase OTP| |
|Glitch Detector|One of Ignore, filter, interrupt, reset or erase OTP| |
|KSU 1-bit ECC Error|One of Ignore, filter, interrupt, reset or erase OTP| |
|KSU 2-bit ECC Error|One of Reset or erase OTP| |
|L2 ICACHE Parity Error|One of Reset or erase OTP| |
|Mailbox Authorization|One of Ignore, filter, interrupt, reset or erase OTP| |
|OTP Alarm|One of Reset or erase OTP| |
|PRS0|One of Ignore, filter, interrupt, reset or erase OTP| |
|PRS1|One of Ignore, filter, interrupt, reset or erase OTP| |
|PRS2|One of Ignore, filter, interrupt, reset or erase OTP| |
|QSPI Reseed Error| | |
|Secure Boot Fail|One of Ignore, filter, interrupt, reset or erase OTP| |
|Secure Lock Error|One of Reset or erase OTP| |
|Selftest Error|One of Reset or erase OTP| |
|SE Assert|One of Reset or erase OTP| |
|SE CPU Major Fault|One of Reset or erase OTP| |
|SE ICACHE Error|One of Reset or erase OTP| |
|SE RAM ECC 1-bit Error|One of Ignore, filter, interrupt, reset or erase OTP| |
|SE RAM ECC 2-bit Error|One of Reset or erase OTP| |
|SE Watchdog|One of Reset or erase OTP| |
|SOC PLL Fail|One of Ignore, filter, interrupt, reset or erase OTP| |
|Temperature Sensor|One of Ignore, filter, interrupt, reset or erase OTP| |
|TRNG Monitor|One of Ignore, filter, interrupt, reset or erase OTP| |

#### Examples

##### Provisioning for Security

1. Run the following command to generate keypairs for secure boot and secure debug:  
   ```sh  
   commander util genkey --type ecc-p256 --privkey sign_key.pem --pubkey sign_pubkey.pem  
   ```  
   ```c  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to sign_key.pem  
   Writing public key file in PEM format to sign_pubkey.pem  
   DONE  
   ```  
   ```c  
   commander util genkey --type ecc-p256 --privkey command_key.pem --pubkey command_pubkey.pem  
   ```  
   ```c  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to command_key.pem  
   Writing public key file in PEM format to command_pubkey.pem  
   DONE  
   ```
2. Provision the Public Sign Key in Simplicity Commander.  
   To write the Public Sign Key to the device, run the command:  
   ```c  
   commander security writekey --sign sign_pubkey.pem --device SIMG301M104LIH --serialno 440048205  
   ```  
   ```c  
    Device has serial number 000000000000000014b457fffe045a8e  
    ================================================================================  
    Please look through any warnings before proceeding.  
    THIS IS A ONE-TIME command, all code to be run on the device must be signed by this key.  
    Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
    ================================================================================  
    continue  
    DONE  
   ```  
   where `sign_pubkey.pem` is the Public Sign Key in Privacy Enhanced Mail (PEM) format. A third party cannot change this setting once it has been set.
3. Provision the Public Command Key in Simplicity Commander.  
   To write the Public Command Key to the device, run the command:  
   ```c  
    Device has serial number 000000000000000014b457fffe045a8e  
    ================================================================================  
    Please look through any warnings before proceeding.  
    THIS IS A ONE-TIME command, all code to be run on the device must be signed by this key.  
    Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
    ================================================================================  
    continue  
    DONE  
     
    commander security writekey --command command_pubkey.pem --device SiMG301M104LIH --serialno 440048205  
   ```  
   where `command_pubkey.pem` is the Public Command Key in PEM format. A third party cannot change this setting once it has been set.
4. Provision the GBL Decryption Key.  
   - To generate the text file for the GBL Decryption Key, run the command:    
     `commander util genkey --type aes-ccm --outfile aes_key.txt`    
     ```c    
     Using Windows' Cryptographic random number generator    
     DONE    
     ```    
     where `aes_key.txt` contains the randomly generated AES-128 key.  
   - To write the GBL Decryption Key to the HSE device, run the command:    
     `commander security writekey --decrypt aes_key.txt --device SiMG301M104LIH --serialno 440048205`    
     ```c    
     Device has serial number 000000000000000014b457fffe045a8e    
     ================================================================================    
     Please look through any warnings before proceeding.    
     THIS IS A ONE-TIME command, any encrypting of GBL files must be done with this key.    
     Type 'continue' and hit enter to proceed or Ctrl-C to abort:    
     ================================================================================    
     continue    
     DONE    
     ```

##### Enabling Secure Boot and Tamper Configuration

The Secure Boot feature verifies the integrity and authenticity of the host application before allowing it to execute. Enabling this feature is IRREVERSIBLE, which means once enabled, Secure Boot can no longer be disabled throughout the life of the device. The Secure Boot settings are written to the one-time-programmable (OTP) memory. They cannot be changed once programmed. The anti-tamper configuration is provisioned with Secure Boot settings. The anti-tamper configuration determines the response from the device if a tamper event occurs.

> **Note:** The user_configuration.json is a JSON file that contains the desired Secure Boot settings and anti-tamper configuration. Use the following command on the target device (e.g., SiMG301M104LIH) to generate a default configuration file. The content of the JSON file is device-dependent (--device <device name>).
> 
> The security genconfig command above generates a generic configuration file for SiMG301M104LIH consisting of the properties listed in Table: Secure Boot Items (mcu_flags) for Series 3 Devices and Table: Tamper Items for Series 3 Devices. A text editor can be used to modify the default settings shown below to the desired configuration.

```sh
commander security genconfig --nostore -o user_configuration.json --device SiMG301M104LIH --serialno 440048205
```

```c
DONE
```

_Table: Secure Boot Items (mcu_flags) for Series 3 Devices._

|Name|Description|
|---|---|
|SECURE_BOOT_ENABLE|If set, verifies the host image on the Cortex-M33 before releasing the Cortex-M33 from reset.|
|SECURE_BOOT_VERIFY_CERTIFICATE|If set, requires certificate-based signing of the host image.|
|SECURE_BOOT_ANTI_ROLLBACK|If set, prevents secure upgrading to a host image with a lower version than the image that is currently stored in flash.|

##### Enabling Anti-Rollback Protection and Certificate-Based Secure Boot

Enable anti-rollback protection and certificate-based secure boot as follows:

1. Open the user_config.json file created in the previous step with any text editor.
2. Change the SECURE_BOOT_VERIFY_CERTIFICATE setting from 'false' to 'true' and save the file.  
   ```json  
   {  
     "OPN": "SIMG301M104LIH",  
     "VERSION": "1.0.0",  
     "mcu_flags": {  
       "SECURE_BOOT_ANTI_ROLLBACK": true,  
       "SECURE_BOOT_ENABLE": true,  
       "SECURE_BOOT_VERIFY_CERTIFICATE": true  
     },  
     "tamper_filter": {  
       "FILTER_PERIOD": 0,  
       "FILTER_THRESHOLD": 0,  
       "RESET_THRESHOLD": 0  
     },  
     "tamper_flags": {  
       "ALIVE_DURING_SLEEP": false,  
       "DGLITCH_ALWAYS_ON": false  
     },  
     "tamper_levels": {  
       "CRYPTO_ERROR": 4,  
       "DCI_AUTH": 0,  
       "DECOUPLE_BOD": 4,  
       "DPLL_FAIL": 0,  
       "ETAMPDET": 0,  
       "FILTER_COUNTER": 0,  
       "GLITCH_DETECTOR": 0,  
       "KSU_1_BIT_ECC_ERROR": 0,  
       "KSU_2_BIT_ECC_ERROR": 4,  
       "L2ICACHE_PARITY_ERROR": 4,  
       "MAILBOX_AUTH": 0,  
       "OTP_ALARM": 4,  
       "PRS0": 0,  
       "PRS1": 0,  
       "PRS2": 0,  
       "QSPI_RESEED_ERROR": 4,  
       "SECURE_BOOT_FAILED": 0,  
       "SECURE_LOCK_ERROR": 4,  
       "SELFTEST_ERROR": 4,  
       "SE_ASSERT": 4,  
       "SE_CPU_MAJOR_FAULT": 4,  
       "SE_ICACHE_ERROR": 4,  
       "SE_RAM_ECC_1BIT": 0,  
       "SE_RAM_ECC_2BIT": 4,  
       "SE_WATCHDOG": 4,  
       "SOCPLL_FAIL": 0,  
       "TEMP_SENSOR": 0,  
       "TRNG_MONITOR": 0  
     }  
   }  
   ```  
   _Table: Tamper Items for Series 3 Devices._  
   |Name|Description|  
   |---|---|  
   |tamper_levels|The tamper levels of different tamper sources.|  
   |tamper_filter|The settings for tamper filters.|  
   |tamper_flags|The settings for tamper flags.|
3. The following command writes the Secure Boot settings and anti-tamper configuration in user_configuration.json file to the device. This command can be executed only once per device.  
   `commander security writeconfig --configfile user_configuration.json --device SiMG301M104LIH --serialno 440048205`
4. To check the device's Secure Boot settings and anti-tamper configuration, run the security readconfig command.  
   ```c  
   ================================================================================  
   THIS IS A ONE-TIME configuration: Please inspect file before confirming:  
   user_configuration.json  
   Type 'continue' and hit enter to proceed or Ctrl-C to abort:  
   ================================================================================  
   continue  
   DONE  
   ```  
   ```sh  
   commander security readconfig --device SiMG301M104LIH --serialno 440048205  
   ```  
   ```c  
   MCU Flags  
     
   Secure Boot                       : Enabled  
   Secure Boot Verify Certificate    : Enabled  
   Secure Boot Anti Rollback         : Enabled  
   Secure Boot Page Lock Narrow      : Disabled  
   Secure Boot Page Lock Full        : Disabled  
     
   Tamper Levels  
     
   FILTER_COUNTER      : 0  
   SE_WATCHDOG         : 4  
   CRYPTO_ERROR        : 4  
   SE_RAM_ECC_2BIT     : 4  
   SE_CPU_MAJOR_FAULT  : 4  
   L2ICACHE_PARITY_ERROR: 4  
   SECURE_BOOT_FAILED  : 0  
   MAILBOX_AUTH        : 0  
   DCI_AUTH            : 0  
   SE_ASSERT           : 4  
   SELFTEST_ERROR      : 4  
   TRNG_MONITOR        : 0  
   SECURE_LOCK_ERROR   : 4  
   GLITCH_DETECTOR     : 0  
   OTP_ALARM           : 4  
   SE_ICACHE_ERROR     : 4  
   SE_RAM_ECC_1BIT     : 0  
   DECOUPLE_BOD        : 4  
   TEMP_SENSOR         : 0  
   DPLL_FAIL           : 0  
   SOCPLL_FAIL         : 0  
   ETAMPDET            : 0  
   KSU_1_BIT_ECC_ERROR : 0  
   KSU_2_BIT_ECC_ERROR : 4  
   QSPI_RESEED_ERROR   : 4  
   PRS0                : 0  
   PRS1                : 0  
   PRS2                : 0  
     
   Tamper Filter  
     
   Filter Period    : 0  
   Filter Threshold : 0  
   Reset Threshold  : 0  
     
   Tamper Flags  
     
   Digital Glitch Detector Always On: Disabled  
   Keep Tamper Alive During Sleep: Disabled  
     
   DONE  
   ```

##### Secure Boot

1. Create a bootloader project for your chosen device as shown below:  
   ![Simplicity Studio Example Projects: Bootloader filter selected; Bootloader – SoC Storage (single 1024 kB OTA) card with CREATE highlighted.](/iot-security-series-3-security-overview/0.1/images/an1504-image1.png)
2. Open the bootloader project's slcp file by double-clicking it.  
   ![Project Explorer: bootloader-storage-single project tree with bootloader-storage-single.slcp highlighted.](/iot-security-series-3-security-overview/0.1/images/an1504-image2.png)
3. In the bootloader core component, enable the secure boot features as shown:  
   ![Bootloader Core configuration: signed and encrypted firmware upgrades, secure boot, and application rollback protection enabled.](/iot-security-series-3-security-overview/0.1/images/an1504-image3.png)
4. Build the bootloader project as shown.  
   ![Simplicity Studio Project menu with Build Project selected for the bootloader-storage project.](/iot-security-series-3-security-overview/0.1/images/an1504-image4.png)
5. Create a keypair for a certificate.  
   ```sh  
   commander util genkey --type ecc-p256 --privkey cert_sign_key.pem --pubkey cert_sign_pubkey.pem  
   ```  
   ```c  
   Generating ECC P256 key pair...  
   Writing private key file in PEM format to cert_sign_key.pem  
   Writing public key file in PEM format to cert_sign_pubkey.pem  
   DONE  
   ```
6. Create a certificate with the new key, signing the certificate with the BL private key.  
   ```sh  
   commander util gencert --cert-type secureboot --cert-version 1 --cert-pubkey cert_sign_pubkey.pem --sign sign_key.pem --outfile bl_cert.bin  
   ```  
   ```c  
   Successfully signed certificate  
   DONE  
   ```
7. Add the certificate into the bootloader.  
   ```sh  
   commander convert bootloader-storage-single.s37 --secureboot --certificate bl_cert.bin --keyfile cert_sign_key.pem --outfile bootloader-storage-single-signed-cert-v1.s37  
   ```  
   ```c  
   Parsing file bootloader-storage-single.s37...  
   Adding certificate to image...  
   Private key matches public key in certificate.  
   Found Application Properties at 0x0100330c  
   Writing Application Properties signature pointer to point to 0x01003810  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: 2e51b2b3f41b5a42f3072bc62e843a3f4406dfe4afd46de20e03b508b662acf7  
   R = 15209BFF03BCD42CA05C0C14175D90D2E25A5FAEDB0ADA18B511144B94C79A13  
   S = C37886136746A193C78AD4AADE541F373A6D61BDBC462C4D6BAD188610FDF49D  
   ```
8. Flash the bootloader to the device.  
   ```sh  
   commander flash bootloader-storage-single-signed-cert-v1.s37 -d SIMG301M104LIH --serialno 440048205  
   ```  
   ```c  
   WARNING: Failed secure boot detected. Issuing a mass erase before flashing to recover the device...  
   Parsing file bootloader-storage-single-signed-cert-v1.s37...  
   Writing 14280 bytes starting at address 0x01000000  
   Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB)  
   Programming range 0x01000000 - 0x01000FFF (4 KB)  
   Programming range 0x01001000 - 0x01001FFF (4 KB)  
   Programming range 0x01002000 - 0x01002FFF (4 KB)  
   Programming range 0x01003000 - 0x01003FFF (4 KB)  
   Programming range 0x01004000 - 0x01004FFF (4 KB)  
   Programming range 0x01005000 - 0x01005FFF (4 KB)  
   Programming range 0x01006000 - 0x01006FFF (4 KB)  
   Programming range 0x01007000 - 0x01007FFF (4 KB)  
   JLinkError: Failed to halt CPU.  
   Closing region 0 (this consumes one OTP bit, consider --noclose on development/testing devices)  
   Flashing completed successfully!  
   DONE  
   ```
9. Reset the device to update the boot status of the device. This step is necessary to prevent Simplicity Commander from performing a masserase in the next section.
10. Build an instance of the sample application as shown below:  
    ![Simplicity Studio Example Projects: Platform – Blink Kernel FreeRTOS card with CREATE highlighted.](/iot-security-series-3-security-overview/0.1/images/an1504-image5.png)  
    ![Simplicity Studio Project menu with Build Project selected; blink_kernel_freertos project highlighted in Project Explorer.](/iot-security-series-3-security-overview/0.1/images/an1504-image6.png)
11. Sign the resulting executable image with the private BL key.  
    ```sh  
    commander convert blink_kernel_freertos_simg301.s37 --secureboot --keyfile sign_key.pem --outfile signed-blink.s37  
    ```
12. Flash the application to the device.  
    ```sh  
    commander flash signed-blink.s37 --device SIMG301M104LIH --serialno 440048205  
    ```  
    ```c  
    Parsing file blink_kernel_freertos_simg301.s37...  
    Found Application Properties at 0x01018878  
    Writing Application Properties signature pointer to point to 0x010194f0  
    Setting signature type in Application Properties: 0x00000001  
    Image SHA256: 73627f86b624bf0bd52b93e857a7518b0408b71dee2dba639f1fc5c67afff284  
    R = F553D3DE255786FB2629C93EEC40E03F223C831D9E7F93E2074C4C83294ABA10  
    S = AC8BD6AF0E680B4590132E3D1317D09E2CEB9EF89434880E6E96369960C724A8  
    Writing to signed-blink.s37...  
    Overwriting file: signed-blink.s37...  
    DONE  
    ```

##### Wrapping a Key for Secure Storage

In this example, you'll generate an asymmetric keypair and wrap it securely.

1. Start with any of the available sample applications in the Simplicity SDK.
2. Add the following snippet of code to create storage for the key material and a key descriptor.  
   ```c  
   #define ECC_P256_PRIVKEY_SIZE (SL_SE_KEY_TYPE_ECC_P256 & SL_SE_KEY_TYPE_ATTRIBUTES_MASK)  
   #define ECC_P256_PUBKEY_SIZE  (2 * ECC_P256_PRIVKEY_SIZE)  
   #define OVERHEAD              (12 + 16)  
   #define P256_BUFFER_SIZE      (ECC_P256_PRIVKEY_SIZE + ECC_P256_PUBKEY_SIZE + OVERHEAD)  
     
   uint8_t key_buffer[P256_BUFFER_SIZE];  
     
   sl_se_key_descriptor_t example_ecc_key = {  
   .type = SL_SE_KEY_TYPE_ECC_P256,  
   .flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY  
            | SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY  
            | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY,  
   .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,  
   .storage.location.buffer.pointer = key_buffer,  
   .storage.location.buffer.size = sizeof(key_buffer)  
   };  
   ```
3. Add a call to the SE manager init function.  
   ```c  
   sl_se_init();  
   ```
4. Set up a context for the SE Manager command and a status variable, then call the generate-key function.  
   ```c  
   sl_se_command_context_t ctx;  
   sl_status_t status;  
     
   status = sl_se_generate_key(&ctx, &example_ecc_key);  
   ```
5. Print the status returned by the API call to confirm success.  
   ```c  
   printf("result of generating a wrapped key is 0x%2.2X\r\n", status);  
   ```  
   Program output:  
   ```c  
   result of generating a wrapped key is 0x00  
   ```

###### Sign and verify a message with the wrapped key

1. Create a sample message to be signed and a buffer for the signature.  
   Program output:  
   ```c  
   result of signing with the wrapped key is 0x00  
   ```  
   ```c  
   char message[] = "message";  
   uint8_t signature[64];  
   ```
2. Call the API to sign the message using the private part of the key from the previous example and check the return value.  
   ```c  
   status = sl_se_ecc_sign(&ctx,  
                           &example_ecc_key,  
                           SL_SE_HASH_SHA256,  
                           false, /* message is not hashed */  
                           message,  
                           sizeof(message),  
                           signature,  
                           sizeof(signature));  
     
   printf("result of signing with the wrapped key is 0x%2.2X\r\n", status);  
   ```
3. Call the API to verify the signature using the public part of the key.  
   ```c  
   status = sl_se_ecc_verify(&ctx,  
                           &example_ecc_key,  
                           SL_SE_HASH_SHA256,  
                           false, /* message is not hashed */  
                           message,  
                           sizeof(message),  
                           signature,  
                           sizeof(signature));  
     
   printf("result of verifying with the wrapped key is 0x%2.2X\r\n", status);  
   ```  
   ```c  
   result of verifying with the wrapped key is 0x00  
   ```

##### Secure SE Firmware Update

This section describes how to upgrade the SE firmware running on the Series 3 device.

1. Locate the SE firmware folder, typically `C:\Users\<user name>\SimplicityStudio\SDKs\simplicity_sdk\util\se_release\public` (replace `<user name>` with your Windows username).
2. Sign the SE firmware updater application with your private signing key  
   ```sh  
   commander convert --secureboot x301_se_fw_upgrade_app_3v3p1.hex --keyfile rootsign-unsafe-privkey.pem --outfile x301_se_fw_upgrade_3v3p1_signed.hex  
   ```  
   ```c  
   Parsing file x301_se_fw_upgrade_app_3v3p1.hex...  
   Found Application Properties at 0x01028838  
   Writing Application Properties signature pointer to point to 0x01029334  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: 605a1afc8196efecc7f87e0b7444ed8268051a8f9d58878a1d64b27c5c5999d2  
   R = 10267CEBD206C9C1E881C2AD3252EED26416C44B8DCB402C0CBC83679B191026  
   S = B180DA23EF1E6962B967B27E87332994A57A75E3DB09C1B45C6905F34DBC4A32  
   Writing to x301_se_fw_upgrade_3v3p1_signed.hex...  
   DONE  
   ```
3. Flash the signed SE firmware updater application to the device  
   ```sh  
   commander flash x301_se_fw_upgrade_3v3p1_signed.hex --device SiMG301M114LIH --serialno 440048205  
   ```
4. Check the version of the SE firmware to confirm that the update was successful  
   ```c  
   SE ROM version : 5.2  
   SE Firmware version : 3.3.1  
   Serial number : 000000000000000094a081fffe53b457  
   Debug lock : Disabled  
   Device erase : Enabled  
   Secure debug unlock : Disabled  
   Tamper status : OK  
   Secure boot : Enabled  
   Boot status : 0x20 - OK  
   Command key installed : False  
   Sign key installed : True  
   DONE  
   ```  
   ```sh  
   commander security status --device SiMG301M114LIH --serialno 440048205  
   ```

##### Enabling and Working with Secure Debug

The debug lock is an important feature to prevent attackers from using the debug interface to perform illegal operations on the device. The following sections describe how to apply three different locks to the Series 3 debug interface. Only secure debug lock is described here, for other debug lock modes, refer to [AN1190](https://docs.silabs.com/iot-security/latest/series2-secure-debug/).

1. The following command enables the secure debug unlock.  
   ```sh  
   commander security lockconfig --secure-debug-unlock enable --device SIMG301M104LIH --serialno 440048205  
   ```  
   ```c  
   Secure debug unlock was enabled  
   DONE  
   ```
2. After enabling the Secure Debug feature, lock the debug interface using the following command.  
   ```sh  
   commander security lock --device SIMG301M104LIH --serialno 440048205  
   ```  
   ```c  
   Device is now locked.  
   DONE  
   ```

#### Revision History

**September, 2025**

- Initial release.

### Series 3 AXiP

#### Series 3 AXiP

> **Note**: This section replaces _AN1509: Series 3 AXiP_. Further updates to this application note will be provided here.

Silicon Labs® Series 3 platform introduces new Authenticated eXecute in Place (AXiP) and Encrypted eXecute in Place (EXiP) features for protection of memory contents.

While devices with in-package flash are delivered secure by default with AXiP enabled on two pre-defined regions, developers are able to configure up to eight code regions of customizable sizes with AXiP, EXiP, or no protection (code is stored in plaintext) through SE Manager APIs or DCI commands, allowing for flexibility in device setup. This applica- tion note will further discuss the importance of encrypted and authenticated memory contents, the fundamentals of AXiP and EXiP features, and will provide examples for customizing this feature.

##### Key Points

- AXiP and EXiP overview
- Configuring code regions
- Development device considerations

#### Series 3 Security Features

Protecting IoT devices against security threats is central to a quality product. Silicon Labs offers several security options to help devel- opers build secure devices, secure application software, and secure paths of communication to manage those devices. Silicon Labs' security offerings were significantly enhanced by the introduction of the Secure Engine on Series 2 products. Series 3 products contin- ue to include and expand upon existing Secure Engine Technology The Secure Engine is a tamper-resistant component used to se- curely store sensitive data and keys and to execute cryptographic functions and secure services.

##### User Assistance

In support of these products Silicon Labs offers the following application notes:

|Document|Summary|Applicability|
|---|---|---|
|[AN1190: Series 2 and 3 Secure Debug](https://docs.silabs.com/iot-security/latest/series2-secure-debug/)|How to lock and unlock Series 2 debug access, including background information about the SE|Secure Vault Mid and High|
|[AN1218: Series 2 and 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/)|Describes the secure boot process on Series 2 devices using SE|Secure Vault Mid and High|
|[AN1222: Production Programming of Series 2 and 3 Devices](https://docs.silabs.com/iot-security/latest/prod-programming-series2-and-series3/)|How to program, provision, and configure security information using SE during device production|Secure Vault Mid and High|
|[AN1247: Anti-Tamper Protection Configuration and Use (this document)](https://docs.silabs.com/iot-security/latest/efr32-secure-vault-tamper/)|How to program, provision, and configure the anti-tamper module|Secure Vault High|
|[AN1268: Authenticating Silicon Labs Devices using Device Certificates](https://docs.silabs.com/iot-security/latest/authenticating-devices-using-device-certificates/)|How to authenticate a device using secure device certificates and signatures, at any time during the life of the product|Secure Vault High|
|[AN1271: Secure Key Storage](https://docs.silabs.com/iot-security/latest/efr32-secure-key-storage/)|How to securely "wrap" keys so they can be stored in non-volatile storage.|Secure Vault High|

##### Key Reference

Silicon Labs security implementations use asymmetric key pairs and symmetric keys. The table below clarifies key names, applicability, and relevant documentation.

|Key Name|Customer Programmed|Purpose|Used in|
|---|---|---|---|
|Public Sign key|Yes|Secure Boot binary authentication and/or OTA upgrade payload authentication|AN1218 (primary), AN1222|
|Public Command key|Yes|Secure Debug Unlock or Disable Tamper command authentication|AN1190 (primary), AN1222, AN1247|
|OTA Decryption key (or GBL Decryption key)|Yes|Decrypting GBL payloads used for firmware upgrades|AN1222 (primary), UG266/UG489|
|Attestation key aka Private Device Key|No|Device authentication for secure identity|AN1268|
|AXiP Key|No|Used on Series 3 devices for encryption/decryption and authentication of firmware placed in flash|AN1509|
|EXiP Key|No|Used on Series 3 devices for encryption/decryption of firmware placed in flash|AN1509|

#### Introduction

As embedded devices are increasingly used in critical applications such as healthcare devices, industrial controls, and IoT devices, security of these devices is paramount. Embedded devices in these systems often perform essential functions or contain sensitive data, making them targets for attacks. Silicon Labs introduced the Secure Engine as part of the new Series 2 portfolio, which introduced many new security features into the device offerings. Series 3 devices expand upon those offerings by including and improving previous security features, and introducing new security features, such as Authenticated eXecute in Place (AXiP) and Encrypted eXecute in Place (EXiP). These features help to provide protection for code placed in flash memory.

Three of the main principles of security are ensuring confidentiality, integrity, and authenticity. Confidentiality guarantees data cannot be accessed by unauthorized parties. Integrity guarantees data has not been tampered with or modified. Authenticity guarantees data is received from an authorized source. AXiP uses AES-GCM encryption, which helps to ensure integrity, confidentiality, and authenticity of code placed in external memory through encrypting the data, which ensures confidentiality, and including an authentication tag, to en- sure the data placed in memory is from an authorized source, and has not been modified. EXiP uses AES-CTR, which helps to ensure confidentiality only, as only encryption is applied to data in flash memory.

While Silicon Labs will always recommend implementing the highest level of security available on Series 3 devices, it is ultimately up to end-device manufacturers to make their own risk analysis to determine the level of security to implement in their devices. As with any engineering solution, there will be tradeoffs that should be analyzed when implementing these features. For example, AXiP, the highest security option adds a 4-byte MAC to each 32-bytes of ciphertext, which will in turn, consume more memory. EXiP, will result in the same data size between plaintext and ciphertext, however, it will not come with the additional benefit of ensuring authenticity and integ- rity.

The following sections will continue to go further in depth on the AXiP and EXiP features of Series 3, including details on the functions of and how to implement each feature.

#### Authenticated eXecute in Place

Series 3 devices introduce the new AXiP feature which enhances the security of flash by providing encryption and authentication of external flash contents through the EXTMEM and SE subsystems. The SE is involved by providing the AXiP and EXiP keys, generating a unique per-region IV, and configuring code regions for AXiP, EXiP, or no protection. The EXTMEM subsystem handles memory access through a high speed QSPI interface with dedicated hardware to encrypt, decrypt, and authenticate data. Because all memory read and write operations on Series 3 devices are routed through the SE and EXTMEM subsystems, AXiP is seamlessly integrated into the firmware flashing and execution process. Each step is handled securely by these systems, requiring no user interaction to generate keys, manage encryption, or verify authenticity.

##### Algorithm Used

AXiP utilizes the AES-GCM encryption algorithm. AES-GCM is a widely adopted authenticated encryption mode that combines the confidentiality of AES-CTR with the integrity assurance of a Message Authentication Code (MAC).

The AES-GCM algorithm takes in 32-bytes of plaintext and encrypts it with the AXiP Key stored within the SE using an IV generated by the SE for each AXiP enabled code region. The output of this computation is 32-bytes of ciphertext appended with a 4-byte MAC. This 4-byte MAC is independently verifiable per 32-byte blocks of ciphertext. The MAC stored is not directly accessible by the host core, because it has no associated logical address. More details on the differences between physical and logical addresses are covered in [Configuring Code Regions](configuring-code-regions#configuring-code-regions).

On decryption, the MAC is verified per 32-bytes of data before decrypting and executing instructions. If the ciphertext is modified at any time, the MAC will no longer be valid, which will cause the MAC verification to fail. If MAC verification fails, a hard fault will occur. This helps to ensure strong integrity, but introduces an additional memory consumption, which should be considered when planning memory usage.

![AES-GCM Algorithm Overview](/iot-security-series-3-axip/0.1/images/an1509-aes-gcm-algorithm-review.png)

##### AXiP Key

The AXiP feature utilizes a single 256-bit AES key that is derived at boot from a device-unique Physical Unclonable Function (PUF) seed. The PUF is only available while the device is powered on, and the AXiP key derived from this unique seed when needed. This ensures that the AXiP key has enhanced resistance to physical attacks. As this key is derived from the PUF, it is permanent for the lifetime of the device. The AXiP key is shared across all AXiP-configured code regions of the device.

##### IV Generation

Unique initialization vectors ensure that multiple encryptions of identical plaintexts yield different ciphertexts. In AXiP, IVs are generated using the True Random Number Generator (TRNG) and are stored within the SE's MTP. In order to prevent IV reuse, which could introduce predictable bit patterns, a new IV is generated when flashing a code region with AXiP enabled. For more details, see [Considerations for Development Devices](considerations-for-development-devices#considerations-for-development-devices).

##### AXiP Default Device Configuration

Series 3 devices with in-package flash are delivered secured by default, with AXiP enabled out of the box on two code regions. No additional configuration is required to use AXiP on a factory-new in-package flash devices, users only need to flash a firmware image to the predefined code region to implement AXiP.

Unlike in-package flash devices, external flash devices require external flash initialization and SE firmware programming before AXiP is enabled. After the external flash is set up, two regions are configured for AXiP, similar to the default configuration of in-package flash devices. Beyond these external flash initialization steps, region configuration and usage are equivalent to in-package devices.

Typically, a factory-new in-package flash device is set up with Code Region 0 designated for bootloader use. This region is configured with AXiP enabled and a fixed size of 32 kB in logical address space. Code Region 1 is generally intended for application code. It is also AXiP-enabled and sized in multiples of 32 kB logical space, depending on application requirements. The data region is located after the final configured code region, and is a variable size dependent on code region configuration. The default code region sizes may vary among Series 3 OPNs, depending on the flash capacity of the in-package flash devices.

An example of default device configuration is shown below on a 2048 kB flash SixG301 device. Additional details on physical and logical flash mapping on devices with AXiP enabled can be found in [Physical versus Logical Mapping](configuring-code-regions#physical-versus-logical-mapping).

> **Note:** By default, the initial 192 kB of flash memory is allocated for SE Firmware. This region is reserved and not accessible to the user.

![Example of Default Device Configuration on a 2048 kB SixG301 Device with In-Package Flash](/iot-security-series-3-axip/0.1/images/an1509-default-device-configuration.png)

#### Encrypted eXecute in Place

Series 3 devices introduce the new EXiP feature which enhances the security of external flash by providing encryption during program- ming and decryption of ciphertext during execution, through the SE and EXTMEM subsystems.

##### Algorithm Used

EXiP utilizes the AES-CTR encryption algorithm which provides confidentiality for flash contents. When EXiP is enabled, 16 bytes at a time will be taken to encrypt plaintext or decrypt ciphertext with the EXiP Key stored within the SE using an IV generated by the SE for each EXiP enabled code region.

While EXiP uses less memory than AXiP, it is considered a less secure solution, due to the underlying algorithm differences. Not only could an attacker modify ciphertext without detection, since there is no integrity or authenticity check on the data, AES-CTR is also vulnerable to bit-flipping attacks. This allows an attacker to XOR bits in the ciphertext, which results in the same bits being flipped in the plaintext, once decrypted.

![AES-CTR Algorithm Overview](/iot-security-series-3-axip/0.1/images/an1509-aes-ctr-algorithim-overview.png)

##### EXiP Key

The EXiP feature utilizes a single 256-bit AES key that is derived at boot from a device-unique Physical Unclonable Function (PUF) seed. The PUF is only available while the device is powered on, and the EXiP key derived off of this unique seed when needed. This ensures that the EXiP key has enhanced resistance to physical attacks. As this key is derived from the PUF, it is permanent for the lifetime of the device. This EXiP key is shared across all EXiP-configured code regions of the device, and is a separate key from the AXiP key.

##### IV Generation

Unique initialization vectors ensure that multiple encryptions of identical plaintexts yield different ciphertexts. In EXiP, IVs are generated using the true random number generator and are stored within the SE's MTP. In order to prevent IV reuse, which could introduce pre- dictable bit patterns, a new IV is generated when flashing a code region with EXiP enabled. For more details, refer to the [Considerations for Development Devices](considerations-for-development-devices#considerations-for-development-devices) section.

##### EXiP Device Configuration

On Series 3 devices EXiP is not enabled by default. A user must configure their device for EXiP in order to utilize the feature. Refer to [Configuring Code Regions](configuring-code-regions#configuring-code-regions) for more details on how to configure code regions for EXiP.

#### Configuring Code Regions

Devices with in-package flash are delivered secure by default, with AXiP enabled on two code regions, so no additional configuration is typically required. However, users working with external flash devices, or those with specific application needs, may choose to configure code regions for greater flexibility. Configuring code regions is highly application dependent, so some consideration and planning is needed. This section will serve as a guide to helping users understand how to plan out code region configurations.

There are two methods that can be used in order to set a custom code region configuration. One method is to use SE Manager APIs, such as `sl_se_code_region_get_config`, `sl_se_code_region_apply_config`, and `sl_se_code_region_close`, which respectively read, apply, and close the custom region configuration. More details on these APIs can be found in our [SE Manager Documentation](https://docs.silabs.com/gecko-platform/latest/platform-security-api/sl-se-manager).

The second method is configuring code regions through the DCI on the device using Simplicity Commander. This is the main method used in upcoming sections of this document.

##### Data Regions versus Code Regions

Series 3 devices introduce the concept of separate code regions and data regions in flash. Code regions are made up of 32 kB erasable pages which are used to store firmware images. Each code region supports only one updatable firmware image, which is why it is standard practice to allocate one region for the bootloader and another for the application firmware. Alternatively, they can be combined within a single region, in which case both must be updated simultaneously and share the same version number.

Data regions are 4 kB erasable pages which are used to store data, and are most commonly used for NVM3 and GBLv4 storage. The XiP features (AXiP and EXiP) are only applicable to code regions, not to data regions. This does not mean that data in the data region cannot be protected; NVM3 and GBLv4 data can be encrypted before it is written to the data region.

It is important to take into account the size of the data region required by an application when configuring code regions, as resizing code regions impacts the size of the data region. Configuring code regions via OTA updates is not supported. Thus, users should ensure enough space is reserved for the bootloader, application firmware, NVM3, GBLv4, and any other required components, for the lifetime of the device.

##### Physical versus Logical Mapping

Differences in physical and logical flash mapping must be considered when resizing regions to ensure no code or data regions are overwritten. Physical flash space is allocated to regions based on configuration (AXiP, EXiP, plaintext) and region type (code, data, or reserved for SE firmware).

One reserved region in physical flash is the 192 kB area allocated for SE Firmware. It is placed at the beginning of physical flash and ends at the start of user-accessible flash, or the start of code region 0.

When AXiP is enabled, an extra 4-bytes of MAC data is stored for every 32-bytes of ciphertext. Thus, this results in 4 kB of MAC data stored for every 32 kB ciphertext data. This MAC is not directly accessible, because it has no associated logical address, but must be accounted for when calculating code and data region sizes.

For EXiP, plaintext code regions, and data regions, one-to-one mapping is used between physical and logical flash maps, independent of other code regions. Address translation between physical and logical flash mapping is handled by the EXTMEM subsystem.

![Physical versus Logical Mapping of Custom Configured SixG301 Device](/iot-security-series-3-axip/0.1/images/an1509-phyical-vs-logical-mapping.png)

An example of a SixG301 device with a custom code region configuration is shown above. The image illustrates a side-by-side comparison of physical and logical address space. In this example, AXiP is enabled on Region 0 and 1, resulting in 4 kB of MAC data stored per 32 kB of ciphertext. The EXiP, plaintext, and data regions map one to one.

To determine the remaining flash available for the data region, subtract the total size of all configured code regions (including MAC overhead) and the reserved SE firmware area from the total flash size. The result is the available space for the data region. For example:

**Data Region Size = (Total Flash) - (Reserved SE Firmware Region) - (Total Code Region Size, including MAC overhead)**

##### Code Region Configuration File

To configure code regions via the DCI, Commander takes in a YAML format configuration file, which can be generated by reading the current configuration from the device. The examples section of this document contains step-by-step instructions on how to use this file to reconfigure code regions. An example code region configuration file in YAML format is shown below.

```json
regions:
  - size_kb: 32
    protection: encrypted_authenticated
  - size_kb: 1408
    protection: encrypted_authenticated
```

Listed below are the required fields for the configuration file as well as their acceptable values.

###### Regions

- Up to 8 regions can be configured  
  - Each region is listed as a bullet point, starting from Region 0 at the top of the file, and incrementing one region at a time.  
  - Each region must have a size and protection type set.

###### Size

- Each region must be sized as a multiple of 32 kB.

##### Protection Type

- Setting the protection to `encrypted_authenticated` enables AXiP on the code region.
- Setting the protection to `encrypted` enables EXiP on the code region.
- Setting the protection to `none` disables all protection on the code region, resulting in the code stored in plaintext.

For example, the code region configuration for the custom configuration illustrated in Figure 5.1 is listed below.

```json
regions:
  - size_kb: 32
    protection: encrypted_authenticated
  - size_kb: 640
    protection: encrypted_authenticated
  - size_kb: 256 
    protection: encrypted
  - size_kb: 128 
    protection: none
```

> **Note:** When code regions are modified, firmware images must also be updated to ensure the linker files align with the code region configuration. Refer to [Platform Software Documentation](https://docs.silabs.com/gecko-platform/5.2.1/platform-memory-model/#resizing-code-regions) for details on modifying linker files to match code region configurations.

##### Closing a Code Region

Once code regions are configured and firmware is programmed to the device, code regions **must** be closed. Closing a code region locks the code region to prevent writes to the region, as well as further region configuration. Each time a code region is closed, the SE's MTP is updated, which causes an SE OTP bit to be used. More details on SE OTP bits are covered in the following section.

> **Note:** To open a closed code region, an erase of the region must be performed.

#### Considerations for Development Devices

When developing with AXiP or EXiP-enabled devices, certain considerations must be taken into account. Specifically, SE OTP bits are consumed each time an IV is generated and when a code region is closed. This occurs because each of these operations triggers an update to the SE MTP memory. The OTP bits serve to prevent rollback attacks by ensuring that the SE MTP cannot be reverted to a previous state.

By default, IVs are regenerated each time a code region is erased to prepare the region for reprogramming. Additionally, flashing a firmware image using Simplicity Commander automatically triggers the closure of the associated code region. During development, where devices are frequently flashed and erased, this default behavior can lead to exhaustion of SE OTP memory.

The SE OTP counter is at least 2 kB in size and may be allowed to overflow into the next available OTP region if space permits. How- ever, once all available OTP space is exhausted, the device enters an EOL (End of Life) state and can no longer be reflashed. This section outlines best practices to avoid SE OTP exhaustion during development.

##### Reading SE OTP Count

The current number of OTP bits consumed can be read through the use of the following command. Once SE OTP is consumed, the device will enter an EOL state. In this state, requested operations such as reflashing a device will not be able to be carried out.

```sh
commander security otprollbackcount -d sixg301
```

```json
Number of used OTP rollback bits: 9 
DONE
```

##### Skip Closing a Code Region

When using Simplicity Commander, code regions are closed automatically when using the commander flash command. To avoid clos- ing a code region when running this command, a user can specify the --noclose flag, which will leave the region open. This option is only intended for use to prevent exhaustion of OTP bits on development devices when continuous reflashing is done.

> **Note:** Closing a code region is a prerequisite for Secure Boot, as it enables the SE to access Region 0 to perform signature validation on the bootloader firmware. Therefore, on development devices with secure boot enabled, code regions must be closed in order for firmware to be executed by the SE.

```sh
commander flash example.hex --noclose -d sixg301
```

```c
Parsing file example.hex...
Writing 168756 bytes starting at address 0x01000000 
Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB) 
Erasing range 0x01008000 - 0x010B7FFF (1 sector, 704 KB) 
Programming range 0x01000000 - 0x01001FFF (8 KB)
...
Programming range 0x010B6000 - 0x010B7FFF (8 KB)
Flashing completed successfully!
DONE
```

On production devices, a code region must be closed after firmware programming to prevent further modification of the region. This can be done through the flashing command, without specifying the --noclose flag, or through a standalone DCI command in Simplicity Commander, shown in [Closing a Code Region](examples#closing-a-code-region).

##### Transition to Development Device Command

In order to avoid resource exhaustion on development devices due to IV rolling, the transition to development command (also referred to as the Skip IV Roll command) can be used to issue a one-time command which will enforce the same IV to be used for the lifetime of the device. As this flag is enabled in OTP, this setting cannot be reversed once enabled. **Devices with this option set must only be used for development purposes.** Once Skip IV Rolling is enabled, devices should be considered non-secure and should not enter production, as reusing IVs on devices in the field can introduce vulnerabilities which could lead to data confidentiality being impacted. When this option is not set, IVs will continue to be rolled on each flash erase, which will maintain security of the encrypted data.

To permanently disable IV rolling on a development device, issue the following command. This command was added in Simplicity Commander version 1.19.2 release.

```sh
commander security transitiontodevelopment -d sixg301
```

```c
================================================================================
THIS IS A ONE-TIME command which permanently changes the security properties of the device. Once done, the device permanently uses the same IV for encryption of flash, which is not secure (using the same IV and same key can lead to exposure of the encrypted data).
This should only be enabled on development devices to prevent exhausting OTP rollback bits after repeated flash/erase cycles.

Type 'continue' and hit enter to proceed or Ctrl-C to abort:
================================================================================
continue
The device has been permanently transitioned to NOT SECURE development mode DONE
```

> **Note:** This command prevents OTP bits from being consumed during IV generation only. OTP consumption will still occur during code region closures and firmware version updates; therefore, OTP exhaustion remains possible even when this command is used.

#### Examples

##### Prerequisites

At the time of publication, this document was written using Simplicity Commander version 1.19.2 and SE Firmware version 3.3.1. It is a requirement to upgrade to at least these versions before proceeding, but it is recommended to upgrade to the latest version of both products, if a newer version is available. Install the latest version of Simplicity Commander delivered via silabs.com, to ensure you have the latest features and bugfixes. Additionally, it is recommended to upgrade devices to the latest SE Firmware version, delivered as part of the Simplicity SDK, as support for new Commander instructions, bug fixes, features, and vulnerability patches may be included in these updated versions.

> **Note:** Before continuing with the steps listed in this section, refer to [Considerations for Development Devices](considerations-for-development-devices#considerations-for-development-devices) for important informa- tion on using AXiP and EXiP on development devices.

##### Using AXiP Out of the Box

When using an in-package flash device with default configuration, all that needs to be done is to flash a valid image to the device. This section shows how to read the default region configuration on the device and program a firmware image with automatic closing of code regions.

On devices with external flash, AXiP is not enabled out of the box. Once the external flash is initialized and SE firmware is program- med, AXiP is configured to the default two-region setup (bootloader and application), matching the behavior of in-package flash devi- ces.

###### Reading Default Code Region Configuration

To read the region configuration details from a device, issue the following command. This command is not required to be run for use AXiP out of the box, it is only intended to display the current configuration status.

```sh
commander security readregionconfig -d sixg301
```

```c
Index        : 0
Size         : 32 kB
Protection   : Encrypted and authenticated 
Closed       : False

Index       : 1
Size        : 1408 kB
Protection  : Encrypted and authenticated
Closed      : False

DONE
```

###### Flashing a Device with AXiP Enabled

To use AXiP on this device, simply flash the firmware image to the device using the following command. This command will auto- matically close the code regions after flashing is completed successfully.

```sh
commander flash example.hex -d sixg301
```

```c
Parsing file example.hex...
Writing 168756 bytes starting at address 0x01000000 
Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB) 
Erasing range 0x01008000 - 0x010B7FFF (1 sector, 704 KB) 
Programming range 0x01000000 - 0x01001FFF (8 KB)
...
Programming range 0x010B6000 - 0x010B7FFF (8 KB) 
Closing region 1
Closing region 0
Flashing completed successfully! DONE
```

##### Custom Code Region Configuration

Modifying the region configuration can be done on devices with open code regions. If code regions are closed, they cannot be modified or reconfigured until they are erased, which will reopen the closed code region.

> **Note:** The following steps begin with a device which is in the default configuration, where all configured code regions are open. If a user is reconfiguring a device with closed code regions, issue a commander device masserase or a commander device recover command to the device before proceeding.

1. To begin modifying a device's code region configuration, a configuration YAML file must be generated. The recommended way to do this is to read out the current configuration into a YAML file using the following command.  
   ```sh  
   commander security readregionconfig --outfile region_config.yaml -d sixg301  
   ```  
   ```c  
   Writing parsed configuration to file region_config.yaml...   
   DONE  
   ```  
   Below is a copy of the contents of the region_config.yaml file. This was read out from a device in the default code region config- uration state.  
   ```c  
   regions:  
    - size_kb: 32  
        protection: encrypted_authenticated  
    - size_kb: 1408  
        protection: encrypted_authenticated  
   ```
2. Modify the code region_config.yaml file and save the modified file. More details on the allowed fields for this file can be found in the [Code Region Configuration File](configuring-code-regions#code-region-configuration-file) section of this document. An example of a modified region_config.yaml file is shown below.  
   ```c  
   regions:  
       - size_kb: 32  
         protection: encrypted_authenticated  
       - size_kb: 256   
         protection: encrypted  
       - size_kb: 64   
         protection: none  
   ```
3. Write the new configuration file to the device using the following command.  
   ```sh  
   commander security writeregionconfig region_config.yaml -d sixg301  
   ```  
   ```c  
   Reading configuration from file region_config.yaml...   
   Writing region configuration to device...  
   DONE  
   ```
4. Read out the configuration of the device to verify settings were applied successfully.  
   ```sh  
   commander security readregionconfig -d sixg301  
   ```  
   ```c  
   Index       : 0  
   Size        : 32 kB  
   Protection  : Encrypted and authenticated  
   Closed      : False  
     
   Index       : 1  
   Size        : 256 kB   
   Protection  : Encrypted   
   Closed      : False  
     
    Index      : 2    
    Size       : 64 kB  
    Protection : Plaintext   
    Closed     : False  
     
    DONE  
   ```
5. Once the code regions are configured, firmware can be programmed to the regions using the commander flash command. In this example, the `--noclose` flag is used to later illustrate how to close a code region independently from flashing.  
   ```sh  
   commander flash bootloader.hex --noclose -d sixg301  
   ```  
   ```c  
   Parsing file bootloader.hex...  
   Writing 18788 bytes starting at address 0x01000000   
   Erasing range 0x01000000 - 0x01007FFF (1 sector, 32 KB)   
   Programming range 0x01000000 - 0x01000FFF (4 KB)   
   Programming range 0x01001000 - 0x01001FFF (4 KB)   
   Programming range 0x01002000 - 0x01002FFF (4 KB)   
   Programming range 0x01003000 - 0x01003FFF (4 KB)   
   Programming range 0x01004000 - 0x01004FFF (4 KB)   
   Programming range 0x01005000 - 0x01005FFF (4 KB)   
   Programming range 0x01006000 - 0x01006FFF (4 KB)   
   Programming range 0x01007000 - 0x01007FFF (4 KB)   
   Flashing completed successfully!  
   DONE  
   ```

##### Closing a Code Region

1. The following command can be used to close a code region. The command takes in a region index, starting from 0, and an optional code region version number. This command was run following the previous step where a bootloader was flashed to a device. Closing a code region is required after regions are configured and firmware is programmed.  
   > **Note:** The code region version can only be set when a code region is closed. This functionality is supported exclusively through the DCI using this command.  
   ```sh  
   commander security closeregion 0 --codeversion 2 -d sixg301  
   ```  
   ```c  
   Succesfully closed code region 0 (version 0x00000002)  
   DONE  
   ```
2. To verify the code region was closed, read out the current code region configuration.  
   ```sh  
   commander security readregionconfig -d sixg301  
   ```  
   ```c  
   Index         : 0  
   Size          : 32 kB  
   Protection    : Encrypted and authenticated   
   Closed        : True  
     
   Index         : 1  
   Size          : 256 kB   
   Protection    : Encrypted  
   Closed        : False  
     
   Index         : 2  
   Size          : 64 kB  
   Protection    : Plaintext  
   Closed         : False  
     
   DONE  
   ```

#### Revision History

##### Revision 0.1

September, 2025

- Initial revision

## Production Guide

### Silicon Labs IoT Security Production Guide

Securing an IoT device is a highly complicated and costly process. You must generate public and private keys for secure boot and secure debug, sign code with a private key, store all the private keys in an HSM, place the public keys for secure boot and secure debug in one-time-programmable (OTP) memory, flip OTP bits for secure boot and secure debug, and flash the encrypted code and identity certificates within the hardware.

CPMS streamlines the programming part of this process for you. Even the most advanced security features, certificates, and identities can be programmed in a secure, fast, and cost-efficient way at the Silicon Labs factories. This section provides details on CPMS, in addition to Public Key Infrastructure (PKI) Recommendations.

- [**Custom Part Manufacturing Service**](/iot-security/1.3.0/iot-security-cpms/): Explains the process for ordering custom Series 2 parts through the CPMS, including details on security settings and use cases for configuring a device for an untrusted manufacturing environment and importing custom wrapped keys.
- [**PKI Recommendations**](/iot-security/1.3.0/iot-security-pki-recommendations/): Outlines the recommended establishment, management, and security of PKI for business partners and customers of Silicon Labs.

### PKI Recommendations

This section outlines the recommended establishment, management, and security of Public Key Infrastructure (PKI) for business partners and customers of Silicon Labs. PKI plays a pivotal role in ensuring secure communication, data integrity, and authentication within our business ecosystem. This document sets forth recommended practices for the creation, management, and protection of secret keys and certificates by our partners and customers.

#### Scope

These recommendations apply to all business partners and customers involved in transactions, communications, or collaborations with Silicon Labs and Silicon Labs Services that necessitate the use of PKI technology.

#### Responsibilities

##### Business Partners and Customers Responsibilities

- **Creation of Secret Keys and Certificates**: Business partners and customers should generate their secret keys securely and procure associated digital certificates from reputable Certificate Authorities (CAs) or generating their own digital certificates in accordance with the recommendations in this document. It is imperative that secret keys are generated using robust methods and are not shared with unauthorized parties.
- **Protection of Secret Keys**: Business partners and customers should implement comprehensive security measures to safeguard their secret keys against unauthorized access, loss, or theft. This encompasses encryption, access controls, regular key rotation where applicable, and employing secure storage methodologies. Backup and recovery of the secret keys is essential, and should be considered in case of disaster recovery needs. Keys should be stored in a well-managed and protected hardware security module (HSM).
- **Revocation and Renewal**: Business partners and customers should promptly revoke compromised or no longer required certificates and renew certificates before expiration to maintain ongoing security. Affected parties should have a way to determine status of certificate revocation and/or renewal through a hosted certificate revocation list (CRL) or online certificate status protocol (OCSP).
- **Ensure Internal Security**: In addition to the material security, business partners and customers should also maintain effective security around their organization and it's operations, staff and contractors. This means maintaining endpoints and infrastructure in a secure way, such as patching operating systems and applications, hardening user applications and restricting administrative privileges. People in the organization and those managing the keys and certificates should be verified as trusted and secure.
- **Audits**: Business partners and customers should conduct regular audits of PKI and CA infrastructure and operations to confirm adherence to these recommendations and industry standards.

#### Security Controls

NIST (National Institute of Standards and Technology) is an indispensable tool to navigate and strengthen cybersecurity systems and can be referenced as a guide for further recommendation on these Security Controls.

- **Access Controls**: Business partners and customers should implement access controls to limit access to secret keys and certificates to authorized personnel exclusively. This includes implementing role-based access control (RBAC) and conducting regular access reviews to ensure that only essential individuals have access to sensitive cryptographic materials.
- **Encryption**: All secret keys and sensitive certificate information should be encrypted during transmission and storage using robust cryptographic algorithms and protocols.
- **Key Management**: Business partners and customers should adopt robust key management practices, encompassing key generation, storage, rotation, and destruction, in accordance with industry best practices and standards.
- **Monitoring and Auditing**: Business partners and customers should implement monitoring and auditing mechanisms to monitor access to secret keys and certificates, detect unauthorized activities, and generate audit trails for compliance purposes.

#### Revision History

This document will undergo periodic review and updates as necessary to reflect changes in technology, security requirements, or regulatory mandates.

#### Contact Information

For inquiries or concerns regarding these recommendations, contact [certificateauthority@silabs.com](mailto:certificateauthority@silabs.com).

### Custom Part Manufacturing Service

#### Custom Part Manufacturing Service

This section describes how to order custom Series 2 and Series 3 parts through the Custom Part Manufacturing Service (CPMS). It also explains how to customize device identity security certificates and wrap custom keys.

For more information about Silicon Labs security features, see [IoT Endpoint Security Fundamentals](/iot-security/1.3.0/iot-endpoint-security-fundamentals).

##### What is CPMS?

Custom Part Manufacturing Service (CPMS) allows you to customize Silicon Labs hardware – wireless SoCs, modules, MCUs – at the factory. The CPMS self-service web portal guides you through the customization process and its various customizable features and settings. You can place orders for customized test and production units to our factories securely via the CPMS portal.

Unlike traditional flash programming, CPMS is a secure provisioning service that enables you to customize your chips with several highly advanced features such as secure boot, secure debug, encrypted OTA, public, private and secret keys, secure identity certificates, and more.

The custom features, identities, and certificates are injected on the hardware securely, quickly, and cost-efficiently at the world’s safest place, the Silicon Labs factories.

##### Why Choose CPMS?

Securing an IoT device is a highly complicated and costly process. You must:

- Generate public and private keys for secure boot and secure debug
- Sign code with a private key
- Store all the private keys in a Hardware Security Module (HSM)
- Place the public keys for secure boot and secure debug in one-time-programmable (OTP) memory
- Flip OTP bits for secure boot and secure debug
- Flash the encrypted code and identity certificates within the hardware

CPMS streamlines the programming part of this process for you. Even the most advanced security features, certificates, and identities can be programmed in a secure, fast, and cost-efficient way at the Silicon Labs factories.

#### CPMS Portfolio

##### Features supported in CPMS

The following table summarizes feature support by device family and security level:

|Device family / security level|Secure Debug|Secure Boot|Tamper|Public sign key (OTP)|Public command key (OTP)|OTA decryption key (OTP)|Custom keys (wrapped)|AXiP|Custom identity (certs in flash)|Custom identity (certs in OTP)|Flash programming|Custom marking|Other customizations|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|**Series 2 SVM–VSE (Secure Vault Mid – Virtual Secure Engine)**|✅|✅|—|✅|✅|—|—|—|✅|—|✅|✅|✅|
|**Series 2 SVM–HSE (Secure Vault Mid – Hardware Secure Engine)**|✅|✅|—|✅|✅|✅|—|—|✅|—|✅|✅|✅|
|**Series 2 SVH–HSE (Secure Vault High – Hardware Secure Engine)**|✅|✅|✅|✅|✅|✅|✅|—|—|✅|✅|✅|✅|
|**Series 3 Secure Vault**|✅|✅|✅|✅|✅|✅|✅|✅|✅|—|✅|✅|✅|
|**SiWx917**|—|—|—|—|—|—|—|—|—|—|✅|✅|✅|

> **Note:** Ecosystem identity support is available only on select devices. Contact your sales representative or Silicon Labs technical support for more information.

#### SE Firmware

Select the latest available SE firmware version to stay current with bug fixes and security patches. Silicon Labs also recommends updating the SE firmware as new versions become available.

For information about implementing SE firmware field upgrades, see [Production Programming of Series 2 and Series 3 Devices](/iot-security/1.3.0/prod-programming-series2-and-series3).

Select the appropriate SE firmware version for the target device OPN, as shown in the following figure.

![SE Firmware Programming](/iot-security-cpms/0.3/images/cpms-se-firmware.png)

#### Debug Lock Settings

CPMS provides four debug lock settings for this required field:

- Standard Debug Lock
- Secure Debug Lock
- Permanent Lock
- Unlocked

If you select **Secure Debug Lock**, you must provide a public command key. CPMS provisions the public command key to the device, if required, and applies the selected debug lock setting.

For more information about each debug lock setting, see [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/1.2.2/series2-secure-debug/).

The following table summarizes the available settings in the [CPMS portal](https://console.silabs.com/login):

|CPMS Setting|Behavior|How Unlock Works|
|---|---|---|
|Unlocked|Debug access remains fully enabled.|Unlock is not required.|
|Standard Debug Lock|Debug access is locked at boot.|Can be unlocked only by performing a device erase (flash memory is erased).|
|Secure Debug Lock|Debug access is locked at boot and protected by a challenge-response mechanism.|Can be temporarily unlocked using Secure Debug Unlock with a provisioned public command key.|
|Permanent Lock|Debug access is permanently disabled. Device erase and Secure Debug are blocked.|The device cannot be unlocked.|

> **Note:** Enabling **Secure Debug Lock** in the CPMS portal permanently disables device erase.

To configure the required debug lock setting, select one of the available options in the [CPMS portal](https://console.silabs.com/login), as shown in the following figure.

![screenshot](/iot-security-cpms/0.3/images/cpms-debug-lock-section-settings.png)

#### AXiP Configuration

Authenticated eXecute in Place (AXiP) is a Series 3 feature that protects executable code stored in QSPI flash to ensure integrity, confidentiality, and authenticity. At a high level, AXiP is implemented by the Secure Engine (SE) and EXTMEM subsystems. These components perform encryption and authentication during programming and automatically verify code during execution without requiring application firmware to manage cryptographic keys.

|Flash Configuration|Key Used|
|---|---|
|Plaintext|None|
|EXiP (Encrypted eXecute in Place)|EXiP key|
|AXiP (Authenticated eXecute in Place)|AXiP key|

> **Note:** AXiP and EXiP keys are PUF-derived keys. These keys cannot be modified during the CPMS provisioning process.

##### How AXiP Works

- AXiP uses AES-GCM authenticated encryption. If authentication fails during execution, the device faults. This behavior prevents the execution of modified code.
- For SixG301 (xG301) devices with in-package flash, AXiP is enabled by default for two code regions (typically a bootloader region and an application region). The default region sizes depend on the flash size and can be inspected using Simplicity Commander.
- Series 3 devices support up to eight code regions. Each region can be configured for AXiP, EXiP, or plaintext protection.

For more information about AXiP, see [Series 3 AXiP](https://www.silabs.com/documents/public/application-notes/an1509-series3-axip.pdf).

##### AXiP Using CPMS

Users with specific application requirements can customize code region configurations. This includes adding new code regions (up to eight), adjusting code region sizes, and selecting the protection type, such as AXiP, EXiP, or plaintext.

After configuring code regions and programming firmware, the code region **must** be closed to prevent further configuration changes or writes. Closing a region updates the Secure Engine MTP (consuming an OTP bit), and reopening it requires erasing the region.

In CPMS, code regions are automatically closed when a firmware image is uploaded in the **Flash Programming** section. Code regions can remain open only when firmware images are not uploaded as part of the CPMS provisioning process.

> **Note:** Programming AXiP or EXiP regions programs the entire region, including unused space, which is padded with `0xFF`. Before selecting an AXiP region size, evaluate the current firmware size, expected future updates (such as bug fixes and security patches), and programming costs.

##### Customize Code Region Configurations

- In the **Authenticated eXecute in Place (AXiP)** section, Region 0 and Region 1 are displayed with their default configurations. These regions can also be customized as part of the CPMS provisioning process.  
  As shown in the following figure, you can customize the CPMS label, Memory Block Size, Protection Mode, and Code Region Close options based on your requirements.  
  ![screenshot](/iot-security-cpms/0.3/images/cpms-axip-section-reg0-reg1-custom-config-updated.png)

> **Note:** Regardless of the selected option, the corresponding code regions must be closed if a firmware image is uploaded in the **Flash Programming** section.

- To add and customize additional regions, click **Add Region**.  
  ![screenshot](/iot-security-cpms/0.3/images/cpms-axip-section-add-region.png)
- The [CPMS Console UI](https://cpms.silabs.com/login) provides a **Flash Layout** view to assist with code region size planning. Use this view as a reference when defining code region sizes to help avoid memory overruns and ensure correct configuration.  
  ![screenshot](/iot-security-cpms/0.3/images/cpms-axip-section-flash-layout.png)
- The **Flash Layout** view displays a warning if the configured region size exceeds the available memory, as shown in the following figure.  
  ![screenshot](/iot-security-cpms/0.3/images/cpms-axip-section-flash-layout-overrun.png)

#### Secure Boot with RTSL Settings

Secure Boot with RTSL is a security feature available on Silicon Labs Series 2 and Series 3 devices. It validates the integrity and authenticity of each firmware image before the image is allowed to run on the device.

Establishing a complete root of trust requires enabling secure boot in both the device OTP and the user-generated bootloader. The secure boot setting stored in device OTP causes the first-stage bootloader in the Secure Engine to verify the signature of the user-generated and signed second-stage bootloader.

The next link in the chain of trust is established by enabling secure boot in the second-stage bootloader. This setting causes the second-stage bootloader to verify the signature of the application image before execution.

In CPMS, you can quickly configure the OTP settings required for secure boot. Because OTP settings are irreversible, review each setting carefully before making a selection.

The Secure Boot with RTSL OTP settings include:

- Enable bit
- Certificates Required bit
- Anti-Rollback Enable bit
- Flash page locking settings

For detailed information about these settings, see [Series 2 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/index.html).

After you select these settings, CPMS prompts you to provide a Secure Boot Key, also known as a public sign key. This key is used verify the firmware image signed by the corresponding private key.

For more information about the public sign key, see [Secure Boot Key](standard-security-keys#secure-boot-key).

The following figure shows the Secure Boot configurations available in CPMS for Series 2 devices.

![CPMS Configure Secure Boot screenshot](/iot-security-cpms/0.3/images/cpms-secure-boot-section-series2-setting.png)

The following figure shows the Secure Boot configurations available in CPMS for Series 3 devices.

![CPMS Configure Secure Boot S3 screenshot](/iot-security-cpms/0.3/images/cpms-secure-boot-section-series3-setting.png)

As described earlier, establishing a complete root of trust for secure boot requires enabling secure boot in both the device OTP and the bootloader image uploaded through CPMS. If Secure Boot with RTSL is enabled in OTP but secure boot is not enabled in the bootloader, the device verifies only the bootloader image signature. In this configuration, the application image signature is not verified.

Silicon Labs recommends establishing a complete root of trust to reduce the device attack surface. For instructions on creating a bootloader project with secure boot enabled, see [Generating the Bootloader](03-configure-device-untrusted#generating-the-bootloader).

> **Important:** Enabling Secure Boot in the CPMS portal enables Secure Boot only in the Secure Engine (SE) OTP. To complete the root of trust, Secure Boot must also be enabled in the bootloader (BTL) image to ensure that the application image signature is verified. Both configurations are required to establish a complete Secure Boot chain.

![Secure Boot in OTP vs Bootloader](/iot-security-cpms/0.3/images/cpms-secure-boot-otp-btl-image.png)

##### Enabling Secure Boot with RTSL on a VSE Device

A few extra steps are required to establish a full root of trust when enabling secure boot on a Virtual SE (VSE) device in CPMS. As outlined previously, the secure boot settings in OTP will need to be enabled and a public signing key should be uploaded to CPMS as the first steps to enable secure boot. This public signing key will be provisioned in the device’s OTP memory by CPMS and will be used by the device to verify the signature on the second stage bootloader. For the second stage bootloader to verify the signature on the application on a VSE part, the bootloader will use the public signing key stored in the top page of main flash. Refer to [Series 2 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/index.html) for more information on enabling secure boot with RTSL on a VSE device.

Follow the steps outlined in this section to place the public signing key in flash using a token file.

1. When creating a public and private signing key pair for secure boot, use the `--tokenfile` flag to write the public signing key to a token file. For more information, see [Util Commands](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-commands/util-commands#util-commands).  
   ```c  
   commander util genkey --type ecc-p256 --privkey  
   sign_privkey.pem --pubkey sign_pubkey.pem --tokenfile  
   sign_pubkey.txt  
   ```
2. Flash the signed bootloader and application images to the device using the command described in step 3. For instructions on generating and signing bootloader and application images, see the **Provision Public Sign Key and Secure Boot Enabling** section in [Examples - Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/mcu-bootloader/latest/series2-secure-boot-with-rtsl/03-examples#provision-public-sign-key-and-secure-boot-enabling).
3. Flash the token file to the device using the `flash` command. For more information, see [Util Commands](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-commands/util-commands#util-commands).  
   ```c  
   commander flash --tokenfile sign_pubkey.txt  
   ```  
   To provision the OTA decryption key on a VSE device, follow the steps in [OTA Decryption Key for VSE Devices](https://docs.silabs.com/iot-security/latest/iot-security-cpms/standard-security-keys#ota-decryption-key-for-vse-devices).  
   An OTA decryption key is required when the **Required Encrypted Upgrade Images** flag is enabled.
4. Use the `readmem` command to dump the flash contents, including the token file, signed bootloader, and signed application firmware, to a HEX file. For more information, see [Dump Flash Contents to File](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-commands/memory-read-commands#dump-flash-contents-to-file).  
   ```c  
   commander readmem --region @mainflash --outfile all.hex  
   ```  
   Before uploading the file to the CPMS portal, flash all.hex to a test device to verify that the application runs correctly.
5. Upload the file **all.hex** to CPMS using the **App and Bootloader** selection in the Flash Programming section. As mentioned, this hex image should contain the token file, signed bootloader, and signed application. This will establish a full root of trust on the VSE device, ensuring that only authentic firmware can run on the device.  
   ![CPMS Flash Programming screenshot](/iot-security-cpms/0.3/images/cpms-flash-programming.png)

#### Tamper Response

In CPMS, the default tamper configuration is automatically displayed for Secure Vault High (SVH) HSE and Series 3 Secure Vault devices. These configurations can be customized only for Secure Vault High and Series 3 Secure Vault devices.

Anti-tamper protection is available only on Secure Vault High and Series 3 Secure Vault devices. Each tamper configuration can be assigned one of five tamper response levels, ranging from ignoring the tamper event to erasing the device OTP.

When tamper protection is configured on a Secure Vault High or Series 3 Secure Vault device, CPMS requires a public command key.

For more information about anti-tamper protection, see [Anti-Tamper Protection Configuration and Use](/iot-security/1.3.0/efr32-secure-vault-tamper).

For Series 2 devices, configure tamper settings in the CPMS portal as shown in the following figure.

![screenshot](/iot-security-cpms/0.3/images/cpms-tamper-settings-series2.png)

For Series 3 devices, configure tamper settings in the CPMS portal or optionally upload a `configuration.json` file, as shown in the following figure.

![CPMS Configure Secure Boot screenshot](/iot-security-cpms/0.3/images/cpms-configure-secure-boot-jsonfile.png)

#### Standard Security Keys

The following sections describe the security keys supported by CPMS.

> **Important:** When using asymmetric key pairs, upload only the **public key** to the CPMS portal. CPMS programs the public key onto the device. Store the corresponding **private key** securely and do not share it.

For symmetric keys (for example, AES keys or decryption keys), handle and store the keys according to your security requirements. Upload these keys only when required by the use case.

Silicon Labs strongly recommends generating all keys using robust methods, storing private keys in a managed and protected Hardware Security Module (HSM), and restricting access to authorized personnel.

##### Secure Boot Key

The Secure Boot Key, also known as the public signing key, is used to authenticate the signature of a bootloader or application image.

CPMS accepts this key in `.pub`, `.pem`, or `.der` format. Generate the key as part of a public/private key pair, and provide only the public key to CPMS.

For more information about this key pair, see [Series 2 and Series 3 Secure Boot with RTSL](https://docs.silabs.com/iot-security/latest/series2-secure-boot-with-rtsl/).

##### Command Key

The Command Key is used to disable tamper responses and perform Secure Debug Unlock operations.

CPMS accepts this key in `.pub`, `.pem`, or `.der` format. Generate the key as part of a public/private key pair, and provide only the public key to CPMS.

For more information about this key pair and its usage, see:

- [Series 2 and Series 3 Secure Debug](https://docs.silabs.com/iot-security/1.2.2/series2-secure-debug/)
- [Anti-Tamper Protection Configuration and Use](/iot-security/1.3.0/efr32-secure-vault-tamper)

##### OTA Decryption Key

The OTA Decryption Key, also known as the GBL Decryption Key, is used for decrypting GBL payloads used for firmware upgrades. This key will only be required if you enable “require encrypted firmware upgrade files” in the bootloader. Refer to [Silicon Labs Gecko Bootloader User’s Guide](https://docs.silabs.com/mcu-bootloader/latest/bootloader-user-guide-gsdk-4/) for more information. An example of creating a bootloader with encrypted upgrades required is shown in [Generating the Bootloader](03-configure-device-untrusted#generating-the-bootloader).

On HSE and Series 3 Secure Vault devices, you can provide a 16-byte decryption key to CPMS for provisioning to the device.
On VSE devices, you can provide this key to CPMS only through a token file, similar to the public sign key used for secure boot.

###### OTA Decryption Key for VSE Devices

A few additional steps are required to setup a VSE device to use an OTA Decryption Key in CPMS. Refer to _Key Provisioning_ in [Production Programming of Series 2 and Series 3 Devices](/iot-security/1.3.0/prod-programming-series2-and-series3/07-key-provisioning) for more information.

1. Generate the key using the `util genkey` command.  
   ```c  
   commander util genkey --type aes-ccm --outfile aes_key.txt  
   ```
2. Once the key is generated, it needs to be written to a place accessible to the bootloader. This key can be placed in either the app properties struct of the GBL, or in the top page of main flash. Only one of these methods need to be used.  
   To write the OTA Decryption key into the Application properties struct of the bootloader project, use the following command.  
   ```c  
   commander convert bootloader.hex --aeskey aes_key.txt --outfile bootloader-keys.hex  
   ```  
   Note when using this method:  
   - The `--aeskey` option for the convert command requires Simplicity Commander v1.12.3 or above.  
   - The GBL Decryption Key can only be added to the GBL with Application Properties Struct v1.2 or higher (GSDK v4.1.0 or higher).  
   - This procedure must be implemented before signing the GBL image for Secure Boot.  
   To write the OTA Decryption Key to the top page of flash on a VSE device, use the following command.  
   ```c  
   commander flash --tokenfile aes_key.txt  
   ```

#### Additional Custom Keys

##### Key Wrapping

Secure Vault High and Series 3 Secure Vault devices support key wrapping, a feature that encrypts keys using a Physically Unclonable Function (PUF) key. A PUF key is secret, random, and unique to each device. PUF keys are not stored in flash and are not vulnerable to flash extraction attacks.

CPMS allows customers to provide their own keys, which will be wrapped by the secure element and stored on the device. This means that the firmware image does not need to contain the key at any point in production.

> **Note:** CPMS supports a maximum of 10 custom wrapped keys.

To use this feature, provide the following fields to CPMS:

1. **Key Auth**: An 8-byte password that must be provided by software whenever the key is used. This password can be disabled by setting the Key Auth to 0x0000000000000000.
2. **Key Value**: The value of the key to be wrapped (max 200 bytes).
3. **Key Metadata**: 4 bytes of key metadata that include information such as the key type, allowed uses, and key length. For information about generating this value for an existing key, see [Import Custom Wrapped Keys for Series 2 Devices](04-import-custom-wrapped-keys-series-2) and [Import Custom Wrapped Keys for Series 3 Devices](05-import-custom-wrapped-keys-series-3).
4. **Key Address**: The address in user flash to which the key should be programmed.  
   ![CPMS Custom Keys screenshot](/iot-security-cpms/0.3/images/cpms-custom-keys.jpg)

#### Custom Certificates

CPMS allows you to customize the device identity certificate chain. Certificates use the X.509 format and must conform to [RFC 3280](https://datatracker.ietf.org/doc/html/rfc3280). For an example of a Silicon Labs device certificate, see [Authenticating Silicon Labs Devices Using Device Certificates](/iot-security/1.3.0/authenticating-devices-using-device-certificates/03-r-secureidentity).

##### Certificate Storage on Series 2 and Series 3 Devices

Certificate storage locations vary by device security type.

|Device Security Level|Certificate Location|Customization Support|Availability|
|---|---|---|---|
|Series 2 Secure Vault High (HSE)|Both certificates stored in SE OTP|Device certificate can be customized|Programmed by default|
|Series 2 Secure Vault Mid (VSE and HSE)|Both certificates injected into device flash (user-specified address)|Custom certificates supported through CPMS|Available through CPMS certificate injection|
|Series 3 Secure Vault (SixG301)|Both certificates injected into device flash (user-specified address)|Custom device certificates supported through CPMS|Available through CPMS certificate injection|

> **Note:** For devices that use flash-based certificate storage, you specify the storage address during CPMS configuration.

Currently, CPMS supports customization of the following device certificate fields:

1. **Common Name**: User-defined name of up to 30 characters. The value is appended with the device 64-bit EUI (for example, `EUI:xxxxxxxxxxxxxxxx`) and ends with either `S:SE0 ID:MCU` or `S:FL0 ID:MCU`, depending on the device security type.
2. **Organization**: User-defined company name of up to 64 characters.
3. **Country**: Valid two-letter country code (for example, `US`).
4. **Organizational Unit**: User-defined value of up to 64 characters.

If you require additional certificate customizations, specify them in the **Special Instructions** section of CPMS.
![CPMS Custom Identity screenshot](/iot-security-cpms/0.3/images/cpms-custom-identity.jpg)

#### Configuring a Device for an Untrusted Manufacturing Environment Example

This example will show how to order a custom part that is secure from the moment it leaves Silicon Labs. It has secure boot, secure debug lock, and encrypted upgrades enabled so that an untrusted contract manufacturer cannot access the debug port or upload un- signed and/or unencrypted applications.

This example uses an EFR32MG21B, which is a Secure Vault High part. Secure Vault Base, Secure Vault Mid, or Series 3 Secure Vault parts do not support the same customization options. As a result, some sections of this example do not apply to those devices.

##### CPMS

This section provides detailed information on starting a new custom part in CPMS and configuring the debug lock and Secure Boot.

1. In a browser, open CPMS at [https://console.silabs.com/cpms](https://console.silabs.com/cpms).  
   ![CPMS Console Login screenshot](/iot-security-cpms/0.3/images/cpms-console-landing.jpg)
2. Log in using your [www.silabs.com](http://www.silabs.com/) account credentials.
3. Give your sample order a name and select the part to be customized.  
   ![CPMS Part Name Entry screenshot](/iot-security-cpms/0.3/images/cpms-part-name.png)  
   a. Name: Enter _Example-1_. This name will be used within CPMS to help differentiate between custom devices.  
   ![CPMS Part Selection screenshot](/iot-security-cpms/0.3/images/cpms-configure-device-section-part-creation-step3a.png)  
   b. Part: Select any Secure Vault Mid or High part. In this example, select the part **EFR32MG21B010F1024IM32-B**. As you begin to type your part, the list will filter the part list based on your entry.  
   ![CPMS Part Selected screenshot](/iot-security-cpms/0.3/images/cpms-configure-device-section-create-cust-step-3b.png)  
   c. Once you have successfully entered a name for your order and selected the part to be customized, the **Create New Customization** button is enabled. You can begin to customize this part for your sample order.
4. Click **Create New Customization**. This takes you to the part customization page. Change the following configurations (configurations not listed can be left as the default):  
   a. Debug Lock: Select **Secure**.  
   ![CPMS Security Options Debug Lock screenshot](/iot-security-cpms/0.3/images/cpms-security-options.jpg)  
   b. Configure Secure Boot, Flash Lock, and Tamper Settings using the following steps:  
   ```c  
     To read the `user_configuration.json` file from the device, run the following command:  
     
    ```C  
     commander security genconfig --nostore --outfile user_configuration.json --device sixg301  
    ```  
     
    ```C  
     Configuration file written to user_configuration.json  
     DONE  
    ```  
   ```  
   For this example, turn off **Require Verify Certificate Before Secure Boot** because this example does not use certificates  
   When configuring Series 2 devices, use manual configuration. When configuring Series 3 devices, use either of the following methods.  
   - Manual Configuration: Set the options in the portal. This method is avaiable for both Series 2 and Series 3 customizations.    
     ![CPMS Configure Secure Boot screenshot](/iot-security-cpms/0.3/images/cpms-configure-secure-boot.png)  
   - Upload configuration file for Series 3 devices (optional): This method can only be used when customizing Series 3 devices. Upload a user_configuration.json file that sets Secure Boot settings and Tamper Responses.    
     ![CPMS Configure Secure Boot screenshot](/iot-security-cpms/0.3/images/cpms-configure-secure-boot-jsonfile.png)  
   c. Before you enter the keys and images, you need to generate them. This is covered in the following sections.

##### Generate and Configure an Application

To generate and configure an application:

1. Open Simplicity Studio.
2. In the Launcher view, click **EXAMPLE PROJECTS & DEMOS**.
3. Search for _blink_, and select the **Platform - Blink Bare-metal** project.
4. Click **Finish**.
5. There should now be a `blink_baremetal` project open in the Simplicity IDE view. Open `blink_baremetal.slcp`.  
   ![screenshot](/iot-security-cpms/0.3/images/image24.jpg)
6. Click on the **SOFTWARE COMPONENTS** tab.
7. In the Search bar, search for _bootloader_.
8. Click **Platform > Bootloader > Bootloader Application Interface**, and click **Install**.  
   ![screenshot](/iot-security-cpms/0.3/images/image25.jpg)
9. The application image will need an **application_properties.c** file as shown below to enable secure boot. The `.cert` pointer is set to NULL to disable the application certificate option. The signatureType and signatureLocation fields are filled by Simplicity Commander when signing the application image using the convert command.  
   ![screenshot](/iot-security-cpms/0.3/images/image26.jpg)
10. Now that the configuration is set, "Build" the project. This will generate binaries for the project.

![screenshot](/iot-security-cpms/0.3/images/image27.png)

###### Generating the Bootloader

To generate and configure a bootloader.

1. Now go back to the Launcher and search for _bootloader_.
2. Locate and **Create** the **Internal Storage Bootloader (single image on 1MB device)** example.
3. Open **bootloader-storage-internal-single.slcp**.
4. Click the **Software Components** tab, search for **Bootloader Core** and then click **Configure**.
5. Click **Require encrypted firmware upgrade files** and **Enable Secure Boot**.  
   ![screenshot](/iot-security-cpms/0.3/images/image28.png)
6. Build the project (if the build button is greyed out, you may need to click on the project in the Project Explorer).

##### Generating the Sign Key, the Command Key, and the OTA Decryption Key

Enabling secure boot and secure debug requires importing public keys. Ideally, these keys would be generated and managed by an HSM. This example will use Commander.

1. Create a sign key pair for secure boot.  
   ```C  
   commander util genkey --type ecc-p256 --privkey cpms-sign-priv.pem -- pubkey cpms-sign-pub.pem  
   ```  
   ```C  
   Generating ECC P256 key pair…  
   Writing private key file in PEM format to cpms-sign-priv.pem  
   Writing public key file in PEM format to cpms-sign-pub.pem  
   DONE  
   ```
2. Create a command key pair for secure debug:  
   ```C  
   commander util genkey --type ecc-p256 --privkey cpms-cmd-priv.pem -- pubkey cpms-cmd-pub.pem  
   ```  
   ```C  
   Generating ECC P256 key pair…  
   Writing private key file in PEM format to cpms-cmd-priv.pem  
   Writing public key file in PEM format to cpms-cmd-pub.pem  
   DONE  
   ```
3. Create an OTA decryption/encryption key for GBL upgrades:  
   ```C  
   commander util genkey --type aes-ccm --outfile cpms-gbl.txt  
   ```  
   ```C  
   Using Windows’ Cryptographic random number generator  
   DONE  
   ```

##### Signing and Merging the Application and Bootloader Images

We now need to prepare our application and bootloader for CPMS. First, we need to sign the images. Then, since CPMS requires the firmware image to be in one file, we need to merge the signed hex files. We will do this using the Simplicity Commander command line interface.

1. Open a terminal and navigate to your Simplicity Studio workspace.
2. Sign the bootloader:  
   ```C  
   commander convert internal-storage-bootloader-single.hex --secureboot --keyfile cpms-sign-priv.pem --outfile cpms-btl-signed.hex  
   ```  
   ```C  
   Parsing file internal-storage-bootloader-single.hex…  
   Found Application Properties at 0x000024a8  
   Writing Application Properties signature pointer to point to 0x000025e0  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: ca36debc860cdb720aabe9fdd37dc730172fe34571aedc452b52f9ef5a824264  
   R = 3E8E58AF660F769FE25E9262E6899188B61716723352367F0EC96DF6C7133B20  
   S = 5C36A7B3124F320C9B9B56B80D2F1A1D8B3593BC008E11B50015E3BEE4638537  
   Writing to cpms-btl-signed.hex  
   DONE  
   ```  
   This will create the **cpms-btl-signed.hex** signed image file in your workspace.
3. Sign the application:  
   ```C  
   commander convert blink_baremetal.hex --secureboot --keyfile cpms-sign-priv.pem --outfile cpms-app-signed.hex  
   ```  
   ```C  
   Parsing file blink_baremetal.hex…  
   Found Application Properties at 0x000061bc  
   Writing Application Properties signature pointer to point to 0x000064d8  
   Setting signature type in Application Properties: 0x00000001  
   Image SHA256: 030b8cdb43e7666b1a015ada8a658a96169be086177548b692a385edb5840295  
   R = 0C64B8EC9FEFD081EFEBF08E0744A13CA606BD654C1A6B108AF2F5C06AECD5A1  
   S = CA9DE6279F50C86CD317365FD98380D097D90764A9EDEFE06623FE9126763844  
   Writing to cpms-app-signed.hex  
   DONE  
   ```  
   This will create the **cpms-app-signed.hex** signed image file in your workspace.
4. Merge the signed hex files:  
   ```C  
   commander convert cpms-app-signed.hex cpms-btl-signed.hex -o cpms-merged.hex  
   ```  
   ```C  
   Parsing file cpms-app-signed.hex…  
   Parsing file cpms-btl-sgined.hex…  
   Writing to cpms-merged.hex…  
   DONE  
   ```  
   This will create **cpms-merged.hex** in your workspace.

##### Programming the Keys and Flash Memory

This section describes how to upload the public signing key and the merged signed HEX file.

The screenshots in this section show how to provision keys in OTP memory on devices that use a Hardware Secure Engine (HSE).

For VSE devices, provision the public signing key and OTA decryption key to flash based on your security requirements. For more information, see [OTA Decryption Key for VSE Devices](https://docs.silabs.com/iot-security/latest/iot-security-cpms/standard-security-keys#ota-decryption-key-for-vse-devices).

1. In CPMS, return to the **Standard Security Keys** section.
2. Click the blue upload button in the **Public Sign Key** field. In the file explorer pop-up, find and select the **cpms-sign-pub.pem** file.  
   ![CPMS Public Sign Key screenshot](/iot-security-cpms/0.3/images/cpms-standard-security-keys.jpg)
3. Click the blue upload button in the **Public Command Key** field. In the file explorer pop-up, find and select the **cpms-cmd-pub.pem** file.  
   ![CPMS Public Command Key screenshot](/iot-security-cpms/0.3/images/cpms-public-command-key.jpg)
4. For the OTA Decryption Key, copy the key value (in hex) from **cpms-gbl.txt** into the **OTA Decryption Key** field.  
   ![CPMS OTA Decryption Key screenshot](/iot-security-cpms/0.3/images/cpms-ota-decryption-key.png)

> **Note:** When customizing AXiP configurations on **Series 3 devices**, follow the instructions in the [AXiP Configuration](axip-configuration) section.

1. Scroll down to the **Flash Programming** section.  
   ![CPMS Flash Programming screenshot](/iot-security-cpms/0.3/images/cpms-flash-programming.png)
2. Click **CLICK HERE OR DRAG DROP TO UPLOAD A FILE**.
3. Navigate to your workspace. On Windows this will be in **C:/Users/<username>/SimplicityStudio/v5_workspace**.
4. Select **cpms-merged.hex** and click **Open**. CPMS only accepts Intel Hex files for firmware images.
5. You should now be able to see the binary added to your customization in CPMS.  
   ![CPMS Hex Uploaded screenshot](/iot-security-cpms/0.3/images/cpms-flash-hex-uploaded.jpg)
6. Scroll to the top of the page, and click **Review Order**.  
   ![CPMS Review Order screenshot](/iot-security-cpms/0.3/images/cpms-review-order.jpg)
7. Review the order details and the security configurations you entered.
8. After you place the order, the CPMS team processes the request and delivers sample parts for evaluation.
9. After you receive the samples, evaluate them to confirm that they meet the expected functionality and requirements. If the samples meet your expectations, approve the sample OPN in the CPMS portal to proceed with the production flow.

#### Import Custom Wrapped Keys

To import a custom wrapped key into CPMS, have the following field values available:

- Value
- Address
- Auth
- Metadata

The following examples show how to obtain the metadata value for asymmetric and symmetric keys:

- [Example 1: Import a Custom Wrapped Asymmetric Key](#example-1-import-a-custom-wrapped-asymmetric-key)
- [Example 2: Import a Custom Wrapped Symmetric Key](#example-2-import-a-custom-wrapped-symmetric-key)

##### Example 1: Import Custom Wrapped Asymmetric Keys

###### Prepare Custom Wrapped Keys for CPMS

The following steps demonstrate how to generate the wrapped key and required metadata for CPMS:

1. In Simplicity Studio, open the **Launcher** view, and then click **EXAMPLE PROJECTS & DEMOS**.
2. Search for _SE Manager_.
3. Create a project from the **Platform - SE Manager Digital Signature (ECDSA and EdDSA)** example.  
   ![screenshot](/iot-security-cpms/0.3/images/image35.jpg)
4. CPMS automatically wraps the key and writes it to flash. To emulate this behavior for testing, use the Memory System Controller (MSC) to write the key to flash. To enable the MSC, open **se_manager_signature.slcp**.
5. Open the **SOFTWARE COMPONENTS** tab.
6. Search for _msc_.
7. Click **MSC Peripheral**, and then click **Install**.  
   ![screenshot](/iot-security-cpms/0.3/images/image25.jpg)
8. Modify the `create_wrap_asymmetric_key` function in **app_se_manager_signature.c** to use the CPMS key. Instead of generating a key, import the ECC key. In **app_se_manager_signature.c**, line **255**, replace the following line:

```C
   print_error_cycle(sl_se_generate_key(&cmd_ctx, &asymmetric_key_desc), &cmd_ctx);
```

with:

```C
// YOUR KEY VALUE GOES HERE:
static uint8_t user_key[64] =
{
     0x79, 0x7D, 0x86, 0xE3, 0x5B, 0xAA, 0x03, 0xA5,
     0xEE, 0x09, 0xAB, 0x5E, 0x7E, 0xB1, 0x2D, 0xC3,
     0x92, 0xFC, 0xCE, 0xDC, 0xD0, 0x2A, 0xB0, 0xF7,
     0x56, 0x5E, 0x73, 0x30, 0x86, 0x1D, 0xAE, 0xD5,
     0xDD, 0x8A, 0x84, 0xA2, 0x87, 0x0F, 0xCC, 0x2B,
     0x70, 0x66, 0xAE, 0xE0, 0x88, 0x44, 0x2C, 0xCC,
     0x0C, 0x53, 0xCE, 0x9D, 0x26, 0xBB, 0xB3, 0x04,
     0xA8, 0xB7, 0xB9, 0xE5, 0x20, 0x43, 0x62, 0xAE
};

sl_se_key_descriptor_t plaintext_desc = {
     .type = key_type,
     .flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY
              | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY,
     .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
     .storage.location.buffer.pointer = user_key,
     .storage.location.buffer.size = 64
};

if (sl_se_import_key(&cmd_ctx, &plaintext_desc, &asymmetric_key_desc) != SL_STATUS_OK) return SL_STATUS_FAIL;
```

This code imports the key into the Secure Engine, wraps it, and stores the wrapped key in **asymmetric_key_buf**, which is referenced by **asymmetric_key_desc.storage.location.buffer.pointer**.

![screenshot](/iot-security-cpms/0.3/images/image36.png)

1. Write the wrapped key blob to flash. Add the following lines to `create_wrap_asymmetric_key`:  
   ```C  
   // YOUR KEY ADDRESS GOES HERE:  
   unsigned int wrapped_key_address = 0x00080000;  
     
   printf("\nWriting key into flash at 0x%08x...\n", wrapped_key_address);  
     
   // Clear out the old wrapped key MSC_ErasePage((uint32_t*)wrapped_key_address);  
     
   // Flash the new wrapped key MSC_WriteWord((uint32_t*)wrapped_key_address, asymmetric_key_buf, sizeof(asymmetric_key_buf));  
     
   // Update the key descriptor to point to the key in flash asymmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)wrapped_key_address;  
   This code will import your key into the Secure Engine, wrap it, then store the wrapped key to the **asymmetric\_key\_buf** that **asym- metric\_key\_desc.storage.location.buffer.pointer** is pointing to.  
     
   ![screenshot](resources/image36.png)  
     
   ```
2. Print the keyspec required by CPMS. Add the following lines to `create_wrap_asymmetric_key`:  
   ![screenshot](/iot-security-cpms/0.3/images/image37.jpg)  
   ```C  
   unsigned int keyspec;  
     
   if (sli_se_key_to_keyspec(&asymmetric_key_desc, &keyspec) != SL_STATUS_OK) return SL_STATUS_FAIL;  
     
   printf("\nKeyspec: 0x%08x\n", keyspec);  
     
   return SL_STATUS_OK;  
   ```
3. Keys imported using CPMS use a different bus master than the CPU, so the key descriptor must be updated. In `create_wrap_symmetric_key`, edit the `symmetric_key_desc.flags` field to remove `SL_SE_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY` and add `SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS` (line **229**):  
   ```C  
   asymmetric_key_desc.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY  
                | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY  
                | SL_SE_KEY_FLAG_NON_EXPORTABLE  
                | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS;  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/image38.png)
4. Build the project.  
   ![screenshot](/iot-security-cpms/0.3/images/image39.jpg)
5. Flash the project to the target device.  
   ![screenshot](/iot-security-cpms/0.3/images/image40.jpg)
6. In the **Debug Adapters** window, right-click the adapter for your device, and then click **Launch Console**.  
   ![screenshot](/iot-security-cpms/0.3/images/image41.jpg)
7. Click the **Serial 1** tab, and then press **Enter** to start the console.
8. Reset the device. The program prompts you to select a key type: plaintext, wrapped, or volatile. Type a space, and then press **Enter** to select **wrapped**.  
   ![screenshot](/iot-security-cpms/0.3/images/image42.png)
9. Press **Enter** four more times to display the keyspec in the console. When importing a custom wrapped key into CPMS, use this value as the **Key Metadata** value.  
   ![screenshot](/iot-security-cpms/0.3/images/image43.png)

###### Use the Wrapped Key in the Application

The following steps show how to use the wrapped key in the application without the plaintext key:

1. After the key is wrapped and stored in flash, verify that the application can use it without including the plaintext key. In **app_se_manager_signature.c**, comment out lines **255** to **278** and lines **283** to **289**.  
   ![screenshot](/iot-security-cpms/0.3/images/image44.png)
2. The application now sets up the key descriptor to point to the location of the wrapped key in flash without requiring knowledge of the key value.
3. Repeat steps **12** through **17** to verify that the wrapped key can still be used. If the flash is erased (for example, by using a Commander device unlock command), the application fails because the wrapped key is no longer available in flash. The wrapped key must be stored in flash by a previous process.  
   ![screenshot](/iot-security-cpms/0.3/images/image45.png)

##### Example 2: Import a Custom Wrapped Symmetric Key

###### Prepare Custom Wrapped Keys for CPMS

The following steps demonstrate how to generate the wrapped key and required metadata for CPMS:

1. In Simplicity Studio, open the **Launcher** view, and then click **EXAMPLE PROJECTS & DEMOS**.
2. Search for _SE Manager_.
3. Create a project from the **Platform - SE Manager Block Cipher** example.  
   ![screenshot](/iot-security-cpms/0.3/images/image35.jpg)
4. CPMS automatically wraps the key and writes it to flash. To emulate this behavior for testing, use the Memory System Controller (MSC) to write the key to flash. To enable the MSC, open **se_manager_block_cipher.slcp**.
5. Open the **SOFTWARE COMPONENTS** tab.
6. Search for _msc_.
7. Click **MSC Peripheral**, and then click **Install**.  
   ![screenshot](/iot-security-cpms/0.3/images/image46.jpg)
8. Modify the `create_wrap_symmetric_key` function in **app_se_manager_block_cipher.c** to use the CPMS key. Instead of generating a key, import the AES key. In **app_se_manager_block_cipher.c**, line **259**, replace the following line:  
   ```C  
   print_error_cycle(sl_se_generate_key(&cmd_ctx, &symmetric_key_desc), &cmd_ctx);  
   ```  
   with:  
   ```C  
   // YOUR KEY VALUE GOES HERE:  
   static uint8_t user_key[16] =  
   {  
     0x70, 0xF4, 0x82, 0x4E, 0x49, 0xBD, 0x97, 0xAB,  
     0x65, 0x65, 0x32, 0x22, 0xA0, 0x70, 0xB5, 0x16  
   };  
     
   sl_se_key_descriptor_t plaintext_desc = {  
   .type = SL_SE_KEY_TYPE_AES_128,  
   .flags = 0,  
   .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,  
   .storage.location.buffer.pointer = user_key,  
   .storage.location.buffer.size = 16  
   };  
     
   if (sl_se_import_key(&cmd_ctx, &plaintext_desc, &symmetric_key_desc) != SL_STATUS_OK) return SL_STATUS_FAIL;  
   ```  
   This code imports the key into the Secure Engine, wraps it, and stores the wrapped key in **symmetric_key_buf**, which is referenced by **symmetric_key_desc.storage.location.buffer.pointer**.  
   ![screenshot](/iot-security-cpms/0.3/images/image47.png)
9. Write the wrapped key blob to flash. Add the following lines to `create_wrap_symmetric_key`:  
   ```C  
   // YOUR KEY ADDRESS GOES HERE:  
   unsigned int wrapped_key_address = 0x00080000;  
     
   printf("Writing key into flash at 0x%08x...\n", wrapped_key_address);  
     
   // Clear out the old wrapped key MSC_ErasePage((uint32_t*)wrapped_key_address);  
     
   // Flash the new wrapped key  
   MSC_WriteWord((uint32_t*)wrapped_key_address, symmetric_key_buf, sizeof(symmetric_key_buf));  
     
   // Update the key descriptor to point to the key in flash symmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)wrapped_key_address;  
   ```
10. Print the keyspec required by CPMS. Add the following lines to `create_wrap_symmetric_key`:  
    ```C  
    unsigned int keyspec;  
      
    if (sli_se_key_to_keyspec(&symmetric_key_desc, &keyspec) != SL_STATUS_OK) return SL_STATUS_FAIL;  
      
    printf("\nKeyspec: 0x%08x\n", keyspec);  
      
    return SL_STATUS_OK;  
    ```  
    ![screenshot](/iot-security-cpms/0.3/images/image48.jpg)
11. Keys imported using CPMS use a different bus master than the CPU, so the key descriptor must be updated. In `create_wrap_symmetric_key`, edit the `symmetric_key_desc.flags` field to include `SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS` (line **247**):  
    ```C  
    symmetric_key_desc.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS;  
    ```  
    ![screenshot](/iot-security-cpms/0.3/images/image49.png)
12. Build the project.  
    ![screenshot](/iot-security-cpms/0.3/images/image50.jpg)
13. Flash the project to the target device.  
    ![screenshot](/iot-security-cpms/0.3/images/image51.jpg)
14. In the **Debug Adapters** window, right-click the adapter for your device, and then click **Launch Console**.  
    ![screenshot](/iot-security-cpms/0.3/images/image52.jpg)
15. Click the **Serial 1** tab, and then reset the device. The program prompts you to select a key type: plaintext, wrapped, or volatile. Type a space, and then press **Enter** to select **wrapped**.  
    ![screenshot](/iot-security-cpms/0.3/images/image53.png)
16. Press **Enter** once more to display the keyspec in the console. When importing a custom wrapped key into CPMS, use this value as the **Key Metadata** value.  
    ![screenshot](/iot-security-cpms/0.3/images/image54.png)  
    Press **Enter** two more times to verify that the key can be used successfully. If you press **Enter** again after this, the program attempts to use the key as a ChaCha20-Poly1305 key, which causes the operation to fail.  
    ![screenshot](/iot-security-cpms/0.3/images/image55.png)

###### Use the Wrapped Key in the Application

The following steps show how to use the wrapped key in the application without the plaintext key:

1. After the key is wrapped and stored in flash, verify that the application can use it without including the plaintext key. In **app_se_manager_block_cipher.c**, comment out lines **259** to **275** and lines **280** to **286**.  
   ![screenshot](/iot-security-cpms/0.3/images/image56.png)
2. The application now sets up the key descriptor to point to the location of the wrapped key in flash without requiring knowledge of the key value.
3. Repeat steps **11** through **15** to verify that the wrapped key can still be used. If the flash is erased (for example, by using a Commander device unlock command), the application fails because the wrapped key is no longer available in flash. The wrapped key must be stored in flash by a previous process.  
   ![screenshot](/iot-security-cpms/0.3/images/image57.png)

#### Importing Custom Wrapped Keys Example for Series 3 devices

To import custom wrapped keys into CPMS, four fields are required: key value (to be wrapped), address, auth, and metadata.

After the key field values are available, refer to [Additional Custom Keys](https://docs.silabs.com/iot-security/latest/iot-security-cpms/addl-custom-keys) section for more information on how to enter the custom key fields on the CPMS portal.

The following examples emulate the CPMS custom key provisioning process.
Additonally, the examples will also show how to get the metadata value for an asymmetric and a symmetric key.

##### Example: Importing Custom Wrapped Asymmetric Keys

Part 1: Preparing Custom Wrapped Keys for CPMS

The following steps demonstrate how to generate the wrapped key and required metadata for CPMS:

1. In Simplicity Studio v6, navigate to the 'Devices', select the Device OPN (for example, SIMG301M104LIL).
2. Click on **EXAMPLE PROJECTS AND DEMOS**, and search for _SE Manager_.
3. Create a project from the _Platform Security - SoC SE Manager Digital Signature (ECDSA and EdDSA)_ example.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-rainier-creating-se-manager-project.png)
4. Open the created project in VS code to start editing the code.  
   ![screenshot](/iot-security-cpms/0.3/images/05-section-opening-project-vs-code.png)
5. In the **app_se_manager_signature.c** file, define a persistent address to store the wrapped asymmetric key.  
   ![screenshot](/iot-security-cpms/0.3/images/asym-key-addr-macro.png)
6. In the **create_wrap_asymmetric_key** function, update the wrapped key descriptor to the following:  
   ```C  
   //Set up a key descriptor pointing to a wrapped key buffer  
   asymmetric_key_desc.type = key_type;  
   asymmetric_key_desc.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY  
                             //| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY   
                             | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY  
                             | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS; // SL_SE_KEY_FLAG_NON_EXPORTABLE;  
   asymmetric_key_desc.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED;  
   // Set pointer to a RAM buffer to support key generation  
   asymmetric_key_desc.storage.location.buffer.pointer = asymmetric_key_buf;  
   asymmetric_key_desc.storage.location.buffer.size = sizeof(asymmetric_key_buf);  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-asymkey-desc-update-step6.png)
7. In the **app_se_manager_signature.c** file, in the **create_wrap_asymmetric_key** function, add the plaintext key to be wrapped and stored in the flash. Since a custom key is being provided, replace **sl_se_generate_key** with **sl_se_import_key** as shown below.  
   ```C  
       static uint8_t cpms_key[ECC_PRIVKEY_SIZE] = {   
       0x90, 0x64, 0xbe, 0x3e, 0xd2, 0x1f, 0xaf, 0x99,   
       0x8f, 0x53, 0x32, 0x67, 0x2d, 0x47, 0xa3, 0x5e,   
       0xff, 0x5d, 0xca, 0xdf, 0x33, 0x45, 0x19, 0x75,   
       0xc5, 0xac, 0x7f, 0xc7, 0x00, 0x75, 0xbf, 0x9f   
       };  
     
       sl_se_key_descriptor_t plain_key = {  
           .type = SL_SE_KEY_TYPE_ECC_P256,  
           .flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY  
                    | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY  
                    | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS,  
           .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,  
           .storage.location.buffer.pointer = cpms_key,  
           .storage.location.buffer.size = ECC_PRIVKEY_SIZE,  
       };  
     
       if (sl_se_import_key(&cmd_ctx, &plain_key, &asymmetric_key_desc) != SL_STATUS_OK){  
           printf("\n\rCouldn't import key\n\r");  
           return SL_STATUS_FAIL;  
       }  
       else{  
           printf("\n\rSuccessfully imported the asymmetric key....\n\r");  
     
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-import-ecc-key-function.png)
8. In the **create_wrap_asymmetric_key** function, add the following code to store the key in the data region and change the wrapped key pointer to the address in data region.  
   ```C  
       //0x011f8000 is the start address for data region on the specific device.  
       sl_status_t st = sl_se_data_region_erase(&cmd_ctx, 0x011f8000, 1);  
       if (st != SL_STATUS_OK) {  
           printf("\n\rCouldn't erase data region location\n\r");  
           return st;  
       }  
       sl_status_t status = sl_se_data_region_write(&cmd_ctx,  
                                                WRAPPED_KEY_ADDR,   // destination in flash  
                                                asymmetric_key_buf,          // source buffer  
                                                80);            // length in bytes  
     
       if(status != SL_STATUS_OK){  
           printf("\n\rCouldn't store asymmetric key\n\r");  
           return status;  
       }  
       else{  
           printf("\n\rSuccessfully stored asymmetric key\n\r");  
           asymmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)WRAPPED_KEY_ADDR; //This is where the wrapped key is stored. Will be used for verification.  
           printf("\n\rThe wrapped key address is 0x%08x....\n\r", WRAPPED_KEY_ADDR);  
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-data-region-write-step8.png)
9. In the **create_wrap_asymmetric_key** function, add the following code to print the keyspec. This keyspec is entered on the CPMS portal when entering custom keys to wrapped and stored on the device.  
   ```C  
       unsigned int keyspec;  
     
       if (sli_se_key_to_keyspec(&asymmetric_key_desc, &keyspec) != SL_STATUS_OK){  
           printf("\n\rCouldn't get key spec....\n\r");  
           return SL_STATUS_FAIL;  
       }   
       else{  
           printf("\n\rKeyspec: 0x%08x\n\r", keyspec);  
     
           return SL_STATUS_OK;  
     
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-keyspec-step9.png)
10. Build the project.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-build-ecc-project-step10.png)
11. Flash the project to the target device.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-flash-ecc-project-step11.png)
12. Open Simplicity Studio. From the _Tools_ tab open _Simplicity Device Manager_.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-open-sdm-step12.png)
13. In the Simplicity Device Manager tool, in _Devices_ tab, open 'serial1' for your device.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-opening-serial-terminal-step13.png)
14. Reset the device. The program will first ask which type of key you want to use: plaintext, wrapped, or volatile. Type a    space, and then press Enter to select the second option, wrapped.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-selecting-wrapped-key-step14.png)
15. In the serial terminal, now press SPACE to select ECC 256 bytes key, then press ENTER.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-asymm-keyspec-step15.png)  
    The serial terminal output above, shows the flash address where the wrapped key is stored, the keyspec (**metadata** entered in the CPMS portal) and the successful verification of the wrapped key.

Part 2: Using the Wrapped Key in the Application

The following steps show how the wrapped key can be used in the application without the plaintext key:

1. The key is now wrapped and stored in flash. To verify that the key stored in the flash is correct, comment out application code that wraps and stores the plaintext key and point the storage location of the key descriptor to the external memory address. Rebuild the program and check that they is verified successfully.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-verification-step16.png)  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-verification-output-step16.png)

##### Example: Importing Custom Wrapped Symmetric Keys

Part 1: Preparing Custom Wrapped Keys for CPMS

The following steps demonstrate how to generate the wrapped key and required metadata for CPMS:

1. In Simplicity Studio v6, navigate to the 'Devices', select the Device OPN (for example, SIMG301M104LIL).
2. Click on **EXAMPLE PROJECTS AND DEMOS**, and search for _SE Manager_.
3. Create a project from the _Platform Security - SoC SE Manager Block Cipher_ example.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-creating-sym-key-prj.png)
4. Open the created project in VS code to start editing the code.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-open-sym-key-prj.png)
5. In the **app_se_manager_signature.c** file, define key size and a persistent address to store the wrapped aes/ symmetric key.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-size-addr-setp5.png)
6. In the **create_wrap_symmetric_key** function, update the wrapped key descriptor to the following:  
   ```C  
   //Set up a key descriptor pointing to a wrapped key buffer  
   symmetric_key_desc.type = key_type;  
   symmetric_key_desc.flags = SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS; //Commented out for CPMS: SL_SE_KEY_FLAG_NON_EXPORTABLE;  
   symmetric_key_desc.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED;  
   symmetric_key_desc.storage.location.buffer.pointer = symmetric_key_buf;  
   symmetric_key_desc.storage.location.buffer.size = sizeof(symmetric_key_buf);  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-keydesc-to-wrapp-addr-setp6.png)
7. In the **app_se_manager_signature.c** file, in the **create_wrap_symmetric_key** function, add the plaintext key to be wrapped and stored in the flash. Since a custom key is being provided, replace **sl_se_generate_key** with **sl_se_import_key** as shown below.  
   ```C  
       static uint8_t data_in[AES128_KEY_SIZE] = {   //Remember to define AES_KEY_SIZE  
           0xb1, 0xe9, 0x51, 0x6a, 0xa0, 0x85, 0x02, 0xbd,   
           0x5f, 0x12, 0x9d, 0x67, 0x9c, 0x1c, 0x42, 0x4f  
       };  
       sl_se_key_descriptor_t plain_key = {  
           .type = SL_SE_KEY_TYPE_AES_128,  
           .flags = SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS,  
           .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,  
           .storage.location.buffer.pointer = data_in,  
           .storage.location.buffer.size = AES128_KEY_SIZE,  
       };  
     
       if((sl_se_import_key(&cmd_ctx, &plain_key, &symmetric_key_desc))!= SL_STATUS_OK){  
           printf("\n\rCouldn't import the AES key\n\r");  
       }  
       else{  
           printf("\n\rSuccessfully imported the AES key....\n\r");  
     
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-key-import-step7.png)
8. In the **create_wrap_symmetric_key** function, add the following code to store the key in the data region and change the wrapped key pointer to the address in data region.  
   ```C  
       //0x011f8000 is the start address for data region on the specific device.  
       sl_status_t st = sl_se_data_region_erase(&cmd_ctx, 0x011f8000, 1);  
       if (st != SL_STATUS_OK) {  
           printf("\n\rCouldn't erase data region location\n\r");  
           return st;  
       }  
       sl_status_t status = sl_se_data_region_write(&cmd_ctx,  
                                                   WRAPPED_SYM_KEY_ADDR,   // destination in flash  
                                                   symmetric_key_buf,          // source buffer  
                                                   60);            // length in bytes  
     
       if(status != SL_STATUS_OK){  
           printf("\n\rCouldn't store asymmetric key\n\r");  
           return status;  
       }  
       else{  
           printf("\n\rSuccessfully stored asymmetric key\n\r");  
           symmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)WRAPPED_SYM_KEY_ADDR; //This is where the wrapped key is stored. Will be used for verification.  
           printf("\n\rThe wrapped key address is 0x%08x....\n\r", WRAPPED_SYM_KEY_ADDR);  
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-extrnal-memory-write-step8.png)
9. In the **create_wrap_symmetric_key** function, add the following code to print the keyspec. This keyspec is entered on the CPMS portal when entering custom keys to wrapped and stored on the device.  
   ```C  
       unsigned int keyspec;  
     
       if (sli_se_key_to_keyspec(&symmetric_key_desc, &keyspec) != SL_STATUS_OK){  
           printf("\n\rCouldn't get key spec....\n\r");  
           return SL_STATUS_FAIL;  
       }   
       else{  
           printf("\n\rKeyspec: 0x%08x\n\r", keyspec);  
           return SL_STATUS_OK;  
       }  
   ```  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-keyspec-step9.png)
10. Build the project.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-project-build-step10.png)
11. Flash the project to the target device.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-section-05-aes-project-flash-step12.png)
12. Open Simplicity Studio. From the _Tools_ tab open _Simplicity Device Manager_.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-open-sdm-step12.png)
13. In the Simplicity Device Manager tool, in _Devices_ tab, open 'serial1' for your device.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-opening-serial-terminal-step13.png)
14. Reset the device. The program will first ask which type of key you want to use: plaintext, wrapped, or volatile. Type a space, and then press Enter to select the second option, wrapped.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-selecting-wrapped-key-step14.png)
15. In the serial terminal, now press SPACE to select 128-bit AES key length, then press ENTER.  
    ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-project-output-step15.png)  
    The serial terminal output above, shows the flash address where the wrapped key is stored, the keyspec (**metadata** entered in the CPMS portal), the successful verification of the wrapped key, and successful MAC generation.

Part 2: Using the Wrapped Key in the Application

The following steps show how the wrapped key can be used in the application without the plaintext key:

1. The key is now wrapped and stored in flash. To verify that the key stored in the flash is correct, comment out application code that wraps and stores the plaintext key and point the storage location of the key descriptor to the external memory address. Rebuild the program and check that they is verified successfully.  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-verification-step16.png)  
   ![screenshot](/iot-security-cpms/0.3/images/cpms-05-section-aes-verification-output-step16.png)