cancel
Showing results for 
Search instead for 
Did you mean: 

Write protection error when erasing sector with secure boot

giubacchio
Associate III

Hello,

I'm developing an application with OEMiRoT and trustzone for STM32H563.

I'm getting a write protection error (WRPERR) when I try to erase a secure flash sector from secure code that is not protected neither by write protection or HDP. I'm using the method HAL_FLASHEx_Erase() and I mapped the region as readable and writable with the memory management tool of CubeMX.


If I try to do the same process without the secure boot provisioning, everything works as expected. I would like to know if there are any additional operation in order to write/erase flash at runtime when secure boot is used.

Any help is really appreciated!
Thank you,
Giulio

7 REPLIES 7
Bubbles
ST Employee

Hi @giubacchio,

as it works without the secure boot, you surely have the basics done correctly. Which means the option byte configuration.

The OEMiRoT may still use additional layer of protection, for example MPU or HDP extension (though MPU would not result in WRPERR).

The most likely cause of this problem is that the application is not running as privileged. It needs to relay the task of erasing or programming the flash to privileged code.

BR,

J

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

giubacchio
Associate III

Hi @Bubbles,

thank you for your answer. I already tried to set my application as privileged by means of the SVC_Handler, but it didn't help. Indeed, the arm CONTROL register is set to 1100, meaning that I should have privileged rights. I also verified that MPU and HDP are not protecting that sector. Have you any other suggestion?

Thank you,
Giulio

Jocelyn RICARD
ST Employee

Hello @giubacchio ,

You should check the actual configuration of the flash sector address you want to erase using the debugger.

1) Check optionbyte configuration: Is sector in the secure area ?

2) Check SAU : is sector not defined as non secure ?

3) Double check MPU

4) Check that your code is requesting a secure erase: usage of secure register

Best regards

Jocelyn

 

giubacchio
Associate III

Hello @Jocelyn RICARD ,

I checked all the points you mentioned and I don't see anything that could cause the problem. I tried different MPU settings as well as its disabling. I also tried disabling ICACHE (HAL_ICACHE_Disable()) before trying to erase the flash sector, without success. 

Option bytes related to Write Sector Protection and HDP are not protecting the sector I'm trying to erase.

Regarding point 1: if I am not wrong, from the secure zone I should be able to erase both secure and non secure sectors. However, I get the same error if I try to erase secure or non-secure sectors, as well as sectors in bank 1 or bank 2. In a few words, I tried many permutations (if not all) gaining always the same result..

I haven't any other ideas about what to try. I have attached to this message the memory viewed from the Memory Management Tool of STM32CubeMX: I don't know if it is normal that it is not present the region DOWNLOAD_NONSECURE_CODE_REGION. Do you know if it possible to remove also the region related to the donwnload area of the secure zone? I tried to modify the flash_layout file in this sense without success. 

Thank you,
Giulio

 

Jocelyn RICARD
ST Employee

Hello @giubacchio ,

I'm sorry it is a bit difficult to know what you have exactly done, and what is your actual setup.

 

By default OEMiROT defines secure sectors only at beginning of the flash containing the OEMiROT_Boot and the secure application. So, if you need some spare secure sectors to be use by the secure application you need to adapt the mapping so that non secure application is shifted, and include these few sectors in the secure watermarks.

Other solution is to use the second bank, at the end of instance to avoid dealing with OEMiROT default mapping.

In this case you will also need to setup the secure watermasks for bank2.

I don't use the Memory Management Tool of CubeMX as it often doesn't do what I want.

Best regards

Jocelyn

giubacchio
Associate III

Hello @Jocelyn RICARD,

my setup is reduced as much as possible: I have just added the erase operation in the secure part of the ROT example for NUCLEO-H563ZI of the firmware STM32Cube_FW_H5_V1.5.1, and it is enough to reproduce the problem.

Since I am not able to modify the secure watermarks of bank 2 my goal is now to erase a non-secure sector from the secure app; indeed, setting any different limit than the one provided in the script ob_flash_programming.sh which set the bank 2 as completely non-secure seems to invalid the booting phase and the debug opening (do you have any ideas on why this happens?)

After several trials, and thanks to this intuition, I discovered that by marking the type erase as FLASH_TYPEERASE_SECTORS_NS instead of FLASH_TYPEERASE_SECTORS permits me to successfully erase the non-secure sector. For some reason this was not necessary when I flashed the firmware without bootloader: this has made the debugging of this problem really painful.

It remains now to discover if it is possible to activate somehow the secure zone in the second bank or if this is hindered somehow from the secure bootloader. 

Thank you,
Giulio

Jocelyn RICARD
ST Employee

Hello @giubacchio ,

I'm sorry for late answer, I missed your reply.

Yes, writing to non secure from secure requires using this specific flag. Sorry I didn't understood enough your point.

I should be possible to setup some sectors secure in second bank, but this requires changing a bit the code in low_level_security.c here:

 /* the bank 2 must be fully unsecure */
  else if (flash_option_bytes_bank2.WMSecEndSector >= flash_option_bytes_bank2.WMSecStartSector)
  {
    BOOT_LOG_INF("BANK 2 secure flash [%d, %d] : OB [%d, %d]", PAGE_MAX_NUMBER_IN_BANK, 0, (int)flash_option_bytes_bank2.WMSecStartSector,
                 (int)flash_option_bytes_bank2.WMSecEndSector);
    BOOT_LOG_ERR("Unexpected value for secure flash protection");
    Error_Handler();
  }

 

Also, you will need to patch the postbuild.bat (if you are on a PC) to remove the lines

 

set "command=%python%%applicfg% flash --layout %preprocess_bl2_file% -b sec2_start -m RE_BL2_SEC2_START -d 0x2000 %update% --vb >> %current_log_file% 2>&1"
%command%
IF !errorlevel! NEQ 0 goto :error

set "command=%python%%applicfg% flash --layout %preprocess_bl2_file% -b sec2_end -m RE_BL2_SEC2_END -d 0x2000 %update% --vb >> %current_log_file% 2>&1"
%command%
IF !errorlevel! NEQ 0 goto :error

 or change them with some hard coded value reflecting the configuration you want.

Best regards

Jocelyn