How to start with OEMiRoT on STM32C5

How to start with OEMiRoT on STM32C5 85min

Literature


Target description

The purpose of this article is to provide a step by step guide on how to use the OEM immutable Root of Trust (OEMiRoT) example of the STM32CubeFW provided by ST.
This article describes the oemirot_overwrite example using the STM32C5A3 Nucleo board, examples for the NUCLEO-C542RC NUCLEO-C562RE are also available in the STM32CubeFW. The specific list of boards that are supported is given below:

  • NUCLEO-C5A3ZG: crypto device, 1 MB flash
  • NUCLEO-C562RE: crypto device, 512 KB flash
  • NUCLEO-C542RC: crypto device, 256 KB flash


Introduction

This practical example demonstrates how to perform the following operations:

  • Run the OEMiRoT example of the STM32CubeFW.
    • Provisioning preparation.
    • Application firmware compilation, and encrypted/signed image generation.
    • Perform the provisioning and installation of the OEMiRoT code and the application firmware.
    • Execute the installed firmware.
  • Modification of the user application or firmware version, and how to perform a firmware update installation.
  • Provisioning and RDP2 setting.
  • Regression from RDP2 to RDP0.
  • Generation of new encryption and authentication keys.
  • Changing OEMKEY and BSKEY passwords.
  • Adapt flash layout configuration.
  • Modifications to production mode.
  • Note:
    • The STM32C5 devices don't support Trust Zone.
    • The STM32C5 devices have no RDP1 level.

Prerequisites

  • Hardware
    • C5A3ZG Nucleo board (MB2310)
Figure 1 Nucleo board STM32C5A3
  • Required tools
    • STM32Cube_SW_Package_C5_2.0.0 [1] or later.
    • STM32CubeProgrammer[2] Software programming tool for STM32 (STM32CubeProgrammer v2.22.0 or later version).
      • Including STM32TrustedPackageCreator.
    • IAR Embedded Workbench® rev 9.60.3 + patch EWARMv9_STM32C5xx_V0.5.0 or later.
      • The patch is available in the STM32CubeFW: STM32Cube_SW_Package_C5_x.x.x\IDEs_patches\EWARM.
    • Terminal emulator supporting YModem protocol (for example, Tera Term for Windows, or Minicom for Linux® and MacOs®)
    • Python 3.10 or later.
Information
TPC is installed together with CubeProgrammer in bin folder located in default STM32CubeProgrammer path : C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin Pin this tool to the task bar to simplify the OEMiRoT Getting started process :


  • Environment setup
    • Download the STM32Cube_SW_Package_C5 and install it.
    • Note: the provided examples support Windows®, Linux® and MacOs® environments, for this article Windows® environment has been used.
Warning
Place STM32Cube_SW_Package close to the C: root to avoid a long Windows® path.


  • Install the Python modules:
  • The requirement.txt file is located in the STM32Cube_SW_Package_C5_x.x.x\rot\rot_provisioning folder.
  • Open a command window and execute: pip install -r requirements.txt.
  • The provisioning directory of the STM32CubeSW contains the provisioning script and the provisioning.ini file.
Figure 2 STM32Cube_SW_C5
  • Open the provisioning.ini with a text editor:
Figure 3 STM32Cube_SW_C5
  • The STM32_PRG_PATH is the location of the latest STM32CubeProgrammer installation.
    • If that version of STM32CubeProgrammer is already located in the path, no specific path setting is needed.
    • If another STM32CubeProgrammer version is used, follow these settings steps:
      • Open a command prompt in administrator mode.
      • In C:\Windows\System32> type: $env:MY_PRG_PATH = "C:\path_to_Cube_programmer\STM32CubeProgrammer_rev_x.x.x\bin"
      • Verify the setting of the new windows environment variable: type: $env:MY_PRG_PATH
      • Edit the provisioning.ini to include the new variable.
The figure below shows an example to be adapted to the actual STM32CubeProgrammer installation path.
Figure 4 Add system variable
Warning
The defined environment variable is only valid for this prompt window. If the variable must stay valid even after a PC reboot choose, the process indicated below
  • To define environment in a more permanent way use the windows graphical interface "edit the system environment variables".
  • Type: "edit the system environment variables" in the windows search, launch it. Administration rights are needed for this operation.
  • Click: "Environment Variables" => click "New" User variables=> enter variable name and link to the STM32CubeProgrammer binary.
Figure 5 Graphic interface to add system variable
  • Note: When using this second option, this variable needs to be manually deleted when it is no longer needed.

1. OEMiRoT provisioning with default configuration

This chapter explains how to perform the OEMiRoT provisioning using the default proposed configuration.
It is advised to run this example before trying other configuration settings.
All the provisioning steps are managed by the script that is provided.
The current support mode of this example is dual slot overwrite mode:

  • Two flash slots: one slot to download the encrypted/signed application firmware image and another slot to install the application firmware.
  • Overwrite mode: a firmware update is done without backup of the previous installed application firmware.

1.1. Launch the provisioning script

The target Nucleo board must be in RDP0. In this configuration, there is no need to perform a regression. A regression is necessary in any other RDP configuration. The provisioning script is located in STM32Cube_SW_Package_C5_x.x.x\examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\provisioning.
From a console (Windows PowerShell or command prompt for example) launch: python provisioning.py

  • All the executed steps are documented in the script execution.
  • The script stops at the step described in the figure below.
  • Open the \NUCLEO-C5A3ZG\provisioning\config\mx_memory_config.ini file as described below.
Figure 6 Default memory configuration
  • The mx_memory_config.ini file indicates the default configuration of the example.
  • Keep the default value for a first run (the modification of this configuration is explained in a next chapter).
  • The script stops at the following warning.
  • Obviously, for a commercial product the default keys provided in this public example must not be used. The way the key is defined is explained later in this document.
    • For a first run, keep the default provided keys.
  • Continue the script execution up to the RDP level selection step.
  • Minimum RDP level: the device does not boot if the RDP level is below this minimum selected RDP level.
  • The final RDP level is the level that the device is set to at the end of the provisioning performed by the script.
Warning
The regression from RDP2_BS or RDP2 to RDP0 is only possible if the OEMKEY has been provisioned.

This script performs the provisioning of default OEMKEY and BSKEY passwords. But for a commercial product it is important to define specific keys, if they are lost any regression from RDP2 no longer possible, even STMicroelectronic cannot retrieve such locked board.

  • Open the \examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\ewarm\oemirot_overwrite.eww
    • Note: IAR Embedded Workbench is used for this article, all other supported toolchains behave in a very similar way.
  • Check the project -> option to verify that the correct device is recognized (see figure below)
    • If not, install the IAR patch provided in the STM32Cube_SW_Package_C5_x.x.x\IDEs_patches\EWARM
Figure 10 IAR STM32C5 device configuration
  • Both the oemirot and the application are in the same project.
Figure 11 OEMiRoT boot and appli
  • Note: For limitations related to some IAR version, refer to the appendix.
  • Right click on "oemirot - release" => select " rebuild all".
    • The integrated prebuild propagates the memory configuration (see mx_memory_config.ini in the compilation log) into the project (linker file and flash_layout.h).
    • In the log observe the preparation for the provisioning (path to files, keys and selected RDP level).
  • Right click on "appli - release" => select " rebuild all".
    • As for the oemirot - release, the integrated prebuild propagates the memory configuration (see mx_memory_config.ini in the compilation log) into the project (linker file and flash_layout.h).
    • Additionally, the compilation log contains the postbuild execution information at the end of the compilation.
      • The postbuild generates two application firmware images:
Figure 12 Postbuild created application images
  • appli_provisioning_sign.hex: this signed file is used for the first application installation during the provisioning phase. Since the provisioning needs to be done in a trusted environment this file does not need to be encrypted.
  • appli_fwu_enc_sign.bin: signed and encrypted image used in case of a firmware update. For a FWU, this image is transferred to the download slot and is securely installed by the boot code.
  • Continue the script execution
  • Before launching the provisioning, it indicates that the board must be in RDP0. It is the case if all the steps indicated in this article are correctly completed.
  • For a successful installation, the messages in the figure below must appear:
  • Check the following log files:
    • ...\examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\provisioning\cubeprogrammer_cmd.txt : indicates all the executed commands.
    • ...\examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\provisioning\provisioning.log : provides all the details of the provisioning.
  • In RDP0 the provisioning can be executed again without any regression.

1.2. Execute the application

  • Launch the terminal emulator
  • Select “ Serial” and the STLink Virtual COM Port
  • Setup -> Serial port …
  • Set speed to 115200 and data to 8 bit
  • Click: New Setting
Figure 14 Tera term setting
  • Reset the board (black reset button)
    • The code installed during the provisioning is executed.
Figure 15 Execution of application
  • The code execution shows the following information and performed steps:
    • The system clock frequency is indicated.
    • The option bytes verification.
    • The download slot verification: if a firmware update is done, this download slot contains the new encrypted/signed image.
    • Primary execution slot verification.
    • Executed application version
  • Note
    • The primary slot is the flash memory slot reserved for application firmware installation.
    • The secondary slot is the flash memory slot reserved to download an encrypted signed application image.

Keep your terminal emulator open to perform an application firmware update as explained in the next sections.

1.3. Application Firmware Update (FWU)

  • The same firmware update procedure applies to all RDP including RDP2 levels where the debugger is not accessible.
  • The YMODEM protocol is used to download a new encrypted/signed application firmware image.
  • The OEMiRoT boot detects the new image and installs it after verification of the authenticity and integrity.

1.3.1. Generation of a new application image using the IDE and the postbuild

  • Open the application code (appli - release) using the IDE (IAR for this example).
  • Change to be made to the main.c:
    • from: const uint8_t UserAppId = 'A'
    • to: const uint8_t UserAppId = 'B'
  • Rebuild all =>
    • A new appli.hex is created in the folder: NUCLEO-C5A3ZG\ewarm\appli\release\Exe\
    • Through the postbuild a new encrypted/signed image is generated: appli_fwu_enc_sign.bin in the folder: examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\bin\

1.3.2. Generation of new application image using TPC, image version change

  • In the previous section a new application image and a new signed/encrypted application image are generated but the image version has not been changed.
  • Using Trusted Package Creator (TPC) it is possible to generate a new signed/encrypted image from any .hex file and also to change the image version.
  • To generate a new signed/encrypted image firmware application firmware update proceed as following:
Figure 16 New encrypted/signed application image generation
  • Enter the link to the appli_fwu_code_image.xml. This file contains all the required information for the tool (keys location, Endianess, allocated Firmware area size, and so on).
  • Enter the location of the .hex file, in our case: \examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\ewarm\appli\release\Exe\appli.hex
  • Enter the new version number' of the application.
  • Click "Generate Image" => the display shows that the image was generated successfully.

1.3.3. Performing a firmware update

  • To install the new generated firmware, the first step is the download of the new encrypted/signed image into the flash download slot.
  • The authentication, decryption, integrity check and installation are done in a safe way through the boot code installed previously.
  • Note: The same procedure is applicable if the device is in RDP2. In this case a firmware update can be done in a non-trusted environment since the installation of the new firmware is performed using an encrypted firmware.
  • To perform a firmware update, proceed as follows using the terminal emulator.
1.3.3.1. Download the new encrypted and signed image into the flash download slot
Figure 17 New firmware image transfer in the flash download slot
  • The different steps are indicated in the figure above:
    • The YMODEM protocol is used to transfer the new firmware image into the flash donwload slot.
    • Select the new encrypted and signed image located in the folder: examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\bin.
    • If the image was correctly downloaded, the successful message indicated in the figure above is displayed.
1.3.3.2. Installation of the new application firmware image
  • The installation of the new application firmware image is done as indicated in the figure below:
    • Type "3" to request the installation
    • Type "1"" to initiate a device reset, the boot application performs the new installation after verifying the authenticity and integrity of the new user application.
Figure 18 Installation of the new firmware image
1.3.3.3. Execution of the new installed application firmware
  • The new application firmware is directly executed after the installation.
Figure 19 Execution of the new installed application firmware
  • The modification are available in the main.c to change the comment to version B.
  • The new image version is changed using TPC.

2. Change of the default configuration

After a successful trial using the default configuration proposed by the example, customization can now be started.

2.1. Setting the min RDP level and final RDP level

As explained:

  • The device boot is not be possible if the min RDP level is set higher than the RDP level of the device.
  • The final RDP is the RDP level that the device must be set to.

2.1.1. Min RDP2, final RDP0

In RDP0, just rerun the provisioning script without performing a regression.

  • Execute the provisioning script and set the min RDP level to RPD2 and the final RDP to RDP0.
  • When the provisioning is completed and a device reset is performed to execute the application, the device does not boot.

2.1.2. Final RDP2

Selecting final RDP to RDP2, the device is closed at the end of the provisioning performed by the script.
The debugger connection to the device is then denied.
But a firmware update is still possible.

2.1.2.1. Regression from RDP2 to RDP0

Launch the provisioning script with the option -r according to the figure below.

Figure 20 Perform a regression from RDP2 to RDP0


2.2. Encryption and authentication key generation

As already mentioned, it is important not to use the default keys of STM32CubeSW example for a commercial product.
New Authentication and Encryption keys can be generated using STM32 Trusted Package Creator (TPC).
The figure below shows how to proceed:

Figure 21 Generate new authentication and encryption keys


2.3. Changing OEMKEY and BSKEY passwords

To prevent anyone from performing a regression from "RDP2" -> "RDP0" or, if applicable, a transition from "RDP2 with boundary scan" -> "RDP2", it is important to personalize the OEMKEY and BSKEY passwords.

  • Refer to the article How to set the RDP password keys for STM32C5.
  • In RDP0, both passwords can be changed.
  • The provisioning script automatically sets the passwords as defined in the regression_rdp_key and transition_bs_key files (see figure below).
Figure 22 Regression and transition password files
Warning
In case both OEMKEY and BSKEY passwords are already provisioned before launching the OEMiRoT script, these two passwords are replaced by the passwords defined in the regression_rdp_key and transition_bs_key files.


2.4. Adjust the flash layout

At the beginning of this article, the default flash memory configuration is shown.
This memory configuration needs to be adapted to the needs and size of the application.

  • Open the \NUCLEO-C5A3ZG\provisioning\config\mx_memory_config.ini file as described below.
Figure 23 Adjust the flash configuration
  • To add an encrypted/signed image reserved for data content, modify to: data image = 1.
  • The oemirot_size is the flash size reserved for the OEMiRoT boot code application.
  • The app_size is the flash size reserved for the application image download and installation slots.
  • The data_size is the flash size reserved for application data download and installation slots.

Note:

  • All the flash sizes need to be defined in steps of flash page size: 0x2000.
  • The provisioning manages automatically the new flash layout configuration for the OEMiRoT, application projects and for the Option Bytes.

2.5. Change from development mode to production mode

By default the OEMiRoT provisioning is set in development mode, this means:

  • The logs are enabled (bigger OEMiRoT (boot code) binary size).
  • Script execution is stopped in case of error.

For production, the OEMiRoT configuration must be changed by commenting out the define according to the figure below:

Figure 24 Change from development mode to production mode

Commenting the #define_OEMIROT_DEV_MODE:

  • The logs are disabled (Smaller OEMiRoT binary size).
  • A reset is generated in case of error (not provisioning script execution stop).
  • Note: after this change, it may be useful to optimize the flash memory configuration (see section Adjust the flash layout).

3. Appendix

3.1. IAR related limitations

  • In case of flash layout configuration changes (mx_memory_config.ini: cf next slides), both projects must be fully rebuild (1 time), or built twice to ensure the changes are properly considered.
  • In case of an error message: PermissionError: Permission denied:'C:......\examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\oemirot\flash_layout.h' => close the file from IAR.

3.2. Provisioning script options

  • The different options proposed for the provisioning script are displayed as shown in the figure below:
Figure 25 Provisioning script options
  • --no-gen: Programs the device Option Byte (OB) and binaries. Requires all binaries be generated ahead of the operation.
  • -a: Generates data binaries then programs the device (OB and binaries). Avoids the need of user interaction during the script execution. The projects must already be build and generated prior to this step.
  • -v: Enables debug logs (more detailed logs than what is provided by default).
  • -r: Performs the regression from RDP_2 or RDP2_BS to RDP_0.
  • -wr: Performs the regression from RDP_2 or RDP2_BS to RDP_0 and automatically launchs the provisioning.
  • --stlink-sn: Useful if several boards are connected on host. Not required if only one board is connected.

3.3. How to develop a production script

After executing the provisioning script with the final configuration, open the following log file:

  • \examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\provisioning\cubeprogrammer_cmd.txt
  • This log file indicates all the different STM32CubeProgrammer commands that have been launched.
Figure 26 Executed STM32CubeProgrammer commands during the device provisioning
  • At line 5: the OEMKEY password is provisioned (4x 32 bytes)
  • At line 6: the BSKEY password is provisioned (1x 32 bytes)
  • Note:
    • If the passwords are provisioned, they can be changed but never removed. The RDP2 transitions are possible for an owner who knows the passwords.
    • If these two passwords are never provisioned, the RDP2 transitions not possible (see RM0522).
      • => If a customer wants to avoid any possible regression, the line 5 and 6 must be removed from the production script.
      • ! A regression no longer possible, even by STMicroelectronics.

3.4. STM32TrustedPackageCreator imgtool customization

3.4.1. imgtool embedded in the STM32TrustedPackageCreator

  • For image creations, the STM32TrustedPackageCreator installed together with the STM32CubeProgrammer is done using the imgtool executable.
  • The imgtool manages the encryption, signature, header, version control and so on.
  • During the compilation of the "appli-release" ensure that a postbuild is performed to create the images. This postbuild uses the imgtool embedded in the STM32TrustedPackageCreator at the link set through the environment variable (see Prerequisites section).
  • The imgtool.exe is located in the bin\Utilities\Windows folder (see figure below).
Figure 27 Image tool embedded in the STM32TrustedPackageCreator


3.4.2. imgtool embedded in the STM32Cube_SW

The STM32Cube_SW includes a script: \middleware\mcuboot\scripts\imgtool.py

Figure 28 Image tool embedded in the STM32CubeSW example
  • This imgtool can be customized, for instance, to use a Hardware Security Module (HSM) for private key authentication, to change encryption and signature cryptographic scheme and so on.
  • An executable (imgtool.exe) can be generated using PyInstaller.
  • To use this generated imgtool.exe, the imgtool of the STM32TrustedPackageCreator (bin\Utilities\Windows) can be replaced with this new executable.

4. References