Showing results for 
Search instead for 
Did you mean: 

CRYPT HAL driver of STM32WB not compatible with openssl and STM32 crypto library (bug?)

Associate III


The crypto HAL driver ( function CRYP_SetKey in file stm32wbxx_hal_cryp.c ) of the STM32WB accesses the key as "array of uint32_t" (lines 2919 etc):

       hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey);

       hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U);

       hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U);

       hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U);

thus the key and nonce must be swapped by customer software. This is not compatible with openssl generated key nor STM32 crypto library usage on other STM32 mcus (could be declared as bug). The "CRYP_DATATYPE_8B" byte swapping only applies to cipher and plain buffer.

Better would be:

       hcryp->Instance->KEYR3 = __REV( *(uint32_t *)(hcryp->Init.pKey) );

       hcryp->Instance->KEYR2 = __REV( *(uint32_t *)(hcryp->Init.pKey + 1U) );

       hcryp->Instance->KEYR1 = __REV( *(uint32_t *)(hcryp->Init.pKey + 2U) );

       hcryp->Instance->KEYR0 = __REV( *(uint32_t *)(hcryp->Init.pKey + 3U) );

Same for nonce (lines 1685 etc):

           hcryp->Instance->IVR3 = __REV( *(uint32_t *)(hcryp->Init.pInitVect) );

           hcryp->Instance->IVR2 = __REV( *(uint32_t *)(hcryp->Init.pInitVect + 1U) );

           hcryp->Instance->IVR1 = __REV( *(uint32_t *)(hcryp->Init.pInitVect + 2U) );

           hcryp->Instance->IVR0 = __REV( *(uint32_t *)(hcryp->Init.pInitVect + 3U) );

Best regards


Jocelyn RICARD
ST Employee

Hello Paul,

thank you for raising this point.

I will ask internally and come back to you

Best regards


Jocelyn RICARD
ST Employee

Hello Paul,

I had discussion with our development team.

We agree this key and IV ordering in memory is not directly compatible with the byte stream usually in use.

Now, you have 2 ways to manage this:

1- Either you store keys in memory in the way it is expected by the HAL. The examples use arrays of uint32_t, so key content looks the same as openssl.

2- Either you store keys in memory in stream order (use an array of bytes). In that case, you need to use the _REV() macro before providing the key to HAL

So, this is not considered as a bug. Just a different approach.

I hope this answers your question

Best regards