我正在处理一个 BIM、BIM 要从外部闪存加载应用程序映像、并使用 AES256-GMC96进行加密。
在一个操作中对映像进行签名和加密。
在器件上解密图像时、会对图像进行区块解密、首先创建用于验证签名的哈希算法、然后在验证签名后、在从外部闪存复制到内部闪存时会再次对签名进行区块解密。 这很正常。
我还想使用的是验证标签。 crypto_AESCTL_SAVE_context 似乎是解密区块时要设置的标志、但需要为计算出的整个图像设置标签。
以下代码是基于 AESGCMCC26XX.c 的工作代码、不适用于标签验证。 我 认为 AESSetCtrl ()函数应该在 AES_GCM_Decrypt_enable ()函数中,但不能理解这一点。 任何提示都会很感激。
int aes_gcm_decrypt_enable(uint8_t* aes256_key, uint8_t* iv)
{
if (crypto_module_powered)
{
// Something has gone wrong
aes_gcm_decrypt_disable();
}
if (!crypto_module_powered)
{
PRCMPowerDomainOn(PRCM_PERIPH_CRYPTO);
while (PRCMPowerDomainsAllOn(PRCM_PERIPH_CRYPTO) != PRCM_DOMAIN_POWER_ON);
PRCMPeripheralRunEnable(PRCM_PERIPH_CRYPTO);
PRCMLoadSet();
while (!PRCMLoadGet());
crypto_module_powered = true;
}
AESInvalidateKey(AES_KEY_AREA_6);
AESInvalidateKey(AES_KEY_AREA_7);
// Load AES-256 key
if (AESWriteToKeyStore(aes256_key, AES256_KEY_LENGTH, AES_KEY_AREA_6) != AES_SUCCESS)
{
return EXIT_FAILURE;
}
// Load IV (nonce)
HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ((uint32_t *)iv)[0];
HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ((uint32_t *)iv)[1];
HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ((uint32_t *)iv)[2];
chiper_block_count = 1;
return EXIT_SUCCESS;
}
int aes_gcm_decrypt_chunk(uint8_t* data, uint16_t data_length)
{
if (chiper_block_count == 0)
{
return EXIT_FAILURE;
}
if (data_length > AES_GCM_MAX_CHUNK_LENGTH)
{
return EXIT_FAILURE;
}
IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
AESSelectAlgorithm(AES_ALGSEL_AES);
if (AESReadFromKeyStore(AES_KEY_AREA_6) != AES_SUCCESS)
{
return EXIT_FAILURE;
}
uint32_t aesCtrl = CRYPTO_AESCTL_GCM_M |
CRYPTO_AESCTL_CTR |
CRYPTO_AESCTL_SAVE_CONTEXT |
CRYPTO_AESCTL_CTR_WIDTH_32_BIT;
AESSetCtrl(aesCtrl);
// Big endian counter value
HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = (uint32_t)(((chiper_block_count & 0x00FF) << 24) |
((chiper_block_count & 0xFF00) << 8));
// Calculate for next chunk
chiper_block_count += (data_length / AES_GCM_CHIPER_BLOCK_LENGTH);
AESSetDataLength(data_length);
AESSetAuthLength(0);
AESStartDMAOperation(data, data_length, decrypt_buf, data_length);
if(AESWaitForIRQFlags(AES_RESULT_RDY | AES_DMA_BUS_ERR) & AES_DMA_BUS_ERR)
{
return EXIT_FAILURE;
}
// Make sure to also clear DMA_IN_DONE even if there is no authenticated data
AESIntClear(AES_RESULT_RDY | AES_DMA_IN_DONE | AES_DMA_BUS_ERR);
memcpy(data, decrypt_buf, data_length);
return EXIT_SUCCESS;
}
void aes_gcm_decrypt_disable(void)
{
AESInvalidateKey(AES_KEY_AREA_6);
AESInvalidateKey(AES_KEY_AREA_7);
// Power down crypto module sub modules.
AESSelectAlgorithm(0x00);
if (crypto_module_powered)
{
PRCMPowerDomainOff(PRCM_PERIPH_CRYPTO);
while (PRCMPowerDomainsAllOff(PRCM_PERIPH_CRYPTO) != PRCM_DOMAIN_POWER_OFF);
crypto_module_powered = false;
}
}
此致 Erlend