2022-01-04 02:05 AM
Hi,
I am currently trying out the AES Accelerator of the STM32WB55, using the HAL. It is working fine on its own, but I am unable to get matching results to MbedTLS. So Ciphertexts and Tags generated by the Accelerator are not matching those generated by MbedTLS, and decryption of Accelerator Ciphertexts using MbedTLS fails (tags and cleartext do not match).
In the process of checking different configuration options, i stumbled upon the header size. STM32CubeMX forces the header size to be 1 with no apparent reason. I tried the Accelerator and MbedTLS both with header sizes of 0 and 1 (by manually changing the CubeMX-generated code, termed additional data with MbedTLS), both do not match.
Is there a reason why CubeMX forces the header size to be 1?
I am appending the relevant code, in this case with header size 0. Did I make some mistake somewhere? Or is there some other hidden reason to this?
CRYP_HandleTypeDef hcryp1;
__ALIGN_BEGIN uint32_t pKeyAES1[8] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};
__ALIGN_BEGIN uint32_t pInitVectAES1[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000};
__ALIGN_BEGIN uint32_t HeaderAES1[1] __ALIGN_END = {
0x00000000};
void MX_AES1_Init(void)
{
hcryp1.Instance = AES1;
hcryp1.Init.DataType = CRYP_DATATYPE_8B;
hcryp1.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp1.Init.pKey = (uint32_t *)pKeyAES1;
hcryp1.Init.pInitVect = (uint32_t *)pInitVectAES1;
hcryp1.Init.Algorithm = CRYP_AES_GCM_GMAC;
hcryp1.Init.Header = NULL;
hcryp1.Init.HeaderSize = 0;
hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
if (HAL_CRYP_Init(&hcryp1) != HAL_OK)
{
Error_Handler();
}
}
int main(void)
{
// HAL Initialization...
MX_AES1_Init();
#define GCM_TAG_LEN 16
#define IV_LEN 16
#define KEYSIZE 32
#define DATA_SIZE 256
printf("Debugging AES accelerator...\n");
// Initialize data
uint8_t dummyData[DATA_SIZE];
memset(dummyData, 5, DATA_SIZE);
uint8_t dummyKey[KEYSIZE];
memset(dummyKey, 9, KEYSIZE);
uint8_t dummyIV[IV_LEN];
memset(dummyIV, 1, IV_LEN);
uint8_t dummyHeader[4] = {0};
//Encrypt and decrypt dummy data using the AES-Accelerator & AES-GCM
uint8_t accCipher[DATA_SIZE];
uint8_t accTag[GCM_TAG_LEN];
memcpy(pKeyAES1, dummyKey, KEYSIZE);
memcpy(pInitVectAES1, dummyIV, IV_LEN);
HAL_StatusTypeDef halstatus = HAL_CRYP_Encrypt(&hcryp1, (uint32_t *) dummyData, DATA_SIZE, (uint32_t *) accCipher, 1000);
if (halstatus != HAL_OK) {
printf("Debug: HAL failed during encryption of data!");
}
halstatus = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp1, (uint32_t *) accTag, 1000);
if (halstatus != HAL_OK) {
printf("Debug: HAL failed during encryption -> tagging of data!");
}
uint8_t accCleartext[DATA_SIZE];
uint8_t accTag2[GCM_TAG_LEN];
halstatus = HAL_CRYP_Decrypt(&hcryp1, (uint32_t *) accCipher, DATA_SIZE, (uint32_t *) accCleartext, 1000);
if (halstatus != HAL_OK) {
printf("Debug: HAL failed during decryption of data!");
}
HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp1, (uint32_t *) accTag2, 1000);
//check accelerator result for inconsistencies
if (halstatus != HAL_OK) {
printf("Debug: HAL failed during decryption -> tagging of data!");
}
if (memcmp(dummyData, accCleartext, DATA_SIZE) != 0) {
printf("Debug: AES encryption / decryption did not match!\n");
}
if (memcmp(accTag, accTag2, GCM_TAG_LEN) != 0) {
printf("Debug: AES Tags did not match.\n");
}
// Encrypt and decrypt dummy data using MbedTLS & AES-GCM
uint8_t mbedCipher[DATA_SIZE];
uint8_t mbedTag[GCM_TAG_LEN];
mbedtls_gcm_context c;
mbedtls_gcm_init(&c);
mbedtls_gcm_setkey(&c, MBEDTLS_CIPHER_ID_AES, dummyKey, KEYSIZE*8);
int ret2 = mbedtls_gcm_crypt_and_tag(&c, MBEDTLS_GCM_ENCRYPT, DATA_SIZE, dummyIV, IV_LEN, NULL, 0, dummyData, mbedCipher, GCM_TAG_LEN, mbedTag);
uint8_t mbedCleartext[DATA_SIZE];
uint8_t mbedTag2[GCM_TAG_LEN];
int ret3 = mbedtls_gcm_crypt_and_tag(&c, MBEDTLS_GCM_DECRYPT, DATA_SIZE, dummyIV, IV_LEN, NULL, 0, mbedCipher, mbedCleartext, GCM_TAG_LEN, mbedTag2);
if (ret2 != 0 || ret3 != 0) {
printf("Debug: MbedTLS failed.\n");
}
// Check MbedTLS result against accelerator results & for internal MbedTLS inconsistencies
if (memcmp(mbedCipher, accCipher, DATA_SIZE) != 0) {
printf("Debug: Ciphers do not match between AES acc and Mbed!\n");
}
if (memcmp(mbedCleartext, accCleartext, DATA_SIZE) != 0) {
printf("Debug: Clear text does not match between AES acc and Mbed!\n");
}
if (memcmp(mbedTag, accTag, GCM_TAG_LEN) != 0) {
printf("Debug: Tags do not match between AES acc and Mbed!\n");
}
if (memcmp(dummyData, mbedCleartext, DATA_SIZE) != 0) {
printf("Debug: MbedTLS encrypted data does not match initial data!\n");
}
if (memcmp(mbedTag, mbedTag2, GCM_TAG_LEN) != 0) {
printf("Debug: MbedTLS tags do not match each other!\n");
}
// Try do decrypt accelerator Ciphertext using MbedTLS
uint8_t accToMbedCleartext[DATA_SIZE];
uint8_t accToMbedTag2[GCM_TAG_LEN];
int ret4 = mbedtls_gcm_crypt_and_tag(&c, MBEDTLS_GCM_DECRYPT, DATA_SIZE, dummyIV, IV_LEN, NULL, 0, accCipher, accToMbedCleartext, GCM_TAG_LEN, accToMbedTag2);
if(ret4 != 0) {
printf("MbedTLS failed.");
}
// Check resulting cleartext against initial data and MbedTLS tag against accelerator tag
if(memcmp(accToMbedCleartext, dummyData, DATA_SIZE) != 0) {
printf("Debug: MbedTLS decryption of accelerator ciphertext does not match initial data.\n");
}
if(memcmp(accToMbedTag2, accTag, GCM_TAG_LEN) != 0) {
printf("Debug: MbedTLS decryption tag does not match accelerator tag.\n");
}
}
This is the resulting output:
Debugging AES accelerator...
Debug: Ciphers do not match between AES acc and Mbed!
Debug: Tags do not match between AES acc and Mbed!
Debug: MbedTLS decryption of accelerator ciphertext does not match initial data.
Debug: MbedTLS decryption tag does not match accelerator tag.
Solved! Go to Solution.
2022-01-18 05:48 AM
For anyone stumbling over this, here is the solution:
2022-01-18 05:48 AM
For anyone stumbling over this, here is the solution: