test_crypto.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-30 CDT first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #if defined(BSP_USING_HWCRYPTO)
  15. #define ARR_SIZE(arr) (sizeof(arr)/sizeof(*arr))
  16. #define PRINT_DIGIT_ARR(arr) do { \
  17. rt_kprintf("%s: ", #arr); \
  18. for(int i = 0; i < ARR_SIZE(arr); i++) \
  19. rt_kprintf("%d ", arr[i]); \
  20. rt_kprintf("\n"); \
  21. } while(0)
  22. #define WDT_DEVICE_NAME "crypto"
  23. static void _crypto_cmd_print_usage(void)
  24. {
  25. #if defined(BSP_USING_RNG)
  26. rt_kprintf("crypto_sample [option] \n");
  27. rt_kprintf(" rang: get random number from rang module. \n");
  28. rt_kprintf(" e.g. msh >crypto_sample rang get \n");
  29. #endif
  30. #if defined(BSP_USING_CRC)
  31. rt_kprintf("crypto_sample [option] \n");
  32. rt_kprintf(" crc: test crc module. \n");
  33. rt_kprintf(" e.g. msh >crypto_sample crc 16/32 \n");
  34. #endif
  35. #if defined(BSP_USING_AES)
  36. rt_kprintf("crypto_sample [option] \n");
  37. rt_kprintf(" aes: test aes module. \n");
  38. #if defined(HC32F460)
  39. rt_kprintf(" e.g. msh >crypto_sample aes 128 \n");
  40. #elif defined (HC32F4A0) || defined (HC32F448) || defined (HC32F472) || defined (HC32F4A8)
  41. rt_kprintf(" e.g. msh >crypto_sample aes 128/192/256 \n");
  42. #endif
  43. #endif
  44. #if defined(BSP_USING_HASH)
  45. rt_kprintf("crypto_sample [option] \n");
  46. rt_kprintf(" hash: test hash module. \n");
  47. rt_kprintf(" e.g. msh >crypto_sample hash test \n");
  48. #endif
  49. }
  50. #if defined(BSP_USING_CRC)
  51. /* menuconfig:
  52. Hardware Drivers Config--->On-Chip Peripheral Driver--->Using Hardware Crypto --->
  53. [*]Enable Hardeware CRC
  54. * CRC16命令调用:crypto_sample crc 16
  55. * CRC32命令调用:crypto_sample crc 32
  56. * 程序功能:打印CRC输入数据和计数结果,使用第三方软件计算数据,再做比较
  57. */
  58. #define CRC16_WIDTH 16U
  59. #define CRC32_WIDTH 32U
  60. static void crc_test(rt_uint32_t width)
  61. {
  62. rt_uint8_t temp_in[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  63. struct rt_hwcrypto_ctx *ctx;
  64. rt_uint32_t result = 0;
  65. /* CRC16_X25 */
  66. struct hwcrypto_crc_cfg cfg =
  67. {
  68. .last_val = 0xFFFFU,
  69. .poly = 0x1021U,
  70. .width = CRC16_WIDTH,
  71. .xorout = 0xFFFFU,
  72. .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT,
  73. };
  74. /* CRC32 */
  75. if (width == CRC32_WIDTH)
  76. {
  77. cfg.last_val = 0xFFFFFFFFUL;
  78. cfg.poly = 0x04C11DB7UL;
  79. cfg.width = CRC32_WIDTH;
  80. cfg.xorout = 0xFFFFFFFFUL;
  81. cfg.flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT;
  82. ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
  83. }
  84. else if (width == CRC16_WIDTH)
  85. {
  86. ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC16);
  87. }
  88. else
  89. {
  90. rt_kprintf("crc%d not support! \n", width);
  91. return;
  92. }
  93. rt_hwcrypto_crc_cfg(ctx, &cfg);
  94. rt_kprintf("temp_in: ");
  95. for (int i = 0; i < sizeof(temp_in) / 2U; i++)
  96. {
  97. rt_kprintf("%d ", temp_in[i]);
  98. }
  99. rt_kprintf("\n");
  100. result = rt_hwcrypto_crc_update(ctx, temp_in, sizeof(temp_in) / 2U);
  101. rt_kprintf("crc%d result: 0x%x \n", width, result);
  102. /* Accumulate test */
  103. PRINT_DIGIT_ARR(temp_in);
  104. result = rt_hwcrypto_crc_update(ctx, &temp_in[sizeof(temp_in) / 2U], sizeof(temp_in) / 2U);
  105. rt_kprintf("crc%d result: 0x%x \n", width, result);
  106. rt_hwcrypto_crc_destroy(ctx);
  107. }
  108. #endif
  109. #if defined(BSP_USING_AES)
  110. #define AES_DATA_LEN 32U /* data of length must be a multiple of 16(128 Bit) */
  111. static void aes_test(rt_uint16_t key_bitlen)
  112. {
  113. rt_uint32_t result = RT_EOK;
  114. struct rt_hwcrypto_ctx *ctx;
  115. rt_uint8_t enc_out[AES_DATA_LEN];
  116. rt_uint8_t dec_out[AES_DATA_LEN];
  117. const char *enc_in = "abcdefghijksdwpa123456789asdfghj";
  118. const char *key128 = "1234567890abcdef";
  119. const char *key192 = "1234567890abcdefghijklmn";
  120. const char *key256 = "1234567890abcdefghijklmnopqrstuv";
  121. const char *key;
  122. rt_uint8_t type_max = 1U;
  123. hwcrypto_type types[] =
  124. {
  125. HWCRYPTO_TYPE_AES_ECB,
  126. HWCRYPTO_TYPE_AES_CBC,
  127. HWCRYPTO_TYPE_AES_CTR,
  128. HWCRYPTO_TYPE_AES_CFB,
  129. HWCRYPTO_TYPE_AES_OFB,
  130. };
  131. const char *type_str[] =
  132. {
  133. "aes_ecb",
  134. "aes_cbc",
  135. "aes_ctr",
  136. "aes_cfb",
  137. "aes_ofb",
  138. };
  139. #if defined (HC32F4A8)
  140. type_max = 5U;
  141. #endif
  142. for (int i = 0; i < type_max; i++)
  143. {
  144. ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), types[i]);
  145. if (ctx == RT_NULL)
  146. {
  147. rt_kprintf("create AES context err!");
  148. return;
  149. }
  150. switch (key_bitlen)
  151. {
  152. case 128:
  153. key = key128;
  154. break;
  155. case 192:
  156. key = key192;
  157. break;
  158. case 256:
  159. key = key256;
  160. break;
  161. default:
  162. key = key128;
  163. break;
  164. }
  165. result = rt_hwcrypto_symmetric_setkey(ctx, (rt_uint8_t *)key, key_bitlen);
  166. #if defined (HC32F4A8)
  167. const char *iv = "1234567812345678";
  168. result = rt_hwcrypto_symmetric_setiv(ctx, (const rt_uint8_t *)iv, strlen(iv));
  169. #endif
  170. if (result == RT_EOK)
  171. {
  172. result = rt_hwcrypto_symmetric_crypt(ctx, HWCRYPTO_MODE_ENCRYPT, AES_DATA_LEN, (rt_uint8_t *)enc_in, enc_out);
  173. if (result != RT_EOK)
  174. {
  175. goto _exit;
  176. }
  177. rt_kprintf("%s src data:", type_str[i]);
  178. for (int i = 0; i < AES_DATA_LEN; i++)
  179. {
  180. rt_kprintf("%c", enc_in[i]);
  181. }
  182. rt_kprintf("\n");
  183. rt_kprintf("%s enc data:", type_str[i]);
  184. for (int i = 0; i < AES_DATA_LEN; i++)
  185. {
  186. rt_kprintf("%02x ", enc_out[i]);
  187. }
  188. rt_kprintf("\n");
  189. result = rt_hwcrypto_symmetric_crypt(ctx, HWCRYPTO_MODE_DECRYPT, AES_DATA_LEN, (rt_uint8_t *)enc_out, dec_out);
  190. if (result != RT_EOK)
  191. {
  192. goto _exit;
  193. }
  194. rt_kprintf("%s dec data:", type_str[i]);
  195. for (int i = 0; i < AES_DATA_LEN; i++)
  196. {
  197. rt_kprintf("%c", dec_out[i]);
  198. }
  199. rt_kprintf("\n");
  200. _exit:
  201. rt_hwcrypto_symmetric_destroy(ctx);
  202. }
  203. }
  204. }
  205. #endif
  206. #if defined(BSP_USING_HASH)
  207. #define HASH_SHA256_MSG_DIGEST_SIZE (32U)
  208. static void hash_sha256_test(void)
  209. {
  210. const char *in = "0123456789abcdefghijklmnopqrstuvwxyz";
  211. uint8_t out[HASH_SHA256_MSG_DIGEST_SIZE];
  212. struct rt_hwcrypto_ctx *ctx;
  213. ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA256);
  214. if (ctx != RT_NULL)
  215. {
  216. rt_hwcrypto_hash_update(ctx, (rt_uint8_t *)in, rt_strlen(in));
  217. rt_kprintf("hash in data:");
  218. for (int i = 0; i < rt_strlen(in); i++)
  219. {
  220. rt_kprintf("%c", in[i]);
  221. }
  222. rt_kprintf("\n");
  223. rt_hwcrypto_hash_finish(ctx, out, HASH_SHA256_MSG_DIGEST_SIZE);
  224. rt_kprintf("hash out data:");
  225. for (int i = 0; i < HASH_SHA256_MSG_DIGEST_SIZE; i++)
  226. {
  227. rt_kprintf("%x ", out[i]);
  228. }
  229. rt_kprintf("\n");
  230. rt_hwcrypto_hash_destroy(ctx);
  231. }
  232. }
  233. #endif
  234. static int crypto_sample(int argc, char *argv[])
  235. {
  236. rt_err_t ret = RT_EOK;
  237. if (argc != 3)
  238. {
  239. goto _exit;
  240. }
  241. #if defined(BSP_USING_RNG)
  242. if (!rt_strcmp("rang", argv[1]))
  243. {
  244. if (!rt_strcmp("get", argv[2]))
  245. {
  246. rt_uint32_t result = rt_hwcrypto_rng_update();
  247. rt_kprintf("random number = %x \n", result);
  248. }
  249. else
  250. {
  251. goto _exit;
  252. }
  253. }
  254. #endif
  255. #if defined(BSP_USING_CRC)
  256. else if (!rt_strcmp("crc", argv[1]))
  257. {
  258. rt_uint32_t width = atoi(argv[2]);
  259. if (width == CRC16_WIDTH || width == CRC32_WIDTH)
  260. {
  261. crc_test(width);
  262. }
  263. else
  264. {
  265. goto _exit;
  266. }
  267. }
  268. #endif
  269. #if defined(BSP_USING_AES)
  270. else if (!rt_strcmp("aes", argv[1]))
  271. {
  272. rt_uint32_t key_bitlen = atoi(argv[2]);
  273. if (key_bitlen == 128 || key_bitlen == 192 || key_bitlen == 256)
  274. {
  275. aes_test(key_bitlen);
  276. }
  277. else
  278. {
  279. goto _exit;
  280. }
  281. }
  282. #endif
  283. #if defined(BSP_USING_HASH)
  284. else if (!rt_strcmp("hash", argv[1]))
  285. {
  286. if (!rt_strcmp("test", argv[2]))
  287. {
  288. hash_sha256_test();
  289. }
  290. else
  291. {
  292. goto _exit;
  293. }
  294. }
  295. #endif
  296. else
  297. {
  298. goto _exit;
  299. }
  300. return ret;
  301. _exit:
  302. _crypto_cmd_print_usage();
  303. return -RT_ERROR;
  304. }
  305. MSH_CMD_EXPORT(crypto_sample, crypto [option]);
  306. #endif