【GD32L233C-START评测】14. CAU加密算法之AES
[复制链接]
之前的帖子可以参考:
【GD32L233C-START评测】1.开箱
【GD32L233C-START评测】2.手把手创建新工程
【GD32L233C-START评测】3.移植FreeRTOS到GD32L233
【GD32L233C-START评测】4. 移植RT-Thread到GD32L233
【GD32L233C-START评测】5. IIC驱动OLED
【GD32L233C-START评测】6. 获取RTC时间并通过OLED显示
【GD32L233C-START评测】7. PWM驱动LED
【GD32L233C-START评测】8. TRNG真随机数生成
【GD32L233C-START评测】9. CRC检验
【GD32L233C-START评测】10. ADC读取芯片内部温度
【GD32L233C-START评测】11.DAC输出电压值_ADC读取外部电压值
【GD32L233C-START评测】12. 硬件IIC驱动OLED
【GD32L233C-START评测】13. CAU加密算法之DES/TDES
上一篇帖子讲解了GD32L233C的加密算法DES/TDES,这个加密算法是64位的,相对而言要简单一些。本文将讲解如何使用AES加密算法。
一、数据手册
AES加密算法的详情请参考《用户手册》23.4.2AES加密处理流程。
从这章我们可以知道AES加密算法是由多个秘钥的,可以支持三种秘钥长度,128位,192位256位,也就是16个字节,24字节和32个字节。
AES明文数据是128位的密文数据也是128位的,也就是16字节位单位,所以明文数据最少要为16个字节,如果超过16字节的话需要是16字节的倍数。
如:32字节,64字节等,对于不足16整数倍字节的数据可以使用软件方式进行补齐然后再加密。
输出的密文也是128位的,与明文数据是对应的。
本帖以16字节明文为单位来操作。
对于CBC加密方式还需要一个128位(即16字节)的初始化向量,可以自行设置。
数据手册可以参考如下:
二、代码实现
查看了用户手册之后,我们队AES加密算法已经有了初步的了解了。软件需要需要先定义秘钥以及初始化向量,这个根据自己的情况自行定义。
测试软件定义如下:
1. 128位,192位,256位秘钥定义如下:
/* 128 bits(16Bytes) secret key */
uint8_t key_128[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
};
/* 192 bits(24Bytes) secret key */
uint8_t key_192[24] = {0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
};
/* 256 bits(32Bytes) secret key */
uint8_t key_256[32] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
2. 初始化向量定义如下
/* Vector for cbc type */
uint8_t vectors[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
3.明文(也就是期望被加密的数据)定义如下:
__attribute__((aligned(4)))
uint8_t plaintext[TEXT_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10
};
4. 其他变量,宏定义等定义
Key_select数组指针用来指向128位,192位,256位秘钥的地址,keysize数组用来表示128位,192位,256位秘钥的数据长度,这两个数组用于传递给算法入口,让模块知道我们使用那种秘钥进行加密与解密。
#define TEXT_SIZE (16)
/* Used for get the type of the secret keys */
uint8_t *key_select[3] = {key_128, key_192, key_256};
/* Used for description secret type */
uint16_t keysize[3] = {128, 192, 256};
uint8_t encrypt_result[TEXT_SIZE];
uint8_t decrypt_result[TEXT_SIZE];
uint32_t i = 0;
cau_parameter_struct text;
5. 初始化时钟以及CAU模块
/* enable CAU clock */
rcu_periph_clock_enable(RCU_CAU);
/* deinitialize CAU */
cau_deinit();
cau_struct_para_init(&text);
6. AES ECB加解密测试代码
128位,192位,256位加解密操作都进行了,使用循环的方式直接操作三次,先加密再解密,直接对比就可以知道三种加密方式的密文的差异以及解密之后的数据是否正确。
/* AES ECB encryption/decryption test */
static void cau_aes_ecb_test(void)
{
for(i = 0; i < 3; i++)
{
/* encryption in ECB mode */
/* ECB mode: AES 128 -> AES 192 -> AES 256 */
text.alg_dir = CAU_ENCRYPT;
text.key = key_select[i];
text.key_size = keysize[i];
text.input = plaintext;
text.in_length = TEXT_SIZE;
if(SUCCESS == cau_aes_ecb(&text, encrypt_result))
{
printf(" Encrypted Data with AES %d Mode ECB :\r\n\r\n", keysize[i]);
data_display(TEXT_SIZE, encrypt_result);
}
/* decryption in CTR mode */
/* CTR mode: AES 128 -> AES 192 -> AES 256 */
text.alg_dir = CAU_DECRYPT;
text.key = key_select[i];
text.key_size = keysize[i];
text.input = encrypt_result;
text.in_length = TEXT_SIZE;
if(SUCCESS == cau_aes_ecb(&text, decrypt_result))
{
printf(" Decrypted Data with AES %d Mode ECB :\r\n\r\n", keysize[i]);
data_display(TEXT_SIZE, decrypt_result);
}
}
}
6. AES CBC加解密测试代码
CBC算法需要传递一个128位初始化向量vector,如下所示。同ECB算法一样,128位,192位,256位秘钥的方式都进行了一遍。
/* AES CBC encryption/decryption test */
static void cau_aes_cbc_test(void)
{
for(i = 0; i < 3; i++)
{
/* encryption in CBC mode */
/* CBC mode: AES 128 -> AES 192 -> AES 256 */
text.alg_dir = CAU_ENCRYPT;
text.key = key_select[i];
text.key_size = keysize[i];
text.iv = vectors;
text.input = plaintext;
text.in_length = TEXT_SIZE;
if(SUCCESS == cau_aes_cbc(&text, encrypt_result))
{
printf(" Encrypted Data with AES %d Mode CBC :\r\n\r\n", keysize[i]);
data_display(TEXT_SIZE, encrypt_result);
}
/* decryption in CBC mode */
/* CBC mode: AES 128 -> AES 192 -> AES 256 */
text.alg_dir = CAU_DECRYPT;
text.key = key_select[i];
text.key_size = keysize[i];
text.iv = vectors;
text.input = encrypt_result;
text.in_length = TEXT_SIZE;
if(SUCCESS == cau_aes_cbc(&text, decrypt_result)) {
printf("nDecrypted Data with AES %d Mode CBC :\r\n\r\n", keysize[i]);
data_display(TEXT_SIZE, decrypt_result);
}
}
}
三、测试效果
如下所示,每种加密方式加密出来的密文都是不一样的,但是解密之后的明文都是一样的,和初始明文一样,测试成功。
|