使用分block计算AES CMAC 返回值一直是BUSY,已经配置过时钟
-
static void alg_config(aes_algorithm_config_t *algConfig,uint32_t *inPtr, uint32_t *outPtr, uint32_t len,hcu_msg_type_t msgType)
{
algConfig->msgLen = len;
algConfig->dataInputPtr = inPtr;
algConfig->dataOutputPtr = outPtr;
algConfig->msgType = msgType;
}static status_t status = STATUS_SUCCESS;
/* HCU configuration */ hcu_user_config_t hcuUserConfig = { .swap = MODE_SWAPPING_NO, .carryType = HCU_USING_POLLING, }; uint32_t key[4] = { 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA }; /* HCU state */ hcu_state_t hcuState;
#if 1
/* HCU initial */
HCU_DRV_Init(&hcuUserConfig, &hcuState);/* AES-CMAC configuration */ hcu_cmac_config_t cmacConfig = { .macPtr = uAppCmacOut, .macLen = 16, }; /* AES encrypt algorithm configuration */ aes_algorithm_config_t encryptCfg = { .dataInputPtr = uAddr, .msgLen = uLen, .swKeyPtr = key, .hwKeySelected = false, .msgType = MSG_ALL, .keySize = KEY_SIZE_128_BITS, }; /* HCU initial */ HCU_DRV_Init(&hcuUserConfig, &hcuState); /* 分段处理 AES BLOCK 每一块最多只有0xFFFF */ alg_config(&encryptCfg, uAddr + 0, NULL, 0x9FFC, MSG_START); status |= HCU_DRV_GenerateMAC(&encryptCfg, &cmacConfig); /* Middle block */ alg_config(&encryptCfg, uAddr + 0x27FF, NULL, 0x9FFC, MSG_MIDDLE); status |= HCU_DRV_GenerateMAC(&encryptCfg, &cmacConfig); /* Middle block */ alg_config(&encryptCfg, uAddr + 0x4FFE, NULL, 0x9FFC, MSG_MIDDLE); status |= HCU_DRV_GenerateMAC(&encryptCfg, &cmacConfig); /* Last block */ alg_config(&encryptCfg, uAddr + 0x77FD, NULL, 0x9FFC, MSG_END); status |= HCU_DRV_GenerateMAC(&encryptCfg, &cmacConfig); /* 等待处理结束 */ while(hcuState.cmdInProgress); /* Deinit HCU at the end */ HCU_DRV_DeInit(&hcuState); return memcmp(&uAppCmacOut[0],(uint8_t *)APPCMACDATAADD,16);
#endif
return status;程序长度为0x27FF0,起始地址为0x18010 CMAC对每个block有要求是16的倍数码?
-
以下回答由AI生成,看是否能帮助你:
根据提供的代码和描述,您在使用分块计算AES CMAC时遇到了返回值一直是STATUS_BUSY的问题。这可能与CMAC算法对输入数据长度的要求有关,尤其是当数据不是16字节(128位)的倍数时,需要进行适当的填充。此外,还需要确保每个分块的配置正确无误。
问题分析
CMAC 输入数据长度要求:
CMAC算法要求输入数据的长度必须是16字节的倍数。如果输入数据不是16字节的倍数,则需要在最后一个块中进行填充。具体来说,CMAC会在最后一个块中添加一个额外的比特(通常是一个1),然后用0填充到16字节的边界[1]。分块处理:
您的程序将数据分成了多个块,每个块的大小为0x9FFC(40,956字节),这显然不是16字节的倍数。因此,每个块的末尾可能需要进行填充,以确保每个块的长度都是16字节的倍数。
特别是最后一个块,它的长度可能不足16字节的倍数,因此需要特别处理。状态检查:
您在每次调用HCU_DRV_GenerateMAC后立即检查了返回状态,并将其与status变量进行了按位或操作。如果任何一个块的处理失败(例如返回STATUS_BUSY),则最终的status将会包含STATUS_BUSY。这可能是导致您始终看到STATUS_BUSY的原因之一。
另外,您在最后使用了一个while(hcuState.cmdInProgress);循环来等待命令完成。这个循环可能会导致程序卡住,如果命令确实处于忙碌状态而没有完成。解决方案
确保每个块的长度是16字节的倍数:
在每个块的末尾进行填充,确保其长度为16字节的倍数。对于最后一个块,如果数据不足16字节,则按照CMAC的标准进行填充。
例如,可以在每个块的末尾添加一个1,然后用0填充到16字节的边界。处理最后一个块:
对于最后一个块,确保其长度是16字节的倍数。如果最后一个块的数据长度不足16字节,则需要进行填充。
例如,假设最后一个块的数据长度为n字节(n < 16),则可以在该块的末尾添加一个1,然后用0填充到16字节的边界。改进状态检查:
在每次调用HCU_DRV_GenerateMAC后,检查返回状态。如果返回STATUS_BUSY,可以考虑添加一个超时机制,避免程序无限期地等待。
例如,可以使用一个计数器或定时器来限制等待时间,如果超过一定时间仍未完成,则认为操作失败。优化等待逻辑:
while(hcuState.cmdInProgress);这种无限循环可能会导致程序卡住。可以考虑使用轮询或其他更高效的方式来等待命令完成。例如,可以每隔一段时间检查一次cmdInProgress标志,或者使用中断驱动的方式。
修改建议
以下是修改后的代码示例,确保每个块的长度为16字节的倍数,并处理最后一个块的填充:
static status_t status = STATUS_SUCCESS; /* HCU configuration */ hcu_user_config_t hcuUserConfig = { .swap = MODE_SWAPPING_NO, .carryType = HCU_USING_POLLING, }; uint32_t key[4] = { 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA }; /* HCU state */ hcu_state_t hcuState; /* HCU initial */ HCU_DRV_Init(&hcuUserConfig, &hcuState); /* AES-CMAC configuration */ hcu_cmac_config_t cmacConfig = { .macPtr = uAppCmacOut, .macLen = 16, }; /* AES encrypt algorithm configuration */ aes_algorithm_config_t encryptCfg = { .dataInputPtr = NULL, .msgLen = 0, .swKeyPtr = key, .hwKeySelected = false, .msgType = MSG_ALL, .keySize = KEY_SIZE_128_BITS, }; /* Program length and start address */ uint32_t programLength = 0x27FF0; uint32_t startAddress = 0x180
帮助没办法联网的电脑使用YCT
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...