cancel
Showing results for 
Search instead for 
Did you mean: 

What is the goal of the firewall configuration constraint on dual bank products

BEnge.1
Associate III

Hi,

One of the requirement for the FLASH layout on dual bank product (like the STM32L4 that I use) is that the FWALL code section overlaps the the FWALL NVdata (see the attached image).

If I understand correctly the reason is that if the banks are swapped the keys stored in the Secure Engine Code are still protected by the Firewall. My questions are:

  1. Can the banks be swapped without performing a mass erase first ? If not than what is the advantage of that overlap rule.
  2. How can the banks be swapped? (I know from the attached image that if SYSCFG_MEMRMP / FB_MODE = 1, banks are swapped but how can those variables be set practically ?)
  3. If the KMS is used, the keys are stored in the FWALL NVdata Code section not in the FWALL Code section. If the FWALL NVdata section is bigger than the FWALL Code section and the banks are swapped, isn't that possible the keys are outside the firewall protection ?

Thanks in advance,

Benjamin

7 REPLIES 7
Fred
ST Employee

Hi,

your understanding is correct, you need to maintain a symmetry of the firewall segments between Bank1 and Bank2 in case an attacker manages to take control of the FB_MODE bit.

This FB_MODE is a control bit that the user code can set.

In the SBSFU code, you can see in SFU_IMG_InitImageHandling() that we have a sanity check about it:

/*

  * Sanity check: the firewall NVdata segment must overlap the firewall code segment

  */

 if (((SFU_PROTECT_FWALL_NVDATA_ADDR_START - FLASH_BANK_SIZE) > SFU_PROTECT_FWALL_CODE_ADDR_START) ||

   ((SFU_PROTECT_FWALL_NVDATA_ADDR_START + SFU_PROTECT_FWALL_NVDATA_SIZE - FLASH_BANK_SIZE) <

    (SFU_PROTECT_FWALL_CODE_ADDR_START + SFU_PROTECT_FWALL_CODE_SIZE)))

 {

  TRACE("\r\n= [FWIMG] Firewall NVdata segment doesn't overlap firewall code segment\r\n");

  e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR;

 }

Indeed, we may also do the opposite check too in case of KMS.

The mapping itself is defined in the 'Linker_Common' folder.

You can check these definitions:

 /* Protected code segment start address and length (it has to be multiple of 256 bytes). */

 FWALL_InitStruct.CodeSegmentStartAddress   = SFU_PROTECT_FWALL_CODE_ADDR_START;

 FWALL_InitStruct.CodeSegmentLength      = SFU_PROTECT_FWALL_CODE_SIZE;

 /* Protected Non volatile data segment (in Flash memory) start address and length */

 FWALL_InitStruct.NonVDataSegmentStartAddress  = SFU_PROTECT_FWALL_NVDATA_ADDR_START;

 FWALL_InitStruct.NonVDataSegmentLength     = SFU_PROTECT_FWALL_NVDATA_SIZE;

BEnge.1
Associate III

Thanks for the quick reply @Fred​. So do you confirm that in the current state of the SBSFU package, the keys are not protected by the firewall in case of bank swap if I use the KMS?

Also, doesn't the signature of the user code ensures that it is not malicious? In this case it ensures that it wont try to do a bank swap to retrieve the keys, no ?

Fred
ST Employee

Hi,

it is not exactly what I meant.

In fact in KMS you have 2 categories of keys:

  • the keys handled by SBSFU are stored in the code section
  • the user keys are handled in the NVDATA section

So, the point concerns only the user keys.

For these keys, as long as your NVDATA segment is not bigger than your code segment then you are on the safe side.

But, because our sanity check is designed only to check the code is covered by the data, if your data is bigger than the code then you might have the problem you identified.

Nevertheless, the mapping is your responsibility (as an SBSFU integrator I would say) so you just need to make sure your 2 sections have a symmetry.

Also, please note that some of my colleagues are implementing the encryption (with AES GCM) of the user keys. This should be available in the coming months for the WL variant of SBSFU.

Regarding the signature : yes, indeed the signature is here to ensure the authenticity and integrity of the applicative firmware. So, if this firmware has no flaw then you are on the safe side for the inner attacks.

Now, (at least) two things can still happen:

  1. outter attacks ==> by accessing physically the board the attacker manages to flip the bit (with a laser or whatever)
  2. a bug in your firmware ==> yes the firmware is valid but it might contain a buffer overflow bug. The attacker may use this buffer overflow to introduce some malicious code or conduct a Return oriented Programming attack for instance. We cannot exclude that an attacker might gain control over the bit.

A usual, I will conclude with my standard piece of advice 🙂

I am sharing here only some statements based on what you asked.

You still need to do the security analysis of your system based on your assets and requirements.

BEnge.1
Associate III

Thank you for the comprehensive reply @Fred​. I have one last question related to that:

In fact in KMS you have 2 categories of keys:

  • the keys handled by SBSFU are stored in the code section
  • the user keys are handled in the NVDATA section

Looking at the code I was able to find a link between __ICFEDIT_KMS_DataStorage_start__ defined in mapping_sbsfu.ld and the kms code but I don't understand how the SBSFU_AES_1_128 key can be stored in the code section and Test_Key_AES256 can be stored in the NVDATA section as those are both defined in the same kms_platf_objects_config.h file. Could you explain me that ?

Fred
ST Employee

I see : my wording was not appropriate.

I should have distinguished static/embedded and dynamic keys.

In fact both keys you indicate are embedded keys so static keys.

SBSFU_AES_1_128 is used only by SBSFU.

Test_Key_AES256 is used by the user application but it is also a static key embedded in the code.

I think that if you want to play around with dynamic user key, you can use these items:

    /* 3 = Import Blob */

    case '3':

     INVOKE_SCHEDULE_NEEDS();

     KMS_UPDATE_StartLocalUpdate();

     tkms_app_print_menu();

     break;

    /* 4 = Tests RSA Static key (requires blob import) */

    case '4' :

     INVOKE_SCHEDULE_NEEDS();

     ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer);

     (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED");

     tkms_app_print_menu();

     break;

    /* 5 = Tests Key derivation (requires blob import) */

    case '5':

     INVOKE_SCHEDULE_NEEDS();

     ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer);

     (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED");

     tkms_app_print_menu();

     break;

BEnge.1
Associate III

Ok, thanks so static keys are stored in the Secure Engine code section and dynamic keys in NVDATA section, right ?

Thanks!

Correct.