cancel
Showing results for 
Search instead for 
Did you mean: 

AES 256 GCM Decryption on STM32L562

Dick Mincher
Associate III

Hello,

I am trying to decrypt some data on the L5. The data below can be fed directly into a python crypto library and get a valid result. I am trying to understand the 32-bit alignment requirements of the L5 as well as any possible byte swapping needed. Also, the lengths of the data and the header -- do they get specified in words or bytes? My header is 3 bytes in length and my data is 20 bytes.

How do I set this up to make it work? Apologies for the state of the code -- it's a "work in progress" . 🙂

Thank you in advance!

D i c k

	uint8_t iv8[16] =   {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
	uint8_t key8[32]=  {32 bytes};
	//uint8_t iv8[12] =   {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
	uint8_t aad8[3] =  {0x42, 0x24, 0x02};
	uint8_t dc8[20] =   {0x66, 0x9b, 0xaa, 0xd4, 0xbc, 0x87, 0xed, 0x03, 0xfa, 0xbf, 0x66, 0xfc, 0x0e, 0x6b, 0x36, 0x85, 0xb7, 0x3a, 0xd7, 0x45};
	uint8_t plaintext8[20];
	uint8_t outtag8[16];
	
	uint32_t key32[8];
	memset(key32, 0, sizeof(key32));
	memcpy(key32, key8, sizeof(key8));
	
	uint32_t aad32[4];
	memset(aad32, 0, sizeof(aad32));
	memcpy(aad32, aad8, sizeof(aad8));
	
	uint32_t iv32[4];
	memset(iv32, 0, sizeof(iv32));
	memcpy(iv32, iv8, sizeof(iv8));
	
	uint32_t dc32[12];
	memset(dc32, 0, sizeof(dc32));
	memcpy(dc32, dc8, sizeof(dc8));
 
	uint32_t plaintext32[10];
	memset(plaintext32, 0x66, sizeof(plaintext32));
 
	uint32_t outtag32[4];
	memset(outtag32, 0x99, sizeof(outtag32));
 
	
	hcryp.Instance = AES;
	hcryp.Init.Algorithm = CRYP_AES_GCM_GMAC;
	hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
	hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
	
	hcryp.Init.DataType      = CRYP_DATATYPE_8B;
	hcryp.Init.KeySize       = CRYP_KEYSIZE_256B;
	hcryp.Init.pKey          = key32;
	hcryp.Init.Algorithm     = CRYP_AES_GCM_GMAC;
	
	hcryp.Init.pInitVect     = iv32;
	hcryp.Init.Header        = aad32;
	hcryp.Init.HeaderSize    = 3;
	
	if (HAL_CRYP_Init(&hcryp) != HAL_OK)
	{
	Error_Handler();
	}
	
	if (HAL_CRYP_Decrypt(&hcryp, dc32, 20, plaintext32,99999)!= HAL_OK)
	{
	Error_Handler();
	}
	/* Wait for processing to be done */
	while (HAL_CRYP_GetState(&hcryp) != HAL_CRYP_STATE_READY);
	
	/* Compute the authentication TAG */
	if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, outtag32, 99999) != HAL_OK)
	{
	/* Processing Error */
	Error_Handler();
	}

2 REPLIES 2
Dick Mincher
Associate III

I have been able to get further by byte swapping everything. See the _bswap32 calls below.

I suspect that DataType might be the issue but I don't know what gets swapped and what doesn't. The code below returns the data correctly however the outtag32 returned is wrong. It's not byte swapped, looks nothing like what I expect. It seems odd that I can get the data decrypted but the resulting tag is wrong. Perhaps it has something to do with the header (aad) or length but I would expect the resulting data not to be correct.

What am I missing?

Thanks,

D i c k

	uint8_t iv8[] =   {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
	uint8_t key8[]=  {32 bytes};
	//uint8_t iv8[] =   {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
	uint8_t aad8[] =  {0x42, 0x24, 0x02};
	uint8_t tag8[] =  {0xee, 0x20, 0xac, 0xfb, 0x41, 0x9c, 0x86, 0xc9, 0x9a, 0x87, 0x57, 0x5a, 0x97, 0x78, 0x52, 0xda};
	uint8_t dc8[] =   {0x66, 0x9b, 0xaa, 0xd4, 0xbc, 0x87, 0xed, 0x03, 0xfa, 0xbf, 0x66, 0xfc, 0x0e, 0x6b, 0x36, 0x85, 0xb7, 0x3a, 0xd7, 0x45};
	uint8_t plaintext8[32];
	static int32_t result;
	uint8_t outtag8[16];
 
	uint32_t key32[8];
	memset(key32, 0, sizeof(key32));
	memcpy(key32, key8, sizeof(key8));
	for (int i = 0; i < 8; i++)
		key32[i] = _bswap32(key32[i]);
 
 
	uint32_t aad32[4];
	memset(aad32, 0, sizeof(aad32));
	memcpy(aad32, aad8, sizeof(aad8));
	//for(int i = 0; i < 4; i++)
	//	aad32[i] = _bswap32(aad32[i]);
 
	uint32_t iv32[4];
	memset(iv32, 0, sizeof(iv32));
	memcpy(iv32, iv8, sizeof(iv8));
	for(int i = 0; i < 4; i++)
		iv32[i] = _bswap32(iv32[i]);
 
	uint32_t dc32[12];
	memset(dc32, 0, sizeof(dc32));
	memcpy(dc32, dc8, sizeof(dc8));
	//for(int i = 0; i < 12; i++)
	//	dc32[i] = _bswap32(dc32[i]);
 
	uint32_t plaintext32[10];
	memset(plaintext32, 0x66, sizeof(plaintext32));
 
	uint32_t outtag32[4];
	memset(outtag32, 0x99, sizeof(outtag32));
 
	hcryp.Instance = AES;
	hcryp.Init.pKey = (uint32_t *)pKeyAES;
	hcryp.Init.Algorithm = CRYP_AES_GCM_GMAC;
	hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
	hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
 
	hcryp.Init.DataType      = CRYP_DATATYPE_8B;
	hcryp.Init.KeySize       = CRYP_KEYSIZE_256B;
	hcryp.Init.pKey          = key32;
	hcryp.Init.Algorithm     = CRYP_AES_GCM_GMAC;
 
	hcryp.Init.pInitVect     = iv32;
	hcryp.Init.Header        = aad32;
	hcryp.Init.HeaderSize    = 1;
 
	if (HAL_CRYP_Init(&hcryp) != HAL_OK)
	{
	Error_Handler();
	}
 
	if (HAL_CRYP_Decrypt(&hcryp, dc32, sizeof(dc8), plaintext32,99999)!= HAL_OK)
	{
	Error_Handler();
	}
	/* Wait for processing to be done */
	while (HAL_CRYP_GetState(&hcryp) != HAL_CRYP_STATE_READY);
 
	/* Compute the authentication TAG */
	if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, outtag32, 99999) != HAL_OK)
	{
	/* Processing Error */
	Error_Handler();
	}

Dick Mincher
Associate III

In looking at the details of GCM the aad (additionally authenticated data) has no relation to the success of the decryption, only in the generation of the tag. So the aad must be the issue. It is 3 bytes and the length specified is 1 (one word). I tried swapping, padding (zero?) and can't come up with the recipe to make it work.

So close.

D i c k