2019-11-16 04:59 PM
In the code below I have AES GCM correctly decrypting data using the Cryptolib. I am trying to decrypt the same data using the HAL_CRYP_AES_XXXX functions and it isn't working.
Key is 32 bytes. iv is 12 bytes. header data (aad) is 3 bytes. message data (dc) is 20 bytes.
I have seen that the data must be a multiple of 16 bytes. Do I simply pad with zeros and report size as 32 bytes in my case? Does the iv need to be padded? Or the header?
Does the data, key, aad, or iv need to be byte swapped somehow?
Is the CrypHandle.Init.DataType = CRYP_DATATYPE_8B correct?
I've tried lots of different combinations and haven't hit on one that seems to work.
Suggestions?
Thank you.
uint8_t key[]= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
uint8_t iv[] = {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
uint8_t aad[] = {0x42, 0x24, 0x02};
uint8_t tag[] = {0xee, 0x20, 0xac, 0xfb, 0x41, 0x9c, 0x86, 0xc9, 0x9a, 0x87, 0x57, 0x5a, 0x97, 0x78, 0x52, 0xda};
uint8_t dc[] = {0x66, 0x9b, 0xaa, 0xd4, 0xbc, 0x87, 0xed, 0x03, 0xfa, 0xbf, 0x66, 0xfc, 0x0e, 0x6b, 0x36, 0x85, 0xb7, 0x3a, 0xd7, 0x45};
uint8_t plaintext[32];
static int32_t result;
uint8_t outtag[16];
void aestest(void)
{
#ifdef SWAES
AESGCMctx_stt ctx;
int32_t outlen = sizeof(plaintext);
int32_t outtaglen = 16;
__CRC_CLK_ENABLE();
ctx.mAADsize = sizeof(aad);
ctx.mIvSize = sizeof(iv);
ctx.mKeySize = sizeof(key) - 1;
ctx.mTagSize = sizeof(tag);
ctx.pmTag = tag;
ctx.pmKey = key;
ctx.mFlags = E_SK_DEFAULT;
result = AES_GCM_Decrypt_Init(&ctx, key, iv);
result = AES_GCM_Header_Append(&ctx, aad, sizeof(aad));
result = AES_GCM_Decrypt_Append(&ctx, dc, sizeof(dc), plaintext, &outlen);
result = AES_GCM_Decrypt_Finish(&ctx, outtag, &outtaglen);
#else
CRYP_HandleTypeDef CrypHandle;
CrypHandle.Instance = AES;
CrypHandle.Init.DataType = CRYP_DATATYPE_8B;
CrypHandle.Init.KeySize = CRYP_KEYSIZE_256B;
CrypHandle.Init.pKey = key;
CrypHandle.Init.ChainingMode = CRYP_CHAINMODE_AES_GCM_GMAC;
CrypHandle.Init.GCMCMACPhase = CRYP_GCM_INIT_PHASE;
CrypHandle.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE;
CrypHandle.Init.pInitVect = iv;
CrypHandle.Init.Header = aad;
CrypHandle.Init.HeaderSize = sizeof(aad);
CrypHandle.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
CrypHandle.Init.GCMCMACPhase = CRYP_GCM_INIT_PHASE;
if (HAL_CRYP_Init(&CrypHandle) != HAL_OK)
{
Error_Handler();
}
/*------------------------------------------------------------*/
/* GCM init phase */
if (HAL_CRYPEx_AES_Auth(&CrypHandle, NULL, 0, NULL, 99999)!= HAL_OK)
{
Error_Handler();
}
/*------------------------------------------------------------*/
/* GCM header phase */
CrypHandle.Init.GCMCMACPhase = CRYP_GCMCMAC_HEADER_PHASE;
if (HAL_CRYPEx_AES_Auth(&CrypHandle, NULL, 0, NULL, 99999)!= HAL_OK)
{
Error_Handler();
}
/*------------------------------------------------------------*/
/* GCM payload phase */
CrypHandle.Init.GCMCMACPhase = CRYP_GCM_PAYLOAD_PHASE;
if (HAL_CRYPEx_AES_Auth(&CrypHandle, dc, sizeof(dc), plaintext, 99999)!= HAL_OK)
{
Error_Handler();
}
/*------------------------------------------------------------*/
/* GCM final phase */
CrypHandle.Init.GCMCMACPhase = CRYP_GCMCMAC_FINAL_PHASE;
if (HAL_CRYPEx_AES_Auth(&CrypHandle, NULL, sizeof(dc), outtag, 999999)!= HAL_OK)
{
Error_Handler();
}
/*------------------------------------------------------------*/
#endif
}
Solved! Go to Solution.
2019-11-16 07:32 PM
I managed to get it to work. The only change needed was that the iv needed to be changed to:
uint8_t iv[] = {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
The last 32-bit value is a counter which needs to be initialized to 2 according to NIST. Apparently the Cryptolib sets this for you while you must push it yourself to the hardware block.
2019-11-16 07:32 PM
I managed to get it to work. The only change needed was that the iv needed to be changed to:
uint8_t iv[] = {0x04, 0xbc, 0xca, 0xab, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
The last 32-bit value is a counter which needs to be initialized to 2 according to NIST. Apparently the Cryptolib sets this for you while you must push it yourself to the hardware block.