Target description
The purpose of this article is to provide step-by-step instructions on how to generate a boot path using STM32CubeMX.
The example below demonstrates how to configure and provision a boot path for an STiRoT (ST immutable Root of Trust) with a secure and nonsecure user application initial code generation.
This initial code is modified to use the two LEDs and user button on the discovery board, so:
- the blue LED blinks when the secure application is running.
- the user button can be used to jump from the secure to the nonsecure application.
- the green LED blinks when the nonsecure application is running.
Read Secure Boot STM32H5 How to Introduction before starting the practical example described below.
For more technical details which may be useful to know before getting started, check out the following articles:
The example described in this article uses boot path number 2, as shown in the figure below.
Note: This boot path includes STiRoT (one boot stage, no OEMiRoT), a secure user application, and a nonsecure user application.
Prerequisites
To execute the example described below, you'll need an STM32H573I-DK discovery board:
You'll also need the following tools:
- STM32CubeMX_6.9.0 or later (see STM32CubeMX ST web page[1])
- IAR Embedded Workbench rev 9.20.1 or later
- STM32CubeProgrammer rev 2.13.0
Note:
- STM32 Trusted Package Creator (TPC) is automatically installed during the STM32CubeMX installation. This TPC version is dedicated to STM32CubeMX and installed in the STM32CubeMX/utilities folder.
- The latest STM32Cube_FW revision is installed through STM32CubeMX (see appendix).
- If needed, set the Windows environment variable (see appendix). It is required in case the H5 doesn’t appear in the STM32CubeMX Access to MCU Selector
1. Setting up the STM32CubeMX project
Launch STM32CubeMX
- Click on Access to MCU Selector (for this example, it's easier to enable only the necessary GPIOs, so it's advised to use the MCU selector instead of the board selector).
- From the Series column, select STM32H5, and select the device used in STM32H5-DK.
- Click start project.
- Enable TrustZone, as shown in Figure 3. (For the STiRoT boot path, TrustZone needs to be enabled.)
Create the STM32CubeMX project:
- Type the name of the project (if it doesn't already exist, the related folder will be created).
- Choose a folder for the project (avoid a long path).
- Check that both the Secure Project and Nonsecure Project checkboxes are checked (they should be checked by default).
- Select the relevant toolchain; for this example EWARM is used.
- Go to File > Save Project. The project folder (if it doesn't already exist) and the STM32H5_STiROT_SLed_NSLed.ioc file will be created.
2. GPIO configuration
For this example, three GPIOs need to be configured on the discovery board:
- PF4 for the blue LED, used by the secure user application.
- PC13 for the blue user button used to jump to the nonsecure user application.
- PI9 for the green LED, used in the nonsecure user application.
In STM32CubeMX, select the Pinout & Configuration window:
To configure the GPIO for the blue LED:
- Click on PF4 and select GPIO_Output. This will configure a push pull output that is needed to drive a LED.
- Click right on PF4 and select Cortex-M33 secure. This assigns the GPIO to the secure user application code
To configure the blue user button:
- Click left on PC13 and select GPIO_Input.
- Click right on PC13 and select Cortex-M33 secure. This assigns the GPIO to the secure user application code.
To configure the GPIO for the green LED proceed as follows:
- Click left on PI9 and select GPIO_Output. This will configure a push pull output that is needed to drive a LED.
- Click right on PI9 and select Cortex-M33 non secure. This GPIO is then assigned to the nonsecure user application code
- Click on System Core and select GPIO. A summary of the newly configured settings is displayed as shown in the figure below:
3. STiRoT boot path configuration
To configure the boot path (number 2 in Figure 10), proceed as follows:
- Click on Boot Path and Debug Authentication.
- Click on Select.
- Select ST immutable Root of Trust (STiRoT). TrustZone was already activated in the steps described above (Figure 3). This selection will define the UBE option byte (Figure1), but you don't need to change the configuration of this option byte).
- Click on Next.
- Select Secure Application (in this example, there is no OEMiRoT, so no second boot stage).
- Click on Finish.
Note: in some STM32CubeMX versions, the Debug Authentication Configure button can't be selected before completing the STiRoT boot path configuration.
When you click on Finish, the message indicated by number 7 in Figure 10 will most likely appear. The default configuration file is set for a fully secure user application, so the next two figures demonstrate how to change this.
In the Project Manager window, select Edit Config Files, as shown in the figure below:
This automatically opens the STM32Trusted Package Creator (TPC), and the following window is displayed (Figure 12).
- Deselect Is the firmware full secure (don't change any other settings for this example).
- Click on Generate OBKey.
Notes:
- Figure 12 above shows the path where the STiROT_Config.xml file is located. This file contains the complete settings for the STiRoT.
- A default firmware execution area and download area are defined. During the provisioning stage, the download area is used to store the encrypted user application, which is decrypted by the STiRoT and then installed in the execution area (refer to the STiRoT for STM32H5 article).
- The firmware area size is the total size of the secure and nonsecure user application codes (the secure area size is indicated separately).
- The generated STiROT_Config.obk file is used during the provisioning stage to configure the STiRoT in the device.
As mentioned above, for this example you don't need to make any other changes to the default configuration.
However, if you write your own code that doesn't fit in these defined sizes, you will need to change the default settings and regenerate the OBKey when the final code size has been defined.
To protect your own developed code, you need to regenerate the encryption and authentication keys.
Select H5-Image Gen1 as shown in Figure 13 below. There's no need to modify anything here.
- The STiROT_Code_Image.xml file contains the settings needed to generate the images.
- Two paths are indicated for binary files:
- During the code compilation using the IDE, a binary file containing the compiled secure and nonsecure user applications is created.
- The IDE will also perform a post-build command to generate a single encrypted and signed binary image from these binary input files.
- Note: The abovementioned paths are updated by STM32CubeMX and must not be modified.
- Close the STM32 Trusted Package Creator
4. Debug authentication
Refer to the Debug Authentication for STM32H5 article for more details.
A (fully functional) default configuration file and related OBKey file are provided with the STM32Cube firmware.
To customize Debug Authentication, follow these steps:
- In STM32CubeMX, go to the Project Manager tab and select Boot Path and Debug Authentication. Click the Configure button.
This launches the STM32 Trusted Package Creator (installed with STM32CubeProgrammer) and the DA_Config.xml file is automatically opened.
- The key_1_root key is needed to reopen the device or to perform a regression. To protect your own developed application, this key needs to be regenerated. If regenerated, it's important to not lose this new key.
- Don't regenerate the key for this example
- The permission mask is set to allow all possible regressions and debug openings in the secure and nonsecure user applications. See Debug Authentication STM32H5 How to Introduction for more details.
This permission mask, called the SOC mask, is stored in the device during the provisioning process. The owner of the root key now has the defined privileges to perform a regression or open the debugger, according to the set permissions.
- Click on Generate OBkey to generate the OBKey file that will be used during the provisioning:
- Close the STM32 Trusted Package Creator
5. Initial code generation and modification
- In STM32CubeMX, select Project Manager.
- Ensure that Sign Binary(ies) is selected. With each user application code compilation using the IDE, an encrypted and signed binary file is created, containing both the secure and nonsecure user applications (Compilation > post-build command).
- Note that the start and end addresses are indicated for the secure and nonsecure applications, as defined by the STiRoT configuration.
- Click on Generate Code. If this popup message appears, follow the steps below:
- Click Yes to generate the code.
- If you want to enable the instruction cache, select the Pinout tab (see Figure 9, select ICache located just below the GPIO configuration).
- Open the generated user application.
Open the secure user application code
- Comment out NonSecure_Init(), used for starting in the nonsecure user application code (replaced with the code below).
- Insert the code shown below
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_4);
HAL_Delay(500);
if (HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) == 0x1)
{
NonSecure_Init();
}
This code will make the blue LED blink with the chosen delay, showing that the secure user application is running.
If the blue user button is pushed, the jump to the nonsecure application is done via NonSecure_Init().
- Compile the code using the IDE (Project > Rebuild all).
Note: the secure code needs to be compiled first (before the nonsecure code).
Open the nonsecure user application
- Insert the code shown below
HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_9);
HAL_Delay(800);
This code will make the geen LED blink with the chosen delay, showing that the nonsecure user application is running.
- Compile the code using the IDE (Project > Rebuild all).
For this STiRoT use case, two binary files are created, as shown in Figure 21 below:
- The assembled binary code of the secure and nonsecure user applications.
- The binary code obtained after the encryption and signature of the assembled binary code. This signed and encrypted file is generated through the automatically called post-build command (Sign Binary(ies) ticked, as shown in Figure 16).
6. Device provisioning
For device provisioning, the previously generated OBKey files are used to configure the device STiRoT accordingly and to configure the debug authentication according to the permission mask.
The encrypted and signed binary file is uploaded to the download area, defined during the STiRoT configuration.
The STiRoT verifies authenticity, and decrypts and installs the secure and nonsecure user applications in the execution area, defined during the STiRoT configuration.
For the provisioning stage, the STM32Cube Programmer Command Line (CLI) is called automatically by the provisioning script.
It's important that the path to STM32Cube Programmer is correct in the env.bat file. Check and update as shown in Figure 22 below.
Don't modify the path to STM32 Trusted Package Creator included in STM32CubeMX!
Provisioning of the device is done using the provided provisioning script. Follow these steps to execute it:
- Connect your board using the USB cable (USB STLink connector).
- Double-click on the provisioning.bat file shown in Figure 23 below.
- Provisioning: depending on the script revision it is indicated as Step1 or Option Byte Programming. All the settings done previously through STM32CubeMX are automatically applied on the device by the provisioning script.
- The previously set STiRoT configuration (generation of the related STiRoT_Config.obk file).
- The previously set Debug Authentication configuration (generation of the related DA_Config.obk file).
- In this first step, the script will automatically update the option bytes accordingly.
- Provisioning step 2: image generation
- The user application code image is generated during the compilation and the post-build phase.
- Image generation is not applicable for this example. Press any key.
- Provisioning step 3: board provisioning
- Check the indicated boot switch position before pressing any key.
- The STM32H5 device provisioning is executed, the configuration is stored, and the user application codes are installed
- Note: For Linux and Mac operating systems, the end users may have to change manually the attribute of .sh scripts to executable.
The final step is the product state configuration; for this example the device is set to CLOSED
When the message saying the board has been configured correctly is displayed, you can close script.
See Introduction to Silicon device life cycle and Debug Authentication for detailed explanations.
7. Code execution
- Press the black reset button. The blue LED is now blinking, showing that the secure user application is running.
- Press the blue button. The green LED is now blinking, showing that the jump to the nonsecure application was successful and that the nonsecure application is running.
8. STM32Cube Programmer & discovery command
- Start STM32Cube Programmer and try to connect.
- An error message is displayed, because the device was set to a CLOSED state and the debugger can't be connected, even to see the nonsecure user application code.
- To reopen the debugger, a debug authentication is needed and this can only be done by the owner of the root key.
The product state can be viewed using the Discover command (see Figure 24 below):
- In STM32Cube Programmer, click on the shield icon.
- Select Debug Authentication.
- Click on Discover; the lifecycle CLOSED is now displayed.
An example of how to reopen the debugger, view the code, and attach an IDE to perform a step-by-step application execution is shown in chapter 6.1 of How to start with STiROT on STM32H573
9. Regression
A regression will remove the user applications and protections.
After completing a hands-on exercise, if your board is not in an OPEN state, it's recommended that you perform a regression especially if you have regenerated the root key.
- Double-click to start the regression script shown in Figure 25 below.
- The regression is performed automatically. The debug authentication is done using the root key and according to the permissions defined during the STiRoT configuration.
- Note: For Linux and Mac operating systems, the end users may have to change manually the attribute of .sh scripts to executable.
You can now connect STM32Cube Programmer and see that the debugger is open again, and that the flash memory was fully erased.
10. Appendix
10.1. STM32CubeMX installation
To install STM32CubeMX, go to STM32CubeMX ST web page [1]
10.2. STM32CubeFW installation
The STM32Cube firmware needs to be installed through STM32CubeMX:
- Step 1: define the repository folder (Figure 26 below).
- In STM32CubeMX: Help > Updater Settings.
- Click Browse and select the desired repository for the STM32Cube firmware.
- Step 2: STM32Cube firmware installation (Figure 27 below).
- In STM32CubeMX, select Install/Remove.
- In the description frame, select STM32H5.
- Select the STM32Cube firmware package to install.
If you have the STM32CubeH5 .zip file stored locally, it can be installed by dragging and dropping this file in the description window.
Note: only official STM32Cube firmware releases can be installed via STM32CubeMX.
11. References