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 explain step by step how to use the OEMiRoT (OEM immutable Root of Trust) example of the STM32CubeFW provided by ST.
This article describes the oemirot_overwrite example using the STM32C5A3 Nucleo board, but examples for the NUCLEO-C542RC NUCLEO-C562RE are also available in the STM32CubeFW.

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


Introduction

Through this practical example, the user will learn 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, firmware version and 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 has 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 upper.
    • 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 (e.g. Tera Term for Windows, or Minicom for Linux and MacOs)
    • Python 3.10 or later.
Info white.png Information
TPC installed together with CubeProgrammer in bin folder located in default STM32CubeProgrammer path : C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin You can pin this tool to the task bar to simplify the OEMiRoT Getting started process :

Security PinToTask.png


  • 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 white.png 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 folder STM32Cube_SW_Package_C5_x.x.x\rot\rot_provisioning.
  • 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 your latest STM32CubeProgrammer installation.
    • If it's the version of STM32CubeProgrammer you want to use, no specific path setting needs to be done.
    • But if you want to use another STM32CubeProgrammer version than the latest installed one, the following settings need to be done.
      • 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 picture below shows an example to be adapted to your own STM32CubeProgrammer installation path.
Figure 4 Add system variable
Warning white.png Warning
The defined environment variable will be only valid for this prompt window. If you want to define a variable that stays valid even after a PC reboot chose the second way indicated below
  • Another way is to use the windows graphical interface "edit the system environment variables".
  • Type: "edit the system environment variables" in the windows search, launch it (admin rights needed).
  • 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: Using this second option you will need to delete manually this variable once you don't need it anymore.

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 provided script.
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 used Nucleo board must be in RDP0, perform a regression if it's not the case. 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 etc ...) launch: python provisioning.py

  • All the executed steps are documented in the script execution.
  • The script will stop 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 provided example.
  • Keep the default value for a first run (the modification of this configuration will be explained in a next chapter).
  • The script will stop at the following warning.
Security Key warning.png
  • Obviously for a commercial product the default keys provided in this public example should not be used (a next chapter will show how to define your own keys).
    • For a first run keep the default provided keys.
  • Continue the script execution till the RDP level selection.
Security OEMiRoT RDP-selection.png
  • About the minimum RDP level: the device boot will not be possible if it is at an RDP level below this minimum selected RDP level.
  • The final RDP level is the level that the device will be set at the end of the provisioning performed by the script.
Warning white.png Warning
The regression from RDP2_BS or RDP2 to RDP0 will only be possible if the OEMKEY has been provisioned.

This script will perform the provisioning of default OEMKEY and BSKEY passwords. But for a commercial product it's important to define your own keys, but if they are lost any regression from RDP2 will not be possible anymore, even STMicroelectronic can't retrieve such locked board.

  • Note: Be aware that if an OEMKEY password has been programmed, this password can be changed but not erased. If it is wanted to set a device in RDP2 without any possibility to perform a regression it is needed to never provision these passwords.
  • Refer to:
  • For a first run, select RDP0.
  • The script will stop and ask you to generate the boot binary.
Security Build boot binary.png
  • Open the \examples\advanced\rot\oemirot_overwrite\NUCLEO-C5A3ZG\ewarm\oemirot_overwrite.eww
    • Note: IAR Embedded Workbench is used for this article, but using another supported toolchain is very similar.
  • Check Project -> option to verify that the correct device is recognized (see figure below)
    • If not, you need to 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: about limitations related to some IAR version, refer to the appendix.
  • Click right 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 you can also observe the preparation for the provisioning (path to files, keys and selected RDP level).
  • Click right 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).
    • But additionally, you can see in the compilation log that a postbuild is executed 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 doesn't 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 will be securely installed by the boot code.
  • Continue the script execution
  • Before launching the provisioning, it indicates that the board must be in RDP0. It should be the case if you have followed all the steps indicated in this article.
  • For a successful installation you should see the different messages of the figure below:
Security Provisioning RDP0.png
  • You can check two 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 your 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 different information and performed steps:
    • The system clock frequency is indicated.
    • The option bytes verification.
    • The download slot verification: if a firmware update will be done, this download slot will contain 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 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 will detect the new image and install 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 your IDE (IAR for this example).
  • Change in 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\
    • And 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 previous section a new application image and a new signed/encrypted application image have been generated but the image version has not been changed.
  • Using Trusted Package Creator (TPC) it is possible to generate a new signed/encrypted image form 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 needed information for the tool (keys location, Endianess, allocated Firmware area size, etc....).
  • 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 is showing that the image has been 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 will be performed without possible access to the application code in clear.
  • To perform a firmware update, proceed as following using your 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 has been correctly downloaded, the succeed 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 will perform 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
  • You can see the modification done previously in the main.c to change the comment to version B.
  • And the new image version changed using TPC.

2. Change of the default configuration

After successful trial using the default configuration proposed by the example, you can start to customize according to your needs.

2.1. Setting the min RDP level and final RDP level

As already explained prevously:

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

2.1.1. Min RDP2, final RDP0

In RDP0 you can 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 will not boot.

2.1.2. Final RDP2

Selecting final RDP to RDP2, the device will be closed at the end of the provisioning performed by the script.
The debugger connection to the device will then not be possible anymore.
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's obviously important to not 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 avoid that anybody can perform a regression from "RDP2" -> "RDP0" or if applicable a transition from "RDP2 with boundary scan" -> "RDP2", it's important to personalize the OEMKEY and BSKEY passwords.

  • Refer to article How to set the RDP password keys for STM32C5.
  • In RDP0 both passwords can be changed.
  • The provisioning script automatically set 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 white.png Warning
In case you had already provisioned the two OEMKEY and BSKEY passwords before launching the OEMiRoT script, these two passwords will be 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 your own needs and application size.

  • 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, it means:

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

For production, the OEMiRoT configuration should 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 can make sense 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 shall be fully rebuild (1 time), or built 2 times to ensure the changes are properly considered.
  • In case of 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 proposed options 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 have already been generated previously.
  • -a: Generates data binaries then program the device (OB and binaries). Avoid the need of user interaction during the script execution. It requires that the projects have already been build and generated previously.
  • -v: Enables debug logs (more detailed logs than the 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 launch automatically 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 your own production script

After executing the provisioning script with all final wanted configuration that you want to apply for your own production, you can 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 once it can be changed but never be removed. The RDP2 transitions will be possible for an owner knowing the passwords.
    • If these two passwords are never provisioned the RDP2 transitions will never be possible (see RM0522).
      • => If a customer wants to avoid any possible regression, the line 5 and 6 must be remove from the production script.
      • ! A regression will then never be possible anymore 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 using the imgtool executable.
  • The imgtool manages the encryption, signature, header, version control etc ....
  • During the compilation of the "appli-release" you have observed that a postbuild is performed to create the images. This postbuild is using 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 etc ....
  • 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