打印
[国产单片机]

【东软载波ESF0654 PDS开发板活动】测试RT-Thread+硬件加密(CR...

[复制链接]
957|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件加密模块主要用于由硬件对数据进行加密或解密操作,支持的标准有AES。AES(AdvancedEncryption Standard)是最新的分组对称密码算法,兼容联邦信息处理标准出版物(FIPS PUB 197, 2001 年 11 月 26 日)规定的高级加密标准(AES)。AES支持多种模式的加密方式:
AES-ECB模式加密和解密
AES-CBC模式加密和解密
AES-CTR模式加解密和解密
AES-GCM模式解密和解密
本次在ES32F0654单片机平台上对AES-CBC模式加密和解密进行测试,关于AES-CBC模式加密和解密的具体详情如下:
AES-CBC模式加密
AES是以 128位作为一个数据单元进行加密,下图介绍了AES加密分组链(AES-CBC
模式加密。该模式首先将明文消息分成多个 128 位数据明文单元。在CBC 加密过程中,一个数据单元经过执行位/字节/半字交换后作为明文单元(P1),通过与一个128 位初始化向量(IV)进行异或运算(IV^P1),作为第一个输入单元(I1)。该输入单元通过 AES算法(AEA)在加密状态下使用 128位密钥进行加密处理。生成的 128 位输出单元(O1)将直接用作密文(C1),即C1 = O1。然后,第一个密文单元与第二个明文数据单元进行异或运算(C1^P2),从而生成第二个输入单元(I2)。第二个输入单元通过以上AES 处理而生成第二个密文单元。 加密处理会不断将后续密文单元和明文单元链接到一起,直到消息中所有的明文单元都加密完成为止。如果消息中最后的数据单元不是一个 128 位数据单元,则由应用程序按照一定规则对不完整数据单元进行加密。
1K = 密钥; C = 密文; I = 输入块; Ps= 交换前(解码时)或 交换后(编码时)的明文;P = 明文;IV =
始化向量。
2IVx = [IVxRIVxL], R = 右, L= 左。
3:如果密钥大小 =128: 密钥 =[K3 K2];

操作示例:
1. 设置CRYPT_CON.CRYSEL = 0,选择算法类型为 AES
2.
设置 CRYPT_CON.ENCS= 1,选择加密
3.设置 CRYPT_CON.AESKS= 0,选择密钥长度 128bit
4.
设置 CRYPT_CON.MODE= 1,选择 CBC模式
5. CRYPT_KEY0...CRYPT_KEY3 中填入 128bit 长度的密钥,填入 KEY3/2/1/0位置
6. CRYPT_IV0/1/2/3 填入初始向量
7. CRYPT_DATA0/1/2/3 中写入需要加密的明文
8. 设置CRYPT_CON.GO = 1,启动加密
9. 通过CRYPT_IF.DONE 判断加密是否完成,如果 CRYPT_IF.DONE = 0,则加密完成
10. CRYPT_DATA0/1/2/3 中读出已经加密的密文
11. 回到步骤 7 继续进行加密
12. 所有加密完成

AES-CBC模式解密
AES是以 128位作为一个数据单元进行解密,下图介绍了AES密码分组链接(AES-CBC)模式解密。该模式首先将密文消息分成多个128 位数据密文单元,第一个密文单元(C1)经过位/字节/半字交换后作为一个输入单元(I1),该输入单元(I1)通过AES 算法(AEA)在解密状态下使用 128位密钥进行解密处理, 生成的 128 位输出单元(O1),再与IV 进行异或运算(O1^IV),从而生成第一个明文单元。然后,第二个密文单元作为下一个输入单元,经过以上AES 解密处理,生成的输出单元再与第一个密文单元进行异或运算(O2^C1),从而生成第二个明文数据单元(P2)。依次进行解密,直到消息中所有的密文单元都解密完成为止。
  图
17-4 AES-CBC
模式解密
   
1K = 密钥; C = 密文; I = 输入块; Ps= 交换前(解码时)或 交换后(编码时)的明文;P = 明文;IV =
始化向量。
2IVx = [IVxRIVxL], R = 右, L= 左。
3: 如果密钥大小 =128: 密钥 =[K3 K2];
操作示例:
1. 设置CRYPT_CON.CRYSEL = 0,选择算法类型为 AES
2.
设置 CRYPT_CON.ENCS= 0,选择解密
3. 设置CRYPT_CON.AESKS = 0,选择密钥长度 128bit

4. 设置 CRYPTCON.MODE= 1,选择 CBC模式
5. CRYPT_KEY0...CRYPT_KEY3 中填入 128bit 长度的密钥,填入 KEY3/2/1/0位置
6. CRYPT_IV0/1/2/3 填入初始向量
7. CRYPT_DATA0/1/2/3 中写入需要解密的密文
8. 设置CRYPT_CON.GO = 1,启动解密
9. 通过CRYPT_IF.DONE 判断解密是否完成,如果 CRYPT_IF.DONE = 0,则解密完成
10. CRYPT_DATA0/1/2/3 中读出已经解密的明文
11. 回到步骤 7 继续进行解密
12. 所有解密完成

使用特权

评论回复

相关帖子

沙发
一路向北lm|  楼主 | 2019-12-22 13:08 | 只看该作者
新建bsp_crypt.c bsp_crypt.h 主要实现对硬件加密的测试,这里以AES-CBC为例:
1. crypt初始化
void crypt_module_init(void)
{
          /* Clear lpuart_handle_t structure */
        memset(&h_crypt, 0x0, sizeof(md_crypt_init_t));

        //初始化crypt
        h_crypt.mode  = MD_CRYPT_MODE_CBC;      //ASE-CBC模式
        h_crypt.order = MD_CRYPT_FIFO_ORDER_3;
        h_crypt.type  = MD_CRYPT_TYPE_32;
       
        md_crypt_init(&h_crypt);
        md_crypt_enable_fifo(CRYPT);
}
2.新建一个RT-Thread任务线程对AES-CBC 加密和解密进行测试,具体代码如下:
#include "board.h"
#include "rtthread.h"

struct rt_thread Task1_thread;
struct rt_thread Task2_thread;
struct rt_thread Task3_thread;

rt_uint8_t rt_task1_thread_stack[1024];
rt_uint8_t rt_task2_thread_stack[1024];
rt_uint8_t rt_task3_thread_stack[1024];

md_crypt_init_t h_crypt1;

uint8_t loop  = 0;
uint8_t count = 0;
uint8_t error = 0;

//测试初始数据 128*4位数据
uint32_t plain[16] = {0x3243F6A8, 0x885A308D, 0x313198A2, 0xE0370734,
                      0x3243F6A8, 0x885A308D, 0x313198A2, 0xE0370734,
                      0x3243F6A8, 0x885A308D, 0x313198A2, 0xE0370734,
                      0x3243F6A8, 0x885A308D, 0x313198A2, 0xE0370734};
//用于存放输出数据
uint32_t result[16] = {0};

//存放的正确加密数据
uint32_t expect[16] = {0x925afa80, 0x48a07d7a, 0xd868c5f2, 0xc39468a6,
                       0x1db9bf55, 0xf0be8867, 0x5f04cbc2, 0xfac9578c,
                       0xf4a47fad, 0x5961e322, 0xd6a04406, 0x01754289,
                       0x1c22ee2f, 0xa04608aa, 0xc22f6429,0x9240066d};
//128位的密钥
uint32_t key[4] = {0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c};
//128位的初始化向量
uint32_t ivr[4] = {0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff};

void task1(void *parameter);
void task2(void *parameter);
void task3(void *parameter);

int main()
{
  rt_kprintf("The Project is ES32F0654 RT-Thread Demo.........\r\n");       
  rt_thread_init(&Task1_thread,"task1",
                       task1,RT_NULL,&rt_task1_thread_stack[0],
                       sizeof(rt_task1_thread_stack),3,20);
        rt_thread_init(&Task2_thread,"task2",
                       task2,RT_NULL,&rt_task2_thread_stack[0],
                       sizeof(rt_task2_thread_stack),3,20);
        rt_thread_init(&Task3_thread,"task3",
                       task3,RT_NULL,&rt_task3_thread_stack[0],
                       sizeof(rt_task3_thread_stack),3,20);
        rt_thread_startup(&Task1_thread);       
  rt_thread_startup(&Task2_thread);       
        rt_thread_startup(&Task3_thread);       
}


//任务1:状态指示
void task1(void *parameter)
{
        while(1)
        {
                LED1_TOGGLE;
                LED2_TOGGLE;
                rt_thread_delay(500);       
                rt_kprintf("Thread1 is running.........\r\n");       
        }  
}
unsigned int num;
//任务2:产生一个随机数
void task2(void *parameter)
{
  while(1)
        {
                num = trng_module_get_data();
                rt_thread_delay(500);       
                rt_kprintf("Thread2 is running Generate random number:%d \r\n",num);       
        }  
}

/* aes cbc key = 128bits
* input         32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
* cipher key        2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
* iv                f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
* refer result        92 5a fa 80 48 a0 7d 7a d8 68 c5 f2 c3 94 68 a6
                1d b9 bf 55 f0 be 88 67 5f 04 cb c2 fa c9 57 8c
                f4 a4 7f ad 59 61 e3 22 d6 a0 44 06 01 75 42 89
                1c 22 ee 2f a0 46 08 aa c2 2f 64 29 92 40 06 6d
*/
void test_aes_cbc_128()
{       
        //开始AES加密
        md_crypt_set_key0(CRYPT, key[3]);
        md_crypt_set_key1(CRYPT, key[2]);
        md_crypt_set_key2(CRYPT, key[1]);
        md_crypt_set_key3(CRYPT, key[0]);

        md_crypt_set_iv0(CRYPT, ivr[3]);
        md_crypt_set_iv1(CRYPT, ivr[2]);
        md_crypt_set_iv2(CRYPT, ivr[1]);
        md_crypt_set_iv3(CRYPT, ivr[0]);
        md_crypt_enable_iv(CRYPT);
        md_crypt_encrypt(&h_crypt1,(uint8_t*)plain, (uint8_t*)result, sizeof(plain));
        //打印加密后的数据
rt_kprintf("The encrypt result is :\r\n");               
for(loop =0;loop<16;loop++)
        {
                   rt_kprintf("0X%08x  ",result[loop]);       
        }
         rt_kprintf("\r\n");       
       
        //开始AES解密
        md_crypt_set_key0(CRYPT, key[3]);
        md_crypt_set_key1(CRYPT, key[2]);
        md_crypt_set_key2(CRYPT, key[1]);
        md_crypt_set_key3(CRYPT, key[0]);

        md_crypt_set_iv0(CRYPT, ivr[3]);
        md_crypt_set_iv1(CRYPT, ivr[2]);
        md_crypt_set_iv2(CRYPT, ivr[1]);
        md_crypt_set_iv3(CRYPT, ivr[0]);
        md_crypt_enable_iv(CRYPT);
        md_crypt_decrypt(&h_crypt1,(uint8_t*)expect, (uint8_t*)result, sizeof(expect));       
        //打印加密后的数据
rt_kprintf("The decrypt result is :\r\n");       
        for(loop =0;loop<16;loop++)
        {
                   rt_kprintf("0X%08x  ",result[loop]);       
        }
        rt_kprintf("\r\n");       
       

        //输出解答密过程的错误率
}

//测试AES-CBC 加密和解密
void task3(void *parameter)
{
  while(1)
        {       
                rt_kprintf("Thread3 is running test_aes_cbc_128 \r\n",num);       
                test_aes_cbc_128();
                rt_thread_delay(1000);       
        }  
}


使用特权

评论回复
板凳
一路向北lm|  楼主 | 2019-12-22 13:09 | 只看该作者
测试结果如下:
输入原始数据:128*4 位
*            32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*                32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
初始化向量 * iv                   f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
密钥:      * cipher key        2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c

加密后的结果:
* refer result        92 5a fa 80 48 a0 7d 7a d8 68 c5 f2 c3 94 68 a6
                    1d b9 bf 55 f0 be 88 67 5f 04 cb c2 fa c9 57 8c
                    f4 a4 7f ad 59 61 e3 22 d6 a0 44 06 01 75 42 89
                    1c 22 ee 2f a0 46 08 aa c2 2f 64 29 92 40 06 6d
对照串口打印的数据刚好一致:

使用特权

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

本版积分规则

277

主题

3805

帖子

76

粉丝