Skip to main content
MBuen.1
Senior
September 22, 2021
Question

Replace SBSFU Uart local loader for USB. Crypto in Secure Engine is failing.

  • September 22, 2021
  • 10 replies
  • 3381 views

Hey guys,

I need to replace Uart for USB on my SBSFU local loader. I manage to create the USB comm in SBSFU quite easily, using UART structure provided in the SBSFU examples. My problem is when i receive firmware header, my code get stuck on the following part in the Secure Engine:

int32_t status;
 PKA_ECDSAVerifInTypeDef ECDSA_verif = {0};
 const uint8_t *pSign_r;
 const uint8_t *pSign_s;
 /* Firmware metadata to be authenticated and reference MAC */
 const uint8_t *pPayload; /* Metadata payload */
 int32_t payloadSize; /* Metadata length to be considered for hash */
 uint8_t *pSign; /* Reference MAC (ECCDSA signed SHA256 of the FW metadata) */
 const uint8_t *pPub_x;
 const uint8_t *pPub_y;
 /* buffer for sha256 computing */
 uint8_t MessageDigest[CRL_SHA256_SIZE];
 int32_t MessageDigestLength = 0;
 
 /* the key to be used for crypto operations (as this is a pointer to m_aSE_FirmwareKey or m_aSE_PubKey it can be a
 local variable, the pointed data is protected) */
 uint8_t *pKey;

This is inside the SE_CRYPTO_Authenticate_Metadata on the Secure Engine (i configured my debugger with SBSFU and SE .elf, so that i could be able to debug both codes). Code goes until line number two of the code snippet above, then after that i see with debug that code keeps looping in this part of startup file:

Reset_Handler:
 Infinite_Loop:
 b Infinite_Loop
 .size Reset_Handler, .-Reset_Handler

This is the call stack until infinite loop: 

Thread #1 [main] 1 [core: 0] (Suspended : Breakpoint)	
	SE_CRYPTO_Authenticate_Metadata() at se_crypto_bootloader.c:1.064 0x8000bcc	
	SE_CallGateService() at se_callgate.c:841 0x80023ac	
	SE_CallGate() at se_callgate.c:311 0x80002b8	
	SE_VerifyHeaderSignature() at se_interface_bootloader.c:701 0x8003bb8	
	SFU_LOADER_VerifyFwHeader() at sfu_loader.c:942 0x8005342	
	SFU_COM_USB_DataPktRxCpltCallback() at sfu_loader.c:733 0x80055e2	
	SFU_COM_USB_Receive() at sfu_com_loader.c:358 0x8004b4c	
	SFU_LOADER_DownloadNewUserFw() at sfu_loader.c:135 0x8005516	
	SFU_BOOT_SM_DownloadNewUserFw() at sfu_boot.c:748 0x80043b2	
	SFU_BOOT_SM_Run() at sfu_boot.c:416 0x80047a4	
	<...more frames...>	

I fell this could be something related to my ram partitioning. Here's how my mapping_sbsfu.ld is:

/* SE Code region */
VECTOR_SIZE = 0x200;
__ICFEDIT_SE_Code_region_ROM_start__ = 0x08000000 + VECTOR_SIZE;
__ICFEDIT_SE_CallGate_region_ROM_start__ = __ICFEDIT_SE_Code_region_ROM_start__; /* No need to do +4 as we have dummy bytes in SE_CoreBin .ld file */
__ICFEDIT_SE_CallGate_region_ROM_end__ = __ICFEDIT_SE_Code_region_ROM_start__ + 0x1FF;
 
/* SE key region */
__ICFEDIT_SE_Key_region_ROM_start__ = __ICFEDIT_SE_CallGate_region_ROM_end__ + 0x1;
__ICFEDIT_SE_Key_region_ROM_end__ = __ICFEDIT_SE_Key_region_ROM_start__ + 0xFF;
 
/* SE Startup */
__ICFEDIT_SE_Startup_region_ROM_start__ = __ICFEDIT_SE_Key_region_ROM_end__ + 0x1;
__ICFEDIT_SE_Code_nokey_region_ROM_start__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x100;
__ICFEDIT_SE_Code_region_ROM_end__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x31FF;
 
/* SE IF ROM */
__ICFEDIT_SE_IF_region_ROM_start__ = __ICFEDIT_SE_Code_region_ROM_end__ + 1;
__ICFEDIT_SE_IF_region_ROM_end__ = __ICFEDIT_SE_IF_region_ROM_start__ + 0x5FF;
 
/* SBSFU Code region */
__ICFEDIT_SB_region_ROM_start__ = __ICFEDIT_SE_IF_region_ROM_end__;
__ICFEDIT_SB_region_ROM_end__ = 0x0801FFFF;
 
/* LOADER code region : 20 kBytes area aligned on 4kBytes address, MPU protection constraints */
__ICFEDIT_LOADER_region_ROM_start__ = __ICFEDIT_SB_region_ROM_end__ + 0x1;
__ICFEDIT_LOADER_region_ROM_end__ = 0x0802FFFF;
 
SE_Entry_Secure_ROM_Region_Length = __ICFEDIT_SE_CallGate_region_ROM_end__ - __ICFEDIT_SE_CallGate_region_ROM_start__ + 1;
SE_Key_region_ROM_Length = __ICFEDIT_SE_Key_region_ROM_end__ - __ICFEDIT_SE_Key_region_ROM_start__ + 1;
SE_Startup_region_ROM_Length = __ICFEDIT_SE_Code_nokey_region_ROM_start__ - __ICFEDIT_SE_Startup_region_ROM_start__ ;
SE_ROM_region_Length = __ICFEDIT_SE_Code_region_ROM_end__ - __ICFEDIT_SE_Code_nokey_region_ROM_start__ + 1;
SE_IF_region_ROM_Length = __ICFEDIT_SE_IF_region_ROM_end__ - __ICFEDIT_SE_IF_region_ROM_start__ + 1;
SB_ROM_region_Length = __ICFEDIT_SB_region_ROM_end__ - __ICFEDIT_SB_region_ROM_start__ + 1;
LOADER_ROM_region_Length = __ICFEDIT_LOADER_region_ROM_end__ - __ICFEDIT_LOADER_region_ROM_start__ + 1;
 
/* RAM section */
/* SE stack is placed 1st in RAM, stack overflow does not write on other RAM area */
__ICFEDIT_SE_region_RAM_start__ = 0x20000000;
__ICFEDIT_SE_region_RAM_stack_top__ = 0x20000400;
__ICFEDIT_SE_region_RAM_end__ = 0x20000FFF;
 
/* LOADER communication region when bypass mode activated */
__ICFEDIT_LOADER_COM_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1;
__ICFEDIT_LOADER_COM_region_RAM_end__ = __ICFEDIT_LOADER_COM_region_RAM_start__ + 0x0F;
 
/* LOADER RAM1 region */
__ICFEDIT_LOADER_region_RAM_start__ = __ICFEDIT_LOADER_COM_region_RAM_end__ + 1;
__ICFEDIT_LOADER_region_RAM_end__ = 0x2002FFFF;
 
/* SBSFU RAM1 region */
__ICFEDIT_SB_region_RAM_start__ = __ICFEDIT_LOADER_COM_region_RAM_end__ + 1;
__ICFEDIT_SB_region_RAM_end__ = 0x2004FFFF;
 
SE_RAM_region_Length = __ICFEDIT_SE_region_RAM_end__ - __ICFEDIT_SE_region_RAM_stack_top__ + 1;
LOADER_RAM_region_Length = __ICFEDIT_LOADER_region_RAM_end__ - __ICFEDIT_LOADER_region_RAM_start__ + 1;
SB_RAM_region_Length = __ICFEDIT_SB_region_RAM_end__ - __ICFEDIT_SB_region_RAM_start__ + 1;
 
MEMORY
{
 SE_Entry_Secure_ROM_Region (rx) : ORIGIN = __ICFEDIT_SE_CallGate_region_ROM_start__, LENGTH = SE_Entry_Secure_ROM_Region_Length
 SE_Key_region_ROM (rx) : ORIGIN = __ICFEDIT_SE_Key_region_ROM_start__, LENGTH = SE_Key_region_ROM_Length
 SE_Startup_region_ROM (rx) : ORIGIN = __ICFEDIT_SE_Startup_region_ROM_start__, LENGTH = SE_Startup_region_ROM_Length
 SE_ROM_region (rx) : ORIGIN = __ICFEDIT_SE_Code_nokey_region_ROM_start__, LENGTH = SE_ROM_region_Length
 SE_IF_region_ROM (rx) : ORIGIN = __ICFEDIT_SE_IF_region_ROM_start__, LENGTH = SE_IF_region_ROM_Length
 SB_ROM_region (rx) : ORIGIN = __ICFEDIT_SB_region_ROM_start__, LENGTH = SB_ROM_region_Length
 LOADER_ROM_region (rx) : ORIGIN = __ICFEDIT_LOADER_region_ROM_start__, LENGTH = LOADER_ROM_region_Length
 SE_RAM_region (xrw) : ORIGIN = __ICFEDIT_SE_region_RAM_stack_top__, LENGTH = SE_RAM_region_Length
 LOADER_RAM_region (xrw) : ORIGIN = __ICFEDIT_LOADER_region_RAM_start__, LENGTH = LOADER_RAM_region_Length
 SB_RAM_region (xrw) : ORIGIN = __ICFEDIT_SB_region_RAM_start__, LENGTH = SB_RAM_region_Length
 RAM_SHARED (rw) : ORIGIN = 0x20030000, LENGTH = 10K
}

I changed the __ICFEDIT_SB_region_RAM_end__ to 0x2004FFFF to see if it would solve anything but the behaviour kept the same.

I also had to alter the SB ROM lenght, since i'm now using USB and the code is bigger.

Hope anyone can help me.

Thanks in advance,

Matheus

This topic has been closed for replies.

10 replies

Jocelyn RICARD
ST Employee
September 22, 2021

Hello Matheus,

I guess you are using STM32WB.

You seem to be stuck in the PKA but I have no idea why.

But as your debugger seems not aligned with actual code, this is not sure.

You should be able to see exactly at which line of code you are stuck.

Maybe clean and recompile everything will help in this debugger source alignment

Best regards

Jocelyn

MBuen.1
MBuen.1Author
Senior
September 22, 2021

Hey @Jocelyn RICARD​ , you're right, i'm using STM32WB. I'll double check that my debug. I was thinking this was correct, since i configured CubeIDE to also use the SECore .elf during debugging.

It should be quite straight foward to replace UART for USB in SBSFU local loader, right? Do you advice me to pay attention to something in specific?

MBuen.1
MBuen.1Author
Senior
September 22, 2021

That call stack was inside of SecureEngine, when i debug only SBSFU code, this is the part that my code get stuck, more specifically at line 25:

SE_ErrorStatus SE_VerifyHeaderSignature(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxFwRawHeader)
{
 SE_ErrorStatus e_ret_status;
 uint32_t primask_bit; /*!< interruption mask saved when disabling ITs then restore when re-enabling ITs */
 
 /* Check if the call is coming from SFU code */
 __IS_SFU_RESERVED();
 
#ifdef SFU_ISOLATE_SE_WITH_MPU
 if (0U != SE_IsUnprivileged())
 {
 uint32_t params[1] = {(uint32_t)pxFwRawHeader};
 SE_SysCall(&e_ret_status, SE_CRYPTO_HL_AUTHENTICATE_METADATA, peSE_Status, &params);
 }
 else
 {
#endif /* SFU_ISOLATE_SE_WITH_MPU */
 
 /* Set the CallGate function pointer */
 SET_CALLGATE();
 
 /* Enter Secure Mode */
 SE_EnterSecureMode(&primask_bit);
 
 e_ret_status = (*SE_CallGatePtr)(SE_CRYPTO_HL_AUTHENTICATE_METADATA, peSE_Status, primask_bit, pxFwRawHeader);
 
 /* Exit Secure Mode */
 SE_ExitSecureMode(primask_bit);
#ifdef SFU_ISOLATE_SE_WITH_MPU
 }
#endif /* SFU_ISOLATE_SE_WITH_MPU */
 
 return e_ret_status;
 
}

After that i guess the code goes to SecureEngine area, and that's why i configured the SecureEngine .elf in my debug.

MBuen.1
MBuen.1Author
Senior
September 22, 2021

Without SecureEngine .elf, after the above code snippet i got a message that code is in function SE_Core_Bin_start and debugger doesn't have the symbols to process it.

MBuen.1
MBuen.1Author
Senior
September 22, 2021

I really do think is something related to RAM, or allocation.. i don't know. I left the PKA_ECDSAVerifInTypeDef ECDSA_verif variable unintialized and the code went a little bit further, that's what is making me think this is a memory map problem.

Jocelyn RICARD
ST Employee
September 23, 2021

Hello @MBuen.1​ 

Adding SECodeBin.elf to the debugger configuration should give you access to the symbols.

One example is provided here

Best regards

Jocelyn

MBuen.1
MBuen.1Author
Senior
September 23, 2021

Hello @Jocelyn RICARD​ ,

I was the one that provided the example there, that print i provided is exactly what i'm using to debug this project. I'm already able to access the secure engine symbols and it's from this symbols that i found out that my code is breaking in that PKA call.

Don't you have any idea why it could be breaking in that line?

Replace UART for USB shouldn't have any major problem, right?

Should i use hardware semaphores in STM32WB even if my loader is not using BLE?

Regards,

Matheus

MBuen.1
MBuen.1Author
Senior
September 27, 2021

Hello? Could anyone help me?

alister
Senior III
September 27, 2021

>Could anyone help me?

Disable all your protections and step/debug and/or devise tests that definitively isolate where the problem is.

MBuen.1
MBuen.1Author
Senior
September 27, 2021

Yeah mate.. I know that and i'm doing it for idk, the past three weeks and i'm still stuck. I just want a hint that could help me.

alister
Senior III
September 27, 2021

Think what could be wrong and devise a test to see if it is.

A contender is the question several days ago whether your SE is loaded at the address it was linked at correctly. Open its binary in a hex editor and compare with flash.

You will need any decent protections disabled to do that.

Or check the SBSFU and SE map files to confirm nothing in their links collide, and read memory, either in the debugger or in STM32CubeProgrammer to confirm what's there matches their binary. Convert elfs to binary if you've only elfs.

Step into the fault with the debugger. Compare the code you're stepping with the list file.

Add an SE call that do nothing and test that works.

klang.1
Associate
June 1, 2022

I am trying to use USB port too, on STM32L496ZGT, USB Virtual Port Tx/Rx are working fine when debug separately.

But always fail at __IS_SFU_RESERVED();

main() --> SFU_BOOT_RunSecureBootService() --> SE_Startup(void)

-->  __IS_SFU_RESERVED();

I compare map file, not much difference to the one with UART in the 2_images example

Need help !

Thanks,

Kevin