Skip to main content
ali rostami
Associate III
October 23, 2022
Question

Enabling SFU_MPU_PROTECT_ENABLE causes a problem

  • October 23, 2022
  • 10 replies
  • 3295 views

In my project the microcontroller is STM32F756VGT6, I changed the example "2_Images_OSC" of STM32f769I-Discovery to be compatible with this microcontroller.

Right now everything seems O.K and I can upgrade the application with SBSFU. But when I uncomment the definition of SFU_MPU_PROTECT_ENABLE I get to a problem and here is the message I get from terminal:

======================================================================
= (C) COPYRIGHT 2017 STMicroelectronics =
= =
= Secure Boot and Secure Firmware Update =
======================================================================
 
 
= [SBOOT] SECURE ENGINE INITIALIZATION SUCCESSFUL
= [SBOOT] STATE: CHECK STATUS ON RESET
 INFO: A Reboot has been triggered by a Software reset!
 Memory fault
========= End of Execution ==========

Here is the MPU config:

#define SFU_PROTECT_MPU_MAX_NB_SUBREG (8U)
 
/**
 * @brief Region 0 - Enable the read/write operations for the full peripheral area in unprivileged
 * mode.
 * Execution capability disabled
 */
#define SFU_PROTECT_MPU_PERIPH_1_RGNV MPU_REGION_NUMBER0
#define SFU_PROTECT_MPU_PERIPH_1_START 0x00000000U
#define SFU_PROTECT_MPU_PERIPH_1_SIZE MPU_REGION_SIZE_4GB
#define SFU_PROTECT_MPU_PERIPH_1_SREG 0x83U /*!< 4GB / 8 * 5 ==> only peripheral area allowed */
#define SFU_PROTECT_MPU_PERIPH_1_PERM MPU_REGION_FULL_ACCESS
#define SFU_PROTECT_MPU_PERIPH_1_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_PERIPH_1_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_PERIPH_1_B MPU_ACCESS_BUFFERABLE
#define SFU_PROTECT_MPU_PERIPH_1_C MPU_ACCESS_NOT_CACHEABLE
 
/**
 * @brief Region 1 - Enable the read/write operations for RCC peripheral area in privileged mode.
 * Execution capability disabled
 * Inner region inside the Region 0
 */
#define SFU_PROTECT_MPU_PERIPH_2_RGNV MPU_REGION_NUMBER1
#define SFU_PROTECT_MPU_PERIPH_2_START RCC_BASE
#define SFU_PROTECT_MPU_PERIPH_2_SIZE MPU_REGION_SIZE_1KB
#define SFU_PROTECT_MPU_PERIPH_2_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_PERIPH_2_PERM MPU_REGION_PRIV_RW
#define SFU_PROTECT_MPU_PERIPH_2_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_PERIPH_2_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_PERIPH_2_B MPU_ACCESS_BUFFERABLE
#define SFU_PROTECT_MPU_PERIPH_2_C MPU_ACCESS_NOT_CACHEABLE
 
/**
 * @brief Region 2 - Enable the read/write operations for full flash area in unprivileged mode.
 * Execution capability disabled
 */
#define SFU_PROTECT_MPU_FLASHACC_RGNV MPU_REGION_NUMBER2
#define SFU_PROTECT_MPU_FLASHACC_START FLASH_BASE /*!< Flash memory area */
#define SFU_PROTECT_MPU_FLASHACC_SIZE MPU_REGION_SIZE_1MB
#define SFU_PROTECT_MPU_FLASHACC_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_FLASHACC_PERM MPU_REGION_FULL_ACCESS
#define SFU_PROTECT_MPU_FLASHACC_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_FLASHACC_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_FLASHACC_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_FLASHACC_C MPU_ACCESS_CACHEABLE
 
/**
 * @brief Region 3 - Enable the execution for SB/SFU Full area (SBSFU + SE + Keys) in unprivileged mode.
 * Read only capability configured
 * Inner region inside the Region 2
 */
#define SFU_PROTECT_MPU_FLASHEXE_RGNV MPU_REGION_NUMBER3
#define SFU_PROTECT_MPU_FLASHEXE_START FLASH_BASE /*!< Flash memory area */
#define SFU_PROTECT_MPU_FLASHEXE_SIZE MPU_REGION_SIZE_128KB
#define SFU_PROTECT_MPU_FLASHEXE_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_FLASHEXE_PERM MPU_REGION_PRIV_RO_URO
#define SFU_PROTECT_MPU_FLASHEXE_EXECV MPU_INSTRUCTION_ACCESS_ENABLE
#define SFU_PROTECT_MPU_FLASHEXE_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_FLASHEXE_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_FLASHEXE_C MPU_ACCESS_CACHEABLE
 
/**
 * @brief Region 4 - Enable the read/write operation in privileged mode for Header of active slots
 * Execution capability disabled
 * Inner region inside the Region 2
 */
#define SFU_PROTECT_MPU_HEADER_RGNV MPU_REGION_NUMBER4
#define SFU_PROTECT_MPU_HEADER_START SLOT_ACTIVE_1_HEADER
#define SFU_PROTECT_MPU_HEADER_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_HEADER_SIZE MPU_REGION_SIZE_1KB
#define SFU_PROTECT_MPU_HEADER_PERM MPU_REGION_PRIV_RW
#define SFU_PROTECT_MPU_HEADER_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_HEADER_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_HEADER_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_HEADER_C MPU_ACCESS_CACHEABLE
 
/**
 * @brief Region 5 - Enable the read/write operation in unprivileged mode for RAM area.
 * Execution capability disabled
 */
#define SFU_PROTECT_MPU_SRAMACC_RGNV MPU_REGION_NUMBER5
#define SFU_PROTECT_MPU_SRAMACC_START RAMDTCM_BASE /*!< RAM memory area */
#define SFU_PROTECT_MPU_SRAMACC_SIZE MPU_REGION_SIZE_512KB
#define SFU_PROTECT_MPU_SRAMACC_SREG 0xE0U /*!< 512 Kbytes / 8 * 5 ==> 64K + 240K Kbytes */
#define SFU_PROTECT_MPU_SRAMACC_PERM MPU_REGION_FULL_ACCESS
#define SFU_PROTECT_MPU_SRAMACC_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_SRAMACC_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_SRAMACC_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_SRAMACC_C MPU_ACCESS_CACHEABLE
 
/**
 * @brief Region 6 - Enable the read/write operation in privileged mode for Secure Engine RAM area.
 * Execution capability disabled
 * Inner region inside the Region 5
 * Address must be aligned on 4KB as size is 4KB
 */
#define SFU_PROTECT_MPU_SRAM_SE_RGNV MPU_REGION_NUMBER6
#define SFU_PROTECT_MPU_SRAM_SE_START SFU_SENG_RAM_ADDR_START /*!< SE RAM memory area */
#define SFU_PROTECT_MPU_SRAM_SE_SIZE MPU_REGION_SIZE_16KB
#define SFU_PROTECT_MPU_SRAM_SE_SREG 0xC0U /*!< 16 Kbytes / 8 * 6 ==> 12 Kbytes */
#define SFU_PROTECT_MPU_SRAM_SE_PERM MPU_REGION_PRIV_RW
#define SFU_PROTECT_MPU_SRAM_SE_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_SRAM_SE_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_SRAM_SE_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_SRAM_SE_C MPU_ACCESS_CACHEABLE
 
/**
 * @brief Region 7 - Enable the execution for Secure Engine flash area in privileged mode.
 * Read only capability configured
 * Inner region inside the Region 3
 */
#define SFU_PROTECT_MPU_EXEC_SE_RGNV MPU_REGION_NUMBER7
#define SFU_PROTECT_MPU_EXEC_SE_START FLASH_BASE /*!< Flash memory area */
#define SFU_PROTECT_MPU_EXEC_SE_SIZE MPU_REGION_SIZE_64KB
#define SFU_PROTECT_MPU_EXEC_SE_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_EXEC_SE_PERM MPU_REGION_PRIV_RO
#define SFU_PROTECT_MPU_EXEC_SE_EXECV MPU_INSTRUCTION_ACCESS_ENABLE
#define SFU_PROTECT_MPU_EXEC_SE_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_EXEC_SE_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_EXEC_SE_C MPU_ACCESS_CACHEABLE
 
/**
 * MPU configuration for UserApp execution
 * =======================================
 * Reconfiguration of existing regions (useless during UserApp execution)
 * MPU constraint = Region base address should be aligned on Region size
 */
 
/**
 * @brief Region 3 - Enable the execution for active slots in unprivileged mode.
 * Read only capability configured
 * Inner region inside the Region 2
 */
#define APP_PROTECT_MPU_FLASHEXE_RGNV MPU_REGION_NUMBER3
#define APP_PROTECT_MPU_FLASHEXE_START FLASH_BASE
#define APP_PROTECT_MPU_FLASHEXE_SIZE MPU_REGION_SIZE_1MB
#define APP_PROTECT_MPU_FLASHEXE_SREG 0xCCU /*!< subregion 0 (activated): SBSFU
 subregion 1 (de-activated) : Swap
 subregions 2,3,4 (activated) : active slot(s) */
#define APP_PROTECT_MPU_FLASHEXE_PERM MPU_REGION_PRIV_RO_URO
#define APP_PROTECT_MPU_FLASHEXE_EXECV MPU_INSTRUCTION_ACCESS_ENABLE
#define APP_PROTECT_MPU_FLASHEXE_TEXV MPU_TEX_LEVEL0
#define APP_PROTECT_MPU_FLASHEXE_B MPU_ACCESS_NOT_BUFFERABLE
#define APP_PROTECT_MPU_FLASHEXE_C MPU_ACCESS_CACHEABLE

What is wrong with this MPU config?

This topic has been closed for replies.

10 replies

ali rostami
Associate III
October 27, 2022

So any idea? @JHOUD​ @Jocelyn RICARD​ 

I also couldn't debug SBSFU with Keil, I found something about IAR or CubeIDE, but found nothing about Keil.

Fred
ST Employee
November 3, 2022

Hi @ali rostami​ ,

it seems you face an issue at this stage:

 TRACE("\r\n= [SBOOT] STATE: CHECK STATUS ON RESET");
 
 /* Check the wakeup sources */
 SFU_BOOT_ManageResetSources();
 
 /* RCC access done to identify the wakeup sources, we can switch to unpriviledged */
 SFU_MPU_EnterUnprivilegedMode();

So, at first sight, there can be 2 reasons:

  1. Check that the RCC registers used to get the reset source are accessible ==> Region 1 settings to be verified
  2. Check that after entering unprivileged mode, a particular access is rejected.

This might be related to the check done in : SFU_BOOT_SM_CheckUserFwStatus()

==> need to check your region 4 settings.

Finally, if no problem arises here, then it may be due to the RAM settings with region 5.

These are only ideas, you need to check these directions.

Thanks & Regards,

Fred

ali rostami
Associate III
November 9, 2022

Thanks dear @Fred​ 

Now I found out that the main application is being started.

By limiting its code, I got to that it fails in the configuration of USB in CDC.

So the MPU has an effect on the "MX_USB_DEVICE_Init" function.

After a few tests, I found that if in the body of "SFU_LL_SECU_SetProtectionMPU_UserApp" I reconfigured the MPU before returning from the function by this line:

HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

or this one:

HAL_MPU_Enable(MPU_HFNMI_PRIVDEF);

The USB works. So I think it shows that there are addresses that are not configured by MPU, so when we use one of these 2 lines, it uses the default config for that area.

But I checked the MPU configuration so many times, what do think?

Jocelyn RICARD
ST Employee
November 10, 2022

Hello Ali,

The USB registers are located in the 0x5000 0000 address which is not included in the MPU configuration. It is actually excluded from the default configuration because of SFU_PROTECT_MPU_PERIPH_1_SREG 0x83U.

Reason is to exclude the memory area that can be addressed through FMC and OSPI in a the range 0x60000000 to 0xE0000000. This exclusion is necessary to avoid the speculative accesses in this area which cause unexpected crashes.

So, the solution is to add a specific MPU region for this USB memory area or change value 0x83 to 0x87 to include this range by default just to make sure this is the root cause.

Best regards

Jocelyn

ali rostami
Associate III
November 14, 2022

Hi, @Jocelyn RICARD​ , thanks for your answer.

But are you sure?

I think this area is not excluded because as you said it's in the 0x5000 0000 address, which is located in Block 3 of the memory map, and by defining SFU_PROTECT_MPU_PERIPH_1_SREG  as 0x83 this block would be included because 0x83 causes block 0, block 1 and block 7 to be disabled and excluded. Please correct me if I'm wrong.

And about adding a new specific region, all 8 regions were used. I have no idea How can I do it?

Jocelyn RICARD
ST Employee
November 14, 2022

Hello @ali rostami​ ,

yes, my mistake. I'm used to another MPU configuration that simply disables all access to these regions. Here this is a setting to make regions not executable which is fine.

So, issue is somewhere else.

To understand why you get this you can use debugger an see what exactly generates this memory fault. I think this is the fastest and easiest way to go forward

Best regards

Jocelyn

ali rostami
Associate III
November 14, 2022

Hmm, Yeah thanks to your help @Jocelyn RICARD​ , I could finally debug the main application.

It seems the problem is with the unique ID registers of the microcontroller, which are located in the reserved portion of the memory map (UID_BASE = 0x1FF0F420UL). And as you know, it is not configured by MPU.

So as we just have only 8 regions for MPU in STM32F756, what can I do for this small region? Any idea?

Jocelyn RICARD
ST Employee
November 14, 2022

Hello @ali rostami​ 

Ok good catch !

One solution is to change:

/**
 * @brief Region 2 - Enable the read/write operations for full flash area in unprivileged mode.
 * Execution capability disabled
 */
#define SFU_PROTECT_MPU_FLASHACC_RGNV MPU_REGION_NUMBER2
#define SFU_PROTECT_MPU_FLASHACC_START FLASH_BASE /*!< Flash memory area */
#define SFU_PROTECT_MPU_FLASHACC_SIZE MPU_REGION_SIZE_1MB
#define SFU_PROTECT_MPU_FLASHACC_SREG 0x00U /*!< All subregions activated */
#define SFU_PROTECT_MPU_FLASHACC_PERM MPU_REGION_FULL_ACCESS
#define SFU_PROTECT_MPU_FLASHACC_EXECV MPU_INSTRUCTION_ACCESS_DISABLE
#define SFU_PROTECT_MPU_FLASHACC_TEXV MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_FLASHACC_B MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_FLASHACC_C MPU_ACCESS_CACHEABLE

Goal would be to enable region from 0x08000000 to 0x20000000 instead of 0x08000000 + 1MB

You can do this by setting:

...FLASHACC_START to 0

..FLASHACC_SIZE to 512 MB (512MB is exactly 0x20000000)

Then exclude the first 128 MB using:

...FLASHACC_SREG to 0x03

Best regards

Jocelyn

ali rostami
Associate III
November 15, 2022

Thanks @Jocelyn RICARD​  yeah, but it's a trade-off of using USB or more security, right?

The option bytes are now exposed, doesn't it make any problem? What if I config region 1 for the 3 UID bytes instead of RCC?

Jocelyn RICARD
ST Employee
November 15, 2022

Hello @ali rostami​ ,

This will give you visibility on option bytes in flash mapping, right.

Now, option bytes can be seen and changed in flash registers.

As you will activate RDP2 in production, option bytes cannot be changed any more.

RCC privileged access is a protection against DMA access inside SBSFU. This is a protection against attack when, for instance you use loader to download new image.

Best regards

Jocelyn