on
2024-08-12
5:00 AM
- edited on
2026-03-30
4:09 AM
by
Laurids_PETERSE
This article describes methods to protect code from unauthorized external access in the STM32H5 series. It introduces the new product state feature, which functions similarly to the readout protection (RDP) feature available in other STM32 series, and provides a robust layer of security.
This article is intended for developers working with the STM32H5 microcontroller series who require resources to protect code from external access. The STM32H5 series introduces significant changes to device life cycle management to support enhanced security features. The traditional readout protection (RDP) feature found in other STM32 series is now replaced by the product state feature. Although the mechanism differs, product states serve as the RDP equivalents for STM32H5: Open ≈ RDP0, Closed ≈ RDP2 with regression, and Locked ≈ RDP2 without regression. Users familiar with RDP will find that product states offer equivalent security levels. The following list describes the new states available for this microcontroller series:
The open state corresponds to RDP level 0, and the locked state is equivalent to RDP level 2. There is no direct equivalent to RDP level 1; however, the closed state combines the advantages of level 2 (blocking debug access) with the benefits of level 1 (allowing regression to the open state).
In previous STM32 series, the user manual indicated whether a mass erase occurred during RDP regression. For STM32H5, this behavior is now associated with product state regression and the debug authentication workflow, as detailed in the regression section.
The TZ-Closed state pertains to TrustZone® applications, which are not the primary focus of this article. However, the steps outlined may still be useful for TrustZone® applications.
The following image presents a simplified chart with the available paths and possible ways to perform a regression:
To perform a regression from the closed state, a debug authentication process is required. This process requires a password key stored within the microcontroller for non-TrustZone® applications. Provision a password before transitioning to the closed state. Failure to do so results in permanent loss of debug access, making regression impossible.
This article outlines the procedure for:
Note: At the time of this update, STM32CubeProgrammer supports J-Link without security features. This procedure is intended for use with an ST-LINK tool. For further information about STM32 security implementation over J-Link, refer to the Segger Knowledge base: ST STM32H5 Security Product Lifecycle - SEGGER Knowledge Base
Continue to the following section for a detailed step-by-step guide on the implementation.
To create a password for debug authentication in STM32H5, install the STM32TrustedPackageCreator software. This software is included in the STM32CubeProgrammer installer, which can be downloaded from the following link:
During installation, select the checkbox to install STM32TrustedPackageCreator.
After installation, open the software. In the main window, navigate to the security menu and open OBkey.
In this menu, provide an XML file with the key and implementation parameters. This article demonstrates the process without exploring all parameters. For further details, refer to appendix A of UM2238 - STM32 Trusted Package Creator tool software description.
To facilitate implementation, use the XML template available in the STM32CubeH5 package at the following path (adapt as needed):
STM32Cube_FW_H5_Vx.x.0\Projects\STM32H573I-DK\ROT_Provisioning\DA\Config
Open the DA_ConfigWithPassword.xml file with a text editor.
Before proceeding, note that steps differ for each STM32H5 product line. Refer to the appropriate section below.
Important note: The STM32H503 flash memory interface does not provide OBKeys. An OTP (one-time programmable) memory is used to provision the hash of the password. Once provisioned, the password cannot be changed. For other STM32H5 lines, the password can be changed by performing a regression and provisioning the device again.
For STM32H5 lines without extended cryptographic features, provision a non-encrypted password. Set the DoEncryption parameter to 0 in the DA_ConfigWithPassword.xml file. Update the value field in the password section with the chosen password.
Save and close the file, then return to STM32TrustedPackageCreator. Import the XML file; the password appears in the field below.
For STM32H5 lines with extended cryptographic features, provision an encrypted password. Set the DoEncryption parameter to 1 in the DA_ConfigWithPassword.xml file. Update the value field in the password section with the chosen password.
Save and close the file, then return to STM32TrustedPackageCreator. Import the XML file; the password appears in the field below.
Select an output path to store the generated key files. Click [Select Path], determine the path, and click [Generate OBkey].
Two files are generated in the specified path:
The .obk file holds the password intended for provisioning to the STM32H5, while the .bin file contains the password which in this instance is used to perform debug authentication.
After generating the password, change the product state of the STM32H5 to protect the device.
First, flash the firmware image into the microcontroller using the preferred toolchain. Open STM32CubeProgrammer, connect to the microcontroller, navigate to the [Option Byte] menu, and open the [Product State] drop-down menu.
Change the PRODUCT_STATE option to 17, then press [Apply]. When prompted to apply the default DA-Config, select [No].
The microcontroller enters provisioning mode, and STM32CubeProgrammer disconnects from the device. To reconnect, change the connection mode to hot plug and reconnect to the target.
After connecting, navigate to the [Secure Programming Menu] and open the [Provisioning] tab. Import the .obk file and click [Start Provisioning]. Upon completion, a confirmation menu appears.
At this point, the STM32H5 device has the keys installed and remains in the provisioning state. Download the firmware to the board. While in provisioning state, the STM32H5 does not execute user code. The code executes only after changing the product state to Closed or Locked.
With the password provisioned, change the product state to Closed (value 72) under the Option Bytes menu.
STM32CubeProgrammer disconnects as the microcontroller enters a protected state. This state blocks external access through the debug port, similar to RDP level 2 protection, but still allows regression.
To perform a regression and recover debug access, connect the debugger to the computer and the target microcontroller. Open STM32CubeProgrammer, navigate to the [Secure Programming] menu, and open the [Debug Authentication] menu.
Click [Discover]. If the target is connected, the table displays the product status and additional information. Click [Browse] and import the .bin file generated earlier. Click [Full Regression] and wait for the process to complete.
When the process finishes, click [OK].
After this process, debug access is restored and the microcontroller returns to the open state.
Product state regression erases embedded memories (SRAM2, flash) and resets all peripherals, including OTFDEC and all cryptographic engines.
Now you know how to protect your code on the STM32H5, as well as to provision a password to perform a regression and get access back to the microcontroller!
The above steps are required to protect memory and code in STM32H5 microcontrollers, which may complicate production line processes. To streamline the procedure, use the STM32CubeProgrammer CLI (command-line interface) to create scripts that execute all necessary steps.
STM32CubeProgrammer CLI is part of a comprehensive ecosystem for managing automated programming workflows. It also supports integration with other platforms, including Python. For further information, refer to the STM32CubeProgrammer documentation: STM32CubeProgrammer software description - User manual
To create a script, open a text editor and add the following code:
-c port=swd mode=normal reset=swrst -d C:\Users\botelhod\STM32CubeIDE\usb\usbd_composite_h563\Debug\usbd_composite_h563.elf -ob PRODUCT_STATE=0x17 --scriptdisconnect -c port=swd mode=hotplug reset=swrst -sdp C:\Users\botelhod\Desktop\DA_ConfigWithPassword.obk -ob PRODUCT_STATE=0x72
The script opens SWD connection by the -c command. Then it downloads an .elf file given by the command -d followed by the image path. After that, it changes the PRODUCT_STATE to the provisioning state by issuing the -ob command. And finally, disconnects (--scriptdisconnect).
In the next step, the script starts a new connection but now using the hot plug mode. Then it provisions the password by the -sdp and finally changes the product state to the closed state, doing all the steps presented in this tutorial.
To proceed with the execution of this script by using the STM32CubeProgrammer, save the code with the .prg extension. Remember to update the lines that contain the path to the .elf and .obk files in the script to the right paths on your own machine.
Then open your terminal (like CMD, if using MS Windows), and navigate to the STM32CubeProgrammer installation folder. It can be done by issuing the following command:
cd C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin
Just remember to update the command to refer the proper installation path on your computer. Once the terminal is in the STM32CubeProgrammer installation path, call the tool with the following command:
STM32_Programmer_CLI -script c:\script.prg
Replace “c:\script.prg” with the correct script path.
This article describes how to implement readout protection on STM32H5 series microcontrollers using the product state feature, which serves as a legacy RDP equivalent. This feature provides protection equivalent to RDP level 2, blocking access through the debug port while allowing regression to an unprotected state with a password. This approach protects code from unauthorized reading and modification.
For questions or support, contact ST through the ST Community or Online Support.
Hope you enjoyed the article and that it has contributed to your knowledge base and our best wishes for your developments!
Here are some useful links that contain material that was used to build this article and can be helpful in your development:
Thanks for great manual! Although, there is one huge flaw, which can lead to bricked device. This article was tested only on STM32H56X series of the MCUs. H56X does not contain several crypto features. That's why we need to set DoEncryption parameter to 0 in DA Config. But H57X have the crypto features, so DoEncryption set to 1 is mandatory. If you provision DA config to H57X with DoEncryption being 0, when doing DA Device Discovery, provisioning integrity reports failure:
discovery: ST provisioning integrity status:0xf5f5f5f5(it supposed to be 0xeaeaeaea)
If you provision to Closed mode with provisioning integrity being 0xf5f5f5f5, device is permanently bricked and cannot be regressed back.
Also, good tip for everyone: After switching to Provisioning state, and provisioning some DA Config, always verify that provisioning integrity is intact, by disconnecting the J-Link, going to Secure Programming, Debug Authentication (DA) tab and pressing Discovery button, it should give you provisioning integrity status into the log window. It must be 0xeaeaeaea. Also, when doing tests, put into your firmware the code to trigger regression or ST Bootloader, and remove it after your whole provisioning process works flawlessly, so in case something fails, you have always a way to recover the MCU.
Why? I am sorry, but why? What was wrong with simple read protection by setting RDP to level 1 like we had before?
Now we have to waste hours and bricked devices for this with no additional benefit. In this case, simpler is better.
I was bit frustrated with this change as well, but in the end, we figured it out pretty quickly, and it offers much more security features and flexibility. And we bricked only one device :D . But yeah. Better manuals would be great, we would avoid one bricked device if this tutorial would account with using H573 (what is still not changed @D.Botelho , @Laurids_PETERSEN ).
Hello @johannespfister,
The STM32H5 series is designed for applications that require a certain level of security. Security specifications are based on certificates that have requirements depending on the application. To meet these security requirements, we needed to update our legacy RDP system, which became the Product State feature described in this tutorial.
Best Regards,
Dan
What is the easiest way to set RDP=1 like read protection to a STM32H563RGT6?
Here is what confuses me:
1. You say we need to load a provide an XML file, but in the linked GitHub you only provide one for the STM32H573I-DK. Where do i get one for other uC's? Can i use the same?
2. @gpe-625 says this How-To is for STM32H56X uC's, but the GitHub link is for an STM32H57
3. In the STM32CubeProgrammer under Option bytes i set PRODUCT_STATE to 72, now it is at 17 (i never set it to 17) and i can't change nor reprogram the device. After setting it to 72 (and it got to 17) the software was gone (uC no longer runs like it used to). How to reset this device?
And i don't know how to prevent bricked devices.
Thank you for your help.
> The STM32H5 series is designed for applications that require a certain level of security
The one that choosed the STM32H563RGT6 no longer works here and we didn't have read protection enabled before, so i don't know why we have the STM32H563RGT6.
Hello @johannespfister,
For the MCU you've specified you can follow the exact steps provided by this tutorial.
1. Yes, you can use the same, just be sure to set the DoEncrypt parameter to 0.
3. You can't jump from 0xED to 0x72 directly as presented on Figure 1. You should pass through state 0x17 to provision the password before going to 0x72 (closed). In provisioning state, the MCU doesn't execute your code, it will be locked in the provisioning mode until you change to the other state. So, to recover your MCU, provision the password, then go to 0x72, and use the password to unlock the debugger and do a regression to open state 0xED. It will allow you to flash another code again.
Best Regards,
Dan