查看: 805|回复: 0

[评测分享] 【STM32H735-DK 测评】③加密测试

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2024-3-21 00:18:59 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 eefocus_3880118 于 2024-3-24 14:07 编辑

    一、前言  
      STM32H735在安全性上的能力也是很强的,在芯片中有个加密和哈希模块,用于各种加密、哈希计算,在有了高主频和硬件模块的支持,使得加解密和哈希计算在这款芯片上速度可以很快。
      那么具体支持哪些加解密与哈希计算呢?那就要看看技术手册的原文
    1.png

    可以看到我们常用的DES/TDES、AES各种算法各种秘钥长度均支持,SHA-1、SHA-2、MD5、HMAC均支持。并且支持DMA。


    二、STM32CubeExpansion_Crypto介绍

      我们平常想要实现加解密,最快的方法就是找一个加解密库,移植过去,然后调用接口,我平常使用mbedtls,这是一个开源的加解密库,但他是纯软件计算,需要占用CPU,速度肯定是比不上结合硬件加密模块的加密算法的。那么在ST的芯片上如果你想使用芯片的硬件加密模块,应该怎么办呢?

      这个问题的答案就是今天本文的主角了,ST的加密库“STM32CubeExpansion_Crypto”,这个加密库ST一直在维护升级,现在已经更新到V4了,还记得我上一次用它还是在2021年,有截图为证

    2.png

    那个时候这个库还不是点击就可以下载,要先写申请,通过后才可以下载,现在进入网址就可以直接下载了(前提是你得注册并登陆,或者以游客身份填写信息下载),网址如下:https://www.st.com/content/st_com/zh/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-expansion-packages/x-cube-cryptolib.html

    3.png

    4.png

    5.png

      这个加密库功能非常强大,几乎涵盖了我们平常能使用到的绝大部分加解密算法,只要你是使用STM32的MCU,你就可以免费试用,真得很

      关于支持哪些芯片,在网页中有写到,我看了一下几乎是涵盖STM32全系MCU了,极个别系列没有,可能是太新了还没支持上,可能是ST没写上,例如H5,网页上没有,但是在加密库的更新说明中是写了,这令我有点困惑

    6.png

    三.实战

      好了话不多说,我们开始实战一下,把这个加密库加入到我们的工程中去使用

    3.1 加密库的下载及讲解
      首先我们要把加密库下载下来,在网页中点击“获取最新版本”,然后再弹出的引导页面选择登陆/注册账号再登陆/以访客身份下载


    下载好后我们把压缩包解压,文件夹内容如下

    7.png

    “_htmresc”是html文件需要使用的资源文件

    8.png

    “Drivers”中存放了各个芯片的HAL库文件以及各个开发板的BSP文件,还有CMSIS

    9.png


    “Middlewares”中存放的就是我们待会儿要使用的加密库文件

    10.png

    “Projects”中存放的是ST基于各个系列的开发板做个各种加解密demo工程及代码,如果你手上恰好有以下开发板的话,就可以直接跑demo了(可以H735-DK不在其中,所以待会儿我要来移植到自己创建的工程中)

    11.png
    3.2 CUBEMX配置并创建工程
    接下来开始创建一个新的工程
    打开cubemx,我们选择从选择MCU开始工程
    12.png

    13.png

    14.png

    配置开启SWD调试

    15.png

    选择高速时钟源为晶振

    16.png

    开启串口3(用于待会儿串口打印输出各种信息)

    串口的引脚需要重新定义一下,CUBEMX中默认的串口3引脚是PC10、PC11,需要手动去右侧的芯片引脚图上重新定义真正使用的引脚(PD8/PD9),这点在上一篇《CoreMark测试评分》中已经说到了

    17.png

    开启CRC,这个一定要开启,加解密库需要使用它

    18.png

    配置时钟树,还是把频率拉满

    19.png

    起个名字,生成Keil工程

    20.png

    3.3 加密库移植及Keil库配置

    把ST加密库复制到工程中

    21.png

    打开Keil


    切换AC6、开启MicroLib

    31.png

    重定向printf

    32.png

    1. #include "stdio.h"
    复制代码
    1. int fputc(int ch, FILE *f)
    2. {
    3.   HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xffff);
    4.   return ch;
    5. }
    复制代码


    开始移植加密库,新增一个组,添加加密库的lib和接口文件

    22.png

    cmox_low_level_template.c文件在STM32_Cryptographic\interface中

    .a文件在STM32_Cryptographic\lib中,H735是使用的M7核,所以我们选择M7的那个文件。添加时默认的文件类型为.c,需要改为.a或者所有文件,才可以看到

    23.png

    添加完成

    24.png

    然后我们需要对这两个文件做一下处理

    cmox_low_level_template.c要去除只读属性,否则我们无法修改其中内容

    25.png

    修改后文件角上的钥匙就不见了

    26.png

    .a文件:右键点击第一个选项,然后把文件类型修改为Library file。不然编译时会有报错

    28.png

    29.png

    然后修改cmox_low_level_template.c文件内容,这里面就只有2个接口,一个是初始化,另一个是去初始化。

    在初始化中需要把CRC进行初始化并启用,因为我们之前在cubemx中已经开启了CRC,所以在main函数中就已经有了CRC的初始化,因此这里我们就不需要做这个动作,直接把图中这两句话注释掉。

    去初始化接口中本来是用于关闭CRC的(如果你程序的其他部分不再需要使用CRC的话),我们这儿就也不去动他了

    因为没有调用其他的接口,所以头文件部分也不需要去补充hal库的名称,直接让他注释掉就好了

    30.png

    最后需要添加一下加密库头文件路径

    33.png

    到此为止,整个库就移植好了。


    这个库使用起来也是非常的简单,只要调用一下初始化,就可以直接调用你想要的加解密接口函数即可


    初始化函数如下

    添加头文件

    34.png

    1. #include "cmox_crypto.h"
    复制代码
    加密库初始化

    35.png

    1.   if (cmox_initialize(NULL) != CMOX_INIT_SUCCESS)
    2.   {
    3.     printf("Crypto lib init fail\r\n");
    4.   }
    5.   else
    6.   {
    7.     printf("Crypto lib init success\r\n");
    8.   }
    复制代码


    如果你不清楚各个加解密接口如何使用,在加密库压缩包中有很多的demo,虽然你手上可能没有一样的板卡可以直接运行代码,但是通过阅读代码并查看对应的注释,也可以侧面了解各个接口是如何使用的


    3.4 AES CBC加解密测试

    这部分我会测试一下使用AES ECB模式,使用128Bit秘钥和256bit秘钥对数据的加解密功能。

    关于数据填充,由于AES从原理上讲是需要按16字节的整数倍进行计算的,从而诞生了很多填充方式,例如PCKS7、ZERO等。这些填充都是需要我们自己去填充好再去进行加密的(真心希望ST后续的加密库可以提供填充方式的参数,这样我就不需要自己在写一个填充函数了),我这里偷个懒,就直接把数据写成16字节的整数倍,这样就不需要填充了


    定义加解密所需的变量

    1. /* 128bit秘钥 */
    2. const uint8_t Key_128bit[] =
    3. {
    4.   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    5. };

    6. /* 256bit秘钥 */
    7. const uint8_t Key_256bit[] =
    8. {
    9.   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    10.   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
    11. };

    12. /* 128bit秘钥加密前的明文 */
    13. const uint8_t Plaintext[] =
    14. {
    15.   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    16. };

    17. /* 128bit秘钥加密后的秘文 */
    18. const uint8_t Ciphertext_128bitKey[] =
    19. {
    20.   0x27, 0x9F, 0xB7, 0x4A, 0x75, 0x72, 0x13, 0x5E, 0x8F, 0x9B, 0x8E, 0xF6, 0xD1, 0xEE, 0xE0, 0x03,
    21. };

    22. /* 256bit秘钥加密后的秘文 */
    23. const uint8_t Ciphertext_256bitKey[] =
    24. {
    25.   0x06, 0x39, 0xE8, 0x7D, 0x0E, 0x36, 0xC0, 0x1C, 0xAF, 0x88, 0x1B, 0x0B, 0x58, 0xF5, 0x00, 0x97,
    26. };

    27. /* 计算得到的秘文 */
    28. uint8_t Computed_Ciphertext[50];

    29. /* 计算得到的明文 */
    30. uint8_t Computed_Plaintext[50];
    复制代码
    AES ECB加密测试函数

    1. void aes_ecb_encrypt_test(void)
    2. {
    3.   cmox_cipher_retval_t ret;
    4.   size_t computed_size;

    5. /******************************************************************************/
    6.   /* AES 128bit 加密测试 */
    7.   printf("AES ECB 128Bit encrypt test\r\n");
    8.   ret = cmox_cipher_encrypt(CMOX_AES_ECB_ENC_ALGO,
    9.                                Plaintext, sizeof(Plaintext),
    10.                                Key_128bit, sizeof(Key_128bit),
    11.                                NULL, 0,
    12.                                Computed_Ciphertext, &computed_size);

    13.   /* 加密是否成功 */
    14.   if (ret != CMOX_CIPHER_SUCCESS)
    15.   {
    16.     printf("encrypt fail\r\n");
    17.     return;
    18.   }

    19.   /* 打印加密结果 */
    20.   printf("encrypt success\r\n");

    21.   printf("encrypt data = ");
    22.   for(int i = 0; i < computed_size; i++)  
    23.   {
    24.     printf("%02X ", Computed_Ciphertext[i]);
    25.   }
    26.   printf("\r\n");

    27. /******************************************************************************/
    28.   /* AES 256bit 加密测试 */
    29.   printf("AES ECB 256Bit encrypt test\r\n");
    30.   ret = cmox_cipher_encrypt(CMOX_AES_ECB_ENC_ALGO,
    31.                                Plaintext, sizeof(Plaintext),
    32.                                Key_256bit, sizeof(Key_256bit),
    33.                                NULL, 0,
    34.                                Computed_Ciphertext, &computed_size);

    35.   /* 加密是否成功 */
    36.   if (ret != CMOX_CIPHER_SUCCESS)
    37.   {
    38.     printf("encrypt fail\r\n");
    39.     return;
    40.   }

    41.   /* 打印加密结果 */
    42.   printf("encrypt success\r\n");

    43.   printf("encrypt data = ");
    44.   for(int i = 0; i < computed_size; i++)  
    45.   {
    46.     printf("%02X ", Computed_Ciphertext[i]);
    47.   }
    48.   printf("\r\n");
    49. }
    复制代码
    AES ECB解密测试函数

    1. void aes_ecb_dencrypt_test(void)
    2. {
    3.   cmox_cipher_retval_t ret;
    4.   size_t computed_size;

    5. /******************************************************************************/
    6.   /* AES 128bit 解密测试 */
    7.   printf("AES ECB 128Bit dencrypt test\r\n");
    8.   ret = cmox_cipher_decrypt(CMOX_AES_ECB_DEC_ALGO,
    9.                                Ciphertext_128bitKey, sizeof(Ciphertext_128bitKey),
    10.                                Key_128bit, sizeof(Key_128bit),
    11.                                NULL, 0,
    12.                                Computed_Plaintext, &computed_size);

    13.   /* 解密是否成功 */
    14.   if (ret != CMOX_CIPHER_SUCCESS)
    15.   {
    16.     printf("dencrypt fail\r\n");
    17.     return;
    18.   }


    19.   /* 打印解密结果 */
    20.   printf("dencrypt success\r\n");
    21.   printf("dencrypt data = ");
    22.   for(int i = 0; i < computed_size; i++)  
    23.   {
    24.     printf("%02x ", Computed_Plaintext[i]);
    25.   }
    26.   printf("\r\n");

    27. /******************************************************************************/
    28.   /* AES 256bit 解密测试 */
    29.   printf("AES ECB 256Bit dencrypt test\r\n");
    30.   ret = cmox_cipher_decrypt(CMOX_AES_ECB_DEC_ALGO,
    31.                                Ciphertext_256bitKey, sizeof(Ciphertext_256bitKey),
    32.                                Key_256bit, sizeof(Key_256bit),
    33.                                NULL, 0,
    34.                                Computed_Plaintext, &computed_size);

    35.   /* 解密是否成功 */
    36.   if (ret != CMOX_CIPHER_SUCCESS)
    37.   {
    38.     printf("dencrypt fail\r\n");
    39.     return;
    40.   }


    41.   /* 打印解密结果 */
    42.   printf("dencrypt success\r\n");
    43.   printf("dencrypt data = ");
    44.   for(int i = 0; i < computed_size; i++)  
    45.   {
    46.     printf("%02x ", Computed_Plaintext[i]);
    47.   }
    48.   printf("\r\n");

    49. }
    复制代码
    把他们放入main运行一下看看

    36.png


    运行结果

    37.png

    两种秘钥的加解密结果都正确,和我用在线工具计算的一致

    128bit秘钥加密结果

    AES ECB 128加密.png

    256bit秘钥加密结果

    AES ECB 256加密.png

    总结一下,AES使用的加解密接口分别是cmox_cipher_encrypt、cmox_cipher_decrypt。

    他们的入参、返回值、注释如下

    1. /**
    2.   * @brief Encrypt or decrypt a message using a symmetric cipher
    3.   *
    4.   * @param P_algo Identifier of the cipher algorithm to use for the computation.
    5.   *               This parameter can be one of the following:
    6.   *               @arg CMOX_AESFAST_ECB_ENC_ALGO
    7.   *               @arg CMOX_AESFAST_CBC_ENC_ALGO
    8.   *               @arg CMOX_AESFAST_CTR_ENC_ALGO
    9.   *               @arg CMOX_AESFAST_CFB_ENC_ALGO
    10.   *               @arg CMOX_AESFAST_OFB_ENC_ALGO
    11.   *               @arg CMOX_AESFAST_XTS_ENC_ALGO
    12.   *               @arg CMOX_AESSMALL_ECB_ENC_ALGO
    13.   *               @arg CMOX_AESSMALL_CBC_ENC_ALGO
    14.   *               @arg CMOX_AESSMALL_CTR_ENC_ALGO
    15.   *               @arg CMOX_AESSMALL_CFB_ENC_ALGO
    16.   *               @arg CMOX_AESSMALL_OFB_ENC_ALGO
    17.   *               @arg CMOX_AESSMALL_XTS_ENC_ALGO
    18.   *               @arg CMOX_AESSMALL_KEYWRAP_ENC_ALGO
    19.   *               @arg CMOX_SM4_ECB_ENC_ALGO
    20.   *               @arg CMOX_SM4_CBC_ENC_ALGO
    21.   *               @arg CMOX_SM4_CTR_ENC_ALGO
    22.   *               @arg CMOX_SM4_CFB_ENC_ALGO
    23.   *               @arg CMOX_SM4_OFB_ENC_ALGO
    24.   * @param P_pInput Buffer of bytes containing the data to encrypt or decrypt
    25.   * @param P_inputLen Length in bytes of the data to encrypt or decrypt
    26.   * @param P_pKey Buffer of bytes containing the key
    27.   * @param P_keyLen Length in bytes of the key
    28.   * @param P_pIv Buffer of bytes containing the IV/nonce
    29.   * @param P_ivLen  Length in bytes of the key
    30.   * @param P_pOutput Buffer of bytes where there will be stored the encrypted or
    31.   *                  decrypted data
    32.   * @param P_pOutputLen Number of bytes that have been processed by the function.
    33.   *        It is an optional parameter and can be set to NULL if not needed.
    34.   * @return cmox_cipher_retval_t Cipher return value
    35.   * @note This single call function cannot be used for AEAD ciphers
    36.   */
    37. cmox_cipher_retval_t cmox_cipher_encrypt(cmox_cipher_algo_t P_algo,
    38.                                          const uint8_t *P_pInput,
    39.                                          size_t P_inputLen,
    40.                                          const uint8_t *P_pKey,
    41.                                          cmox_cipher_keyLen_t P_keyLen,
    42.                                          const uint8_t *P_pIv,
    43.                                          size_t P_ivLen,
    44.                                          uint8_t *P_pOutput,
    45.                                          size_t *P_pOutputLen);
    复制代码
    1. /**
    2.   * @brief Decrypt a message using a symmetric cipher
    3.   *
    4.   * @param P_algo Identifier of the cipher algorithm to use for the computation.
    5.   *               This parameter can be one of the following:
    6.   *               @arg CMOX_AESFAST_ECB_DEC_ALGO
    7.   *               @arg CMOX_AESFAST_CBC_DEC_ALGO
    8.   *               @arg CMOX_AESFAST_CTR_DEC_ALGO
    9.   *               @arg CMOX_AESFAST_CFB_DEC_ALGO
    10.   *               @arg CMOX_AESFAST_OFB_DEC_ALGO
    11.   *               @arg CMOX_AESFAST_XTS_DEC_ALGO
    12.   *               @arg CMOX_AESFAST_KEYWRAP_DEC_ALGO
    13.   *               @arg CMOX_AESSMALL_ECB_DEC_ALGO
    14.   *               @arg CMOX_AESSMALL_CBC_DEC_ALGO
    15.   *               @arg CMOX_AESSMALL_CTR_DEC_ALGO
    16.   *               @arg CMOX_AESSMALL_CFB_DEC_ALGO
    17.   *               @arg CMOX_AESSMALL_OFB_DEC_ALGO
    18.   *               @arg CMOX_AESSMALL_XTS_DEC_ALGO
    19.   *               @arg CMOX_AESSMALL_KEYWRAP_DEC_ALGO
    20.   *               @arg CMOX_SM4_ECB_DEC_ALGO
    21.   *               @arg CMOX_SM4_CBC_DEC_ALGO
    22.   *               @arg CMOX_SM4_CTR_DEC_ALGO
    23.   *               @arg CMOX_SM4_CFB_DEC_ALGO
    24.   *               @arg CMOX_SM4_OFB_DEC_ALGO
    25.   * @param P_pInput Buffer of bytes containing the data to encrypt or decrypt
    26.   * @param P_inputLen Length in bytes of the data to encrypt or decrypt
    27.   * @param P_pKey Buffer of bytes containing the key
    28.   * @param P_keyLen Length in bytes of the key
    29.   * @param P_pIv Buffer of bytes containing the IV/nonce
    30.   * @param P_ivLen  Length in bytes of the key
    31.   * @param P_pOutput Buffer of bytes where there will be stored the decrypted
    32.   *                  data.
    33.   * @param P_pOutputLen Number of bytes that have been processed by the function.
    34.   *        It is an optional parameter and can be set to NULL if not needed.
    35.   * @return cmox_cipher_retval_t Cipher return value
    36.   * @note This single call function cannot be used for AEAD ciphers
    37.   */
    38. cmox_cipher_retval_t cmox_cipher_decrypt(cmox_cipher_algo_t P_algo,
    39.                                          const uint8_t *P_pInput,
    40.                                          size_t P_inputLen,
    41.                                          const uint8_t *P_pKey,
    42.                                          cmox_cipher_keyLen_t P_keyLen,
    43.                                          const uint8_t *P_pIv,
    44.                                          size_t P_ivLen,
    45.                                          uint8_t *P_pOutput,
    46.                                          size_t *P_pOutputLen);
    复制代码
    从注释可以看到,这两个函数不光可以给AES用,还可以给SM4用


    简单解释一下各个入参,以加密接口为例,解密接口类似

    P_algo:需要使用的加密类型,具体可以使用那些枚举,可以看注释

    P_pInput:需要加密的内容(完成填充后的数据)

    P_inputLen:需要加密的数据的长度(这个长度是已经完成填充后的数据的长度,我试过不填充,且长度不是16的整数倍,加密会返回失败)

    P_pKey:秘钥

    P_keyLen:秘钥的长度

    P_pIv:IV的值(如果你的加密算法不需要使用IV,例如ECB,就填NULL)

    P_ivLen:IV的长度(如果你的加密算法不需要使用IV,例如ECB,就填0)

    P_pOutput:加密得到的数据

    P_pOutputLen:加密得到的数据的长度

    3.5 哈希SHA1计算测试
    这里测试一下SHA1计算
    用于哈希计算的原始数据就借用之前AES加密用的明文
    用于测试的变量
    1. /* 计算得到的SHA1结果 */
    2. uint8_t Computed_hash[50];
    复制代码

    测试函数:
    1. void hash_sha1_test(void)
    2. {
    3.   cmox_hash_retval_t ret;
    4.   size_t computed_size;

    5.   ret = cmox_hash_compute(CMOX_SHA1_ALGO,
    6.                              Plaintext, sizeof(Plaintext),
    7.                              Computed_hash,
    8.                              CMOX_SHA1_SIZE,
    9.                              &computed_size);

    10.   if (ret != CMOX_HASH_SUCCESS)
    11.   {
    12.     printf("hash compute fail\r\n");
    13.     return;
    14.   }

    15.   /* 打印哈希计算结果 */
    16.   printf("hash compute success\r\n");

    17.   printf("hash compute result data = ");
    18.   for(int i = 0; i < computed_size; i++)  
    19.   {
    20.     printf("%02X ", Computed_hash[i]);
    21.   }
    22.   printf("\r\n");

    23. }
    复制代码
    38.png


    测试结果

    39.png

    在线计算工具的计算结果

    40.png


    结果一致,测试成功


    总结一下,哈希计算使用的接口为cmox_hash_compute。
    他的入参、返回值、注释如下

    1. /**
    2.   * @brief Compute the digest of a message using a hash algorithm
    3.   *
    4.   * @param P_algo Identifier of the hash algorithm to use for the computation.
    5.   *               This parameter can be one of the following:
    6.   *               @arg CMOX_SHA1_ALGO
    7.   *               @arg CMOX_SHA224_ALGO
    8.   *               @arg CMOX_SHA256_ALGO
    9.   *               @arg CMOX_SHA384_ALGO
    10.   *               @arg CMOX_SHA512_ALGO
    11.   *               @arg CMOX_SHA512_224_ALGO
    12.   *               @arg CMOX_SHA512_256_ALGO
    13.   *               @arg CMOX_SHA3_224_ALGO
    14.   *               @arg CMOX_SHA3_256_ALGO
    15.   *               @arg CMOX_SHA3_384_ALGO
    16.   *               @arg CMOX_SHA3_512_ALGO
    17.   *               @arg CMOX_SHAKE128_ALGO
    18.   *               @arg CMOX_SHAKE256_ALGO
    19.   *               @arg CMOX_SM3_ALGO
    20.   * @param P_pPlaintext Buffer of bytes containing the message to hash
    21.   * @param P_plaintextLen Size in bytes of the message to hash
    22.   * @param P_pDigest Buffer of bytes that will contain the computed digest
    23.   * @param P_expectedDigestLen Desired size in bytes of the digest to compute
    24.   * @param P_pComputedDigestLen Number of bytes generated by the function.
    25.   *        It is an optional parameter and can be set to NULL if not needed.
    26.   * @return cmox_hash_retval_t
    27.   */
    28. cmox_hash_retval_t cmox_hash_compute(cmox_hash_algo_t P_algo,
    29.                                      const uint8_t *P_pPlaintext,
    30.                                      size_t P_plaintextLen,
    31.                                      uint8_t *P_pDigest,
    32.                                      const size_t P_expectedDigestLen,
    33.                                      size_t *P_pComputedDigestLen);
    复制代码
    简单解释一下各个入参

    P_algo:哈希计算方式

    P_pPlaintext:需要进行哈希计算的原始数据

    P_plaintextLen:需要进行哈希计算的原始数据的长度

    P_pDigest:哈希计算结果

    P_expectedDigestLen:期待的长度(这个参数可以去STM32_Cryptographic/include/hash/cmox_XXXX.h文件中找,你用什么哈希计算就去那个文件找)

    P_pComputedDigestLen:计算出的结果的长度

    CryptoTest.part03.rar

    7.67 MB, 下载次数: 0

    CryptoTest.part01.rar

    20 MB, 下载次数: 0

    CryptoTest.part02.rar

    20 MB, 下载次数: 0

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-28 18:11 , Processed in 0.147403 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.