cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with AES and CKS

crwper
Senior

In my application, I have a sequence which looks something like this:

  1. Load an AES key from CKS using SHCI_C2_FUS_LoadUsrKey
  2. Call HAL_Cryp_Init, HAL_Cryp_Decrypt, and HAL_Cryp_DeInit to decrypt a block of data
  3. Unload the key from CKS using SHCI_C2_FUS_UnloadUsrKey
  4. Load an AES key from software (not CKS)
  5. Call HAL_Cryp_Init, HAL_Cryp_Decrypt, and HAL_Cryp_DeInit to decrypt another block of data

This sequence can be repeated several times.

I ran into an issue which presented itself as follows:

  • On the first pass through that sequence, everything worked great
  • On subsequent passes, the decryption using CKS produced the wrong result

I think I've tracked this down to a problem with the AES_KEYR0..7 registers. On the first pass through, when I call the decrypt function after loading the key from CKS, the AES_KEYR0..7 registers are all zero. On subsequent passes, the AES_KEYR0..7 registers contain the value left over from step 5. This seems to interfere with the use of the CKS key.

If I add the following code just before calling SHCI_C2_FUS_LoadUsrKey, everything works great:

/* Clear key in AES1 peripheral */
AES1->KEYR7 = 0;
AES1->KEYR6 = 0;
AES1->KEYR5 = 0;
AES1->KEYR4 = 0;
AES1->KEYR3 = 0;
AES1->KEYR2 = 0;
AES1->KEYR1 = 0;
AES1->KEYR0 = 0;

I haven't been able to find anything in the documentation saying this is needed, so I wanted to ask if this is actually required, or if this should not be needed, and it's just a coincidence that this solved the problem.

If this is needed, it could perhaps be handled in CRYP_SetKey, e.g.:

static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
{
  if (hcryp->Init.pKey != NULL)
  {
    switch (KeySize)
    {
      case CRYP_KEYSIZE_256B:
        hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey);
        hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U);
        hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U);
        hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U);
        hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U);
        hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U);
        hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U);
        hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U);
        break;
      case CRYP_KEYSIZE_128B:
        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);
 
        break;
      default:
        break;
    }
  }
  else
  {
    hcryp->Instance->KEYR7 = 0;
    hcryp->Instance->KEYR6 = 0;
    hcryp->Instance->KEYR5 = 0;
    hcryp->Instance->KEYR4 = 0;
    hcryp->Instance->KEYR3 = 0;
    hcryp->Instance->KEYR2 = 0;
    hcryp->Instance->KEYR1 = 0;
    hcryp->Instance->KEYR0 = 0;
  }
}

I had one other related question. In the FUS documentation, Table 5, in the row for the AES1 resource, it says:

"AES1 is configured in secure mode (key register is accessible only by Cortex®-M0+)"

"AES1 key register is written by FUS with the key requested by user."

"Once AES1 is configured in secure mode, it remains in secure mode until next system reset. There is no way to deactivate the secure mode by software."

However, I have had no problem going back and forth between CKS and software keys as described above, which suggests that the AES key register is accessible from the Cortex-M4 processor once the CKS key has been unloaded. Could you please confirm that this is the case, and that I'm not taking advantage of a bug which could be fixed in the future?

Thank you!

Michael

6 REPLIES 6
Bubbles
ST Employee

Hi @crwper​,

thanks for your report. It indeed looks like the FUS is not handling the AES as expected. If you can access the AES1 KEY registers from CM4, the SYSCFG_SIPCR->AES1 bit is probably not set.

Can you please just specify what version of FUS are you using? I need that to forward the bug to the FUS developers.

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.

Hi J--

I am using FUS version 1.2.0.0.

Interestingly, if I look at AES->KEYR0..7 after calling SHCI_C2_FUS_LoadUsrKey, these registers are set to 0, which is consistent with SYSCFG_SIPCR->AES1 being set (and the key stored at that index is certainly not 0).

Michael

Hi J--

Doing a little more digging, I noticed that in my test application, if I step over the call to SHCI_C2_FUS_LoadUsrKey, I see that SAES1 is 0 before, but is 1 after the function call. However, when SHCI_C2_FUS_UnloadUsrKey is called, SAES1 is reset to 0.

Although the FUS documentation indicates that "Once AES1 is configured in secure mode, it remains in secure mode until next system reset", this does not seem to be the case, as SHCI_C2_FUS_UnloadUsrKey seems to take the processor out of secure mode as well.

Michael

Remy ISSALYS
ST Employee

Hello,

Internal ticket has been open to investigate this issue.

Internal ticket number: 139001 (This is an internal tracking number and is not accessible or usable by customers).

Best Regards

Remy ISSALYS
ST Employee

Hello,

FUS does not manage any initialization or configuration of AES IP in order to keep flexibility for user to manage different configurations. This includes the initialization of the AES. So when AES_KEYRx registers have already been used, they shall be cleared before calling CKS service, either by resetting the AES or by writing zeros to KYERx.

An other solution could also be to call SHCI_C2_FUS_UnloadUsrKey() between the two. This might spare some lines of code and get same result.

AN5185 is wrong on this point: when FUS_UNLOAD_USR_KEY (SHCI_C2_FUS_UnloadUsrKey()) is called, it disables the security of AES1 after clearing the key registers content. So AES1 is available for use without system reset. Documentation will be update in next revision.

Best Regards

Thanks, Remy! It's good to know this is not undocumented functionality.

Michael