打印
[方案相关]

HC32FA AES加密解密 AES128 AES192 AES256驱动

[复制链接]
41|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
测试硬件为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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

166

主题

4160

帖子

5

粉丝