2022-04-28 07:36 AM
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:
Thanks in advance,
Benjamin
2022-04-28 07:44 AM
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;
2022-04-29 01:09 AM
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 ?
2022-04-29 02:19 AM
Hi,
it is not exactly what I meant.
In fact in KMS you have 2 categories of keys:
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:
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.
2022-04-29 04:01 AM
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:
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 ?
2022-04-29 05:10 AM
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;
2022-04-29 07:28 AM
Ok, thanks so static keys are stored in the Secure Engine code section and dynamic keys in NVDATA section, right ?
Thanks!
2022-04-29 08:52 AM
Correct.