我正在处理一个 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