How to start with OEMiRoT on STM32C5
85min
Literature
- RM0522 STM32C5 Reference manual (not yet officially available)
- UM2237 STM32CubeProgrammer software description
- UM2238 STM32TrustedPackageCreator tool software description
- AN2606 STM32 microcontroller system memory boot mode
- It is recommended to read the RDP password keys for STM32C5 article.
- It is recommended to read the OEMiRoT for STM32C5 article.
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)
- 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.
- 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.
- 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.
- Open the provisioning.ini with a text editor:
- 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.
- 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.
- 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.
- 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.
- Note: Be aware that if an OEMKEY password has been programmed, this password can be changed but not erased. If the device is only required to be set in RDP2 with no possible regression, never program the OEMKEY password.
- To avoid the OEMKEY and BSKEY passwords provisioning during production, refer to appendix How to develop your own production script
- Refer to:
- Article: RDP password keys for STM32C5 article and RM0522.
- And section: Define your own OEMKEY and BSKEY passwords
- For a first run, select RDP0.
- The script stops and asks the user to generate the boot binary.
- 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
- Both the oemirot and the application are in the same project.
- 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:
- 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
- Reset the board (black reset button)
- The code installed during the provisioning is executed.
- 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:
- 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
- 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.
1.3.3.3. Execution of the new installed application firmware
- The new application firmware is directly executed after the installation.
- 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.
- Change the application code version as explained in section Generation of a new application image.
- Upload and install the new image using the YMODEM protocol as explained in section Performing a firmware update.
- In RDP2, to recover an empty board run the provisioning script provisioning.py with the option [-r], see section: Provisioning script options.
2.1.2.1. Regression from RDP2 to RDP0
Launch the provisioning script with the option -r according to the figure below.
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:
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).
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.
- 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:
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
- 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:
- --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.
- 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).
3.4.2. imgtool embedded in the STM32Cube_SW
The STM32Cube_SW includes a script: \middleware\mcuboot\scripts\imgtool.py
- 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