cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5 SAES/AES shared key in Trustzone with HAL

ptrchv
Associate II

Hello,

I'm trying to use the SAES/AES shared key functionality in a Trustzone (TZEN=1, RDP = 0), using the functions provided by the HAL library. The board I use is the B-U585I-IOT02A.

The only project example I found is with Trustzone disabled, but it runs correctly with my configuration (TZEN=1, RDP = 0) without any changes. Just one executable image loaded running in non-secure (without the secure - non secure switch).

The code is roughly the following (I removed checks and key/IV definition):

HAL_Init();
SystemClock_Config();
SystemPower_Config();

MX_ICACHE_Init();
MX_RNG_Init();

hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_NO_SWAP;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.pInitVect = (uint32_t *)pInitVectSAES;
hcryp.Init.Algorithm = CRYP_AES_CBC;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
hcryp.Init.KeyMode = CRYP_KEYMODE_SHARED;
hcryp.Init.KeySelect = CRYP_KEYSEL_HW;
hcryp.Init.KeyProtection = CRYP_KEYPROT_DISABLE;

HAL_CRYP_Init(&hcryp)
HAL_CRYPEx_EncryptSharedKey(&hcryp, AESKey256, Encryptedkey, 0, TIMEOUT_VALUE);
HAL_CRYPEx_DecryptSharedKey(&hcryp, Encryptedkey,0, TIMEOUT_VALUE);

hcryp.Instance = AES;
hcryp.Init.DataType = CRYP_NO_SWAP;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.KeyMode = CRYP_KEYMODE_SHARED;
hcryp.Init.Algorithm = CRYP_AES_ECB;

HAL_CRYP_Init(&hcryp);
HAL_CRYP_Encrypt(&hcryp, Plaintext, 16, EncryptedText, TIMEOUT_VALUE);
HAL_CRYP_Decrypt(&hcryp, EncryptedText, 16, DecryptedText, TIMEOUT_VALUE);


The problem is when I try to run it in a Trustzone Project starting in secure and switching to non-secure. I tested this code both from secure (before the switch) and non-secure, attributing all the peripherals (AES, SAES, RNG and ICACHE) to the correct security domain (secure or non-secure). When the peripherals were attributed to secure the following lines were added in the GTZC configuration function in the secure main:

HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_AES, GTZC_TZSC_PERIPH_SEC|GTZC_TZSC_PERIPH_NPRIV)
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_RNG, GTZC_TZSC_PERIPH_SEC|GTZC_TZSC_PERIPH_NPRIV)
HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_SAES, GTZC_TZSC_PERIPH_SEC|GTZC_TZSC_PERIPH_NPRIV)


When I try to use the AES module to perform encryption with the shared key:

HAL_CRYP_Encrypt(&hcryp, Plaintext, 16, EncryptedText, TIMEOUT_VALUE);

the operation times out (I checked with the debugger), even if the function returns HAL_OK. The EncryptedText is therefore all zeros.


This is the call order of HAL functions, with WaitOnCCFlag which times out:

HAL_CRYP_Encrypt(&hcryp, Plaintext, 16, EncryptedText, TIMEOUT_VALUE);
static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)


I checked that both AES (gcm), SAES (in both Normal and Wrapped key modes, using DHUK) were working, with the same project configuration.

I don't understand why this happens, since the key sharing works for the same board configuration (Opition Bytes) if I just load the non-secure image. Is there some configuration step that I am missing?

 

1 ACCEPTED SOLUTION

Accepted Solutions
ptrchv
Associate II

I found the solution to the problem. When you enable the AES and SAES modules via the STMCubeIDE code generator, there are some things that are not setup correctly.

According to the code posted before the first call to HAL_CRYP_Init(&hcryp) configures the SAES by calling HAL_CRYP_MspInit(hcryp).

 

 

if (hcryp->State == HAL_CRYP_STATE_RESET)
{
  hcryp->Lock = HAL_UNLOCKED;
  HAL_CRYP_MspInit(hcryp);
}
void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hcryp->Instance==AES)
  {
    __HAL_RCC_AES_CLK_ENABLE();
  }
  else if(hcryp->Instance==SAES)
  {
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAES;
    PeriphClkInit.SaesClockSelection = RCC_SAESCLKSOURCE_SHSI;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }  
    __HAL_RCC_SAES_CLK_ENABLE();
  }
}

 

 

 When you call HAL_CRYP_Init(&hcryp) the second time to configure AES the check (below) fails and HAL_CRYP_MspInit(hcryp) is not called, not enabling the AES clock.

 

 

if (hcryp->State == HAL_CRYP_STATE_RESET)

 

 

In the example project the HAL_CRYP_MspInit(hcryp) function was modified, so that the clock of both SAES and AES are activated at the first HAL_CRYP_Init(&hcryp) call.

 

 

void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hcryp->Instance==SAES)
  {
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAES;
    PeriphClkInit.SaesClockSelection = RCC_SAESCLKSOURCE_SHSI;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    __HAL_RCC_SAES_CLK_ENABLE();
  /* USER CODE BEGIN SAES_MspInit 1 */
  __HAL_RCC_AES_CLK_ENABLE();
  HAL_Delay(10);
  /* USER CODE END SAES_MspInit 1 */
  }
}

 

 

 

View solution in original post

2 REPLIES 2
ptrchv
Associate II

I saw that the problem is in HAL_CRYP_Init(&hcryp), when configuring the AES modue. The following line:

 

 

MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, cr_value);

 

 

Does not change the value of the CR register which remains fixed to zero. It could be related to this question: https://community.st.com/t5/stm32-mcus-security/aes-ecb-initialization-fails/td-p/614297


ptrchv
Associate II

I found the solution to the problem. When you enable the AES and SAES modules via the STMCubeIDE code generator, there are some things that are not setup correctly.

According to the code posted before the first call to HAL_CRYP_Init(&hcryp) configures the SAES by calling HAL_CRYP_MspInit(hcryp).

 

 

if (hcryp->State == HAL_CRYP_STATE_RESET)
{
  hcryp->Lock = HAL_UNLOCKED;
  HAL_CRYP_MspInit(hcryp);
}
void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hcryp->Instance==AES)
  {
    __HAL_RCC_AES_CLK_ENABLE();
  }
  else if(hcryp->Instance==SAES)
  {
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAES;
    PeriphClkInit.SaesClockSelection = RCC_SAESCLKSOURCE_SHSI;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }  
    __HAL_RCC_SAES_CLK_ENABLE();
  }
}

 

 

 When you call HAL_CRYP_Init(&hcryp) the second time to configure AES the check (below) fails and HAL_CRYP_MspInit(hcryp) is not called, not enabling the AES clock.

 

 

if (hcryp->State == HAL_CRYP_STATE_RESET)

 

 

In the example project the HAL_CRYP_MspInit(hcryp) function was modified, so that the clock of both SAES and AES are activated at the first HAL_CRYP_Init(&hcryp) call.

 

 

void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hcryp->Instance==SAES)
  {
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAES;
    PeriphClkInit.SaesClockSelection = RCC_SAESCLKSOURCE_SHSI;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
    __HAL_RCC_SAES_CLK_ENABLE();
  /* USER CODE BEGIN SAES_MspInit 1 */
  __HAL_RCC_AES_CLK_ENABLE();
  HAL_Delay(10);
  /* USER CODE END SAES_MspInit 1 */
  }
}