AES
AES示例实现了AES的两种加密模式:ECB和CBC,以及三种加密密钥长度:128 bits,192 bits和256 bits。
在示例工程中明文和密文为直接输出,同一条明文应用不同长度的密钥加密可得到对应不同的密文。
- 加密操作时,将明文作为输入,AES加密输出密文数据,并将其与相应原始密文作对比,验证AES加密的正确性。
- 解密操作时,将加密输出的密文作为输入,AES解密输出明文数据,将其与原始明文作对比,验证AES解密的正确性。
以下章节主要介绍使用AES的轮询和中断两种方式对数据进行加解密。
AES示例的源代码和工程文件位于SDK_Folder\projects\peripheral\aes\aes,其中工程文件在文件夹Keil_5下。
代码理解
示例工程流程图如图 6所示:
- 配置AES模块。
AES模块配置代码(ECB)如下:
g_aes_handle.p_instance = AES; g_aes_handle.init.key_size = AES_KEYSIZE_128BITS; g_aes_handle.init.p_key = (uint32_t *)g_key128_ecb; g_aes_handle.init.chaining_mode = AES_CHAININGMODE_ECB; g_aes_handle.init.p_init_vector = NULL; g_aes_handle.init.dpa_mode = DISABLE; g_aes_handle.init.p_seed = (uint32_t *)g_seed; hal_aes_deinit(&g_aes_handle); hal_aes_init(&g_aes_handle);AES模块配置代码(CBC)如下:
g_aes_handle.p_instance = AES; g_aes_handle.init.key_size = AES_KEYSIZE_128BITS; g_aes_handle.init.p_key = (uint32_t *)g_key128_cbc; g_aes_handle.init.chaining_mode = AES_CHAININGMODE_CBC; g_aes_handle.init.p_init_vector = (uint32_t *)g_iv_cbc; g_aes_handle.init.dpa_mode = DISABLE; g_aes_handle.init.p_seed = (uint32_t *)g_seed; hal_aes_deinit(&g_aes_handle); hal_aes_init(&g_aes_handle);- init.key_size:密钥长度设置,可选择AES_KEYSIZE_128BITS、AES_KEYSIZE_192BITS、AES_KEYSIZE_256BITS。此示例选择AES_KEYSIZE_128BITS即128位。
- init.p_key:加密/解密密钥。由用户提供。
- init.chaining_mode:加解密方式设置,可选择AES_CHAININGMODE_ECB、AES_CHAININGMODE_CBC。
- init.p_init_vector:CBC模式中初始化向量,ECB模式中不用配置。
- dpa_mode:配置是否使能DPA功能。
- p_seed:随机序列种子,由用户提供。
- 使用AES加解密API。
以ECB模式为例,CBC模式的加解密可参考ECB加解密接口使用。
- 轮询方式加解密
hal_aes_ecb_encrypt(&g_aes_handle, (uint32_t *)g_plaintext_ecb, sizeof(g_plaintext_ecb), (uint32_t *)g_encrypt_result, 5000) hal_aes_ecb_decrypt(&g_aes_handle, (uint32_t *)g_encrypt_result, sizeof(g_encrypt_result), (uint32_t *)g_decrypt_result, 5000)- 调用hal_aes_ecb_encrypt()接口实现明文的轮询方式加密,加密完成后返回函数执行结果,密文数据在参数g_encrypt_result中。
- 调用hal_aes_ecb_decrypt()接口实现密文的轮询方式解密,解密完成后返回函数执行结果,明文数据在参数g_decrypt_result中。
- 非轮询方式加解密
hal_aes_ecb_encrypt_it(&g_aes_handle, (uint32_t *)g_plaintext_ecb, sizeof(g_plaintext_ecb), (uint32_t *)g_encrypt_result) hal_aes_ecb_decrypt_it(&g_aes_handle, (uint32_t *)g_encrypt_result, sizeof(g_encrypt_result), (uint32_t *)g_decrypt_result) void hal_aes_done_callback(aes_handle_t *haes) { g_int_done_flag = 1; } void hal_aes_error_callback(aes_handle_t *haes) { printf("\r\nGet an Error!\r\n"); }- 调用hal_aes_ecb_encrypt_it()接口实现明文的非轮询方式加密,加密状态即结果通过回调函数hal_aes_done_callback()和hal_aes_error_callback()返回,用户在此函数内可以自定义操作。
- 调用hal_aes_ecb_decrypt_it()接口实现密文的非轮询方式解密,解密状态即结果通过回调函数hal_aes_done_callback()和hal_aes_error_callback()返回,用户在此函数内可以自定义操作。
- 轮询方式加解密
测试验证
- 用GProgrammer下载aes.bin至开发板。
- 将开发板串口连接至PC端,打开并配置GRUart。
- 在GRUart的Receive Data窗口中将会显示AES加解密结果。