STM32Cube系列教程11:STM32 AES加解密模块性能测试

news2024/11/19 16:43:32

文章目录

  • 本次测试环境
    • 本次测试所使用的系统时钟为48MHz
    • 本次测试主要测试对大量数据进行加解密所需的时间,本次为不严谨测试,忽略了程序调用耗时,结果仅供参考。
  • AES算法与数据加解密
    • 加密与解密
    • 对称加解密
    • AES算法
      • AES-ECB
      • AES-CBC
    • 填充算法
      • PKCS7Padding
  • 配置硬件AES模块初始化
  • 编写测试代码
    • 编写填充与解填充代码
    • 编写大小端转换代码
    • 编写aes模块密钥与模式配置代码
    • 封装加解密接口
    • 编写ecb测试代码
    • 编写cbc测试代码
    • 创建密钥与待加密的数据
  • 调用测试接口对aes模块进行测试
    • 测试结果

今天使用NUCLEO-U083RC的评估板,测试一下他内置的AES加速模块性能如何。

全部代码以上传到github:https://github.com/what-sudo/stm32U083


正文开始,本工程基于前期配置的工程模板,感兴趣的可查看之前的文章。
《STM32Cube系列教程10:STM32CubeIDE工程创建+串口DMA+IDLE+printf重定向+软中断处理串口数据+非阻塞延时任务》

本次测试环境

本次测试所使用的系统时钟为48MHz

本次测试主要测试对大量数据进行加解密所需的时间,本次为不严谨测试,忽略了程序调用耗时,结果仅供参考。

AES算法与数据加解密

在使用aes模块之前,这里先简单说一下什么是加解密以及aes算法的特性
以下内容摘录自我的另一篇文章,其中简单讲述了对称加密算法,非对称加密算法,数据散列算法等内容,感兴趣的请移步观看。
《数据安全-签名、加密、与填充》

加密与解密

加密:将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文。
解密:使用密钥及对应的解密算法对密文进行解密,使其恢复成可读明文。

加解密通常需要使明文数据按照一定长度对齐,叫做块大小(BlockSize),例如AES加解密的BlockSize为16字节,RSA加解密的BlockSize等于密钥长度。

如果数据长度无法对齐到要求的长度,就需要使用填充算法,加密前与解密后需要使用相同的填充算法对数据进行填充或解填充。

加密与解密一般需要对数据进行分包,将明文数据分包处理后,使用加密算法对每包数据进行运算,求出密文数据,每包密文数据的长度通常都是等长的,将每包密文依次连接,形成完整的密文数据。

解密时,按照加解密算法对应的包长度,依次将每包密文进行解密运算,拼凑出明文数据。

对称加解密

加密密钥与解密密钥相同的加密算法。
特点:

  1. 算法公开
  2. 计算量小
  3. 速度快,效率高
  4. 密钥传输与密钥管理麻烦

通常用于对大量数据进行加密,
常用的加密算法:AES、DES。

AES算法

AES算法安全性与密钥长度关联,密钥长度越长,越安全。
AES密钥分为AES128、AES192、AES256。
明文需要被分为固定长度的块进行加密,BlockSize为16字节。
数据如果被损坏,解密能正常运算,但会得到错误的明文。
AES算法通常分为ECB与CBC模式,我们通常使用的时CBC模式。

AES-ECB

  • ECB模式是最简单的AES加密模式
  • 使用一个固定长度的密钥
  • 固定的明文将会生成固定的密文,如果有两个相同的明文块,则加密结果也相同。

优点
简单,有利于并行计算,误差不会传递。

缺点
安全性低,容易被爆破

加密流程
在这里插入图片描述
解密流程
在这里插入图片描述

AES-CBC

  • 加解密需要使用一个固定长度的密钥
  • 加解密需要一个16字节的初始向量
  • 相同的明文不会生成相同的密文

优点

安全性比ECB好

缺点

不利于并行计算,误差会被传递,需要保存初始向量IV

加密流程
在这里插入图片描述
解密流程
在这里插入图片描述

填充算法

AES加解密算法仅支持按照block大小进行加解密,如果需要加密的数据无法被block大小整除,则无法加密,因此这里需要对原始数据进行填充,aes加密算法使用的填充方法为PKCS7Padding算法,这也是openssl库中,对aes加解密时默认使用的填充算法,我们需要保证我们加密出的数据能够与openssl互通,因此需要以openssl为标准,(openssl是一个开源的软件库,程序可以使用这个库进行安全通信,数据加解密等操作,详情请自行百度)。
在进行加密操作之前。需要对原始数据进行填充,在密文解密为明文后,需要按照填充规则,对解密数据进行解填充,才能获取到真实的原始数据。

内容摘录自我的另一篇文章,其中简单讲述了对称加密算法,非对称加密算法,数据散列算法等内容,感兴趣的请移步观看。
《数据安全-签名、加密、与填充》

PKCS7Padding

PKCS7是16字节填充的,即填充一定数量的内容,使得成为16的整数倍,而填充的内容取决于需要填充的数目。
例如:

// 原数组
{0x56}
//PKCS7填充结果
{0x56, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f}

// 原数组
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
//PKCS7填充结果
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}

// 原数组
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
//PKCS7填充结果
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
}

如果已经满足了16的整倍数,按照PKCS7的规则,仍然需要在尾部填充16个字节,并且内容是0x10,目的是为了加解密时统一处理填充。
因此进行pkcs7填充后的数据,最多会比原始数据长16个字节
原理讲到这里,下面我们写代码测试一下。

配置硬件AES模块初始化

打开我们的工程模板,在CubeMX配置中,打开Security --> AES配置,勾选Activated功能,注意Data type设置是否为默认值32b,Data width unit与Header width unit需要保持为word类型,其他配置保持默认即可,我这里曾改为CBC模式,系统默认应该时ECB模式,这里无影响,后面我会在代码中重新配置加解密模式与密钥key。保存并生成代码。

在这里插入图片描述

编写测试代码

这里我们主要使用ECB与CBC两种模式,进行多轮加解密,通过计算加解密的时间,来衡量aes模块的性能。

编写填充与解填充代码

通过这两个函数,在加密前与解密后,对数据进行填充与解填充。

/**
 * @brief  pkcs7填充算法
 * @param  p: 需要填充的数据指针
 * @param  len: 需要填充的数据长度
 * @param  block_size: 按照多大的block进行填充,通常为16
 * @return 填充后的数据长度
 * @author joseph
 * @date   2024.5.27
 */
static size_t pkcs7Padding(unsigned char *p, size_t len, uint8_t block_size)
{
    uint8_t i = 0;
    uint8_t padding = 0;
    padding = block_size - len%block_size;

    for (i = 0; i < padding; i++) {
        p[len + i] = padding;
    }

    return (len + padding);
}

/**
 * @brief  pkcs7解填充算法
 * @param  p: 需要解填充的数据指针
 * @param  len: 需要解填充的数据长度
 * @param  block_size: 按照多大的block进行填充,通常为16
 * @return 解填充后的数据长度
 * @author joseph
 * @date   2024.5.27
 */
static size_t pkcs7UnPadding(unsigned char *p, size_t len, uint8_t block_size)
{
    uint8_t unPadding  = 0;
    unPadding  = p[len - 1];
    int i = 0;

    if (unPadding > 16) {
        return -1;
    }

    for (i = 0; i < unPadding; i++) {
        if (p[len - 1 - i] != unPadding)
            return -1;
    }

    return (len - unPadding);
}

编写大小端转换代码

STM32中数据的保存方式为小端模式,但是在openssl中,默认使用的是大端模式,为了保证在使用相同的输入时,能够获取到相同的输出,因此需要进行大小端转换。

#define BLSWAP32(val) \
    ((val) = ((uint32_t)((((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
          (((uint32_t)(val) & (uint32_t)0x0000ff00U) <<  8) | \
          (((uint32_t)(val) & (uint32_t)0x00ff0000U) >>  8) | \
          (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24))))

编写aes模块密钥与模式配置代码

通过这个函数对aes模块进行密钥与算法模式进行配置

typedef enum {
  AES_ALGO_ECB,
  AES_ALGO_CBC,
} AES_Algorithm_t;

/**
 * @brief  aes模块密钥与模式配置代码
 * @param  key: aes密钥指针
 * @param  key_len: aes密钥长度
 * @param  mode: aes算法模式,ECB/CBC
 * @param  iv: 初始向量指针,如果为ECB时,入参NULL即可
 * @return 0:SUCCESS, <0: fail
 * @author joseph
 * @date   2024.5.27
 */
int aes_set_config(uint8_t *key, int key_len, AES_Algorithm_t mode, uint8_t *iv)
{
  int ret = -1;
  CRYP_ConfigTypeDef cryp_conf = {0};
  do {
    if (key_len != 32 || key == NULL) {
      printf("error: The key length only supports 32\n");
      break;
    }

    if (mode == CRYP_AES_CBC && iv == NULL) {
      printf("error: iv param is null\n");
      break;
    }

    for (int i = 0; i < key_len >> 2; i ++)
        BLSWAP32(((uint32_t*)key)[i]);

    if (HAL_CRYP_GetConfig(&hcryp, &cryp_conf) != HAL_OK) {
      printf("error: HAL_CRYP_GetConfig fail\n");
      break;
    }
    cryp_conf.Algorithm = (mode == AES_ALGO_ECB) ? CRYP_AES_ECB : CRYP_AES_CBC;
    cryp_conf.pKey = (uint32_t *)key;

    if (mode == AES_ALGO_CBC) {
      for (int i = 0; i < 4; i ++)
          BLSWAP32(((uint32_t*)iv)[i]);
      cryp_conf.pInitVect = (uint32_t *)iv;
    }

    if (HAL_CRYP_SetConfig(&hcryp, &cryp_conf) != HAL_OK) {
      printf("error: HAL_CRYP_SetConfig fail\n");
      break;
    }
    ret = 0;
  } while (0);
  return ret;
}

封装加解密接口

通过封装的这个接口,完成对数据的加密与解密
##### 注意:代码中的CRYPT_NUM_TIMES 时我进行多轮测试时使用的,正常进行加解密时,应该删除与CRYPT_NUM_TIMES有关的代码,或将CRYPT_NUM_TIMES设置为1。#####


typedef enum {
  AES_ENCRYPTO_MODE,
  AES_DECRYPTO_MODE,
} AES_Crypt_Mode_t;


#define CRYPT_NUM_TIMES 1   // 设置加解密测试轮数

/**
 * @brief  aes加解密接口
 * @param  mode: aes加解密模式,EN/DE
 * @param  in_buffer: 等待加解密的数据指针
 * @param  inlen: 输入的数据长度
 * @param  out_buffer: 保存加解密后数据的内存指针
 * @return 0:输出的数据长度, <0: fail
 * @author joseph
 * @date   2024.5.27
 */
int aes_crypt(AES_Crypt_Mode_t mode, unsigned char *in_buffer, int inlen, unsigned char *out_buffer)
{
  int ret = -1;
  int plain_len = 0;

  memmove(tmp_buffer, in_buffer, inlen);

  do
  {

    start = HAL_GetTick();
    for (i = 0; i < CRYPT_NUM_TIMES; i++)
    {
      memmove(in_buffer, tmp_buffer, inlen);

      if (mode == AES_ENCRYPTO_MODE) {
        plain_len = pkcs7Padding((uint8_t *)in_buffer, inlen, AES_BLOCK_SIZE);
        for (int i = 0; i < plain_len >> 2; i++)
          BLSWAP32(((uint32_t *)in_buffer)[i]);

        if (HAL_CRYP_Encrypt(&hcryp, (uint32_t *)in_buffer, plain_len >> 2, (uint32_t *)out_buffer, 0xff) != HAL_OK)
        {
          printf("error: HAL_CRYP_Encrypt fail\n");
          break;
        }

        for (int i = 0; i < plain_len >> 2; i++)
          BLSWAP32(((uint32_t *)out_buffer)[i]);
      } else {
        for (int i = 0; i < inlen >> 2; i++)
          BLSWAP32(((uint32_t *)in_buffer)[i]);
        if (HAL_CRYP_Decrypt(&hcryp, (uint32_t *)in_buffer, inlen >> 2, (uint32_t *)out_buffer, 0xff) != HAL_OK)
        {
          printf("error: HAL_CRYP_Decrypt fail\n");
          break;
        }

        for (int i = 0; i < inlen >> 2; i++)
          BLSWAP32(((uint32_t *)out_buffer)[i]);

        plain_len = pkcs7UnPadding((uint8_t*)out_buffer, inlen, AES_BLOCK_SIZE);
      }

    }
    end = HAL_GetTick();
    if (i != CRYPT_NUM_TIMES) {
      printf("[%d] error: CRYPT_NUM_TIMES i:%d fail\n", __LINE__, i);
      break;
    }

    interval = end - start;
    printf("%s %d times: %ld\n", mode == 0 ? "encrypto" : "decrypto", CRYPT_NUM_TIMES, interval);

    ret = plain_len;
  } while (0);

  return ret;
}

编写ecb测试代码


int aes_ecb_test(void)
{
  int ret = -1;
  int text_len = strlen(Text);
  int length = 0;

  do {
    memmove(AES_key, AES_key1, 32);
    aes_set_config(AES_key, 32, AES_ALGO_ECB, NULL);

    printf("==== aes_ecb_test 1 ==== \n");
    memset(plain, 0, sizeof(plain));
    memmove(plain, Text, text_len);

    length = aes_crypt(AES_ENCRYPTO_MODE, plain, text_len, cipher);
    if (length < 0) {
      printf("[%d] error: aes_crypt fail\n", __LINE__);
      break;
    }

    printf("encrypto len: %d\n", length);
    // show_hex(cipher, 64);

    memset(plain, 0, sizeof(plain));

    length = aes_crypt(AES_DECRYPTO_MODE, cipher, length, plain);
    if (length < 0) {
      printf("[%d] error: aes_crypt fail\n", __LINE__);
      break;
    }

    printf("decrypto len: %d\n", length);
    // printf("%.*s\n", 64, plain);

    if (text_len == length && memcmp(plain, Text, length) == 0) {
      printf("\naes_ecb_test success\n");
    } else {
      printf("\naes_ecb_test fail\n");
    }

    ret = 0;
  } while (0);

  return ret;
}

编写cbc测试代码


int aes_cbc_test(void)
{
  int ret = -1;
  int text_len = strlen(Text);
  uint16_t length = 0;

  do {
    memmove(AES_key, AES_key1, 32);
    memmove(aesiv, aesiv1, 16);
    aes_set_config(AES_key, 32, AES_ALGO_CBC, aesiv);

    printf("==== aes_cbc_test 1 ==== \n");
    memset(plain, 0, sizeof(plain));
    memmove(plain, Text, text_len);

    length = aes_crypt(AES_ENCRYPTO_MODE, plain, text_len, cipher);
    if (length < 0) {
      printf("[%d] error: aes_crypt fail\n", __LINE__);
      break;
    }

    printf("encrypto len: %d\n", length);
    // show_hex(cipher, 64);

    memset(plain, 0, sizeof(plain));

    length = aes_crypt(AES_DECRYPTO_MODE, cipher, length, plain);
    if (length < 0) {
      printf("[%d] error: aes_crypt fail\n", __LINE__);
      break;
    }

    printf("decrypto len: %d\n", length);
    // printf("%.*s\n", 64, plain);

    if (text_len == length && memcmp(plain, Text, length) == 0) {
      printf("\naes_cbc_test success\n");
    } else {
      printf("\naes_cbc_test fail\n");
    }

    ret = 0;
  } while (0);

  return ret;
}

创建密钥与待加密的数据

以下这些变量是在程序执行过程中需要使用的数据,其中明文数据约3.5k字符,用于测试加解密性能。


// 加解密的key
uint8_t AES_key1[33] = "12345678901234561234567890123456";
// cbc模式下需要使用的初始向量iv
uint8_t aesiv1[17] = "1234567890123456";

// 多轮加密时,需要传入的密钥内存
uint8_t AES_key[32] = {0};
uint8_t aesiv[16] = {0};

// 待加密的原始数据,约3.5K字符。
char Text1[] = " \
-----BEGIN PRIVATE KEY-----                                      \
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCsXDZ8s9ToFi+t \
+HE9KfJSPOYjGR/OxnAUNPxKWoQ6l5nCS9Uhazdl9hF6PDjy0mGE6ZFdW7c+Tsmg \
uTIMVY0BlOT6hRwfxoSLqjF6L99Nb906cOX5eGxEbOE0k9OFkKZw3KGiPpm007TN \
3IBwYRLoVLwnXHFfcsJ4w52GfwOyFAlc99Nv45/o4lzj3yYdBWBey1bLotoTcK1u \
J97iv6DFTb28GN/XR3qbSHNFJsxKtwoj8Rwj3aAq/4cVpH7uhkOOLjCclBdsWTlb \
fmuZJ4ISfHnMDtZjIEH3LAb8ILoGnytcqTd9nb4d0gYsKFsqAjrK4akDq85ZQQx7 \
At4jzY5+C0lwM89WxP0/saph6lsgdhjjS9P8I7dwJyFTaLfiaKIOYf31w9mHrpnS \
yIRGg+Enw+osow6cQ49m6klCnvs46bJ9ZaSg1wqKkrp8VSvBs1tto749NS5YcTKT \
+oQwpqHWpbrEr78oTCYRrf/8ggk0LHP/PRj6GNJYMX62BafInz6RnwWUb6n+BoF8 \
ioXZ17aa0mBAx+REfjwxk1S+5EblhU1a92V5x1YwVUTfnN19FVmXJpv/o3nx6cwk \
c8j0xMRMNPHVJIOGNcgYmlzpRGMC6DYP69Cj64k9uLmESVCRuyQzJjZbANqDNvFa \
0cjpbKkRDOtzxzjjivawPc6okW7W7QIDAQABAoICAADp3aKjI/D1ikmVRE4Y5nYc \
aPL/Y3MgnbJ1uJO+4cmI23PYHAzdgkFx4KaNInK1UFJKzunJ+bpyUJmx+ruSboJA \
bEcggDMEWCFb8n+dgcT78d8pEVAeiqKl7DrLChKcFeAJsQsNUJo+Zd624mes73gT \
oS7P8Gfkdi2Niif8jRGtfMuAtQyKjhmiiO/u0zT2Bx6pgNANWdgerSAS10+n7Vtu \
W2kEBrxETDhrej4SOsllKa3PhI6X0nrcbyQSS+mllvWlLJl/2yej7kgcE8hY9J3k \
UtynFp9gl5szIS6iNOo0f5+NUcQwLX1tZp5ClVrUAKAzFdkHoii18lZYSVT79kkD \
yN66XwwrIRUeZkRAy+gI2IxtsA1T0rexN/bRV/ZRLyW5GVlMnd4z7h8OGj+WcMjh \
PCniGxu03wp2rulRSYPs0/krZ3+mKYNtzkv/2fKJZKlqA8qvsFKWxcODMHtFoglf \
ea6rHoCRckRzIB30I8ro7b+XXZN3B9hgHQuXtwEUq6jnnF9l9x+eEQC/qf2wtxAK \
EO3Dd/fRUbbPEr8gvRBNdbEEQRxMCaKBGHmqu+5RELhsnrgGKmHnbricxouVIS54 \
1MS1DakaqZRJkz//5IYR6lP08kDGqWIbCo5B9vlrJtg3iwHf86W8anBHMZC1PtcC \
lh1anrVvt3V4pr2T3xrPAoIBAQDqyOGddJL7Rx5Wd2RuIXA+8WmIFqBzwsRyS9oN \
Ns1IP9etANzt5Tmhs5yxb7RsI5olwOVtdgVpieUPRkUgrmt1bkSxRPKtZ7k753aV \
rgqNaaOrZGEYwW7jC5xPmQAkqJthhIgTWjJh7N5Sby5nvLsSD4dhp6AfGBN6kEzs \
KH9IlDdO+fuCPgCBGEZnkKIuOM/NFRO/VEJpGRuaGqPMZhbmDKkilP3yfSezqDuT \
3Put+0XsfPzucozDfe/07O99Fwi/zQyI5Wz5ZSICnmkXH7HDbb4jH/VP8rO6HhCf \
z48Hlk3xAY9aD13PSmaJauqwpu2RPsvkse1ZdhZDKeyfiKF7AoIBAQC7706o1us+ \
p+RbY5JqruO5b3+yb0c/sGHX77c/qSFWQ1QOy9iVtmzWR9+yajzUqa5zwIm1awit \
/PFlw444ClESAV4Qy47TwwU4SIGBn2+5g0bQI2/x/TYG+EYxKUiIlvGcZlnrz6/H \
z60y0usTzNTNDKVcjnt7lBEM2XcEGwxNbwWfRzwHGGLFOurJmuKZF1JE9js3nLHN \
QbwPI1JGAnfMKTvLWa9CV3Mq6xhTazoTe1S2ubnG/wa9getgrziiqKlPshmmjzCi \
YK8YiFRF72E+mY/bl5DSiN2X/ltuepGjTe0iZ9Bd64puhmI1Nyoy1vEAME5Fw7je \
CTpaFgKCKbi3AoIBACLpResU13o3xAIVdMCPhlJFsWyD+M3dyzo3ny/R00qH+7kE \
5NUW/a/WtlkIBCsETDqK6VKSdxGPaJkR2NuYM/BdOiel2fQA9WE79L0jCPyoFac5 \
oNp+gM+P/Wk0lfndfGVOwLEn+0/mWdSmJZ9VR/fSiU3zD/MvsE3MQTPofay8JVFA \
CK8AKzEG/AkQT51R40xacvpDPDDGg/0xMuQE1ijU/x1eTDiPdaTYQiulc2MWdvpI \
R4/pRpcXFeQ0ixPtpeZnRhLhEogvCpSbG4NNujAWFGzCpsaBj0oAiHZK9biqF+Lb \
WYaJvGhDZuXOGSG1YKP1U3opHuLrlTnddQrv1RsCggEAKsU8rpoy8ZB+HPpdQSBK \
PVKNykse+PSoX99zYe6Y4qvx/mgQA4p/3IiA9XbOH0v6oudHr90LHaW6PoGx5Tkb \
2DAtez8IY1M35eZCawChCaRBwm6+NGF/ITjxqJCPrF5F4GU+w7cBd0ThUvbDfz8X \
kw70t0rJ+YbqFnWLa4jIVPsWWXh5xdeb6u0MsBMqzNKM65rqQS7NHDyAkyVjvQEk \
yHb937qqczu5vyO/5oQ5tGNWFTvRduNlYk2mBtv51LLzzWpoAgsGc33ze27TVxMy \
m2+RWNV2pSN24veFUXBdor/CXxknR6iqWZsF0LycQvO952AXADOZ6BZLjGMD8SGT \
owKCAQBSY8O/L6/vtICdfyX24S1FTxrQdQVCk03a3LcRnO9Loaxuvawy6lcjicDE \
YAP51EYhOKW9akxBRSEB2soRs92rnuBS522re6k/c8GUc+k3tkj5Go8v8Dqg+biW \
D5Zu2x0rXJ/caO6u0le6UrI+IOScuIPJ6tuu9OhV9sr5zJzAfIUupRpckD6TP7/X \
T6fG4lNteg8ftRfRvYd6g/jEmh/ECHvc5YDdXihDGv028BFj5fWY/iZEjMGektRf \
tPyMMOI4+t93oni0Go8OkF2FIYsquWMEh4IILMm27mVZk7A+FLW+hK/FXec3dogO \
7IbiS/98RTtjVN4NIQJ9Jc8hUhkW                                     \
-----END PRIVATE KEY-----                                        \
";

char *Text = Text1;

// 加解密过程中,需要的内存
uint8_t plain[4096 + 16] = {0};
uint8_t cipher[4096 + 16] = {0};
uint8_t tmp_buffer[4096 + 16] = {0};

// 计算加解密时间所需要的变量
int i = 0;
uint32_t start, end, interval;

调用测试接口对aes模块进行测试

到这里,测试需要的代码已经全部编写完成,只需要在while循环之前调用对应的测试接口,就可以完成对aes模块的性能测试

** 注意: 需要修改上文曾提到的宏CRYPT_NUM_TIMES,通过修改这个宏的值,来设置加密的轮数。这里我已经将其设置为1000

// 分别测试ecb与cbc加密
  aes_ecb_test();
  aes_cbc_test();
 
  while (1)
  {
  	// *****************

测试结果

编译代码,查看是否有编译报错,编译成功后,将代码烧录到单片机,通过串口调试工具,可查看到结果。
数据显示:

加密模式单次计算字节计算轮数总计算字节所用时间(ms)每KB耗时(ms)
ECB加密339210003312.5KB60611.83
ECB解密338110003301.8KB60391.83
CBC加密339210003312.5KB60631.83
CBC解密338110003301.8KB60411.83

在这里插入图片描述
以上就是本次测试的所有内容,结果仅供参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1811541.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ITIL简介重要组成部分

ITIL简介&重要组成部分 ITIL&#xff08;Information Technology Infrastructure Library&#xff09;是一个IT服务管理的最佳实践框架&#xff0c;通过服务战略、服务设计、服务过渡、服务运营和持续服务改进五个核心模块&#xff0c;帮助组织优化IT服务流程&#xff0c;…

嘴尚绝卤味:健康美味,引领卤味新风尚

在快节奏的现代生活中&#xff0c;人们对于美食的追求从未停歇。卤味作为中国传统美食的代表之一&#xff0c;以其独特的口感和丰富的营养&#xff0c;深受广大消费者的喜爱。而在众多卤味品牌中&#xff0c;嘴尚绝卤味凭借其健康、美味的特色&#xff0c;成为了市场上的佼佼者…

Pytorch解决 多元回归 问题的算法

Pytorch解决 多元回归 问题的算法 回归是一种基本的统计建模技术&#xff0c;用于建立因变量与一个或多个自变量之间的关系。 我们将使用 PyTorch&#xff08;一种流行的深度学习框架&#xff09;来开发和训练线性回归模型。 二元回归的简单示例 训练数据集&#xff08;可获取&…

分离式光电液位传感器有哪些特点?

分离式光电液位传感器是一种先进的液位检测技术&#xff0c;在科学技术的不断推进下得到了广泛应用。相比传统的液位传感器&#xff0c;分离式光电液位传感器具有许多独特的特点。 传感器采用了先进的光学技术&#xff0c;将传感器装在需要检测液位的位置&#xff0c;并采用了…

非GIS专业,真的不适合WebGIS开发吗?

到底是哪些人在新中地特训营学GIS开发&#xff1f; 很多同学对GIS开发的认知还停留在GIS专业的学生才能学GIS开发&#xff0c;然而&#xff0c;在新中地教育&#xff0c;非GIS专业的学生几乎占一半。 除了GIS专业&#xff0c;还有测绘、遥感等跟GIS差别不大的专业学生选择来学…

面试官:你讲下接口防重放如何处理?

前言 我们的API接口都是提供给第三方服务/客户端调用&#xff0c;所有请求地址以及请求参数都是暴露给用户的。 我们每次请求一个HTTP请求&#xff0c;用户都可以通过F12,或者抓包工具fd看到请求的URL链接&#xff0c;然后copy出来。这样是非常不安全的&#xff0c;有人可能会…

鸿蒙轻内核A核源码分析系列二 数据结构-位图操作

在进一步分析之前&#xff0c;本文我们先来熟悉下OpenHarmony鸿蒙轻内核提供的位操作模块&#xff0c;在互斥锁等模块对位操作有使用。位操作是指对二进制数的bit位进行操作。程序可以设置某一变量为状态字&#xff0c;状态字中的每一bit位&#xff08;标志位&#xff09;可以具…

Kubernetes——HPA自动伸缩机制

目录 前言 一、概念 1.定义 2.核心概念 3.工作原理 4.HPA的配置关键参数 5.关键组件 5.1HPA控制器&#xff08;HPA Controller&#xff09; 5.2Metrics Server 5.3自定义指标适配器&#xff08;Custom Metrics Adapter&#xff09; 5.4Deployment/ReplicaSet 5.5Po…

文件二维码能快速生成吗?多种类型文件生成二维码的方法

现在将文件做成二维码是一种很常用形式&#xff0c;通过二维码来存储多个文件&#xff0c;在手机上扫码查看内容&#xff0c;对于文件的安全性和用户体验都有很好的提升。用户无需下载文件&#xff0c;扫码就可以快速在线阅读或者下载文件内容&#xff0c;有利于文件的快速分享…

2024年智能制造行业CRM研究(附需求清单、市场格局、选型建议)

在国家大力鼓励智能制造行业与数字化转型这个大背景下&#xff0c;我们选择了2024年智能制造行业数字化的几个关键趋势做深入解读&#xff0c;并对智能制造行业核心的数字化系统CRM进行了全面评估与排名。本文不仅提供了详尽的需求清单&#xff0c;帮助企业明确自身对CRM系统的…

不定时更新 解决无法访问GitHub github.com 打不开 访问加速

1 修改hosts Windows 10为例,‪文件C:\Windows\System32\drivers\etc\hosts 管理员打开记事本来修改 文件-打开-“C:\Windows\System32\drivers\etc\hosts” 20.205.243.168 api.github.com 185.199.108.154 github.githubassets.com 185.199.108.133 raw.githubusercontent.…

1.ei论文会被scopus检索吗文被其检索吗?

ei论文会被scopus检索吗 scopus数据库能检索的专业范围是比较广泛的&#xff0c;涵盖了医学&#xff0c;地球环境科学&#xff0c;化学&#xff0c;数学&#xff0c;工程学&#xff0c;物理&#xff0c;生物科学等领域&#xff0c;也收录了很多会议论文&#xff0c;那么ei论文…

JwtAccessConverterJwtTokenStorejdbc建表结构

文章目录 JWT实现MacTestMacSigner Rsa生成jks证书需要先安装opensslkeytool生成jks (Java Key Store) 文件测试密钥 JwtTokenStoreInMemoryTokenStore&RedisTokenStore&JdbcTokenStore&JwtTokenStore图解JwtTokenStore详解 jdbc实现表结构说明1oauth_client_detai…

Win10系统自带输入法英文变大的问题

现在习惯使用Windows自带的五笔输入法了&#xff0c;但一直以来总会遇到输入时突然英文字母变大了&#xff0c;相隔空间也变大了的情况。 &#xff41;&#xff53;&#xff44;&#xff46;&#xff47;&#xff48;&#xff4b;&#xff4c; asdfghkl 后来知道这是输入法变…

如何在Linux虚拟机服务器上配置和部署Java项目?

在Linux虚拟机上配置和部署Java项目&#xff0c;通常涉及以下步骤&#xff1a; 1. 准备Linux虚拟机 选择合适的Linux发行版 &#xff1a;根据项目需求和个人熟悉程度&#xff0c;选择如Ubuntu LTS、CentOS Stream或Debian等发行版。 安装虚拟机软件 &#xff1a;在宿主机&#…

css图片适配,不随屏幕的大小变化

.carimg {width: 100%;height: 100%;max-width: 100%;max-height: 100%;object-fit: cover; } <img class"carimg" :src"item.imageUrl" alt"" /> 效果&#xff1a; 全屏时 屏幕变小时

985找工作都这么难了吗

经历如下 也不知道自己适合干啥 好想找份实习入门啊

无人机RTMP推流EasyDSS直播平台推流成功,不显示直播按钮是什么原因?

互联网视频云平台/视频点播直播/视频推拉流EasyDSS支持HTTP、HLS、RTMP等播出协议&#xff0c;并且兼容多终端&#xff0c;如Windows、Android、iOS、Mac等。为了便于用户集成与二次开发&#xff0c;我们也提供了API接口供用户调用和集成。在无人机场景上&#xff0c;可以通过E…

Allegro铺铜以及分割操作

Allegro铺铜以及分割操作 一、铺铜全局设置 点击Shape–>Global Dynamic Shape Parameters&#xff0c;在Shape fill中选择Smooth&#xff0c;其他不用管&#xff0c;这个是在铺铜的时候自动避让不同网络&#xff0c;在Void controls中一般填写如下参数&#xff0c;即避让…

cocos creator3.7版本拖拽事件处理

前言&#xff1a;网上能找到的资料都太落后了&#xff0c;导致哥们用AI去写&#xff0c;全是瞎B写&#xff0c;版本都不对。贴点实际有用的。别老捣鼓你那破convertToNodeSpaceAR或者convertToNodeSpace了。 核心代码 touch.getDeltaX() touch.getDeltaY() 在cocoscreator3…