cancel
Showing results for 
Search instead for 
Did you mean: 

Can't create working FIP binary for Trusted Board Boot

gbe
Associate II

Hi, 

we are trying to enable secure boot on a custom board using STM32MP157C.
We are using OpenSTLinux ecosystem v5

  • en.SDK-x86_64-stm32mp1-openstlinux-6.1-yocto-mickledore-mp1-v23.06.21.tar.gz
  • en.sources-stm32mp1-openstlinux-6.1-yocto-mickledore-mp1-v23.06.21.tar.gz

What we already did:

  1. Generated keys using STM32_KeyGen_CLI.exe (publicKeyhash.bin, publicKey.pem, privateKey.pem)
  2. Write publicKeyhash.bin to OTP using STM32_Programmer_CLI.exe
  3. Sign the TF-A (BL2) image(.stm32 file) using STM32_SigningTool_CLI.exe
  4. Verify it worked by getting serial output when booting "NOTICE: Bootrom authentication succeeded"

Next step was embedding certificates in the FIP binary. Until then we built the FIP binary using Makefile.sdk in sources\arm-ostl-linux-gnueabi\tf-a-stm32mp-v2.8.6-stm32mp-r1-r0. If we understand the documentation correctly (https://wiki.st.com/stm32mpu-ecosystem-v5/wiki/TF-A_BL2_Trusted_Board_Boot) generating a FIP with all certificates has to be done using the Makefile in sources\arm-ostl-linux-gnueabi\tf-a-stm32mp-v2.8.6-stm32mp-r1-r0\tf-a-stm32mp-v2.8.6-stm32mp-r1.

So we try to:

  1. Build binaries with TF-A Makefile.sdk all build target and TRUSTED_BOARD_BOOT=1
  2. Create fip.bin with certificates by using TF-A Makefile like shown in ecosystem 6 documentation (https://wiki.st.com/stm32mpu/wiki/TF-A_BL2_Trusted_Board_Boot#STM32_MPU_build_options)

The fip binary contains:

Secure Payload BL32 (Trusted OS): offset=0x1000, size=0x2C, cmdline="--tos-fw"
Secure Payload BL32 Extra1 (Trusted OS Extra1): offset=0x2000, size=0x138C0, cmdline="--tos-fw-extra1"
Secure Payload BL32 Extra2 (Trusted OS Extra2): offset=0x16000, size=0x5C000, cmdline="--tos-fw-extra2"
Non-Trusted Firmware BL33: offset=0x72000, size=0xF5D4C, cmdline="--nt-fw"
FW_CONFIG: offset=0x168000, size=0x1EA, cmdline="--fw-config"
HW_CONFIG: offset=0x169000, size=0x13DC8, cmdline="--hw-config"
Trusted key certificate: offset=0x17D000, size=0x284, cmdline="--trusted-key-cert"
Trusted OS Firmware key certificate: offset=0x17E000, size=0x22A, cmdline="--tos-fw-key-cert"
Non-Trusted Firmware key certificate: offset=0x17F000, size=0x22D, cmdline="--nt-fw-key-cert"
Trusted OS Firmware content certificate: offset=0x180000, size=0x2E3, cmdline="--tos-fw-cert"
Non-Trusted Firmware content certificate: offset=0x181000, size=0x254, cmdline="--nt-fw-cert"
STM32MP CONFIG CERT: offset=0x182000, size=0x23F, cmdline="--stm32mp-cfg-cert"

When flashing this with STM32CubeProgrammer we get:

11:50:42 : STM32CubeProgrammer API v2.20.0 | Windows-64Bits 
11:50:48 : USB speed : High Speed (480MBit/s)
11:50:48 : Manuf. ID : STMicroelectronics
11:50:48 : Product ID : DFU in HS Mode @Device ID /0x500, @Revision ID /0x0000
11:50:48 : SN : 003F00333231510431333437
11:50:48 : DFU protocol: 1.1
11:50:48 : Board : --
11:50:48 : Device ID : 0x0500
11:50:55 : Read TSV File: C:\Users\gbe\Downloads\dev-image-signed\FlashLayout_emmc_rise_v1_6.tsv
11:50:55 : Number of partitions: 13
11:51:05 : Start Embedded Flashing service
11:51:05 : Opening and parsing file: tf-a-stm32mp157c-rise-usb-signed.stm32
11:51:05 : Memory Programming ...
11:51:05 : File : tf-a-stm32mp157c-rise-usb-signed.stm32
11:51:05 : Size : 212.56 KB
11:51:05 : Partition ID : 0x01
11:51:05 : Download in Progress:
11:51:07 : File download complete
11:51:07 : Time elapsed during download operation: 00:00:01.942
11:51:07 : RUNNING Program ...
11:51:07 : PartID: :0x01
11:51:07 : Start operation done successfully at partition 0x01
11:51:07 : Opening and parsing file: fip-stm32mp157c-rise-optee-signed.bin
11:51:07 : Memory Programming ...
11:51:07 : File : fip-stm32mp157c-rise-optee-signed.bin
11:51:07 : Size : 1.51 MB
11:51:07 : Partition ID : 0x03
11:51:07 : Download in Progress:
11:51:10 : File download complete
11:51:10 : Time elapsed during download operation: 00:00:02.359
11:51:10 : RUNNING Program ...
11:51:10 : PartID: :0x03
11:51:10 : Reconnecting the device ...
11:51:40 : Error: Unable to reconnect the target device: time out expired
11:51:40 : Error: Start operation failed at partition 0x03
11:51:40 : Error: TSV flashing service failed
11:51:41 : Disconnected from device.
 And corresponding output over serial from chip:
NOTICE: CPU: STM32MP157F?? Rev.Z
NOTICE: Model: STM32MP157C-Rise Board
NOTICE: Bootrom authentication succeeded
INFO: PMIC version = 0x21
INFO: Reset reason (0x15):
INFO: Power-on Reset (rst_por)
INFO: FCONF: Reading TB_FW firmware configuration file from: 0x2ffdd000
INFO: FCONF: Reading firmware configuration information for: cot_desc
INFO: FCONF: Reading firmware configuration information for: tbbr
INFO: FCONF: Reading firmware configuration information for: stm32mp_io
INFO: Using USB
INFO: Instance 2
INFO: Boot used partition fsbl1
NOTICE: BL2: v2.8-stm32mp1-r1.0(debug):v1.1.0-193-gd7fc783c5-dirty(d7fc783c)
NOTICE: BL2: Built : 09:19:19, Oct 30 2025
NOTICE: TRUSTED_BOARD_BOOT support enabled
INFO: Using crypto library 'stm32_crypto_lib'
INFO: BL2: Doing platform setup
INFO: RAM: DDR3-DDR3L 16bits 533000Khz
INFO: Memory size = 0x20000000 (512 MB)
INFO: DFU USB START...
INFO: phase ID :3, Manifestation 3 at c7183000
INFO: Send detach request
INFO: Receive DFU Detach
INFO: DFU USB STOP...
INFO: BL2: Loading image id 1
INFO: Loading image id=17 at address 0x2ffff000
INFO: Image id=17 loaded: 0x2ffff000 - 0x2ffff23e
ERROR: BL2: Failed to load image id 1 (-80)

It looks like STM32MP CONFIG CERT (id 17) is successfully loaded but then it fails to load FW_CONFIG (id 1).

Any help would be appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions
gbe
Associate II

We made some progress on this topic. Still not clear if this is the final solution, but it looks good at the moment.

  1. We could only create FIP packages with the Makefile of the TF-A package in tf-a-stm32mp-v2.8.6-stm32mp-r1 (not Makefile.sdk) correctly, hence with all required certificates.

  2. It turned out that the STM32MP CONFIG CERT is loaded correctly, which for the STM32MP157 is at id 17.

  3. The error -80 turned out to be while parsing the certificate extension which embeds the non volatile counters

The --tfw-nvctr counter as we understood is added to the STM32MP157 with the OID :1.3.6.1.4.1.4128.2100.1 and is parsed after loading and checking the certificate. During iteration over the OIDs of the x503v3 extension :1.3.6.1.4.1.4128.2100.1 could not be found. The error happens in

stm32-mw-mbedtls/library/oid.c at 6c16e1a3baeba8afae4798886ba7c7632e557b9b · STMicroelectronics/stm32-mw-mbedtls

ret = mbedtls_snprintf(p, n, "%c.%u", component1, component2);

where the escape sequence %c is not interpreted correctly.

See also TF-A with TRUSTED_BOARD_BOOT failed when using mbedtls-3.4.0 - TF-A - lists.trustedfirmware.org for reference.

When the Patch from here feat(libc): add %c support · Yann-lms/arm-trusted-firmware@c5c8280 is applied the extension can be read successfully and the boot process continues as expected.

View solution in original post

2 REPLIES 2
gbe
Associate II

We made some progress on this topic. Still not clear if this is the final solution, but it looks good at the moment.

  1. We could only create FIP packages with the Makefile of the TF-A package in tf-a-stm32mp-v2.8.6-stm32mp-r1 (not Makefile.sdk) correctly, hence with all required certificates.

  2. It turned out that the STM32MP CONFIG CERT is loaded correctly, which for the STM32MP157 is at id 17.

  3. The error -80 turned out to be while parsing the certificate extension which embeds the non volatile counters

The --tfw-nvctr counter as we understood is added to the STM32MP157 with the OID :1.3.6.1.4.1.4128.2100.1 and is parsed after loading and checking the certificate. During iteration over the OIDs of the x503v3 extension :1.3.6.1.4.1.4128.2100.1 could not be found. The error happens in

stm32-mw-mbedtls/library/oid.c at 6c16e1a3baeba8afae4798886ba7c7632e557b9b · STMicroelectronics/stm32-mw-mbedtls

ret = mbedtls_snprintf(p, n, "%c.%u", component1, component2);

where the escape sequence %c is not interpreted correctly.

See also TF-A with TRUSTED_BOARD_BOOT failed when using mbedtls-3.4.0 - TF-A - lists.trustedfirmware.org for reference.

When the Patch from here feat(libc): add %c support · Yann-lms/arm-trusted-firmware@c5c8280 is applied the extension can be read successfully and the boot process continues as expected.

gbe
Associate II

Update 2

After setting the device to closed state via OTP it looked like it was bricked. No booting or flashing was possible anymore. See https://community.st.com/t5/stm32-mpus-software-development/flashing-device-in-closed-device-secured-locked-state-over-usb/m-p/853313). This is now also solved. Here a summary of what we learned:

  1. It turned out that the OTP management utility STM32PRGFW-UTIL .stm32 file needs to be signed with the ROT_KEY with the signing tool, once the device is in locked state. If you do not sign it, you lose access to OTP and also flashing is not possible anymore. Once you use a correctly singed version you gain access to OTP again via STM32Programmer

  2. Also the TF-A BL2 used for programming via USB DFU with STM32Programmer needs to be signed, what we did.

  3. It turned out, what we think is a lack of documentation, that the monotonic OTP counter (anti rollback monotonic counter) is incremented when you lock the device (from 0 to 1). So the tf-a bl2 for emmc or sdcard boot which are already on the device prior to locking and were verified to boot correctly and authenticate correctly prior to lock, do not boot anymore (they have counter 0). No output no error message etc.

  4. You need to have the final producion / after lock TF-A and FIP set to counter 1 minimum to be bootable after locking.

Now secure boot in closed device state is working correctly.