cancel
Showing results for 
Search instead for 
Did you mean: 

FW Signature check error due to hash mismatch

DenysK
Associate II

Hello @Jocelyn RICARD ,

I’m integrating SBSFU v2.7.0 on an STM32WB55 to enable secure OTA firmware updates. I’m hitting a problem where the runtime hash verification fails: the hash computed by SBSFU at boot does not match the hash in the image header, so the image is erased.

I dump the decrypted bytes in RAM (before programming) over LPUART and convert them to a binary for comparison with the build output. Assuming the dump/conversion are correct, the streams match up to ~60 KiB, then diverge consistently until the end of the file. This suggests the symmetric key is correct and the early pipeline is fine, but later bytes are corrupted before or during the decrypt-in-place / program sequence.

Here is how printing every decrypted chunk within DecryptImageInPlace function:

DenysK_0-1759246389237.png

For context, I'm using:

  • Internal MCU flash

  • Single-bank (no swap/rollback)

  • OTA via ST BLE Sensor app

  • Protections temporarily disabled for debugging; verbose logs enabled

What works

  • Ran 1_Image example on NUCLEO-WB55RG successfully.

  • Adapted UserApp example (UART tweak) to our board and performed an encrypted update successfully with the example image.

Integration steps for our app

  • Replaced ST’s UserApp with our project.

  • Added required includes and post-build script.

  • Reused the example linker, adjusted heap/stack, added a shared RAM section for both cores, and ensured the output is padded to a multiple of 16 bytes (AES block size).

  • Did not change SLOT_Active_1 layout (app is much smaller).

  • Set the vector table via mapping_export.h (VTOR at 0x08016200).

  • Built SECoreBin + SBSFU + our UserApp successfully.

  • Full chip erase; provisioned symmetric key; flashed SBSFU.elf.

  • Performed OTA update → FW signature check error.

  • Ensured the hash, firmware size and initialisation vector populated in the header by the scripts match the header fields in memory after loading the firmware.
  • Checked for gaps in memory using the .elf file, to prove loadable regions are address-contiguous.

The post below mentions corruption could happen if the data cache is enabled when the MPU protection is enabled. In my case, I have disabled all protections and also tried to disable cashing (not sure whether it was done correctly) but no success in solving this issue.  

stm32 - Issues in SBSFU usage with MPU for a FreeRTOS based User Application - STM32H7 - Electrical Engineering Stack Exchange

Many thanks for your guidance. I can share dumps or run any diagnostic you recommend.

 

 

7 REPLIES 7
Christian N
ST Employee

This post has been escalated to the ST Online Support Team for additional assistance. We'll contact you directly.

Regards,
Christian

ST Support

Jocelyn RICARD
ST Employee

Hello @DenysK ,

Your description suggests that something goes wrong after some time during download of new firmware.

If you are sure that encrypted part is ok, then some corruption comes during firmware decryption.

First, I don't see how cache could come in the picture in this case. When you have cache related issues this is usually when using DMA: Transfering date through DMA into a cached RAM area required cache cleanup when reading the data from CPU. Also, the issue you refer to is on different MCU that has completely different cache mechanism.

One possible reason could be that AES IP is accessed by another component during this decryption.

I'm not very familiar with WB stack management so difficult to provide more insight.

Would be interesting to see if the decryption issue occurs always at the same address. It may give some clue.

First test I would do is to start back from example and add artificially some data in the default application to make it bigger so that it crosses this 60KB boundary. If issue is reproduce, then we should rapidly find the solution.

Best regards

Jocelyn

Hello @Jocelyn RICARD ,

Thank you for your suggestions.

Using a single binary, I performed three download attempts of the encrypted firmware to our custom board. The decryption issue consistently occurs, though it begins at different memory addresses each time — for example, at 0x0F6C0, 0x0F010, and 0x0F100. I also observed that the corrupted data tends to become repetitive towards the end of the files.

I made some adjustments to ST’s user application example by extending the application size using the linker script —  added a section just before the 16-byte padding that ensures proper AES alignment:

DenysK_0-1759937333662.png

P.S: The binary ended up being filled with zeros rather than 0xAA, but it still seems to function correctly for our testing purposes.

Interestingly, when testing with a 100 KB update, the process fails during the hash digest comparison in the ST example. However, after reducing the padding to 50 KB, the update succeeds and the example application runs correctly. I also noticed that the update progress bar moves smoothly from 0–100% with the 50 KB image, whereas for 100 KB (and our actual application, which is over 200 KB), the progress halts intermittently and the overall update process takes significantly longer.

This makes me wonder whether there might be a limitation or oversight in either the ST BLE Sensor app or the SBSFU package that prevents proper handling of larger firmware updates.

I’ve attached the binaries used in both cases for your reference and comparison.

Regards,

Denys

DenysK
Associate II

Hello @Jocelyn RICARD ,

I haven’t yet verified whether the ciphertext stored in flash matches the .sfb file that was transmitted during the update.

My plan is to compare the device bytes at SlotStart + 0x200 (skip the 0x200-byte header) against the .sfb payload starting at offset 0x200, for the full encrypted length. 

I’ll run this check and update you with the results.

Regards,
Denys

 

DenysK
Associate II

Hello @Jocelyn RICARD ,

I’ve run the test I mentioned earlier.

The ciphertext stored in flash actually mismatches the UserApp.sfb produced by the build, and the divergence begins at about 60 KB (byte offset 0x0EC48 in this run). This indicates the corruption occurs before decryption.

For the comparison I:

  • Stripped the 512-byte header from UserApp.sfb to get the payload.

  • Compared that payload byte-for-byte against the ciphertext read from flash at SlotStart + 0x200 (0x08016200).

I’ve attached a folder with the files I used for comparison.

Please let me know if there are known issues that could cause a repeatable divergence around this offset.

Thanks in advance - I’m happy to share any additional traces or artifacts you need.

Jocelyn RICARD
ST Employee

Hello @DenysK ,

Thank you for the update.

I started thinking about an issue around the usage of AES accelerator that could have been used by CPU2 while decryption was ongoing. But this AES accelerator is only accessed by CPU2 when requested to load a key from CKS.

So, this was very unlikely to happen and you confirm this is not the issue.

This means that corruption occurs during BLE download.

I'm not in BLE stack at all. Now this is quite common use case for OTA, so I guess if something was not working you wouldn't be the first to experience it. So, I think next step is to check possible issue on OTA loader adaptation made for your environment.

Best regards

Jocelyn

Hello @Jocelyn RICARD ,

Thank you for getting back to me.

I think the issue is definitely in the loader project of the SBSFU package.

I tried to run the SBSFU package (1_Image example) on the NUCLEO-WB55RG and perform an update. The only change I made was increasing the example application size to 100 KB in the linker script. Unfortunately this does not work either. 

I’ve been following AN5056 (Integration guide) and UM2262 (Getting started) but I couldn’t find any guidance suggesting the SBSFU loader requires modifications - especially since the default example fails as soon as the application size is increased.

Important to mention that before integrating SBSFU, I used the standalone BLE_Ota loader from STM32Cube_FW_WB_V1.23.0 and unencrypted updates worked fine at our application size using the same ST's Android app. 

At first glance, while comparing that standalone loader to the SBSFU one, I've noticed that the flash driver, the routines that write the image to flash, and the update service/characteristics look identical. However, there are differences - especially around GAP and BLE stack initialisation. The variable names and debug messages are also different, making a diff hard to follow. 

My current suspicion is that a behavioral change may have been introduced in the BLE_Ota loader bundled with SBSFU. 

I’m now trying to adapt the standalone BLE_Ota to work under SBSFU, but time is very tight. 

Do you think it is worth trying older versions of the SBSFU package?

Could you investigate this on your side and suggest any steps that might help us pinpoint the root cause?

Kind regards,

Denys