Skip to main content
Visitor
August 7, 2026
Solved

PKA never sets SR.INITOK when booting via STiRoT in iRoT-Provisioned state (works in OPEN)

  • August 7, 2026
  • 1 reply
  • 11 views

Hi,

We’ve been trying to implement secure-boot on our STM32H573-based device and the new code boots fine when the product state is OPEN. From what I understood, the PROVISIONING state does not boot the user code, and we thus need to put the device in iRoT-Provisioned to see if our boot chain works as expected.

More info about our setup: 

  • Part: STM32H573AIIxQ
  • DBGMCU_IDCODE (0x44024000): 0x10076484
  • Boot: STiRoT (BOOT_UBE=0xC3), TZEN=0xB4
  • Layout: secure app at 0x0C000400 (24 KB), non-secure app at 0x08006400
  • Software: STM32CubeMX-generated project, STM32Cube H5 HAL
  • Debug: ST-LINK + OpenOCD, debug authentication (certificate chain), session reports Secure state

Back to the topic, I can see that te PKA register interface is fully alive, but the PKA compute engine never starts once the
device is in iRoT-Provisioned product state. HAL_PKA_Init() spins in PKA_WaitOnFlagUntilTimeout() waiting for PKA_SR.INITOK, times out after 5 s, and the application lands in Error_Handler().

The exact same binary and the exact same register sequence work in OPEN product state.

I have reduced this to four register accesses that need no application code at all. The behaviour differs purely by product state:

mww 0x44020C64 0x00080000 # RCC_AHB2RSTR: assert PKARST
mww 0x44020C64 0x00000000 # RCC_AHB2RSTR: release PKARST
mdw 0x420C2000 # PKA_CR  -> 0x00000000  (reset took effect, both states)
mww 0x420C2000 0x00000001 # PKA_CR.EN = 1
mdw 0x420C2004 # PKA_SR

which yield:

OPEN product state (0xED): PKA_SR = 0x00000001 -> INITOK set
- iRoT-Provisioned product state (0x2E):  PKA_SR = 0x00000000 -> never sets, indefinitely

In the failing state PKA_SR reads 0x00000000: INITOK clear, BUSY clear, and no error flags (RAMERRF / ADDRERRF / OPERRF all clear). The engine does not appear to start at all, rather than starting and failing.

SAES, PKA and RNG are all three in the NonSecure world. I can confirm that GTZC_S is correctly setup:

  • TrustZone security attribute:   TZSC_SECCFGR3 bit 20 (PKA) is clear in both states. I also drove PKA through the secure  alias at 0x520C2000 in the failing state: byte-identical dead behaviour.
  • TrustZone privilege attribute: TZSC_PRIVCFGR3 = 0x00000000 in both states.

So, my questions are:

  1. Is the PKA expected to be usable by the application after STiRoT hands over in iRoT-Provisioned state (SBS_HDPLSR = 0x8A)?
  2. If yes, what step is missing to get PKA_SR.INITOK to set? I cannot find anything in RM0481 suggesting a requirement beyond enabling the clock and setting PKA_CR.EN.
  3. Any other idea? I have exhausted all my options to be honest.


I cannot give the entirety of the code, but I should be able to provide the generic parts (namely, the Secure/NonSecure main.c) if need be.

Best answer by Alex C

Finally got it working…

STiRoT leaves SAES in a state that retains the shared RNG path, causing PKA_SR.INITOK to remain 0 because, as described in RM0481, INITOK stays low while SAES is using the RNG bus.

Resetting SAES in the secure application before the non-secure handoff fixed it:

__HAL_RCC_SAES_CLK_ENABLE();
__HAL_RCC_SAES_FORCE_RESET();
__DSB();
__HAL_RCC_SAES_RELEASE_RESET();
__DSB();

PKA now initializes normally in IROT_PROVISIONED.

1 reply

Alex CAuthorBest answer
Visitor
August 7, 2026

Finally got it working…

STiRoT leaves SAES in a state that retains the shared RNG path, causing PKA_SR.INITOK to remain 0 because, as described in RM0481, INITOK stays low while SAES is using the RNG bus.

Resetting SAES in the secure application before the non-secure handoff fixed it:

__HAL_RCC_SAES_CLK_ENABLE();
__HAL_RCC_SAES_FORCE_RESET();
__DSB();
__HAL_RCC_SAES_RELEASE_RESET();
__DSB();

PKA now initializes normally in IROT_PROVISIONED.