cancel
Showing results for 
Search instead for 
Did you mean: 

SBSFU not detecting Active Slot Image

jmcoreymv
Associate III

I'm working on integrating the latest SBSFU (v2.6.2) onto an STM32L4A6 platform. I've reviewed both the user manual and application note for the SBSFU, as well as the examples provided.

In my use case:

  • I have an external attached MMC flash
  • I'm not planning to use the internal MCU flash dual-bank capability (so I can have an image larger than half the 1MB flash size)
  • I don't need rollback/swap capability
  • For OTA updates, my user application will download the encrypted image to a location in the external MMC flash. The SBSFU on boot will check for a valid image in that location, and if so, it will copy it to the MCU flash active slot.

 

I was able to get the B-L475E-IOT01A 2_Images_ExtFlash example to boot and run on my board, and it executes the UserApp.

 

For porting the SBSFU to integrate with my custom UserApp I have:

  • Started from the B-L475E-IOT01A 2_Images_ExtFlash example because it seemed like the closest for what I needed.
  • Replaced the example QSPI driver with an MMC flash driver
  • Modified the various linker files how I think they should be modified based on the user manual/app note.
  • Temporarily disabled all security protections in the SBSFU and enabled verbose debugging
  • The example I started from with external flash was putting the FIREWALL NVDATA section in the middle of the MCU flash (0x8080000) as if we were using dual-bank internal flash, so I changed that by referencing the NUCLEO-L432KC 1_Image example which uses the Firewall but places the NVDATA section at the start of the first active slot (0x8020000).
  • I'm able to build the SECoreBin, SBSFU, and custom UserApp successfuly.
  • When I try to use STMCubeProgrammer to flash the resulting combined binary in to the MCU, it loads but it fails to detect a valid image in Active Slot 1 (the master slot), and then it erases that slot because no valid image was found.
  • I'm having trouble figuring out why it's not seeing a valid image in that location, since it should be part of the combined binary produced by the SBSFU scripts.
    • I've added some trace statements to the when SFU_IMG_DetectFW() is called and more specifically for the SFU_LL_FLASH_INT_Read() function.
    • I can see that when it's searching inside the header region, the se_status returns SE_KO, and the se_ret_status returns SE_ERROR, but I'm not sure how to troubleshoot this further.
    • Here's a console output from some trace logging I've added in this region:

 

SFU_IMG_DetectFW -> slot 1
SFU_LL_FLASH_Read internal
Looking in header
pSource: 0x0x8020000, Length: 320 -> pdest: 0x0x20017e78
DoubleECC_Error_Counter: 0
se_status: 1245757
se_ret_status: 100249
SFU_IMG_DetectFW -> slot 1
SFU_LL_FLASH_Read internal
Looking in header
pSource: 0x0x8020000, Length: 320 -> pdest: 0x0x20017e78
DoubleECC_Error_Counter: 0
se_status: 1245757
se_ret_status: 100249
Slot SLOT_ACTIVE_1 not empty : erasing ...

 

Trying to figure out what my next steps should be to determine why the SBSFU is not finding a valid image in active slot 1.

 

Thanks!

12 REPLIES 12
Jocelyn RICARD
ST Employee

Hello @jmcoreymv ,

I don't fully catch what you have done with NVDATA of firewall.

Just be aware that there is a firewall limitation that you can check in errata sheet that impacts the possible mapping solutions.

In any case, my advice will be to debug the modified SBSFU and try to understand what happens.

You can always add SECoreBin symbols to debug inside SECoreBin. Just make sure to disable firewall and once you make it work, re-enable firewall to see if you don't fall in the limitation.

Best regards

Jocelyn

I'm going to work a bit more on trying to load the SECoreBin symbols to debug that further.  Currently all SBSFU protections are disabled.

Regarding the firewall limitation, could you help me understand this better for my use-case?  I have the STM32L4A6, but I don't want to use the dual-bank capability since it will limit my potential image size to a bit under half of the 1MB flash.  Instead I'm using the external MMC flash as my download slot, and giving up swap/rollback capabilities.

Is this still possible to do?  So firewall would be enabled, code and NV data would be protected, but I don't want to place NVDATA in the middle of the MCU flash because that would prevent me from supporting larger images.  Is my understanding correct?

Hello @jmcoreymv ,

the X-CUBE-SBSFU does not use the dual bank capability for update. I mean, the update does not happen using a bank swapping. Update mechanism uses a sector swapping mechanism using a spare sector for robustness in case of reset during the swapping.

The usage of NVData on second bank is used to protect the content of firewall on first bank. Reason is that firewall content moves with bank swapping. So, if you don't have this NVData area on second bank, the firewall content can be exposed. If you remove this, you introduce a weakness. Now, to exploit such weakness an attacker would need to be able to inject code on your target, which is not that easy.

This constraint is described in AN5056 Rev8 Chapter 3.2.2

The risk is to leak the authentication public key and the encryption key.

Authentication public key does not provide any information. Encryption key allows decrypting content of the firmware. So, if attacker manages to inject code, firmware content (outside firewall) has already leaked...

So, risk could be related to what you add inside firewall. Up to you to evaluate the global risk.

Best regards

Jocelyn

 

Hi @Jocelyn RICARD 

Thanks you again for the response.


the X-CUBE-SBSFU does not use the dual bank capability for update. I mean, the update does not happen using a bank swapping. Update mechanism uses a sector swapping mechanism using a spare sector for robustness in case of reset during the swapping.


This makes sense to me.  However in my use-case, I don't think sector swapping is used either from my understanding. "app_sfu.h" contains the "#define SFU_NO_SWAP".

 


The usage of NVData on second bank is used to protect the content of firewall on first bank. Reason is that firewall content moves with bank swapping. So, if you don't have this NVData area on second bank, the firewall content can be exposed. If you remove this, you introduce a weakness. Now, to exploit such weakness an attacker would need to be able to inject code on your target, which is not that easy.

This constraint is described in AN5056 Rev8 Chapter 3.2.2

The risk is to leak the authentication public key and the encryption key.

Authentication public key does not provide any information. Encryption key allows decrypting content of the firmware. So, if attacker manages to inject code, firmware content (outside firewall) has already leaked...


I believe I understand this better now, thank you for the detailed explanation. so I can evaluate the risk for this.  However, the main thing I'm still stuck trying to understand is the following:

In my use-case, I will not be doing bank-swapping at all.  Is it possible to just have the firewall protect the area in bank1 and not bank2 at all? So my UserApp image can span across part of bank 1 and 2?  Or is there no way to include firewall protection and having UserApp images larger than half the flash?

Thanks

Hello @jmcoreymv 

Yes you are not supposed to do bank swapping in such context.

" Is it possible to just have the firewall protect the area in bank1 and not bank2 at all?"

The firewall is an internal isolation. Inside firewall you will find keys and crypto algorithm that are used by the SBSFU to authenticate the firmware.

So, you just need to move the NVDATA part of the firewall to leave maximum space for your application.

Best regards

Jocelyn

Hi @Jocelyn RICARD 

Thank you for confirming/clarifying.  I'm back to my original issue, but this time I'm just using the B-L475E-IOT01A 2_Images_ExtFlash example with minimal modifications to port from the STM32L475 to the STM32L4A6. I put in some dummy responses to the QSPI external flash functions so they succeed (except the compare). 

I've changed the number of active slots to 1, and number of download slots to 1 and disabled all protections.

If I leave the linker files as-is, I'm able to successfully boot the modified example SBSFU+UserApp on my board.  I'm trying to modify the the mapping_fwimg.ld file to the single slot for my use-case, but struggling to get it correct.

 

Here's the modifications I've made to the file (original values are commented out):

__ICFEDIT_SLOT_Active_1_start__  = 0x08020000;
__ICFEDIT_SLOT_Active_1_header__ = 0x08020000;
__ICFEDIT_SLOT_Active_1_end__    = 0x080FE7FF; /* Skip the last 3 flash sectors, used for other purposes */
__ICFEDIT_SLOT_Active_1_len__ = __ICFEDIT_SLOT_Active_1_end__ - __ICFEDIT_SLOT_Active_1_start__ + 1;

/* Original Example
REMOVE__ICFEDIT_SLOT_Active_1_header__ = 0x08089E00;
REMOVE__ICFEDIT_SLOT_Active_1_start__  = 0x0808A000;
REMOVE__ICFEDIT_SLOT_Active_1_end__    = 0x080FFFFF;
*/

/* Dwl slot #1 (472 kbytes) */
__ICFEDIT_SLOT_Dwl_1_start__     = 0x90000000;
__ICFEDIT_SLOT_Dwl_1_end__       = __ICFEDIT_SLOT_Dwl_1_start__ + __ICFEDIT_SLOT_Active_1_len__ - 1;

/* Original Example
REMOVE__ICFEDIT_SLOT_Dwl_1_start__     = 0x90000000;
REMOVE__ICFEDIT_SLOT_Dwl_1_end__       = 0x90075FFF;
*/

 

With these changes, the SBSFU fails to detect the valid image in active slot 1:

= [SBOOT] SECURE ENGINE INITIALIZATION SUCCESSFUL
= [SBOOT] STATE: CHECK STATUS ON RESET
          INFO: A Reboot has been triggered by a Software reset!
= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD
= [SBOOT] STATE: CHECK USER FW STATUS
          No resume required : TRAILER_HDR_TEST not valid!
          Slot SLOT_ACTIVE_1 not empty : erasing ...

 

Are you able to help identify what I might be doing wrong here?

Thanks

I also tried shifting the original active slot 1 header and start addresses an additional 0x1000 to keep it in the same bank 2, and reduced the size of the download slot to match. It errored out the same way as above.

Hi @Jocelyn RICARD 

I wanted to follow up on this as I’m still struggling to figure out how to successfully modify the active slot location and use the full MCU flash space for an image.

Thanks!

I've gotten a bit further since being able to debug inside SECoreBin.

When the SBSFU is checking the master slot (ACTIVE_SLOT_0), for a valid image, via the SFU_LL_FLASH_INT_READ() function, it calls SE_SFU_IMG_Read().  Inside SE_SFU_IMG_Read(), it performs this call to the SE (se_interface_bootloader.c, line 287):

/* Secure Engine Call */

e_ret_status = (*SE_CallGatePtr)(SE_IMG_READ, pSE_Status, primask_bit, pDestination, pSource, Length);
This ends up in the the SE_CallGate() function in se_callgate.c, which then calls 'SE_SP_SMUGGLE()' (line 316).
e_ret_status = SE_SP_SMUGGLE(eID, peSE_Status, arguments);
SE_SP_SMUGGLE returns the error status code which then bubbles up to a failure to detect an image.
 
I haven't figured out why SE_SP_SMUGGLE returns an error, and it looks like it is a call to a set of assembly instructions.

@Jocelyn RICARD I ran across this thread a while back where something was ported to the target chip, in my case an STM32L4A6, to fix this issue? Not sure if this is related/relevant to me.

https://community.st.com/t5/stm32-mcus-security/sbsfu-failure-during-verifying-fw-signature/m-p/289966