How to make your application compatible with Secure Manager

1. Introduction

A change in STM32CubeMX has made the Boot Path feature losing the support of Secure Manager. This guide helps to adapt your application to run with Secure Manager. It addresses two cases:

  • 1) Starting from a simple application generated by STM32CubeMX (or not), independent of Secure Manager.
  • 2) Starting from an STM32CubeMX setup created with Secure Manager Boot Path with a version earlier than 6.14.

This guide uses STM32CubeIDE, but can be adapted for IAR™ or Keil™ IDEs.

2. Prerequisites

This guide assumes you have already installed X-CUBE-SEC-M-H5 V2.1.0 or later version.

The version of STM32CubeMX is 6.14 or higher (not supporting Secure Manager Boot Path)

Here are some helpful articles for these steps:

Secure Manager STM32H5 How to

How to start with Secure Manager default configuration on STM32H5

3. Before starting the adaptation

3.1. Case 1: Simple project

  1. The project already exists, it was created with or without STM32CubeMX, and works standalone.
  2. The project is created from scratch using STM32CubeMX. You have generated the code.

3.1.1. Example preparation

The location of your project is not dependent on the location of Secure Manager package. You can point to Secure Manager package files or copy them into your project.

In the following steps, Secure Manager is located in C:\ST\X-CUBE-SEC-M-H5_V2.1.0, the application is located in C:\Projects\My_SM_Projects .

We start from scratch with STM32CubeMX. Here we select the chip used on the STM32H573-DK board.

Security ChipSelection.png

Select "without TrustZone Activated".

In Secure Manager context, the user application is a simple application.

In Project Manager tab, select the destination of the example: here we use C:\Projects\My_SM_Projects, but it can be any location.

The reason for creating an example like this is that we have an independent location containing all the needed files (such as drivers and middlewares)

600

Now you can set up your peripherals as needed.

  • We set PI9 GPIO as output to control a LED
  • We use USART1 associated to GPIOs PA9 and PA10 to trace output through STLink VCP.

Generate the code, build and check on STM32H573-DK target. TrustZone® on the target must be disabled. This can be checked in option bytes using STM32CubeProgrammer.

From this point we assume you have your project working on your target.

600

You can add in main.c relevant code for LED blinking, and output trace through printf.

3.2. Case 2: Using a STM32CubeMX project generated before release 6.14

3.2.1. Preparation

IMPORTANT First, save the whole project. You may need part of it, especially the ROT_Provisioning\SM directory changes you made.

3.2.2. Migrate to STM32CubeMX 6.14

3.2.2.1. STM32CubeMX migration

The first step is to open your project's IOC file using STM32CubeMX 6.14 or higher. You will get a pop-up asking you to migrate, confirm using the migration dialog box.

As soon as you confirm, the directory ROT_Provisioning/SM is erased, and the env.bat located in ROT_Provisioning is deleted (this file is no longer needed).

The different paths are set in .ini files. For instance, STM32CubeProgrammer location can be changed in ROT_Provisioning\SM\Config\tools.ini

Security Migration Message.png

3.2.2.2. STM32CubeMX Code generation

On first code generation after migration, STM32CubeMX performs the following changes:

  1. Remove the Middlewares\ST\secure_manager_api. This is no longer supported by STM32CubeMX.
  2. Update the driver, as release 6.14 uses a more recent STM32CubeH5. The files impacted here are HAL driver files, and device include files.
  3. The STM32CubeIDE project files have the following changes
    1. In main.c file, the SystemClockConfig implementation is removed
    2. The secure_manager_api files are removed
    3. The associated include files are removed
    4. The associated compilation flag is removed (TFM_PSA_API)

You can follow the different steps to be compatible with Secure Manager 2.0

4. Step 1: Get Secure Manager configuration files

You have two options:

  • Keep these configuration files in the Secure Manager Cube Package.
  • Copy them in your project.

If you come from Case 2, you already have the ROT_Provisioning/DA directory in your project.

Here we propose to get these files into your project.

4.1. Copy the Secure Manager files

The files are located in

C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Projects\STM32H573I-DK\ROT_Provisioning

Copy the whole directory contents to your project You have then

C:\Projects\My_SM_Projects\SampleSMProject\ROT_Provisioning\DA
C:\Projects\My_SM_Projects\SampleSMProject\ROT_Provisioning\SM

For Case 2 (migration), the DA directory is kept and Secure Manager is removed. Depending on the changes you made, you may need to merge them, but the final configuration is the same.

4.2. Adapt configuration files

The Secure Manager python scripts use tools located in C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Utilities

More specifically:

Utilities/PC_Software/ROT_AppliConfig
Utilities/PC_Software/ROT_ITSBuilder

You can point to the original Secure Manager package, or copy this Utilities directory in your project. In that case, add one directory between CubeMX ioc location and the Utilities directory. For instance you can install these directories in Tools, which leads to

  • Tools/Utilities/PC_Software/ROT_AppliConfig
  • Tools/Utilities/PC_Software/ROT_ITSBuilder

Other point of attention is the file config_path.ini located in ROT_Provisioning\SM

This file is a kind of cache. If this is present, remove it in your copy. It will be regenerated with good content.


Note: you can force deletion of the config_path.ini using provisionin.py with -c argument.

In all cases, you will have to point the base directory where the Utilities directory is located.

If you want your project to contain the Utilities directory, copy it to have:

C:\Projects\My_SM_Projects\SampleSMProject\Tools\Utilities

Then, to indicate to Secure Manager scripts to use this directory, modify the following file:

C:\Projects\My_SM_Projects\SampleSMProject\ROT_Provisioning\SM\Config\sm.ini

Replace

[cube]
path = ../../../../../

By

[cube]
path = ../../../Tools

if you leave the Utilies directory in the package, you can set

[cube]
path = C:\ST\X-CUBE-SEC-M-H5_V2.1.0\

5. Step 2: Copy necessary files from Secure Manager's application template

Here starts the adaptation. The principle is to copy files from the Template directory located here

C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Projects\STM32H573I-DK\Template\ROT\SMAK_Appli\

5.1. Copy and adapt project.ini

Copy

cd C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Projects\STM32H573I-DK\Template\ROT\SMAK_Appli
copy project.ini C:\Projects\My_SM_Projects\SampleSMProject

Adapt

The first step is to provide the ROT_Provisioning actual directory. You can use either the relative or the absolute path.

In Secure Manager V2.1.0, sm_config.h was added. This file is generated by the scripts. So, update the path for this file as well.

Edit project.ini in your project.

Replace

[sm]
path=./../../../ROT_Provisioning/SM/
sm_config_header_path = ./Inc/sm_config.h

By

[sm]
path=./ROT_Provisioning/SM/
sm_config_header_path = ./Core/Inc/sm_config.h

Also, replace, in the same file, "STM32H573I-DK_SMAK_Appli_Templates" by your project name. Here "SampleSMProject" in the output lines.

Replace

[cubeide_debug]
linker = ./STM32CubeIDE/STM32H573IIKXQ_FLASH.ld
output = ./STM32CubeIDE/Debug/STM32H573I-DK_SMAK_Appli.bin

[cubeide_release]
linker = ./STM32CubeIDE/STM32H573IIKXQ_FLASH.ld
output = ./STM32CubeIDE/Release/STM32H573I-DK_SMAK_Appli.bin

By

[cubeide_debug]
linker = ./STM32H573IIKXQ_FLASH.ld
output = ./Debug/SampleSMProject.bin

[cubeide_release]
linker = ./STM32H573IIKXQ_FLASH.ld
output = ./Release/SampleSMProject.bin

Here we are in a setup without STM32CubeIDE directory, because we selected in CubeMX the Generate Under Root.

If you use another IDE modify the corresponding binary location in the dedicated section, [iar] for instance.

5.2. Copy project.py

Copy

cd C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Projects\STM32H573I-DK\Template\ROT\SMAK_Appli
copy project.py C:\Projects\My_SM_Projects\SampleSMProject

No changes are needed for this file.

5.3. Copy and possibly adapt STM32CubeIDE/STM32H573IIKXQ_FLASH.ld

This is linker file containing symbolic definitions allowing automatic updates using scripts

Copy

cd C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Projects\STM32H573I-DK\Template\ROT\SMAK_Appli
copy STM32H573IIKXQ_FLASH.ld C:\Projects\My_SM_Projects\SampleSMProject\

Adapt

If you compare original file and the one the from the Templates, you can see that changes are very simple. So, if you have already changed your linker file, you can merge the two to keep your specific items It is important to keep the definitions provided in this linker file. These definitions can be changed by the Secure Manager scripts in case you change the configuration of the Secure Manager.

6. Step 3: Create empty directories

If you use version 2.1.0 of Secure Manager, create the following directories.

cd C:\Projects\My_SM_Projects\SampleSMProject
mkdir Images
mkdir Binary

Images directory are filled automatically by xml files used for image signing. Binary is the output directory for signed image.

Note: These directories are already be present if you come from Case 2. They are automatically generated with version 2.1.0.

7. Step 4: STM32CubeIDE configuration update

7.1. Add prebuild/postbuild in compilation flow

Open your project's properties Add following lines in Properties => C/C++ Build => Settings => Build Steps

Prebuild:

python ../project.py prebuild --compiler CubeIDE_Debug

Postbuild:

python ../project.py postbuild

Security BuildStepsUpdate.png

7.2. Generate firmware binary

Add generation of firmware binary in properties Properties => C/C++ Build => Settings => Tools Settings => MCU/MPU Post build outputs

Security AddBinaryGeneration.png This is the binary that will be used as input at the postbuild step for signature.

This is also the one you mention in project.ini file above

7.3. Change system_stm32h5xx.c

This is already done if you are in Case 2.

In your project you should have a file named system_stm32h5xx.c, located in Drivers/CMSIS. Find the SystemInit() function, and remove all the code.

7.3.1. Add HAL_RCC_DeInit()

As Secure Manager already starts the clocks before jumping to the application, it is important to call the function HAL_RCC_DeInit() before the SystemClock_Config() to make sure you start from a know state.

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  if (HAL_RCC_DeInit() != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

8. Step 5: Add PSA_API

This step is necessary to be able to use the Secure Manager services For this you need to do four different actions:

8.1. Copy the secure_manager_api directory to your environment

The only constraint here is to avoid creating the directory in Middlewares like this: Middlewares\ST\secure_manager_api , because it will be erased on the following STM32CubeMX code generation. So, for instance, you can copy the secure_manager_api in the root directory of your project:

Please select the two folders:

C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Middlewares\ST\secure_manager_api\ipc\nonsecure\
C:\ST\X-CUBE-SEC-M-H5_V2.1.0\Middlewares\ST\secure_manager_api\interface\

into secure_manager_api directory.

8.2. Add sources to your project

Then add the following files to your project. You may not need all of them, depending upon the Secure Manager service you are actually using.

secure_manager_api/interface/src/check_parameters.c
secure_manager_api/interface/src/psa_fwu.c
secure_manager_api/interface/src/psa_ia.c
secure_manager_api/interface/src/psa_its.c
secure_manager_api/interface/src/tfm_crypto_secure_api.c
secure_manager_api/ipc/nonsecure/src/psa_client.c
secure_manager_api/ipc/nonsecure/src/tfm_ns_interface.c

Note that low_level_rng.c is not needed


Here is how it can look like

Security secure manager api.png

8.3. Add TFM_PSA_API to the C Preprocessor

In Properties => C/C++ Build => Settings => Tools Settings => MCU/MPU GCC Compiler => Preprocessor

Add TFM_PSA_API define

Security TFM PSA API Define.png

8.4. Add include paths to new files location

In Properties => C/C++ Build => Settings => Tools Settings => MCU/MPU GCC Compiler => Include Paths

../secure_manager_api/interface/inc/psa
../secure_manager_api/interface/inc
../secure_manager_api/ipc/nonsecure/inc

Security IncludePathsForPSA API.png

From this point, you can check compilation

9. Step 6: Build and download

Now you are almost done. You can build the application. Launch the STM32CubeIDE build. In the build trace you will see:

python ../project.py prebuild --compiler CubeIDE_Debug
2025-06-17 15:47:57,808 - INFO - Running prebuild ...
2025-06-17 15:48:17,362 - INFO - Linker files updated successfully
2025-06-17 15:48:20,729 - INFO - XML images and key updated successfully

Then, once compilation is finished you will see the generation of the binary using objcpy, and the launch of the postbuild command:

...
arm-none-eabi-gcc -o "SampleSMProject.elf" @"objects.list"   -mcpu=cortex-m33 -T"C:\Projects\My_SM_Projects\SampleSMProject\STM32H573IIKXQ_FLASH.ld" --specs=nosys.specs -Wl,-Map="SampleSMProject.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
Finished building target: SampleSMProject.elf
arm-none-eabi-size  SampleSMProject.elf
arm-none-eabi-objdump -h -S SampleSMProject.elf  > "SampleSMProject.list"
arm-none-eabi-objcopy  -O binary SampleSMProject.elf  "SampleSMProject.bin"
text	   data	    bss	    dec	    hex	filename
35176	    104	   2056	  37336	   91d8	SampleSMProject.elf
Finished building: default.size.stdout
Finished building: SampleSMProject.bin
Finished building: SampleSMProject.list
python ../project.py postbuild
2025-06-17 18:50:21,581 - INFO - Postbuild successful

To analyse possible errors from prebuild or postbuild you can check prebuild.log and postbuild.log in the Debug directory.

At this point, you need to provision the Secure Manager to the target using provisioning.py before STEP7.

10. Step 7: Debug application on target

Open the debug configuration.

To make debugger work in secure manager environment you need:

  1. In debugger tab, set"Reset behaviour" as "Software system reset"
  2. In same tab, disable the Verify flash download.

600

Also, check STM32CubeIDE erratas (if any) in wiki.

For instance, with version 1.19.0 you need to add some commands in "Run Commands" of debug configuration when debugging non secure application.

From this point, you can continue to develop and test your application with Secure Manager. STM32CubeMX new code generation does not change the configuration.

11. Conclusion

The setup for having a CubeMX generated project compatible with Secure Manager is straightforward and is needed only once. Following this guide also gives you some useful information about the Secure Manager build environment and its flexibility. This allows you setting up your environment according to your needs.