Nucleo F439ZI AES in GCM Mode Accelerator Struggles
Hi Everyone!
I am trying to understand why I cannot get the result of the AES in GCM mode HAL_CRYP_Encrypt on the F439ZI board to match the AES in GCM result anywhere else. I am using Python's pycryptodome library for result comparison. I have previously seen this very informative post: https://community.st.com/t5/stm32-mcus-security/a-guide-to-the-hal-of-the-aes-accelerator-or-how-to-fix-it/m-p/134252
However, I am still stuck somewhat.
I am also using the default AES-256 key together with the default IV provided by the CubeMX:
CRYP_HandleTypeDef hcryp;
__ALIGN_BEGIN static const uint32_t pKeyCRYP[8] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};
__ALIGN_BEGIN static const uint32_t pInitVectCRYP[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000002};
__ALIGN_BEGIN static const uint32_t HeaderCRYP[1] __ALIGN_END = {
0x00000000};
/**
* @brief CRYP Initialization Function
* None
* @retval None
*/
static void MX_CRYP_Init(void)
{
/* USER CODE BEGIN CRYP_Init 0 */
/* USER CODE END CRYP_Init 0 */
/* USER CODE BEGIN CRYP_Init 1 */
/* USER CODE END CRYP_Init 1 */
hcryp.Instance = CRYP;
hcryp.Init.DataType = CRYP_DATATYPE_32B;
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
hcryp.Init.pKey = (uint32_t *)pKeyCRYP;
hcryp.Init.pInitVect = (uint32_t *)pInitVectCRYP;
hcryp.Init.Algorithm = CRYP_AES_GCM;
hcryp.Init.Header = (uint32_t *)HeaderCRYP;
hcryp.Init.HeaderSize = 1;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
if (HAL_CRYP_Init(&hcryp) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CRYP_Init 2 */
/* USER CODE END CRYP_Init 2 */
}
int main(void)
{
.
.
.
.
MX_CRYP_Init();
uint8_t keyBuff[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint32_t ivBuff[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
uint32_t plain[4] = {0x61616161, 0x61616161, 0x61616161, 0x61616161};
uint8_t ciphertext[16];
if (HAL_CRYP_Encrypt(&hcryp, plain, 4, ciphertext, HAL_MAX_DELAY) != HAL_OK) {
// HANDE THE ERROR
}
// Print debugging information
for (int i = 0; i < 16; ++i) {
char printy[10];
int len = sprintf(printy, " -%x-", ciphertext[i]);
HAL_UART_Transmit(&huart3, (uint8_t*)printy, len, 5000);
}
HAL_UART_Transmit(&huart3, "\n\n", 2, 5000);
}
I am getting the output of: -5c- -21- -c6- -af- -f- -a- -1- -2c- -b2- -a4- -2f- -66- -79- -fc- -92- -db-
When I simulate above in the following Python code:
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
# Key and IV (Initialization Vector) from your STM32 code
key = bytes([0x00] * 32) # 256-bit key
key = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
iv = bytes([0x00] * 15 + [0x02]) # 96-bit IV (12 bytes)
# Header (AAD - Additional Authenticated Data)
header = bytes([0x00]*4)
# Data to encrypt
plaintext = b'aaaaaaaaaaaaaaaa'
plaintext = b'\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61'
# Create AES-GCM cipher object
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
# Encrypt the data
#cipher.update(header) # Add AAD
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
print(f'Ciphertext: {ciphertext.hex()}')
#print(f'Tag: {tag.hex()}')
I get 981e09865ee3f41ea3d5fc7981166d94
I am still lost on why the discrepancy exists. Did lots of looking and read much documentation and posts, but no luck. Any help would be much appreciated.


