cancel
Showing results for 
Search instead for 
Did you mean: 

SBSFU on STM32G0 not able to resume update after interruption

Markus Schwarzl
Associate III

Hi!

I'm succesfully using SBSFU 2.6.2 on a STM32G474 with SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.

Now in another project I wanted to use the same SBSFU configuration on a STM32G0B0 but as this MCU is much less performant I switched to SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM to get faster startup and installation times. But during testing now we happily found out before releasing that with this configuration the installation process does not resume if it is interrupted e.g. by a power-loss. I tried with and without swap-area and also with and without user-validation. Using SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 works as expected. It fails during startup and does not resume the update. As the application is already partially updated it then fails to verify and deletes the image, which is the worst case as any update is then impossible (except loader in SBSFU, which requires wired connection).
I figured out that somehow during CheckTrailerMagic() the "magic" is all 0xFF which is not allowed. This "magic" value is written in WriteTrailerHeader() already with all 0xFF as it is build from the FW-states (?) which are not used if user-validation is disabled...? Not sure if I have a misunderstanding somewhere or where the issue has its root cause as I do not see any link to the cryptp-scheme at those code locations...

Best regards,

Markus Schwarzl

1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello @Markus Schwarzl ,

I made a test on STM32G0B1, using STM32G071 2 images SBSFU example.

First I confirm the issue. For some reason, if the update is interrupted at any point it does not resume. I will create an internal ticket for that. I have no idea of the complexity/time of investigation of such issue.

About ECDSA and timing, I have added a trace in VerifyHeaderSignature() 

I could see the following:

1) Basic boot: 4 sec: ECDSA and hash are checked twice

2) Removing one check (in ExecuteUserFW) I get something around 2.5 s

3) During an update

   - First check when new fw detected.

   - 4 checks during installation

  - 1 more check (or 2 if no patch) after reset

This takes very long time indeed.

This could be reduced again with some small changes in the code.

It all depends on the duration of the timeout.

Best regards

Jocelyn

 

 

View solution in original post

7 REPLIES 7
Jocelyn RICARD
ST Employee

Hello @Markus Schwarzl ,

this is strange that recovery process depends on the crypto scheme. Need to check that.

One workaround could be to come back to ECDSA which is much more robust solution, and make sure that signature verification is done only once.

For security reason this check is done at least twice but may be more. You can add a trace in the code to check this and the remove the multiple calls.

Not sure you will reach same performance as with AES GCM but will definitely improve performance

Best regards

Jocelyn

Markus Schwarzl
Associate III

Hi Jocelyn,

thanks for your quick response!
I'd also suppose that the recovery should be independant from the crypto scheme, but I guess there is somewhere a bug that prevents the recovery with  AES GCM to be correctly handled. I will try to trace and compare with the working crypto-config if I can figure out the root issue.

I also tried your proposal. I added trace output to SFU_IMG_VerifyActiveImg() (I guess this is the location you meant to check!?) and found it already called only once during booting as you can see in the logs below.

MarkusSchwarzl_0-1736234055128.png

(this is a debug build, same behavior with release)

ECDSA takes around 5s to boot. Actually the boot time wouldn't be so problematic but we have to integrate into an existing FW-Update chain and with the ECDSA also the installation time increases dramatically on the STM32G0 which triggers timeout issues during install... that's why I swapped to AES GCM. I'll check the possibilities also in this direction!
BTW: Also SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 works correctly (does recover interrupted installation).

Thanks so far and a happy new year,

Markus

Jocelyn RICARD
ST Employee

Hello @Markus Schwarzl ,

I made a test on STM32G0B1, using STM32G071 2 images SBSFU example.

First I confirm the issue. For some reason, if the update is interrupted at any point it does not resume. I will create an internal ticket for that. I have no idea of the complexity/time of investigation of such issue.

About ECDSA and timing, I have added a trace in VerifyHeaderSignature() 

I could see the following:

1) Basic boot: 4 sec: ECDSA and hash are checked twice

2) Removing one check (in ExecuteUserFW) I get something around 2.5 s

3) During an update

   - First check when new fw detected.

   - 4 checks during installation

  - 1 more check (or 2 if no patch) after reset

This takes very long time indeed.

This could be reduced again with some small changes in the code.

It all depends on the duration of the timeout.

Best regards

Jocelyn

 

 

Jocelyn RICARD
ST Employee

Just one additional comment:

The 4 checks during installation are related to the reading of the version of current firmware.

A very simple change can remove these 4 checks

Create a new function in sfu_fwimg_common.c by first copy pasting CheckAndGetFWHeader() function and removing the signature check:

 

SFU_ErrorStatus GetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader)
{
  SFU_ErrorStatus e_ret_status = SFU_ERROR;

  /* use api read to detect possible ECC error */
  e_ret_status = SFU_LL_FLASH_Read((uint8_t *) pFwImageHeader, (uint8_t *) SlotHeaderAdd[SlotNumber],
                                   sizeof(SE_FwRawHeaderTypeDef));

  return e_ret_status;
}

 

Then, modify SFU_IMG_GetActiveFwVersion to call this new function

 

uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber)
{
  SE_FwRawHeaderTypeDef fw_image_header;
  SFU_ErrorStatus e_ret_status = SFU_ERROR;
  uint16_t version = 0;

  /* check the header of the active FW */
  e_ret_status = GetFWHeader(SlotNumber, &fw_image_header);
  if (e_ret_status == SFU_SUCCESS)
  {
    /* retrieve the version from the header without any further check */
    version = fw_image_header.FwVersion;
  }

  return (version);
}

 

 With this change, you remove the signature check of the current firmware (that was already checked at previous boot) during the update each time we need to read its version inside header.

You end up with an update time significantly reduced.

Best regards

Jocelyn

 

Hi Jocelyn,

thank you again very much for the quick response and raising the issue internally!

We have discussed the topic and will do your proposed adaptions and go with ECDSA!

Even if it is slower (will see after testing if it isn't even faster now) it will be the better approach.

As I'm already fully occupied this week I have to shift the testing to next week and will then update this thread accordingly.

BR,

Markus

Markus Schwarzl
Associate III

Hi Jocelyn,

 

I finally implemented and verified your proposed solutions!

Ending up in 2.3s for startup and 15.3s for installation!

Thanks for your great support!

BR,

Markus

Markus Schwarzl
Associate III

Hi Jocelyn,

I did further testing today and found an issue with your proposed solution.

Removing the header verification as stated above has an impact on SFU_IMG_GetActiveFwVersion(). In case no valid active image is available (image is erased) it returns a header with all 0xFF which results in a reported FW-Version 0xFFFF (65535) and this fails any attempt to install a new FW with the Loader (First Check for FW-Version in Loader and if this is skipped during there is another check during the installation).

I did some modifications so that GetFWHeader() detects an empty slot and returns 0 in such a case. This is still much faster than checking the signature of the header.

Now installation via the loader of th SBSFU (as a failsafe solution if application gets corrupted or deleted) and via the application is working and much faster then in the original version.

 

BR,

Markus