Issue with AES and CKS
In my application, I have a sequence which looks something like this:
- Load an AES key from CKS using SHCI_C2_FUS_LoadUsrKey
- Call HAL_Cryp_Init, HAL_Cryp_Decrypt, and HAL_Cryp_DeInit to decrypt a block of data
- Unload the key from CKS using SHCI_C2_FUS_UnloadUsrKey
- Load an AES key from software (not CKS)
- 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
