CN / EN
文档反馈
感谢关注汇顶文档,期待您的宝贵建议!
感谢您的反馈,祝您愉快!

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所示:

图 6 AES示例工程流程图
  1. 配置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:随机序列种子,由用户提供。
  2. 使用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)
      
      1. 调用hal_aes_ecb_encrypt()接口实现明文的轮询方式加密,加密完成后返回函数执行结果,密文数据在参数g_encrypt_result中。
      2. 调用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");
      }
      
      1. 调用hal_aes_ecb_encrypt_it()接口实现明文的非轮询方式加密,加密状态即结果通过回调函数hal_aes_done_callback()和hal_aes_error_callback()返回,用户在此函数内可以自定义操作。
      2. 调用hal_aes_ecb_decrypt_it()接口实现密文的非轮询方式解密,解密状态即结果通过回调函数hal_aes_done_callback()和hal_aes_error_callback()返回,用户在此函数内可以自定义操作。

测试验证

  1. 用GProgrammer下载aes.bin至开发板。
  2. 将开发板串口连接至PC端,打开并配置GRUart。
  3. 在GRUart的Receive Data窗口中将会显示AES加解密结果。

扫描关注

打开微信,使用“扫一扫”即可关注。