测试硬件为HC32F4A0单片机,使用内部硬件AES模块完成128bit,192bit,256bit AES加密解密功能,AES ECB模式,自动填充0;
目前只有128bit加密解密与测试工具相符,192 256bit测试不相同,希望知道原因的小伙伴在下面留言告知一下原因;
但是我换了一个测试平台后能通过;
上代码:
/*************************************************************************************************************
* 文件名 : hc32f4a0_aes.c
* 功能 : HC32F4A0 AES加密/解密驱动
* 作者 : cp1300@139.com
* 创建时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 详细 : 支持128位/192位/256位加密解密
AES ECB模式,自动填充0
2022-02-16: https://the-x.cn/cryptography/Aes.aspx测试全部通过
http://tool.chacuo.net/cryptaes 测试只有128bit加密通过,192/256不一样,怀疑可能是平台问题
*************************************************************************************************************/
#include "hc32f4a0.h"
#include "hc32f4a0_map.h"
#include "system.h"
#include "hc32f4a0_aes.h"
/*************************************************************************************************************************
* 函数 : void HC32AES_PowerUp(void)
* 功能 : HC32硬件AES上电
* 参数 : 无
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 使用前必须先上电,初始化时钟,使能AES
*************************************************************************************************************************/
void HC32AES_PowerUp(void)
{
SYS_DeviceClockEnable(DEV_AES, TRUE); //使能时钟
}
/*************************************************************************************************************************
* 函数 : void HC32AES_PowerDown(void)
* 功能 : HC32硬件AES掉电
* 参数 : 无
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 掉电后将不能使用AES
*************************************************************************************************************************/
void HC32AES_PowerDown(void)
{
SYS_DeviceClockEnable(DEV_AES, FALSE); //关闭时钟
}
/*************************************************************************************************************************
* 函数 : void HC32AES_SetKey(HC32AES_KEY_SIZE KeySize, const u32 *pKey)
* 功能 : 设置KEY
* 参数 : KeySize:key长度;pKey:key缓冲区
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 将KEY写入到AES_KR寄存器,不会检查AES模块状态
*************************************************************************************************************************/
static void HC32AES_SetKey(HC32AES_KEY_SIZE KeySize, const u32 *pKey)
{
u8 n;
u8 i;
if(pKey == NULL) return;
AES->CR &= ~(0x03 << 3); //清除设置,默认128位密匙
switch(KeySize)
{
case HC32AES_KEY_192 : //192位密匙
{
AES->CR |= 1 << 3;
n = 192/32;
}break;
case HC32AES_KEY_256 : //256位密匙
{
AES->CR |= 2 << 3;
n = 256 / 32;
}break;
default: //128位密匙
{
n = 128/32;
}
}
for (i = 0; i < n; i++)
{
AES->KR = pKey; //写入KEY
}
}
/*************************************************************************************************************************
* 函数 : void HC32AES_Set128BitData(const u8 pData[16])
* 功能 : 写入128bit(16字节)加密/解密数据到寄存器
* 参数 : pData:待加密或解密的数据
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 将数据写入到AES_DR寄存器,不会检查AES模块状态
*************************************************************************************************************************/
static void HC32AES_Set128BitData(const u8 pInData[16])
{
u8 i;
u32* p;
if (pInData == NULL) return;
p = (u32*)pInData;
for (i = 0; i < 4; i++)
{
AES->DR = p;
}
}
/*************************************************************************************************************************
* 函数 : void HC32AES_Get128BitData(u8 pOutData[16])
* 功能 : 读取128bit(16字节)加密/解密数据到寄存器
* 参数 : pData:待加密或解密的数据
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 读取AES_DR寄存器,不会检查AES模块状态
*************************************************************************************************************************/
static void HC32AES_Get128BitData(u8 pOutData[16])
{
u8 i;
u32* p;
if (pOutData == NULL) return;
p = (u32*)pOutData;
for (i = 0; i < 4; i++)
{
p = AES->DR;
}
}
/*************************************************************************************************************************
* 函数 : static bool HC32AES_EncryptOrDecrypt128BitData(u8 pData[16])
* 功能 : 加密或解密128bit数据
* 参数 : pData:待加密/解密数据,同时返回解密/加密后的数据
* 返回 : TRUE:成功;FALSE:失败
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 请提前设置模式,写入KEY,以及设置模式
*************************************************************************************************************************/
static bool HC32AES_EncryptOrDecrypt128BitData(u8 pData[16])
{
u32 TimeOut = 400;
HC32AES_Set128BitData(pData); //写入128bit待加密/解密数据
AES->CR |= BIT0; //开始运算
nop; nop; nop; nop;
while (AES->CR & BIT0) //忙
{
TimeOut--;
if (TimeOut == 0) break;
Delay_US(1);
}
if (AES->CR & BIT0) //忙
{
INFO_S("AES加密/解密失败,忙\r\n");
return FALSE;
}
//加密/解密完成,读取数据
HC32AES_Get128BitData(pData);
return TRUE;
}
/*************************************************************************************************************************
* 函数 : u32 HC32AES_EncryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8 *pData, u32 DataSize)
* 功能 : 加密数据(pData:大小必须是16字节整数倍)
* 参数 : KeySize:key长度;pKey:加密的KEY;pData:待加密数据,同时存放加密后的数据;DataSize:待加密数据长度
* 返回 : 0:加密失败;>0加密后的数据长度(16的整数倍)
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 必须先上电,pData:大小必须是16字节整数倍,DataSize:是实际数据大小,待加密数据不足16字节的时候,后面会补充0
* 缓冲区大小必须是16字节整数倍,如果DataSize不是16字节整数倍,那么pData会比DataSize大,因为加密后的数据必须是16字节整数倍
*************************************************************************************************************************/
u32 HC32AES_EncryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8 *pData, u32 DataSize)
{
u32 TimeOut = 10;
u32 PackCnt = DataSize / 16;
u8 EndPackSize = DataSize % 16;
u32 i;
u32 len = 0;
if (pKey == NULL || pData == NULL || DataSize == 0)
{
ERROR_S("无效参数\r\n");
return 0;
}
while (AES->CR & BIT0) //忙
{
TimeOut--;
if (TimeOut == 0) break;
SYS_DelayMS(1);
}
if (AES->CR & BIT0) //还在忙,等待超时了
{
ERROR_S("错误:AES忙\r\n");
return 0;
}
HC32AES_SetKey(KeySize, pKey); //设置KEY
AES->CR &= ~BIT1; //加密运算
for (i = 0; i < PackCnt; i++)
{
if (HC32AES_EncryptOrDecrypt128BitData(&pData[i*16]) == FALSE)
{
return 0;
}
len += 16;
}
if (EndPackSize) //有余数
{
memset(&pData[i * 16 + EndPackSize], 0, 16 - EndPackSize); //后面数据先清零
if (HC32AES_EncryptOrDecrypt128BitData(&pData[i * 16]) == FALSE)
{
return 0;
}
len += 16;
}
return len;
}
/*************************************************************************************************************************
* 函数 : u32 HC32AES_DecryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8 *pData, u32 DataSize)
* 功能 : 解密数据(pData:大小必须是16字节整数倍)
* 参数 : KeySize:key长度;pKey:加密的KEY;pData:待解密数据,同时存放解密后的数据;DataSize:待解密数据长度(必须16整数倍)
* 返回 : 0:解密失败;>0解密后的数据长度(16的整数倍,实际数据长度可能小于此值,但是后面会被填充0)
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 说明 : 必须先上电,pData:大小必须是16字节整数倍
*************************************************************************************************************************/
u32 HC32AES_DecryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8* pData, u32 DataSize)
{
u32 TimeOut = 10;
u32 PackCnt = DataSize / 16;
u32 i;
u32 len = 0;
if (pKey == NULL || pData == NULL || DataSize == 0)
{
ERROR_S("无效参数\r\n");
return 0;
}
while (AES->CR & BIT0) //忙
{
TimeOut--;
if (TimeOut == 0) break;
SYS_DelayMS(1);
}
if (AES->CR & BIT0) //还在忙,等待超时了
{
ERROR_S("错误:AES忙\r\n");
return 0;
}
HC32AES_SetKey(KeySize, pKey); //设置KEY
AES->CR |= BIT1; //解密运算
for (i = 0; i < PackCnt; i++)
{
if (HC32AES_EncryptOrDecrypt128BitData(&pData[i * 16]) == FALSE)
{
return 0;
}
len += 16;
}
return len;
}
/*************************************************************************************************************
* 文件名 : hc32f4a0_aes.h
* 功能 : HC32F4A0 AES加密/解密驱动
* 作者 : cp1300@139.com
* 创建时间 : 2022-02-16
* 最后修改时间 : 2022-02-16
* 详细 : 支持128位/192位/256位加密解密
*************************************************************************************************************/
#ifndef _HC32F4A0_AES_H_
#define _HC32F4A0_AES_H_
#include "hc32f4a0_system.h"
//密匙长度
typedef enum
{
HC32AES_KEY_128 = 0, //128位密匙
HC32AES_KEY_192 = 1, //192位密匙
HC32AES_KEY_256 = 2, //256位密匙
}HC32AES_KEY_SIZE;
/*
//硬件AES加密模块句柄
typedef struct
{
u32 Key[8]; //存放128/192/256bit key
HC32AES_KEY_SIZE KeySize; //密匙长度
bool isDecry; //解密运算
}HC32AES_HANDLE;
*/
void HC32AES_PowerUp(void); //HC32硬件AES上电
void HC32AES_PowerDown(void); //HC32硬件AES掉电
u32 HC32AES_EncryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8* pData, u32 DataSize); //加密数据(pData:大小必须是16字节整数倍)
u32 HC32AES_DecryptData(HC32AES_KEY_SIZE KeySize, const u32* pKey, u8* pData, u32 DataSize); //解密数据(pData:大小必须是16字节整数倍)
#endif //_HC32F4A0_AES_H_
测试代码
u8 DataBuff[64];
u8 i;
u8 key[32];
u32 len;
memset(key, 0, 32);
key[0] = '1';
HC32AES_PowerUp(); //HC32硬件AES上电
memset(DataBuff, 0, 16);
for (i = 0; i < 10; i++)
{
DataBuff = '0' + i;
DataBuff[10+i] = '0' + i;
}
//128bit加密测试
uart_printf("\r\n128bit加密测试:\r\n");
len = HC32AES_EncryptData(HC32AES_KEY_128, (u32 *)key, DataBuff, 20); //加密数据(pData:大小必须是16字节整数倍
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
//128bit解密测试
uart_printf("\r\n128bit解密测试:\r\n");
len = HC32AES_DecryptData(HC32AES_KEY_128, (u32*)key, DataBuff, len); //解密数据(pData:大小必须是16字节整数倍)
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
//192bit加密测试
uart_printf("\r\n192bit加密测试:\r\n");
len = HC32AES_EncryptData(HC32AES_KEY_192, (u32*)key, DataBuff, 20); //加密数据(pData:大小必须是16字节整数倍
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
//192bit解密测试
uart_printf("\r\n192bit解密测试:\r\n");
len = HC32AES_DecryptData(HC32AES_KEY_192, (u32*)key, DataBuff, len); //解密数据(pData:大小必须是16字节整数倍)
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
//256bit加密测试
uart_printf("\r\n256bit加密测试:\r\n");
len = HC32AES_EncryptData(HC32AES_KEY_256, (u32*)key, DataBuff, 20); //加密数据(pData:大小必须是16字节整数倍
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
//256bit解密测试
uart_printf("\r\n256bit解密测试:\r\n");
len = HC32AES_DecryptData(HC32AES_KEY_256, (u32*)key, DataBuff, len); //解密数据(pData:大小必须是16字节整数倍)
for (i = 0; i < len; i++)
{
uart_printf("%02x", DataBuff);
}
测试结果
128bit 加密对比
192bit加密对比(不相符了),怀疑可能是密码问题
//256bit加密也不相符
//换了一个测试平台,128bit正常
//192bit正常
//256bit正常
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/cp1300/article/details/122967920
|
|