xref: /rk3399_rockchip-uboot/cmd/crypto.c (revision 6cef3c7b7cc45a9c882fc64e5496a416c99313b8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <command.h>
8 #include <crypto.h>
9 #include <dm.h>
10 #include <u-boot/md5.h>
11 #include <u-boot/sha1.h>
12 #include <u-boot/sha256.h>
13 #include <u-boot/sha512.h>
14 #include <rockchip/crypto_fix_test_data.h>
15 
16 #define PERF_TOTAL_SIZE			(128 * 1024 * 1024)
17 #define PERF_BUFF_SIZE			(4 * 1024 * 1024)
18 
19 #define CALC_RATE_MPBS(bytes, ms)	(((bytes) / 1024) / (ms))
20 
21 struct hash_test_data {
22 	const char	*algo_name;
23 	const char	*mode_name;
24 	u32		algo;
25 	const u8	*data;
26 	u32		data_len;
27 	const u8	*hash;
28 	u32		hash_len;
29 	const u8	*key;
30 	u32		key_len;
31 };
32 
33 struct cipher_test_data {
34 	const char	*algo_name;
35 	const char	*mode_name;
36 	u32		algo;
37 	u32		mode;
38 	const u8	*key;
39 	const u8	*twk_key;
40 	u32		key_len;
41 	const u8	*iv;
42 	u32		iv_len;
43 	const u8	*plain;
44 	u32		plain_len;
45 	const u8	*cipher;
46 	u32		cipher_len;
47 	const u8	*aad;
48 	u32		aad_len;
49 	const u8	*tag;
50 	u32		tag_len;
51 };
52 
53 struct rsa_test_data {
54 	const char	*algo_name;
55 	const char	*mode_name;
56 	u32		algo;
57 	const u8	*n;
58 	u32		n_len;
59 	const u8	*e;
60 	u32		e_len;
61 	const u8	*d;
62 	u32		d_len;
63 	const u8	*c;
64 	u32		c_len;
65 	const u8	*sign_in;
66 	u32		sign_in_len;
67 	const u8	*sign_out;
68 	u32		sign_out_len;
69 };
70 
71 struct ec_test_data {
72 	const char	*algo_name;
73 	u32		algo;
74 	const u8	*pub_x;
75 	u32		pub_x_len;
76 	const u8	*pub_y;
77 	u32		pub_y_len;
78 	const u8	*hash_in;
79 	u32		hash_in_len;
80 	const u8	*sign_in;
81 	u32		sign_in_len;
82 };
83 
84 #define IS_MAC_MODE(mode)	((mode) == RK_MODE_CBC_MAC || \
85 				 (mode) == RK_MODE_CMAC)
86 
87 #define IS_AE_MODE(mode)	((mode) == RK_MODE_CCM || \
88 				 (mode) == RK_MODE_GCM)
89 #define HASH_TEST(algo_type, data_in, hash_val) {\
90 	.algo_name = "HASH", \
91 	.mode_name = #algo_type, \
92 	.algo      = CRYPTO_##algo_type, \
93 	.data      = (data_in),\
94 	.data_len  = sizeof(data_in), \
95 	.hash      = (hash_val), \
96 	.hash_len  = sizeof(hash_val) \
97 }
98 
99 #define HMAC_TEST(algo_type, data_in, hash_val, hmac_key) {\
100 	.algo_name = "HMAC", \
101 	.mode_name = #algo_type, \
102 	.algo      = CRYPTO_HMAC_##algo_type, \
103 	.data      = (data_in),\
104 	.data_len  = sizeof(data_in), \
105 	.hash      = (hash_val), \
106 	.hash_len  = sizeof(hash_val), \
107 	.key       = (hmac_key), \
108 	.key_len   = sizeof(hmac_key)\
109 }
110 
111 #define CIPHER_XTS_TEST(algo_type, mode_type, key1, key2, iv_val, in, out) { \
112 	.algo_name  = #algo_type, \
113 	.mode_name  = #mode_type, \
114 	.algo       = CRYPTO_##algo_type,\
115 	.mode       = RK_MODE_##mode_type, \
116 	.key        = (key1), \
117 	.twk_key    = (key2), \
118 	.key_len    = sizeof(key1), \
119 	.iv         = (iv_val), \
120 	.iv_len     = sizeof(iv_val), \
121 	.plain      = (in), \
122 	.plain_len  = sizeof(in), \
123 	.cipher     = (out), \
124 	.cipher_len = sizeof(out) \
125 }
126 
127 #define CIPHER_TEST(algo, mode, key, iv, plain, cipher) \
128 		CIPHER_XTS_TEST(algo, mode, key, NULL, iv, plain, cipher)
129 
130 #define CIPHER_AE_TEST(algo_type, mode_type, key_val, iv_val, \
131 		       in, out, aad_val, tag_val) { \
132 	.algo_name  = #algo_type, \
133 	.mode_name  = #mode_type, \
134 	.algo       = CRYPTO_##algo_type,\
135 	.mode       = RK_MODE_##mode_type, \
136 	.key        = (key_val), \
137 	.key_len    = sizeof(key_val), \
138 	.iv         = (iv_val), \
139 	.iv_len     = sizeof(iv_val), \
140 	.plain      = (in), \
141 	.plain_len  = sizeof(in), \
142 	.cipher     = (out), \
143 	.cipher_len = sizeof(out), \
144 	.aad        = (aad_val), \
145 	.aad_len    = sizeof(aad_val), \
146 	.tag        = (tag_val), \
147 	.tag_len    = sizeof(tag_val), \
148 }
149 
150 #define RSA_TEST(nbits, bn, be, bc, bd, in, out) { \
151 	.algo_name    = "RSA", \
152 	.mode_name    = #nbits, \
153 	.algo         = CRYPTO_RSA##nbits, \
154 	.n            = (bn), \
155 	.n_len        = sizeof(bn), \
156 	.e            = (be), \
157 	.e_len        = sizeof(be), \
158 	.d            = (bd), \
159 	.d_len        = sizeof(bd), \
160 	.c            = (bc), \
161 	.c_len        = sizeof(bc), \
162 	.sign_in      = (in), \
163 	.sign_in_len  = sizeof(in), \
164 	.sign_out     = (out), \
165 	.sign_out_len = sizeof(out) \
166 }
167 
168 #define EC_TEST(name, x, y, hash, sign) { \
169 	.algo_name   = #name, \
170 	.algo        = CRYPTO_##name, \
171 	.pub_x       = (x), \
172 	.pub_x_len   = sizeof(x), \
173 	.pub_y       = (y), \
174 	.pub_y_len   = sizeof(y), \
175 	.hash_in     = (hash), \
176 	.hash_in_len = sizeof(hash), \
177 	.sign_in     = (sign), \
178 	.sign_in_len = sizeof(sign), \
179 }
180 
181 #define EMPTY_TEST() {}
182 
183 const struct hash_test_data hash_data_set[] = {
184 	HASH_TEST(MD5,    foo_data, hash_md5),
185 	HASH_TEST(SHA1,   foo_data, hash_sha1),
186 	HASH_TEST(SHA256, foo_data, hash_sha256),
187 	HASH_TEST(SHA512, foo_data, hash_sha512),
188 	HASH_TEST(SM3,    foo_data, hash_sm3),
189 
190 #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC)
191 	EMPTY_TEST(),
192 	HMAC_TEST(MD5,    foo_data, hmac_md5,    hmac_key),
193 	HMAC_TEST(SHA1,   foo_data, hmac_sha1,   hmac_key),
194 	HMAC_TEST(SHA256, foo_data, hmac_sha256, hmac_key),
195 	HMAC_TEST(SHA512, foo_data, hmac_sha512, hmac_key),
196 	HMAC_TEST(SM3,    foo_data, hmac_sm3,    hmac_key),
197 #endif
198 };
199 
200 const struct cipher_test_data cipher_data_set[] = {
201 #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)
202 	CIPHER_TEST(DES, ECB, des_key, des_iv, foo_data, des_ecb_cipher),
203 	CIPHER_TEST(DES, CBC, des_key, des_iv, foo_data, des_cbc_cipher),
204 	CIPHER_TEST(DES, CFB, des_key, des_iv, foo_data, des_cfb_cipher),
205 	CIPHER_TEST(DES, OFB, des_key, des_iv, foo_data, des_ofb_cipher),
206 
207 	EMPTY_TEST(),
208 	CIPHER_TEST(DES, ECB, tdes_key, tdes_iv, foo_data, tdes_ecb_cipher),
209 	CIPHER_TEST(DES, CBC, tdes_key, tdes_iv, foo_data, tdes_cbc_cipher),
210 	CIPHER_TEST(DES, CFB, tdes_key, tdes_iv, foo_data, tdes_cfb_cipher),
211 	CIPHER_TEST(DES, OFB, tdes_key, tdes_iv, foo_data, tdes_ofb_cipher),
212 
213 	EMPTY_TEST(),
214 	CIPHER_TEST(AES, ECB, aes_key, aes_iv, foo_data, aes_ecb_cipher),
215 	CIPHER_TEST(AES, CBC, aes_key, aes_iv, foo_data, aes_cbc_cipher),
216 	CIPHER_TEST(AES, CFB, aes_key, aes_iv, foo_data, aes_cfb_cipher),
217 	CIPHER_TEST(AES, OFB, aes_key, aes_iv, foo_data, aes_ofb_cipher),
218 	CIPHER_TEST(AES, CTS, aes_key, aes_iv, foo_data, aes_cts_cipher),
219 	CIPHER_TEST(AES, CTR, aes_key, aes_iv, foo_data, aes_ctr_cipher),
220 	CIPHER_XTS_TEST(AES, XTS, aes_key, aes_twk_key,
221 			aes_iv, foo_data, aes_xts_cipher),
222 	CIPHER_TEST(AES, CBC_MAC, aes_key, aes_iv, foo_data, aes_cbc_mac),
223 	CIPHER_TEST(AES, CMAC, aes_key, aes_iv, foo_data, aes_cmac),
224 	CIPHER_AE_TEST(AES, CCM, aes_key, aes_ccm_iv, foo_data, aes_ccm_cipher,
225 		       ad_data, aes_ccm_tag),
226 	CIPHER_AE_TEST(AES, GCM, aes_key, aes_iv, foo_data, aes_gcm_cipher,
227 		       ad_data, aes_gcm_tag),
228 
229 	EMPTY_TEST(),
230 	CIPHER_TEST(SM4, ECB, sm4_key, sm4_iv, foo_data, sm4_ecb_cipher),
231 	CIPHER_TEST(SM4, CBC, sm4_key, sm4_iv, foo_data, sm4_cbc_cipher),
232 	CIPHER_TEST(SM4, CFB, sm4_key, sm4_iv, foo_data, sm4_cfb_cipher),
233 	CIPHER_TEST(SM4, OFB, sm4_key, sm4_iv, foo_data, sm4_ofb_cipher),
234 	CIPHER_TEST(SM4, CTS, sm4_key, sm4_iv, foo_data, sm4_cts_cipher),
235 	CIPHER_TEST(SM4, CTR, sm4_key, sm4_iv, foo_data, sm4_ctr_cipher),
236 	CIPHER_XTS_TEST(SM4, XTS, sm4_key, sm4_twk_key,
237 			sm4_iv, foo_data, sm4_xts_cipher),
238 	CIPHER_TEST(SM4, CBC_MAC, sm4_key, sm4_iv, foo_data, sm4_cbc_mac),
239 	CIPHER_TEST(SM4, CMAC, sm4_key, sm4_iv, foo_data, sm4_cmac),
240 	CIPHER_AE_TEST(SM4, CCM, sm4_key, sm4_ccm_iv, foo_data, sm4_ccm_cipher,
241 		       ad_data, sm4_ccm_tag),
242 	CIPHER_AE_TEST(SM4, GCM, sm4_key, sm4_iv, foo_data, sm4_gcm_cipher,
243 		       ad_data, sm4_gcm_tag),
244 #else
245 	EMPTY_TEST(),
246 #endif
247 };
248 
249 const struct rsa_test_data rsa_data_set[] = {
250 #if CONFIG_IS_ENABLED(ROCKCHIP_RSA)
251 
252 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
253 	RSA_TEST(2048, rsa2048_n, rsa2048_e, rsa2048_c, rsa2048_d,
254 		 rsa2048_sign_in, rsa2048_sign_out),
255 #else
256 	RSA_TEST(4096, rsa4096_n, rsa4096_e, NULL, rsa4096_d,
257 		 rsa4096_sign_in, rsa4096_sign_out),
258 #endif
259 
260 #else
261 	EMPTY_TEST(),
262 #endif
263 };
264 
265 const struct ec_test_data ec_data_set[] = {
266 #if CONFIG_IS_ENABLED(ROCKCHIP_EC)
267 	EC_TEST(ECC_192R1, ecc192r1_pub_x, ecc192r1_pub_y, ecc192r1_hash, ecc192r1_sign),
268 	EC_TEST(SM2, sm2_pub_x, sm2_pub_y, sm2_hash, sm2_sign),
269 #else
270 	EMPTY_TEST(),
271 #endif
272 };
273 
274 static void dump_hex(const char *name, const u8 *array, u32 len)
275 {
276 	int i;
277 
278 	printf("[%s]: %uByte", name, len);
279 	for (i = 0; i < len; i++) {
280 		if (i % 32 == 0)
281 			printf("\n");
282 		printf("%02x ", array[i]);
283 	}
284 	printf("\n");
285 }
286 
287 static inline void print_result_MBps(const char *algo_name,
288 				     const char *mode_name,
289 				     const char *crypt, ulong MBps,
290 				     const u8 *expect, const u8 *actual,
291 				     u32 len)
292 {
293 	if (memcmp(expect, actual, len) == 0) {
294 		printf("[%s] %-8s%-8s PASS    (%luMBps)\n",
295 		       algo_name, mode_name, crypt, MBps);
296 	} else {
297 		printf("[%s] %-8s%-8s FAIL\n",
298 		       algo_name, mode_name, crypt);
299 		dump_hex("expect", expect, len);
300 		dump_hex("actual", actual, len);
301 	}
302 }
303 
304 static inline void print_result_ms(const char *algo_name, const char *mode_name,
305 				   const char *crypt, ulong time_cost,
306 				   const u8 *expect, const u8 *actual, u32 len)
307 {
308 	if (memcmp(expect, actual, len) == 0) {
309 		printf("[%s] %-8s%-8s PASS    (%lums)\n",
310 		       algo_name, mode_name, crypt, time_cost);
311 	} else {
312 		printf("[%s] %-8s%-8s FAIL\n",
313 		       algo_name, mode_name, crypt);
314 		dump_hex("expect", expect, len);
315 		dump_hex("actual", actual, len);
316 	}
317 }
318 
319 int test_hash_perf(struct udevice *dev, u32 algo,
320 		   const u8 *key, u32 key_len, ulong *MBps)
321 {
322 	u32 total_size = PERF_TOTAL_SIZE;
323 	u32 data_size = PERF_BUFF_SIZE;
324 	sha_context ctx;
325 	u8 *data = NULL;
326 	u8 hash_out[64];
327 	int ret, i;
328 
329 	*MBps = 0;
330 
331 	ctx.algo = algo;
332 	ctx.length = total_size;
333 
334 	data = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
335 	if (!data) {
336 		printf("%s, %d: memalign %u error!\n",
337 		       __func__, __LINE__, data_size);
338 		return -EINVAL;
339 	}
340 
341 	memset(data, 0xab, data_size);
342 
343 	ulong start = get_timer(0);
344 
345 	if (key)
346 		ret = crypto_hmac_init(dev, &ctx, (u8 *)key, key_len);
347 	else
348 		ret = crypto_sha_init(dev, &ctx);
349 
350 	if (ret) {
351 		printf("crypto_sha_init error ret = %d!\n", ret);
352 		goto exit;
353 	}
354 
355 	for (i = 0; i < total_size / data_size; i++) {
356 		ret = crypto_sha_update(dev, (u32 *)data, data_size);
357 		if (ret) {
358 			printf("crypto_sha_update error!\n");
359 			goto exit;
360 		}
361 	}
362 
363 	ret = crypto_sha_final(dev, &ctx, hash_out);
364 	if (ret) {
365 		printf("crypto_sha_final error ret = %d!\n", ret);
366 		goto exit;
367 	}
368 
369 	ulong time_cost = get_timer(start);
370 
371 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
372 
373 exit:
374 	free(data);
375 
376 	return ret;
377 }
378 
379 int test_cipher_perf(struct udevice *dev, cipher_context *ctx,
380 		     ulong *MBps, bool enc)
381 {
382 	u32 total_size = PERF_TOTAL_SIZE;
383 	u32 data_size = PERF_BUFF_SIZE;
384 	u8 *plain = NULL, *cipher = NULL;
385 	u8 aad[128], tag[16];
386 	int ret = 0, i;
387 
388 	*MBps = 0;
389 
390 	plain = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
391 	if (!plain) {
392 		printf("%s, %d: memalign %u error!\n",
393 		       __func__, __LINE__, data_size);
394 		return -EINVAL;
395 	}
396 
397 	cipher = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
398 	if (!cipher) {
399 		printf("%s, %d: memalign %u error!\n",
400 		       __func__, __LINE__, data_size);
401 		free(plain);
402 		return -EINVAL;
403 	}
404 
405 	memset(plain, 0xab, data_size);
406 	memset(aad, 0xcb, sizeof(aad));
407 
408 	ulong start = get_timer(0);
409 
410 	for (i = 0; i < total_size / data_size; i++) {
411 		if (IS_MAC_MODE(ctx->mode))
412 			ret = crypto_mac(dev, ctx, plain, data_size, cipher);
413 		else if (IS_AE_MODE(ctx->mode))
414 			ret = crypto_ae(dev, ctx, plain, data_size,
415 					aad, sizeof(aad), cipher, tag);
416 		else
417 			ret = crypto_cipher(dev, ctx, plain, cipher,
418 					    data_size, enc);
419 		if (ret) {
420 			printf("%s, %d:crypto calc error! ret = %d\n",
421 			       __func__, __LINE__, ret);
422 			goto exit;
423 		}
424 	}
425 
426 	ulong time_cost = get_timer(start);
427 
428 	*MBps = CALC_RATE_MPBS(total_size, time_cost);
429 exit:
430 	free(plain);
431 	free(cipher);
432 
433 	return ret;
434 }
435 
436 int test_hash_result(void)
437 {
438 	const struct hash_test_data *test_data = NULL;
439 	sha_context csha_ctx;
440 	struct udevice *dev;
441 	unsigned int i;
442 	u8 out[64];
443 	int ret;
444 
445 	printf("\n=================== hash & hmac test ===================\n");
446 
447 	for (i = 0; i < ARRAY_SIZE(hash_data_set); i++) {
448 		test_data = &hash_data_set[i];
449 		if (test_data->algo == 0) {
450 			printf("\n");
451 			continue;
452 		}
453 
454 		dev = crypto_get_device(test_data->algo);
455 		if (!dev) {
456 			printf("[%s] %-16s unsupported!!!\n",
457 			       test_data->algo_name,
458 			       test_data->mode_name);
459 			continue;
460 		}
461 
462 		csha_ctx.algo   = test_data->algo;
463 		csha_ctx.length = test_data->data_len;
464 
465 		memset(out, 0x00, sizeof(out));
466 		if (test_data->key) {
467 			ret = crypto_hmac_init(dev, &csha_ctx,
468 					       (u8 *)test_data->key,
469 					       test_data->key_len);
470 			ret |= crypto_hmac_update(dev, (void *)test_data->data,
471 						  test_data->data_len);
472 			ret |= crypto_hmac_final(dev, &csha_ctx, out);
473 			if (ret) {
474 				printf("hmac calc error ret = %d\n", ret);
475 				goto error;
476 			}
477 		} else {
478 			ret = crypto_sha_init(dev, &csha_ctx);
479 			ret |= crypto_sha_update(dev, (void *)test_data->data,
480 						 test_data->data_len);
481 			ret |= crypto_sha_final(dev, &csha_ctx, out);
482 			if (ret) {
483 				printf("hash calc error ret = %d\n", ret);
484 				goto error;
485 			}
486 		}
487 
488 		ulong MBps = 0;
489 
490 		test_hash_perf(dev, test_data->algo,
491 			       test_data->key, test_data->key_len, &MBps);
492 		print_result_MBps(test_data->algo_name, test_data->mode_name,
493 				  "", MBps, test_data->hash, out,
494 				  test_data->hash_len);
495 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
496 	}
497 
498 	return 0;
499 error:
500 	printf("%s %s test error!\n",
501 	       test_data->algo_name, test_data->mode_name);
502 	return ret;
503 }
504 
505 int test_cipher_result(void)
506 {
507 	const struct cipher_test_data *test_data = NULL;
508 	struct udevice *dev;
509 	cipher_context ctx;
510 	u8 out[256], tag[16];
511 	int ret;
512 	u32 i;
513 
514 	printf("\n===================== cipher test ======================\n");
515 
516 	for (i = 0; i < ARRAY_SIZE(cipher_data_set); i++) {
517 		test_data = &cipher_data_set[i];
518 		if (test_data->algo == 0) {
519 			printf("\n");
520 			continue;
521 		}
522 
523 		dev = crypto_get_device(test_data->algo);
524 		if (!dev) {
525 			printf("[%s] %-16s unsupported!!!\n",
526 			       test_data->algo_name, test_data->mode_name);
527 			continue;
528 		}
529 
530 		memset(&ctx, 0x00, sizeof(ctx));
531 
532 		ctx.algo    = test_data->algo;
533 		ctx.mode    = test_data->mode;
534 		ctx.key     = test_data->key;
535 		ctx.twk_key = test_data->twk_key;
536 		ctx.key_len = test_data->key_len;
537 		ctx.iv      = test_data->iv;
538 		ctx.iv_len  = test_data->iv_len;
539 
540 		ulong MBps = 0;
541 
542 		test_cipher_perf(dev, &ctx, &MBps, true);
543 
544 		/* AES/SM4 mac */
545 		if (IS_MAC_MODE(ctx.mode))
546 			ret = crypto_mac(dev, &ctx, test_data->plain,
547 					 test_data->plain_len, out);
548 		else if (IS_AE_MODE(ctx.mode))
549 			ret = crypto_ae(dev, &ctx,
550 					test_data->plain, test_data->plain_len,
551 					test_data->aad, test_data->aad_len,
552 					out, tag);
553 		else
554 			ret = crypto_cipher(dev, &ctx, test_data->plain,
555 					    out, test_data->plain_len, true);
556 		if (ret)
557 			goto error;
558 
559 		if (test_data->tag &&
560 		    memcmp(test_data->tag, tag, test_data->tag_len) != 0) {
561 			printf("tag mismatch!!!\n");
562 			dump_hex("expect", test_data->tag, test_data->tag_len);
563 			dump_hex("actual", tag, test_data->tag_len);
564 			goto error;
565 		}
566 
567 		print_result_MBps(test_data->algo_name, test_data->mode_name,
568 				  "encrypt", MBps, test_data->cipher, out,
569 				  test_data->cipher_len);
570 
571 		if (!IS_MAC_MODE(ctx.mode) && !IS_AE_MODE(ctx.mode)) {
572 			test_cipher_perf(dev, &ctx, &MBps, false);
573 			ret = crypto_cipher(dev, &ctx, test_data->cipher,
574 					    out, test_data->cipher_len, false);
575 			if (ret)
576 				goto error;
577 
578 			print_result_MBps(test_data->algo_name,
579 					  test_data->mode_name,
580 					  "decrypt", MBps,
581 					  test_data->plain, out,
582 					  test_data->plain_len);
583 		}
584 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
585 	}
586 	return 0;
587 error:
588 	printf("%s %s test error, ret = %d!\n",
589 	       test_data->algo_name, test_data->mode_name, ret);
590 	return ret;
591 }
592 
593 int test_rsa_result(void)
594 {
595 	const struct rsa_test_data *test_data = NULL;
596 	u8 *hard_out = NULL, *e_tmp;
597 	u32 data_size = 4096 / 8;
598 	ulong start, time_cost;
599 	struct udevice *dev;
600 	rsa_key rsa_key;
601 	int ret, i;
602 
603 	hard_out = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
604 	if (!hard_out) {
605 		printf("%s, %d: memalign %u error!\n",
606 		       __func__, __LINE__, data_size);
607 		return -EINVAL;
608 	}
609 
610 	e_tmp = (u8 *)memalign(CONFIG_SYS_CACHELINE_SIZE, data_size);
611 	if (!e_tmp) {
612 		printf("%s, %d: memalign %u error!\n",
613 		       __func__, __LINE__, data_size);
614 		return -EINVAL;
615 	}
616 
617 	printf("\n====================== rsa test ========================\n");
618 	for (i = 0; i < ARRAY_SIZE(rsa_data_set); i++) {
619 		test_data = &rsa_data_set[i];
620 		if (test_data->algo == 0) {
621 			printf("\n");
622 			continue;
623 		}
624 
625 		dev = crypto_get_device(test_data->algo);
626 		if (!dev) {
627 			printf("[%s] %-16s unsupported!!!\n",
628 			       test_data->algo_name, test_data->mode_name);
629 			continue;
630 		}
631 
632 		/* sign test */
633 		memset(&rsa_key, 0x00, sizeof(rsa_key));
634 		rsa_key.algo = test_data->algo;
635 		rsa_key.n = (u32 *)test_data->n;
636 		rsa_key.e = (u32 *)test_data->d;
637 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
638 		rsa_key.c = (u32 *)test_data->c;
639 #endif
640 
641 		start = get_timer(0);
642 		ret = crypto_rsa_verify(dev, &rsa_key,
643 					(u8 *)test_data->sign_in, hard_out);
644 		if (ret) {
645 			printf("sign test error, ret = %d\n", ret);
646 			goto error;
647 		}
648 		time_cost = get_timer(start);
649 		print_result_ms(test_data->algo_name, test_data->mode_name,
650 				"sign", time_cost, test_data->sign_out,
651 				hard_out, test_data->n_len);
652 
653 		/* verify test */
654 		memset(&rsa_key, 0x00, sizeof(rsa_key));
655 		memset(e_tmp, 0x00, data_size);
656 		memcpy(e_tmp, test_data->e, test_data->e_len);
657 		rsa_key.algo = test_data->algo;
658 		rsa_key.n = (u32 *)test_data->n;
659 		rsa_key.e = (u32 *)e_tmp;
660 #ifdef CONFIG_ROCKCHIP_CRYPTO_V1
661 		rsa_key.c = (u32 *)test_data->c;
662 #endif
663 
664 		start = get_timer(0);
665 		ret = crypto_rsa_verify(dev, &rsa_key,
666 					(u8 *)test_data->sign_out, hard_out);
667 		if (ret) {
668 			printf("verify test error, ret = %d\n", ret);
669 			goto error;
670 		}
671 		time_cost = get_timer(start);
672 
673 		print_result_ms(test_data->algo_name, test_data->mode_name,
674 				"verify", time_cost, test_data->sign_in,
675 				hard_out, test_data->n_len);
676 
677 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
678 	}
679 
680 	free(hard_out);
681 	free(e_tmp);
682 
683 	return 0;
684 error:
685 	free(hard_out);
686 	free(e_tmp);
687 	printf("%s %s test error!\n",
688 	       test_data->algo_name, test_data->mode_name);
689 	return ret;
690 }
691 
692 int test_ec_result(void)
693 {
694 	const struct ec_test_data *test_data = NULL;
695 	ulong start, time_cost;
696 	struct udevice *dev;
697 	ec_key ec_key;
698 	int ret, i;
699 
700 	printf("\n====================== ec test ========================\n");
701 	for (i = 0; i < ARRAY_SIZE(ec_data_set); i++) {
702 		test_data = &ec_data_set[i];
703 		if (test_data->algo == 0) {
704 			printf("\n");
705 			continue;
706 		}
707 
708 		dev = crypto_get_device(test_data->algo);
709 		if (!dev) {
710 			printf("[%s] %-16s unsupported!!!\n",
711 			       test_data->algo_name, "");
712 			continue;
713 		}
714 
715 		/* verify test */
716 		memset(&ec_key, 0x00, sizeof(ec_key));
717 		ec_key.algo = test_data->algo;
718 		ec_key.x = (u32 *)test_data->pub_x;
719 		ec_key.y = (u32 *)test_data->pub_y;
720 
721 		start = get_timer(0);
722 		ret = crypto_ec_verify(dev, &ec_key,
723 				       (u8 *)test_data->hash_in,
724 				       test_data->hash_in_len,
725 				       (u8 *)test_data->sign_in);
726 		if (ret) {
727 			printf("verify test error, ret = %d\n", ret);
728 			goto error;
729 		}
730 		time_cost = get_timer(start);
731 
732 		printf("[%-9s]   %-8s PASS    (%lums)\n",
733 		       test_data->algo_name, "verify", time_cost);
734 
735 		printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
736 	}
737 
738 	return 0;
739 error:
740 	printf("%s test error!\n", test_data->algo_name);
741 	return ret;
742 }
743 
744 static int test_all_result(void)
745 {
746 	int ret = 0;
747 
748 	ret = test_hash_result();
749 	if (ret)
750 		goto exit;
751 
752 	ret = test_cipher_result();
753 	if (ret)
754 		goto exit;
755 
756 	ret = test_rsa_result();
757 	if (ret)
758 		goto exit;
759 
760 	ret = test_ec_result();
761 	if (ret)
762 		goto exit;
763 
764 exit:
765 	return 0;
766 }
767 
768 static int do_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
769 {
770 	return test_all_result();
771 }
772 
773 U_BOOT_CMD(
774 	crypto, 1, 1, do_crypto,
775 	"crypto test",
776 	""
777 );
778