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