cancel
Showing results for 
Search instead for 
Did you mean: 

OBK unusable in non TZ STM32H5

_EFrie
Senior

At present, as of the last Hal version as far as I know, obk cannot be used in a non trust zone project.

FLASH_TYPEPROGRAM_QUADWORD_OBK fails because the NS bits aren't set, among other issues.

Is this by design, IE obk can't be used by non TZ, or is this just simply not a completed or fully fixed feature?

 

Here is what I'm doing

I've edited HAL_FLASHEx_Erase like

#if defined (FLASH_SR_OBKERR)
    else if ((pEraseInit->TypeErase&~(FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_OBK_ALT)
    {
      /* OBK erase to be done */
      FLASH_OBKErase();

      /* Wait for last operation to be completed */
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    }
#endif /* FLASH_SR_OBKERR */

And my code is:

int keyStorageSavePrivate(char* key) {
  uint32_t status;
  uint32_t len = strnlen(key, KEY_STORAGE_SIZE - 16);
  int ret = 0;
  static uint32_t FlashWord[4];
  if (len >= KEY_STORAGE_SIZE - 16) {
    return 1;
  }
  len += 1;  // Add string 0
  HAL_FLASH_Unlock();
  HAL_FLASHEx_OBK_Unlock();
  if (len & 0b1111) {
    len &= ~(0b1111);
    len += 16;
  }
  uint32_t Address = (uint32_t)private_key;
  uint32_t EndAddress = Address + len;
  const char* next = key;


  static uint32_t SectorError;
  static FLASH_EraseInitTypeDef EraseInitStruct;
  pFlash.ProcedureOnGoing = FLASH_NON_SECURE_MASK;
  FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);//Clear
  EraseInitStruct.TypeErase = FLASH_TYPEERASE_OBK_ALT | FLASH_NON_SECURE_MASK;
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
    ret = 6;
    goto lock;
  }

  while (Address < EndAddress) {
    memcpy(FlashWord, next, 16);
    status = HAL_FLASH_Program(
        FLASH_TYPEPROGRAM_QUADWORD_OBK | FLASH_NON_SECURE_MASK, Address,
        (uint32_t)FlashWord);
    if (status == HAL_OK) {
      Address = Address + 16; /* increment for the next Flash word*/
      next += 16;
    } else {
      /* Error occurred while programming */
      ret = 2;
      break;
    }
  }
  if (ret == 0) {
    if (HAL_FLASHEx_OBK_Swap(FLASH_OBK_SWAP_OFFSET_ALL) != HAL_OK) {
      ret = 3;
    }
  }
  HAL_ICACHE_Invalidate();
  lock:
  HAL_FLASH_Lock();
  HAL_FLASHEx_OBK_Lock();
  if (memcmp(private_key, key, len)) {
    ret = 3;
  }
  return ret;
}
1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello @_EFrie ,

If you point on secure peripheral alias (0x5...) this means you have -mcmse compilation flag enabled.

You can see how it works in CMSIS : stm32h573xx.h. This is not related to HAL.

Regarding the OBK address (FLASH_OBK_BASE), I could see in some code that a non trustzone code what forcing usage of FLASH_OBK_BASE_S. I need to double check if both FLASH_OBK_BASE_S and FLASH_OBK_BASE_NS are accessible with TrustZone disabled.

Best regards

Jocelyn

View solution in original post

10 REPLIES 10
Andrew Neil
Super User

https://community.st.com/t5/stm32-mcus-security/stm32h562-reading-obk-in-nonsecure-application-with-trustzone/m-p/746935/highlight/true#M7819 ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

I've looked at that link quite a few times, but the OP ended up using a secure zone to do this.

Jocelyn RICARD
ST Employee

Hello @_EFrie ,

Please remove FLASH_NON_SECURE_MASK from your code, it should work.

This non secure mask is used only when TZ is enabled, and when executing in secure, to be able to write in non secure flash.

Best regards

Jocelyn

 

I couldn’t get it to work at all, are you sure? I just went through this with Hal. The problem is that without tweaking it tries to use the 0x5000 secure flash registers which just doesn’t write any flash.

Just to recap, I just went through this on regular flash, nothing would erase or write until I made sure flash_ns with 4000 base was being used. The way the obk library is presently written only uses the secure 5000 flash base.

Jocelyn RICARD
ST Employee

Hello @_EFrie ,

If you point on secure peripheral alias (0x5...) this means you have -mcmse compilation flag enabled.

You can see how it works in CMSIS : stm32h573xx.h. This is not related to HAL.

Regarding the OBK address (FLASH_OBK_BASE), I could see in some code that a non trustzone code what forcing usage of FLASH_OBK_BASE_S. I need to double check if both FLASH_OBK_BASE_S and FLASH_OBK_BASE_NS are accessible with TrustZone disabled.

Best regards

Jocelyn




If you point on secure peripheral alias (0x5...) this means you have -mcmse compilation flag enabled.

You can see how it works in CMSIS : stm32h573xx.h. This is not related to HAL.


 I'm unclear on your meaning.  If I follow hal to FLASH_Program_QuadWord_OBK it directly chooses depending on IS_FLASH_SECURE_OPERATION() which depends on pFlash.ProcedureOnGoing which can only be set by somewhere setting a non secure flag in hal code.

See stm32h5xx_hal_flash.c around line 876

  reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
  reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);

The manual 7.11.16 FLASH non-secure OBK configuration register
(FLASH_NSOBKCFGR) says 

Register is only available when TZ_STATE = 0xC3. This register is non-secure. It can be
read and written by both secure and non-secure accesses. This register can only be
accessed by privilege code.

Whatever that is supposed to mean, it seems contradictory. 

I'm using Crossworks for Arm, I do see that the -mcmse flag is enabled.  Is this wrong?  If so, then this hides these definitions.

 

#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define FLASH_OBK_HDPL3S_BASE_NS (FLASH_OBK_HDPL3_BASE_NS)                          /*!< FLASH OBK HDPL3 non-secure base address         */
#define FLASH_OBK_HDPL3S_BASE_S  (FLASH_OBK_HDPL3_BASE_S)                           /*!< FLASH OBK HDPL3 secure base address             */
#define FLASH_OBK_HDPL3S_SIZE    (0x0C00U)                                          /*!< 3072 Bytes of secure HDPL3 option byte keys     */

#define FLASH_OBK_HDPL3NS_BASE_NS (FLASH_OBK_HDPL3_BASE_NS + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 non-secure base address         */
#define FLASH_OBK_HDPL3NS_BASE_S  (FLASH_OBK_HDPL3_BASE_S + FLASH_OBK_HDPL3S_SIZE)  /*!< FLASH OBK HDPL3 secure base address             */
#define FLASH_OBK_HDPL3NS_SIZE    (FLASH_OBK_HDPL3_SIZE - FLASH_OBK_HDPL3S_SIZE)    /*!< 2032 Bytes of non-secure HDPL3 option byte keys */
#endif /* CMSE */