crypto_sample.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-06-27 thread-liu first version
  9. */
  10. #include <board.h>
  11. #include "drv_crypto.h"
  12. #include <hwcrypto.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  16. static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
  17. {
  18. unsigned char *buf = (unsigned char *)ptr;
  19. int i, j;
  20. for (i = 0; i < buflen; i += 16)
  21. {
  22. rt_kprintf("%08X: ", i);
  23. for (j = 0; j < 16; j++)
  24. {
  25. if (i + j < buflen)
  26. {
  27. rt_kprintf("%02X ", buf[i + j]);
  28. }
  29. else
  30. {
  31. rt_kprintf(" ");
  32. }
  33. }
  34. rt_kprintf(" ");
  35. for (j = 0; j < 16; j++)
  36. {
  37. if (i + j < buflen)
  38. {
  39. rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
  40. }
  41. }
  42. rt_kprintf("\n");
  43. }
  44. }
  45. #if defined(BSP_USING_RNG)
  46. static rt_err_t hw_rng_sample(int random_num)
  47. {
  48. rt_err_t result = RT_EOK;
  49. int i = 0, num0 = 0, num1 = 0;
  50. if (random_num == 0)
  51. {
  52. return RT_ERROR;
  53. }
  54. for (i = 0; i< random_num; i++)
  55. {
  56. result = rt_hwcrypto_rng_update();
  57. rt_kprintf("%d ", result);
  58. result%2 ? num1++ : num0++;
  59. }
  60. rt_kprintf("\neven numbers : %d, odd numbers: %d\n",num1, num0);
  61. return RT_EOK;
  62. }
  63. #endif
  64. #if defined(BSP_USING_CRC)
  65. static void hw_crc_sample(uint8_t *temp, int size)
  66. {
  67. struct rt_hwcrypto_ctx *ctx;
  68. rt_uint32_t result = 0;
  69. struct hwcrypto_crc_cfg cfg =
  70. {
  71. .last_val = 0xFFFFFFFF,
  72. .poly = 0x04C11DB7,
  73. .width = 32,
  74. .xorout = 0x00000000,
  75. .flags = 0,
  76. };
  77. ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
  78. rt_hwcrypto_crc_cfg(ctx, &cfg);
  79. result = rt_hwcrypto_crc_update(ctx, temp, size);
  80. rt_kprintf("crc result: %x \n", result);
  81. rt_hwcrypto_crc_destroy(ctx);
  82. }
  83. #endif
  84. #if defined(BSP_USING_HASH)
  85. static void hw_hash_sample()
  86. {
  87. struct rt_hwcrypto_ctx *ctx = RT_NULL;
  88. const uint8_t hash_input[] = "RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS).";
  89. static uint8_t sha1_output[20];
  90. static uint8_t sha1_except[20] = {0xff, 0x3c, 0x95, 0x54, 0x95, 0xf0, 0xad,
  91. 0x02, 0x1b, 0xa8, 0xbc, 0xa2, 0x2e, 0xa5,
  92. 0xb0, 0x62, 0x1b, 0xdf, 0x7f, 0xec};
  93. static uint8_t md5_output[16];
  94. static uint8_t md5_except[16] = {0x40, 0x86, 0x03, 0x80, 0x0d, 0x8c, 0xb9,
  95. 0x4c, 0xd6, 0x7d, 0x28, 0xfc, 0xf6, 0xc3,
  96. 0xac, 0x8b};
  97. static uint8_t sha224_output[28];
  98. static uint8_t sha224_except[28] = {0x6f, 0x62, 0x52, 0x7d, 0x80, 0xe6,
  99. 0x9f, 0x82, 0x78, 0x7a, 0x46, 0x91,
  100. 0xb0, 0xe9, 0x64, 0x89, 0xe6, 0xc3,
  101. 0x6b, 0x7e, 0xcf, 0xca, 0x11, 0x42,
  102. 0xc8, 0x77, 0x13, 0x79};
  103. static uint8_t sha256_output[32];
  104. static uint8_t sha256_except[32] = {0x74, 0x19, 0xb9, 0x0e, 0xd1, 0x46,
  105. 0x37, 0x0a, 0x55, 0x18, 0x26, 0x6c,
  106. 0x50, 0xd8, 0x71, 0x34, 0xfa, 0x1f,
  107. 0x5f, 0x5f, 0xe4, 0x9a, 0xe9, 0x40,
  108. 0x0a, 0x7d, 0xa0, 0x26, 0x1b, 0x86,
  109. 0x67, 0x45};
  110. rt_kprintf("======================== Hash Test start ========================\n");
  111. rt_kprintf("Hash Test string: \n");
  112. dump_hex(hash_input, sizeof(hash_input));
  113. /* sh1 test*/
  114. rt_kprintf("\n============ SHA1 Test Start ============\n");
  115. ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA1);
  116. if (ctx == RT_NULL)
  117. {
  118. rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA1);
  119. return ;
  120. }
  121. rt_kprintf("Create sha1 type success!\n");
  122. rt_kprintf("Except sha1 result:\n");
  123. dump_hex(sha1_except, sizeof(sha1_except));
  124. /* start sha1 */
  125. rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
  126. /* get sha1 result */
  127. rt_hwcrypto_hash_finish(ctx, sha1_output, rt_strlen((char const *)sha1_output));
  128. rt_kprintf("Actual sha1 result:\n");
  129. dump_hex(sha1_output, sizeof(sha1_output));
  130. if(rt_memcmp(sha1_output, sha1_except, sizeof(sha1_except)/sizeof(sha1_except[0])) != 0)
  131. {
  132. rt_kprintf("Hash type sha1 Test error, The actual result is not equal to the except result\n");
  133. }
  134. else
  135. {
  136. rt_kprintf("Hash type sha1 Test success, The actual result is equal to the except result\n");
  137. }
  138. /* deinit hash*/
  139. rt_hwcrypto_hash_destroy(ctx);
  140. rt_kprintf("============ SHA1 Test Over ============\n");
  141. /* md5 test*/
  142. rt_kprintf("\n============ MD5 Test Start ============\n");
  143. ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);
  144. if (ctx == RT_NULL)
  145. {
  146. rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_MD5);
  147. return ;
  148. }
  149. rt_kprintf("Create md5 type success!\n");
  150. rt_kprintf("Except md5 result:\n");
  151. dump_hex(md5_except, sizeof(md5_except));
  152. /* start md5 */
  153. rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
  154. /* get md5 result */
  155. rt_hwcrypto_hash_finish(ctx, md5_output, rt_strlen((char const *)md5_output));
  156. rt_kprintf("Actual md5 result:\n");
  157. dump_hex(md5_output, sizeof(md5_output));
  158. if(rt_memcmp(md5_output, md5_except, sizeof(md5_except)/sizeof(md5_except[0])) != 0)
  159. {
  160. rt_kprintf("Hash type md5 Test error, The actual result is not equal to the except result\n");
  161. }
  162. else
  163. {
  164. rt_kprintf("Hash type md5 Test success, The actual result is equal to the except result\n");
  165. }
  166. /* deinit hash*/
  167. rt_hwcrypto_hash_destroy(ctx);
  168. rt_kprintf("============ MD5 Test Over ============\n");
  169. /* sha224 test */
  170. rt_kprintf("\n============ SHA224 Test Start ============\n");
  171. ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA224);
  172. if (ctx == RT_NULL)
  173. {
  174. rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA224);
  175. return ;
  176. }
  177. rt_kprintf("Create sha224 type success!\n");
  178. rt_kprintf("Except sha224 result:\n");
  179. dump_hex(sha224_except, sizeof(sha224_except));
  180. /* start sha224 */
  181. rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
  182. /* get sha224 result */
  183. rt_hwcrypto_hash_finish(ctx, sha224_output, rt_strlen((char const *)sha224_output));
  184. rt_kprintf("Actual sha224 result:\n");
  185. dump_hex(sha224_output, sizeof(sha224_output));
  186. if(rt_memcmp(sha224_output, sha224_except, sizeof(sha224_except)/sizeof(sha224_except[0])) != 0)
  187. {
  188. rt_kprintf("Hash type sha224 Test error, The actual result is not equal to the except result\n");
  189. }
  190. else
  191. {
  192. rt_kprintf("Hash type sha224 Test success, The actual result is equal to the except result\n");
  193. }
  194. rt_hwcrypto_hash_destroy(ctx);
  195. rt_kprintf("============ SHA224 Test Over ============\n");
  196. /* sha256 test*/
  197. rt_kprintf("\n============ SHA256 Test Start ============\n");
  198. ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA256);
  199. if (ctx == RT_NULL)
  200. {
  201. rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA256);
  202. return ;
  203. }
  204. rt_kprintf("Create sha256 type success!\n");
  205. rt_kprintf("Except sha256 result:\n");
  206. dump_hex(sha256_except, sizeof(sha256_except));
  207. /* start sha256 */
  208. rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
  209. /* get sha256 result */
  210. rt_hwcrypto_hash_finish(ctx, sha256_output, rt_strlen((char const *)sha256_output));
  211. rt_kprintf("Actual sha256 result\n");
  212. dump_hex(sha256_output, sizeof(sha256_output));
  213. if(rt_memcmp(sha256_output, sha256_except, sizeof(sha256_except)/sizeof(sha256_except[0])) != 0)
  214. {
  215. rt_kprintf("Hash type sha256 Test error, The actual result is not equal to the except result\n");
  216. }
  217. else
  218. {
  219. rt_kprintf("Hash type sha256 Test success, The actual result is equal to the except result\n");
  220. }
  221. /* destory */
  222. rt_hwcrypto_hash_destroy(ctx);
  223. rt_kprintf("============ SHA256 Test Over ============\n");
  224. rt_kprintf("======================== Hash Test over! ========================\n");
  225. }
  226. #endif
  227. #if defined(BSP_USING_CRYP)
  228. /* key*/
  229. static const rt_uint8_t cryp_key[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
  230. static void hw_aes_cbc(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_mode mode)
  231. {
  232. struct rt_hwcrypto_ctx *ctx;
  233. ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_AES_CBC);
  234. if (ctx == RT_NULL)
  235. {
  236. rt_kprintf("create AES-CBC context err!");
  237. return;
  238. }
  239. rt_hwcrypto_symmetric_setkey(ctx, cryp_key, 128);
  240. rt_hwcrypto_symmetric_crypt(ctx, mode, 32, in, out);
  241. rt_hwcrypto_symmetric_destroy(ctx);
  242. }
  243. static void hw_cryp_sample()
  244. {
  245. rt_uint8_t buf_in[32];
  246. rt_uint8_t buf_out[32];
  247. int i;
  248. /* Populating test data */
  249. for (i = 0; i < sizeof(buf_in); i++)
  250. {
  251. buf_in[i] = i;
  252. }
  253. /* dump primitive data */
  254. rt_kprintf("key : \n");
  255. dump_hex(cryp_key, sizeof(cryp_key));
  256. rt_kprintf("primitive data : \n");
  257. dump_hex(buf_in, sizeof(buf_in));
  258. rt_memset(buf_out, 0, sizeof(buf_out));
  259. /* encrypt */
  260. hw_aes_cbc(buf_in, buf_out, HWCRYPTO_MODE_ENCRYPT);
  261. /* dump encrypt data */
  262. rt_kprintf("AES-enc : \n");
  263. dump_hex(buf_out, sizeof(buf_out));
  264. rt_memset(buf_in, 0, sizeof(buf_in));
  265. /* decrypt */
  266. hw_aes_cbc(buf_out, buf_in, HWCRYPTO_MODE_DECRYPT);
  267. /* dump decrypt data */
  268. rt_kprintf("AES-dec : \n");
  269. dump_hex(buf_in, sizeof(buf_in));
  270. }
  271. #endif
  272. static int crypto(int argc, char **argv)
  273. {
  274. int result = RT_EOK;
  275. static rt_device_t device = RT_NULL;
  276. char *result_str;
  277. if (argc > 1)
  278. {
  279. if (!strcmp(argv[1], "probe"))
  280. {
  281. if (argc == 3)
  282. {
  283. char *dev_name = argv[2];
  284. device = rt_device_find(dev_name);
  285. result_str = (device == RT_NULL) ? "failure" : "success";
  286. rt_kprintf("probe %s %s \n", argv[2], result_str);
  287. }
  288. else
  289. {
  290. rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
  291. }
  292. }
  293. else
  294. {
  295. if (device == RT_NULL)
  296. {
  297. rt_kprintf("Please using 'crypto probe <crypto_name>' first\n");
  298. return -RT_ERROR;
  299. }
  300. if (!strcmp(argv[1], "rng"))
  301. {
  302. #if defined (BSP_USING_RNG)
  303. if (argc == 3)
  304. {
  305. result = hw_rng_sample(atoi(argv[2]));
  306. if(result != RT_EOK)
  307. {
  308. rt_kprintf("please input a legal number, not <%d>\n", atoi(argv[2]));
  309. }
  310. }
  311. else
  312. {
  313. rt_kprintf("rng <number> - generate <number> digital\n");
  314. }
  315. #else
  316. rt_kprintf("please enable RNG first!\n");
  317. #endif
  318. }
  319. else if (!strcmp(argv[1], "crc"))
  320. {
  321. #if defined (BSP_USING_CRC)
  322. int size = 0, i = 0;
  323. if (argc > 3)
  324. {
  325. size = argc - 2;
  326. uint8_t *data = rt_malloc(size);
  327. if (data)
  328. {
  329. for (i = 0; i < size; i++)
  330. {
  331. data[i] = strtol(argv[2 + i], NULL, 0);
  332. }
  333. hw_crc_sample(data, size);
  334. rt_free(data);
  335. }
  336. else
  337. {
  338. rt_kprintf("Low memory!\n");
  339. }
  340. }
  341. else
  342. {
  343. rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
  344. }
  345. #else
  346. rt_kprintf("please enable CRC first!\n");
  347. #endif
  348. }
  349. else if (!strcmp(argv[1], "hash"))
  350. {
  351. #if defined (BSP_USING_HASH)
  352. if (argc == 3)
  353. {
  354. hw_hash_sample();
  355. }
  356. else
  357. {
  358. rt_kprintf("crypto hash sample - hash use sample\n");
  359. }
  360. #else
  361. rt_kprintf("please enable CRC first!\n");
  362. #endif
  363. }
  364. else if (!strcmp(argv[1], "cryp"))
  365. {
  366. #if defined (BSP_USING_CRYP)
  367. if (argc == 3)
  368. {
  369. hw_cryp_sample();
  370. }
  371. else
  372. {
  373. rt_kprintf("crypto cryp sample - encrypt and decrypt data sample\n");
  374. }
  375. #else
  376. rt_kprintf("please enable CRYP first!\n");
  377. #endif
  378. }
  379. else
  380. {
  381. rt_kprintf("Unknown command. Please enter 'crypto' for help\n");
  382. }
  383. }
  384. }
  385. else
  386. {
  387. rt_kprintf("Usage: \n");
  388. rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
  389. rt_kprintf("crypto rng number - generate numbers digital\n");
  390. rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
  391. rt_kprintf("crypto hash sample - hash use sample\n");
  392. rt_kprintf("crypto cryp sample - encrypt and decrypt data\n");
  393. result = -RT_ERROR;
  394. }
  395. return result;
  396. }
  397. MSH_CMD_EXPORT(crypto, crypto function);