2024-04-27 11:42 AM
Good afternoon,
I am trying to encrypt some data using the AES peripheral and compare the results to the same operation in python and .NET.
The cipher text output from the operation on the STM32 is different than that of the other two languages.
The code I am testing is
/**
* @brief AES1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_AES1_Init(void)
{
/* USER CODE BEGIN AES1_Init 0 */
uint8_t key[32] = {0};
uint8_t iv[12] = {0};
/* USER CODE END AES1_Init 0 */
/* USER CODE BEGIN AES1_Init 1 */
/* USER CODE END AES1_Init 1 */
hcryp1.Instance = AES1;
hcryp1.Init.DataType = CRYP_DATATYPE_8B;
hcryp1.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp1.Init.pKey = (uint32_t *)key;
hcryp1.Init.pInitVect = (uint32_t *)iv;
hcryp1.Init.Algorithm = CRYP_AES_GCM_GMAC;
hcryp1.Init.Header = (uint32_t *)HeaderAES1;
hcryp1.Init.HeaderSize = 1;
hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
if (HAL_CRYP_Init(&hcryp1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN AES1_Init 2 */
uint8_t plainText[12] = {72,101,108,108,111,32,87,111,114,108,100,49};
uint8_t cipherText[50] = {0};
HAL_StatusTypeDef status = HAL_CRYP_Encrypt(&hcryp1, (uint32_t*)plainText, 12, (uint32_t*)cipherText, HAL_MAX_DELAY);
if (status != HAL_OK){
}
/* USER CODE END AES1_Init 2 */
}
The output cipher text is
In comparison, the output from the .NET operation is
and python is
What have I missed in using the AES peripheral on the device?
Thank you in advance
Solved! Go to Solution.
2024-04-28 07:35 AM
After reading many other reported issues and various amounts of documentation, I have found the solutions, but also the problems with the implementation of AESGCM within the peripheral (thanks STM).
After all the above is corrected, the encryption and decryption works fine for variable length data, i.e. blocks not equal to 4 bytes.
But, then we come to TAG generation.
If you encrypt 11 bytes of data and generate a TAG using HAL_CRYPEX_AESGCM_GenerateAuthTAG it works fine, however, decryption works but when you generate the TAG for it it is incorrect so the data can not be verified.
It looks like for TAG generation on decryption, the input must be uint32_t therefore, you are unable to generate a TAG for an 11byte input as it is incorrect.
It all works fine if you perform the process on 12 bytes. @Tesla DeLorean your comment about padding makes sense now.
All in all a very frustrating experience, if it was not for the performance I would have given up and reverted to a software implementation.
STM, implementations should at least be able to be verified against known test vectors!
2024-04-27 12:17 PM
Isn't it going to expect data in multiples of 16-bytes? And careful/consistent management of the pad bytes.
AES-CTR less so because you're basically generating an XOR pattern
2024-04-27 12:24 PM - edited 2024-04-28 07:20 AM
AES-GCM doesnt require padding as it is a streaming mode cipher. Therefore it is possible to encrypt 12 bytes of data. Or have I misunderstood your comment?
2024-04-28 07:35 AM
After reading many other reported issues and various amounts of documentation, I have found the solutions, but also the problems with the implementation of AESGCM within the peripheral (thanks STM).
After all the above is corrected, the encryption and decryption works fine for variable length data, i.e. blocks not equal to 4 bytes.
But, then we come to TAG generation.
If you encrypt 11 bytes of data and generate a TAG using HAL_CRYPEX_AESGCM_GenerateAuthTAG it works fine, however, decryption works but when you generate the TAG for it it is incorrect so the data can not be verified.
It looks like for TAG generation on decryption, the input must be uint32_t therefore, you are unable to generate a TAG for an 11byte input as it is incorrect.
It all works fine if you perform the process on 12 bytes. @Tesla DeLorean your comment about padding makes sense now.
All in all a very frustrating experience, if it was not for the performance I would have given up and reverted to a software implementation.
STM, implementations should at least be able to be verified against known test vectors!