xref: /OK3568_Linux_fs/external/security/librkcrypto/test/test_throughput.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
3  */
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <time.h>
9 #include <unistd.h>
10 #include "rkcrypto_core.h"
11 #include "rkcrypto_mem.h"
12 #include "rkcrypto_otp_key.h"
13 #include "rkcrypto_random.h"
14 #include "test_utils.h"
15 #include "rsa_key_data.h"
16 
17 #define TEST_BLOCK_SIZE		1024 * 1024	/* 1MB */
18 #define TEST_OTP_BLOCK_SIZE	500 * 1024
19 #define DURATION		1		/* 1s */
20 #define DATA_BUTT		0xFFFFFFFF
21 
test_otp_key_item_tp(bool is_virt,uint32_t key_id,uint32_t key_len,uint32_t algo,uint32_t mode,uint32_t operation,rk_crypto_mem * fd,uint32_t data_len)22 static int test_otp_key_item_tp(bool is_virt, uint32_t key_id, uint32_t key_len,
23 				uint32_t algo, uint32_t mode, uint32_t operation,
24 				rk_crypto_mem *fd, uint32_t data_len)
25 {
26 	uint32_t res = 0;
27 	rk_cipher_config config;
28 	uint8_t iv[16];
29 	uint8_t in_out[RK_CRYPTO_MAX_DATA_LEN];
30 	struct timespec start, end;
31 	uint64_t total_nsec, nsec;
32 	uint32_t rounds;
33 
34 	nsec = DURATION * 1000000000;
35 
36 	memset(iv, 0x00, sizeof(iv));
37 	test_get_rng(iv, sizeof(iv));
38 
39 	if (is_virt) {
40 		memset(in_out, 0x00, sizeof(in_out));
41 		test_get_rng(in_out, data_len);
42 	}
43 
44 	memcpy(config.iv, iv, sizeof(iv));
45 
46 	config.algo      = algo;
47 	config.mode      = mode;
48 	config.key_len   = key_len;
49 	config.reserved  = NULL;
50 	config.operation = operation;
51 	total_nsec = 0;
52 	rounds = 0;
53 
54 	while (total_nsec < nsec) {
55 		clock_gettime(CLOCK_REALTIME, &start);
56 
57 		if (is_virt)
58 			res = rk_oem_otp_key_cipher_virt(key_id, &config, in_out, in_out, data_len);
59 		else
60 			res = rk_oem_otp_key_cipher(key_id, &config, fd->dma_fd, fd->dma_fd, data_len);
61 
62 		if (res == RK_CRYPTO_ERR_NOT_SUPPORTED) {
63 			if (is_virt)
64 				printf("virt:\totpkey\t[%s-%u]\t%s\t%s\tN/A.\n",
65 				       test_algo_name(algo), key_len * 8, test_mode_name(mode),
66 				       test_op_name(operation));
67 			else
68 				printf("dma_fd:\totpkey\t[%s-%u]\t%s\t%s\tN/A.\n",
69 				       test_algo_name(algo), key_len * 8, test_mode_name(mode),
70 				       test_op_name(operation));
71 
72 			return RK_CRYPTO_SUCCESS;
73 		} else if (res) {
74 			printf("test rk_oem_otp_key_cipher failed! 0x%08x\n", res);
75 			return res;
76 		}
77 
78 		clock_gettime(CLOCK_REALTIME, &end);
79 		total_nsec += (end.tv_sec - start.tv_sec) * 1000000000 +
80 			      (end.tv_nsec - start.tv_nsec);
81 		rounds ++;
82 	}
83 
84 	if (is_virt)
85 		printf("virt:\totpkey\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
86 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
87 		       test_op_name(operation), (data_len * rounds / (1024 * 1024)));
88 	else
89 		printf("dma_fd:\totpkey\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
90 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
91 		       test_op_name(operation), (data_len * rounds / (1024 * 1024)));
92 
93 	return res;
94 }
95 
test_otp_key_virt_tp(void)96 static int test_otp_key_virt_tp(void)
97 {
98 	uint32_t h, j, k;
99 	uint32_t algo, key_id, mode, operation, len, key_len;
100 
101 	const uint32_t algo_tab[] = {
102 		RK_ALGO_AES,
103 		RK_ALGO_SM4,
104 	};
105 	const uint32_t mode_tab[] = {
106 		RK_CIPHER_MODE_ECB,
107 		RK_CIPHER_MODE_CBC,
108 		RK_CIPHER_MODE_CTR,
109 	};
110 	const uint32_t op_tab[] = {
111 		RK_OP_CIPHER_ENC,
112 		RK_OP_CIPHER_DEC,
113 	};
114 
115 	for (h = 0; h < ARRAY_SIZE(algo_tab); h++) {
116 		for (j = 0; j < ARRAY_SIZE(mode_tab); j++) {
117 			for (k = 0; k < ARRAY_SIZE(op_tab); k++) {
118 				algo      = algo_tab[h];
119 				mode      = mode_tab[j];
120 				operation = op_tab[k];
121 				key_id    = RK_OEM_OTP_KEY3;
122 				len       = TEST_OTP_BLOCK_SIZE;
123 
124 				if (algo == RK_ALGO_AES) {
125 					key_len = 32;
126 				} else {
127 					key_len = 16;
128 				}
129 
130 				if (test_otp_key_item_tp(true, key_id, key_len, algo,
131 							 mode, operation, NULL, len))
132 					goto error;
133 			}
134 		}
135 	}
136 
137 	printf("virt:\ttest otp_key throughput SUCCESS.\n\n");
138 	return 0;
139 
140 error:
141 	printf("virt:\ttest otp_key throughput FAILED!!!\n\n");
142 	return -1;
143 }
144 
test_otp_key_fd_tp(void)145 static int test_otp_key_fd_tp(void)
146 {
147 	int res = 0;
148 	uint32_t h, j, k;
149 	uint32_t algo, key_id, mode, operation, len, key_len;
150 	rk_crypto_mem *in_out = NULL;
151 
152 	const uint32_t algo_tab[] = {
153 		RK_ALGO_AES,
154 		RK_ALGO_SM4,
155 	};
156 	const uint32_t mode_tab[] = {
157 		RK_CIPHER_MODE_ECB,
158 		RK_CIPHER_MODE_CBC,
159 		RK_CIPHER_MODE_CTR,
160 	};
161 	const uint32_t op_tab[] = {
162 		RK_OP_CIPHER_ENC,
163 		RK_OP_CIPHER_DEC,
164 	};
165 
166 	if (rk_crypto_init()) {
167 		printf("rk_crypto_init error!\n");
168 		return -1;
169 	}
170 
171 	in_out = rk_crypto_mem_alloc(TEST_OTP_BLOCK_SIZE);
172 	if (!in_out) {
173 		printf("rk_crypto_mem_alloc %uByte error!\n", TEST_OTP_BLOCK_SIZE);
174 		res = -1;
175 		goto out;
176 	}
177 
178 	for (h = 0; h < ARRAY_SIZE(algo_tab); h++) {
179 		for (j = 0; j < ARRAY_SIZE(mode_tab); j++) {
180 			for (k = 0; k < ARRAY_SIZE(op_tab); k++) {
181 				algo      = algo_tab[h];
182 				mode      = mode_tab[j];
183 				operation = op_tab[k];
184 				key_id    = RK_OEM_OTP_KEY3;
185 				len       = TEST_OTP_BLOCK_SIZE;
186 
187 				if (algo == RK_ALGO_AES) {
188 					key_len = 32;
189 				} else {
190 					key_len = 16;
191 				}
192 
193 				if (test_otp_key_item_tp(false, key_id, key_len, algo,
194 							 mode, operation, in_out, len)) {
195 					printf("dma_fd:\ttest otp_key throughput FAILED!!!\n");
196 					res = -1;
197 					goto out;
198 				}
199 			}
200 		}
201 	}
202 
203 	printf("dma_fd:\ttest otp_key throughput SUCCESS.\n\n");
204 
205 out:
206 	if (!in_out)
207 		rk_crypto_mem_free(in_out);
208 
209 	rk_crypto_deinit();
210 	return res;
211 }
212 
test_otp_key_tp(void)213 static int test_otp_key_tp(void)
214 {
215 	if (test_otp_key_fd_tp())
216 		return -1;
217 
218 	if (test_otp_key_virt_tp())
219 		return -1;
220 
221 	return 0;
222 }
223 
test_cipher_item_tp(bool is_virt,uint32_t key_len,uint32_t algo,uint32_t mode,uint32_t operation,void * in_out,uint32_t data_len)224 static int test_cipher_item_tp(bool is_virt, uint32_t key_len, uint32_t algo,
225 			       uint32_t mode, uint32_t operation,
226 			       void *in_out, uint32_t data_len)
227 {
228 	uint32_t res = 0;
229 	rk_handle handle = 0;
230 	rk_cipher_config config;
231 	struct timespec start, end;
232 	uint64_t total_nsec, nsec;
233 	uint32_t rounds;
234 
235 	nsec = DURATION * 1000000000;
236 
237 	test_get_rng(config.iv, sizeof(config.iv));
238 	test_get_rng(config.key, key_len);
239 
240 	if (is_virt)
241 		test_get_rng(in_out, data_len);
242 
243 	config.algo      = algo;
244 	config.mode      = mode;
245 	config.key_len   = key_len;
246 	config.reserved  = NULL;
247 	config.operation = operation;
248 	total_nsec = 0;
249 	rounds = 0;
250 
251 	while (total_nsec < nsec) {
252 		clock_gettime(CLOCK_REALTIME, &start);
253 
254 		res = rk_cipher_init(&config, &handle);
255 		if (res) {
256 			if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
257 				printf("test rk_cipher_init failed! 0x%08x\n", res);
258 				goto error;
259 			}
260 
261 			if (is_virt)
262 				printf("virt:\t[%s-%u]\t%s\tN/A\n",
263 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
264 			else
265 				printf("dma_fd:\t[%s-%u]\t%s\tN/A\n",
266 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
267 			return 0;
268 		}
269 
270 		if (is_virt)
271 			res = rk_cipher_crypt_virt(handle, in_out, in_out, data_len);
272 		else
273 			res = rk_cipher_crypt(handle,
274 					      ((rk_crypto_mem *)in_out)->dma_fd,
275 					      ((rk_crypto_mem *)in_out)->dma_fd,
276 					      data_len);
277 
278 		if (res) {
279 			rk_cipher_final(handle);
280 			printf("test rk_cipher_crypt failed! 0x%08x\n", res);
281 			goto error;
282 		}
283 
284 		rk_cipher_final(handle);
285 
286 		clock_gettime(CLOCK_REALTIME, &end);
287 		total_nsec += (end.tv_sec - start.tv_sec) * 1000000000 +
288 			      (end.tv_nsec - start.tv_nsec);
289 		rounds ++;
290 	}
291 
292 	if (is_virt)
293 		printf("virt:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
294 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
295 		       test_op_name(operation), (data_len * rounds / (1024 * 1024)));
296 	else
297 		printf("dma_fd:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
298 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
299 		       test_op_name(operation), (data_len * rounds / (1024 * 1024)));
300 
301 	return res;
302 error:
303 	if (is_virt)
304 		printf("virt:\t[%s-%u]\t%s\tFailed.\n",
305 		       test_algo_name(algo), key_len * 8, test_mode_name(mode));
306 	else
307 		printf("dma_fd:\t[%s-%u]\t%s\tFailed.\n",
308 		       test_algo_name(algo), key_len * 8, test_mode_name(mode));
309 	return res;
310 }
311 
test_cipher_tp(void)312 static int test_cipher_tp(void)
313 {
314 	int res = 0;
315 	uint32_t h, j, k;
316 	uint32_t algo, mode, operation, len, key_len;
317 	rk_crypto_mem *in_out_fd = NULL;
318 	uint8_t *in_out_virt = NULL;
319 	size_t page_size = getpagesize();
320 
321 	struct test_cipher_item_tp {
322 		uint32_t algo;
323 		uint32_t modes[RK_CIPHER_MODE_MAX];
324 		uint32_t key_len;
325 		uint32_t op[2];
326 	};
327 
328 	static struct test_cipher_item_tp test_item_tbl[] = {
329 		{
330 			.algo  = RK_ALGO_DES,
331 			.modes = {
332 				RK_CIPHER_MODE_ECB,
333 				RK_CIPHER_MODE_CBC,
334 				DATA_BUTT,
335 			},
336 			.key_len = 8,
337 			.op = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC},
338 		},
339 
340 		{
341 			.algo  = RK_ALGO_TDES,
342 			.modes = {
343 				RK_CIPHER_MODE_ECB,
344 				RK_CIPHER_MODE_CBC,
345 				DATA_BUTT,
346 			},
347 			.key_len = 24,
348 			.op = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC},
349 		},
350 
351 		{
352 			.algo  = RK_ALGO_AES,
353 			.modes = {
354 				RK_CIPHER_MODE_ECB,
355 				RK_CIPHER_MODE_CBC,
356 				RK_CIPHER_MODE_CTS,
357 				RK_CIPHER_MODE_CTR,
358 				DATA_BUTT,
359 			},
360 			.key_len = 32,
361 			.op = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC},
362 		},
363 
364 		{
365 			.algo  = RK_ALGO_SM4,
366 			.modes = {
367 				RK_CIPHER_MODE_ECB,
368 				RK_CIPHER_MODE_CBC,
369 				RK_CIPHER_MODE_CTS,
370 				RK_CIPHER_MODE_CTR,
371 				DATA_BUTT,
372 			},
373 			.key_len = 16,
374 			.op = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC},
375 		},
376 
377 	};
378 
379 	if (rk_crypto_init()) {
380 		printf("rk_crypto_init error!\n");
381 		return -1;
382 	}
383 
384 	in_out_fd = rk_crypto_mem_alloc(TEST_BLOCK_SIZE);
385 	if (!in_out_fd) {
386 		printf("rk_crypto_mem_alloc %uByte error!\n", TEST_BLOCK_SIZE);
387 		res = -1;
388 		goto out;
389 	}
390 
391 	if (posix_memalign((void *)&in_out_virt, page_size, TEST_BLOCK_SIZE) || !in_out_virt) {
392 		printf("malloc %uByte error!\n", TEST_BLOCK_SIZE);
393 		res = -1;
394 		goto out;
395 	}
396 
397 	/* Test dma_fd cipher */
398 	for (h = 0; h < ARRAY_SIZE(test_item_tbl); h++) {
399 		for (j = 0; j < ARRAY_SIZE(test_item_tbl[h].modes); j++) {
400 			if (test_item_tbl[h].modes[j] == DATA_BUTT)
401 				break;
402 
403 			for (k = 0; k < ARRAY_SIZE(test_item_tbl[h].op); k++) {
404 				algo      = test_item_tbl[h].algo;
405 				key_len   = test_item_tbl[h].key_len;
406 				mode      = test_item_tbl[h].modes[j];
407 				operation = test_item_tbl[h].op[k];
408 				len       = TEST_BLOCK_SIZE;
409 
410 				if (test_cipher_item_tp(false, key_len, algo, mode,
411 							operation, in_out_fd, len)) {
412 					printf("dma_fd:\ttest cipher throughput FAILED!!!\n");
413 					res = -1;
414 					goto out;
415 				}
416 			}
417 		}
418 	}
419 
420 	printf("dma_fd:\ttest cipher throughput SUCCESS.\n\n");
421 
422 	/* Test virt cipher */
423 	for (h = 0; h < ARRAY_SIZE(test_item_tbl); h++) {
424 		for (j = 0; j < ARRAY_SIZE(test_item_tbl[h].modes); j++) {
425 			if (test_item_tbl[h].modes[j] == DATA_BUTT)
426 				break;
427 
428 			for (k = 0; k < ARRAY_SIZE(test_item_tbl[h].op); k++) {
429 				algo      = test_item_tbl[h].algo;
430 				key_len   = test_item_tbl[h].key_len;
431 				mode      = test_item_tbl[h].modes[j];
432 				operation = test_item_tbl[h].op[k];
433 				len       = TEST_BLOCK_SIZE;
434 
435 				if (test_cipher_item_tp(true, key_len, algo, mode,
436 							operation, in_out_virt, len)) {
437 					printf("virt:\ttest cipher throughput FAILED!!!\n");
438 					res = -1;
439 					goto out;
440 				}
441 			}
442 		}
443 	}
444 
445 	printf("virt:\ttest cipher throughput SUCCESS.\n\n");
446 
447 out:
448 	if (in_out_fd)
449 		rk_crypto_mem_free(in_out_fd);
450 
451 	if (in_out_virt)
452 		free(in_out_virt);
453 
454 	rk_crypto_deinit();
455 	return res;
456 }
457 
test_ae_item_tp(bool is_virt,uint32_t key_len,uint32_t algo,uint32_t mode,void * in,void * out,uint32_t data_len,void * aad,uint32_t aad_len,void * tag)458 static int test_ae_item_tp(bool is_virt, uint32_t key_len, uint32_t algo,
459 			   uint32_t mode, void *in, void *out, uint32_t data_len,
460 			   void *aad, uint32_t aad_len, void *tag)
461 {
462 	uint32_t res = 0;
463 	rk_handle handle = 0;
464 	rk_ae_config config;
465 	struct timespec start, end;
466 	uint64_t total_nsec, nsec;
467 	uint32_t rounds;
468 	uint8_t iv_tmp[32];
469 
470 	nsec = DURATION * 1000000000;
471 
472 	test_get_rng(config.iv, sizeof(config.iv));
473 	test_get_rng(config.key, key_len);
474 
475 	memcpy(iv_tmp, config.iv, sizeof(config.iv));
476 
477 	if (is_virt) {
478 		test_get_rng(in, data_len);
479 		test_get_rng(aad, aad_len);
480 	} else {
481 		test_get_rng(((rk_crypto_mem *)in)->vaddr, data_len);
482 		test_get_rng(((rk_crypto_mem *)aad)->vaddr, aad_len);
483 	}
484 
485 	config.algo      = algo;
486 	config.mode      = mode;
487 	config.key_len   = key_len;
488 	config.reserved  = NULL;
489 	config.aad_len   = aad_len;
490 	config.iv_len    = 12;
491 	config.tag_len   = 16;
492 
493 	/* ENC */
494 	config.operation = RK_OP_CIPHER_ENC;
495 	total_nsec = 0;
496 	rounds = 0;
497 
498 	while (total_nsec < nsec) {
499 		clock_gettime(CLOCK_REALTIME, &start);
500 
501 		res = rk_ae_init(&config, &handle);
502 		if (res) {
503 			if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
504 				printf("test rk_ae_init failed! 0x%08x\n", res);
505 				goto error;
506 			}
507 
508 			if (is_virt)
509 				printf("virt:\t[%s-%u]\t%s\tN/A\n",
510 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
511 			else
512 				printf("dma_fd:\t[%s-%u]\t%s\tN/A\n",
513 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
514 			return 0;
515 		}
516 
517 		if (is_virt) {
518 			res = rk_ae_set_aad_virt(handle, aad);
519 			if (res) {
520 				rk_ae_final(handle);
521 				goto error;
522 			}
523 			res = rk_ae_crypt_virt(handle, in, out, data_len, tag);
524 		} else {
525 			res = rk_ae_set_aad(handle, ((rk_crypto_mem *)aad)->dma_fd);
526 			if (res) {
527 				rk_ae_final(handle);
528 				goto error;
529 			}
530 
531 			res = rk_ae_crypt(handle,
532 					  ((rk_crypto_mem *)in)->dma_fd,
533 					  ((rk_crypto_mem *)out)->dma_fd,
534 					  data_len,
535 					  tag);
536 		}
537 
538 		if (res) {
539 			rk_ae_final(handle);
540 			printf("test rk_ad_crypt failed! 0x%08x\n", res);
541 			goto error;
542 		}
543 
544 		rk_ae_final(handle);
545 
546 		clock_gettime(CLOCK_REALTIME, &end);
547 		total_nsec += (end.tv_sec - start.tv_sec) * 1000000000 +
548 			      (end.tv_nsec - start.tv_nsec);
549 		rounds ++;
550 	}
551 
552 	if (is_virt)
553 		printf("virt:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
554 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
555 		       test_op_name(config.operation), (data_len * rounds / (1024 * 1024)));
556 	else
557 		printf("dma_fd:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
558 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
559 		       test_op_name(config.operation), (data_len * rounds / (1024 * 1024)));
560 
561 	/* DEC */
562 	config.operation = RK_OP_CIPHER_DEC;
563 	memcpy(config.iv, iv_tmp, config.iv_len);
564 	total_nsec = 0;
565 	rounds = 0;
566 	while (total_nsec < nsec) {
567 		clock_gettime(CLOCK_REALTIME, &start);
568 
569 		res = rk_ae_init(&config, &handle);
570 		if (res) {
571 			if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
572 				printf("test rk_ae_init failed! 0x%08x\n", res);
573 				goto error;
574 			}
575 
576 			if (is_virt)
577 				printf("virt:\t[%s-%u]\t%s\tN/A\n",
578 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
579 			else
580 				printf("dma_fd:\t[%s-%u]\t%s\tN/A\n",
581 				       test_algo_name(algo), key_len * 8, test_mode_name(mode));
582 			return 0;
583 		}
584 
585 		if (is_virt) {
586 			res = rk_ae_set_aad_virt(handle, aad);
587 			if (res) {
588 				rk_ae_final(handle);
589 				goto error;
590 			}
591 			res = rk_ae_crypt_virt(handle, out, in, data_len, tag);
592 		} else {
593 			res = rk_ae_set_aad(handle, ((rk_crypto_mem *)aad)->dma_fd);
594 			if (res) {
595 				rk_ae_final(handle);
596 				goto error;
597 			}
598 
599 			res = rk_ae_crypt(handle,
600 					  ((rk_crypto_mem *)out)->dma_fd,
601 					  ((rk_crypto_mem *)in)->dma_fd,
602 					  data_len,
603 					  tag);
604 		}
605 
606 		if (res) {
607 			rk_ae_final(handle);
608 			printf("test rk_ad_crypt failed! 0x%08x\n", res);
609 			goto error;
610 		}
611 
612 		rk_ae_final(handle);
613 
614 		clock_gettime(CLOCK_REALTIME, &end);
615 		total_nsec += (end.tv_sec - start.tv_sec) * 1000000000 +
616 			      (end.tv_nsec - start.tv_nsec);
617 		rounds ++;
618 	}
619 
620 	if (is_virt)
621 		printf("virt:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
622 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
623 		       test_op_name(config.operation), (data_len * rounds / (1024 * 1024)));
624 	else
625 		printf("dma_fd:\t[%s-%u]\t%s\t%s\t%dMB/s.\n",
626 		       test_algo_name(algo), key_len * 8, test_mode_name(mode),
627 		       test_op_name(config.operation), (data_len * rounds / (1024 * 1024)));
628 
629 	return res;
630 error:
631 	if (is_virt)
632 		printf("virt:\t[%s-%u]\t%s\tFailed.\n",
633 		       test_algo_name(algo), key_len * 8, test_mode_name(mode));
634 	else
635 		printf("dma_fd:\t[%s-%u]\t%s\tFailed.\n",
636 		       test_algo_name(algo), key_len * 8, test_mode_name(mode));
637 	return res;
638 }
639 
test_ae_tp(void)640 static int test_ae_tp(void)
641 {
642 	int res = 0;
643 	uint32_t h, j;
644 	uint32_t algo, mode, len, key_len, aad_len;
645 	rk_crypto_mem *in_fd = NULL, *out_fd = NULL, *aad_fd = NULL;
646 	uint8_t *in_virt = NULL, *out_virt = NULL, *aad_virt = NULL;
647 	size_t page_size = getpagesize();
648 	uint32_t aad_buff_len = 1024;
649 	uint8_t tag[16];
650 
651 	struct test_aead_item_tp {
652 		uint32_t algo;
653 		uint32_t modes[RK_CIPHER_MODE_MAX];
654 		uint32_t key_len;
655 		uint32_t aad_len;
656 		uint32_t len;
657 	};
658 
659 	static struct test_aead_item_tp test_item_tbl[] = {
660 		{
661 			.algo  = RK_ALGO_AES,
662 			.modes = {
663 				RK_CIPHER_MODE_GCM,
664 				DATA_BUTT,
665 			},
666 			.key_len = 32,
667 			.aad_len = 1024,
668 			.len     = TEST_BLOCK_SIZE,
669 		},
670 
671 		{
672 			.algo  = RK_ALGO_SM4,
673 			.modes = {
674 				RK_CIPHER_MODE_GCM,
675 				DATA_BUTT,
676 			},
677 			.key_len = 16,
678 			.aad_len = 1024,
679 			.len     = TEST_BLOCK_SIZE,
680 		},
681 	};
682 
683 	if (rk_crypto_init()) {
684 		printf("rk_crypto_init error!\n");
685 		return -1;
686 	}
687 
688 	in_fd = rk_crypto_mem_alloc(TEST_BLOCK_SIZE);
689 	if (!in_fd) {
690 		printf("rk_crypto_mem_alloc %uByte error!\n", TEST_BLOCK_SIZE);
691 		res = -1;
692 		goto out;
693 	}
694 
695 	out_fd = rk_crypto_mem_alloc(TEST_BLOCK_SIZE);
696 	if (!out_fd) {
697 		printf("rk_crypto_mem_alloc %uByte error!\n", TEST_BLOCK_SIZE);
698 		res = -1;
699 		goto out;
700 	}
701 
702 	aad_fd = rk_crypto_mem_alloc(aad_buff_len);
703 	if (!aad_fd) {
704 		printf("rk_crypto_mem_alloc %uByte error!\n", aad_buff_len);
705 		res = -1;
706 		goto out;
707 	}
708 
709 	if (posix_memalign((void *)&in_virt, page_size, TEST_BLOCK_SIZE) || !in_virt) {
710 		printf("malloc %uByte error!\n", TEST_BLOCK_SIZE);
711 		res = -1;
712 		goto out;
713 	}
714 
715 	if (posix_memalign((void *)&out_virt, page_size, TEST_BLOCK_SIZE) || !out_virt) {
716 		printf("malloc %uByte error!\n", TEST_BLOCK_SIZE);
717 		res = -1;
718 		goto out;
719 	}
720 
721 	if (posix_memalign((void *)&aad_virt, page_size, aad_buff_len) || !aad_virt) {
722 		printf("malloc %uByte error!\n", aad_buff_len);
723 		res = -1;
724 		goto out;
725 	}
726 
727 	/* Test dma_fd cipher */
728 	for (h = 0; h < ARRAY_SIZE(test_item_tbl); h++) {
729 		for (j = 0; j < ARRAY_SIZE(test_item_tbl[h].modes); j++) {
730 			if (test_item_tbl[h].modes[j] == DATA_BUTT)
731 				break;
732 
733 			algo      = test_item_tbl[h].algo;
734 			key_len   = test_item_tbl[h].key_len;
735 			mode      = test_item_tbl[h].modes[j];
736 			aad_len   = test_item_tbl[h].aad_len;
737 			len       = test_item_tbl[h].len;
738 
739 			if (test_ae_item_tp(false, key_len, algo, mode,
740 					    in_fd, out_fd, len,
741 					    aad_fd, aad_len, tag)) {
742 				printf("dma_fd:\ttest aead throughput FAILED!!!\n");
743 				res = -1;
744 				goto out;
745 			}
746 		}
747 	}
748 
749 	printf("dma_fd:\ttest aead throughput SUCCESS.\n\n");
750 
751 	/* Test virt cipher */
752 	for (h = 0; h < ARRAY_SIZE(test_item_tbl); h++) {
753 		for (j = 0; j < ARRAY_SIZE(test_item_tbl[h].modes); j++) {
754 			if (test_item_tbl[h].modes[j] == DATA_BUTT)
755 				break;
756 
757 			algo      = test_item_tbl[h].algo;
758 			key_len   = test_item_tbl[h].key_len;
759 			mode      = test_item_tbl[h].modes[j];
760 			aad_len   = test_item_tbl[h].aad_len;
761 			len       = test_item_tbl[h].len;
762 
763 			if (test_ae_item_tp(true, key_len, algo, mode,
764 					    in_virt, out_virt, len,
765 					    aad_virt, aad_len, tag)) {
766 				printf("virt:\ttest aead throughput FAILED!!!\n");
767 				res = -1;
768 				goto out;
769 			}
770 		}
771 	}
772 
773 	printf("virt:\ttest aead throughput SUCCESS.\n\n");
774 
775 out:
776 	if (in_fd)
777 		rk_crypto_mem_free(in_fd);
778 
779 	if (out_fd)
780 		rk_crypto_mem_free(out_fd);
781 
782 	if (aad_fd)
783 		rk_crypto_mem_free(aad_fd);
784 
785 	if (in_virt)
786 		free(in_virt);
787 
788 	if (out_virt)
789 		free(out_virt);
790 
791 	if (aad_virt)
792 		free(aad_virt);
793 
794 	rk_crypto_deinit();
795 	return res;
796 }
797 
test_hash_item_tp(bool is_virt,bool is_hmac,uint32_t algo,uint32_t blocksize,void * input,uint32_t data_len)798 static int test_hash_item_tp(bool is_virt, bool is_hmac, uint32_t algo,
799 			     uint32_t blocksize, void *input, uint32_t data_len)
800 {
801 	int res = 0;
802 	uint32_t data_block = data_len;
803 	uint32_t tmp_len;
804 	uint8_t hash[64];
805 	uint8_t key[MAX_HASH_BLOCK_SIZE];
806 	uint8_t *tmp_data;
807 	rk_handle hash_hdl = 0;
808 	rk_hash_config hash_cfg;
809 	uint32_t key_len;
810 	struct timespec start, end;
811 	uint64_t total_nsec, nsec;
812 	uint32_t rounds;
813 
814 	nsec = DURATION * 1000000000;
815 
816 	if (is_virt)
817 		test_get_rng(input, data_len);
818 
819 	memset(hash, 0x00, sizeof(hash));
820 
821 	memset(&hash_cfg, 0x00, sizeof(hash_cfg));
822 	hash_cfg.algo = algo;
823 
824 	if (is_hmac) {
825 		key_len = blocksize;
826 		test_get_rng(key, key_len);
827 		hash_cfg.key     = key;
828 		hash_cfg.key_len = key_len;
829 	}
830 
831 	total_nsec = 0;
832 	rounds = 0;
833 
834 	res = rk_hash_init(&hash_cfg, &hash_hdl);
835 	if (res) {
836 		if (is_virt)
837 			printf("virt:\t[%12s]\tN/A\n", test_algo_name(algo));
838 		else
839 			printf("dma_fd:\t[%12s]\tN/A\n", test_algo_name(algo));
840 		return 0;
841 	}
842 
843 	while (total_nsec < nsec) {
844 		clock_gettime(CLOCK_REALTIME, &start);
845 
846 		data_block = data_len;
847 
848 		if (is_virt) {
849 			tmp_len    = data_len;
850 			tmp_data   = input;
851 
852 			while (tmp_len) {
853 				data_block = tmp_len > data_block ? data_block : tmp_len;
854 
855 				res = rk_hash_update_virt(hash_hdl, tmp_data, data_block);
856 				if (res) {
857 					rk_hash_final(hash_hdl, NULL);
858 					printf("rk_hash_update_virt[%lu/%u] error = %d\n",
859 					       (unsigned long)(tmp_data - (uint8_t *)input), tmp_len, res);
860 					goto error;
861 				}
862 
863 				tmp_len -= data_block;
864 				tmp_data += data_block;
865 			}
866 		} else {
867 			res = rk_hash_update(hash_hdl, ((rk_crypto_mem *)input)->dma_fd, data_block);
868 			if (res) {
869 				rk_hash_final(hash_hdl, NULL);
870 				printf("rk_hash_update error = %d\n", res);
871 				goto error;
872 			}
873 		}
874 
875 		clock_gettime(CLOCK_REALTIME, &end);
876 		total_nsec += (end.tv_sec - start.tv_sec) * 1000000000 +
877 			      (end.tv_nsec - start.tv_nsec);
878 		rounds ++;
879 	}
880 
881 	res = rk_hash_final(hash_hdl, hash);
882 	if (res) {
883 		printf("rk_hash_final error = %d\n", res);
884 		return -1;
885 	}
886 
887 	if (is_virt)
888 		printf("virt:\t[%12s]\t%dMB/s.\n",
889 		       test_algo_name(algo), (data_len * rounds / (1024 * 1024)));
890 	else
891 		printf("dma_fd:\t[%12s]\t%dMB/s.\n",
892 		       test_algo_name(algo), (data_len * rounds / (1024 * 1024)));
893 
894 	return res;
895 error:
896 	return res;
897 }
898 
test_hash_tp(void)899 static int test_hash_tp(void)
900 {
901 	int res;
902 	uint32_t buffer_len = TEST_BLOCK_SIZE;;
903 	rk_crypto_mem *input_fd = NULL;
904 	uint8_t *input_virt = NULL;
905 	uint32_t i;
906 	size_t page_size = getpagesize();
907 
908 	struct test_hash_item {
909 		uint32_t algo;
910 		uint32_t blocksize;
911 	};
912 
913 	static struct test_hash_item test_hash_tbl[] = {
914 		{RK_ALGO_MD5,        MD5_BLOCK_SIZE},
915 		{RK_ALGO_SHA1,       SHA1_BLOCK_SIZE},
916 		{RK_ALGO_SHA256,     SHA256_BLOCK_SIZE},
917 		{RK_ALGO_SHA224,     SHA224_BLOCK_SIZE},
918 		{RK_ALGO_SHA512,     SHA512_BLOCK_SIZE},
919 		{RK_ALGO_SHA384,     SHA384_BLOCK_SIZE},
920 		{RK_ALGO_SHA512_224, SHA512_224_BLOCK_SIZE},
921 		{RK_ALGO_SHA512_256, SHA512_256_BLOCK_SIZE},
922 		{RK_ALGO_SM3,        SM3_BLOCK_SIZE},
923 	};
924 
925 	static struct test_hash_item test_hmac_tbl[] = {
926 		{RK_ALGO_HMAC_MD5,    MD5_BLOCK_SIZE},
927 		{RK_ALGO_HMAC_SHA1,   SHA1_BLOCK_SIZE},
928 		{RK_ALGO_HMAC_SHA256, SHA256_BLOCK_SIZE},
929 		{RK_ALGO_HMAC_SHA512, SHA512_BLOCK_SIZE},
930 		{RK_ALGO_HMAC_SM3,    SM3_BLOCK_SIZE},
931 	};
932 
933 	if (rk_crypto_init()) {
934 		printf("rk_crypto_init error!\n");
935 		return -1;
936 	}
937 
938 	input_fd = rk_crypto_mem_alloc(buffer_len);
939 	if (!input_fd) {
940 		printf("rk_crypto_mem_alloc %uByte error!\n", buffer_len);
941 		res = -1;
942 		goto out;
943 	}
944 
945 	if (posix_memalign((void *)&input_virt, page_size, TEST_BLOCK_SIZE) || !input_virt) {
946 		printf("malloc %uByte error!\n", TEST_BLOCK_SIZE);
947 		res = -1;
948 		goto out;
949 	}
950 
951 	/* Test virt hash */
952 	for (i = 0; i < ARRAY_SIZE(test_hash_tbl); i++) {
953 		res = test_hash_item_tp(true, false, test_hash_tbl[i].algo,
954 					test_hash_tbl[i].blocksize, input_virt, buffer_len);
955 		if (res) {
956 			printf("virt:\ttest hash throughput FAILED!!!\n");
957 			goto out;
958 		}
959 	}
960 
961 	printf("virt:\ttest hash throughput SUCCESS.\n\n");
962 
963 	/* Test dma_fd hash */
964 	for (i = 0; i < ARRAY_SIZE(test_hash_tbl); i++) {
965 		res = test_hash_item_tp(false, false, test_hash_tbl[i].algo,
966 					test_hash_tbl[i].blocksize, input_fd, buffer_len);
967 		if (res) {
968 			printf("dma_fd:\ttest hash throughput FAILED!!!\n");
969 			goto out;
970 		}
971 	}
972 
973 	printf("dma_fd:\ttest hash throughput SUCCESS.\n\n");
974 
975 	/* Test virt hmac */
976 	for (i = 0; i < ARRAY_SIZE(test_hmac_tbl); i++) {
977 		res = test_hash_item_tp(true, true, test_hmac_tbl[i].algo,
978 					test_hmac_tbl[i].blocksize, input_virt, buffer_len);
979 		if (res) {
980 			printf("virt:\ttest hmac throughput FAILED!!!\n");
981 			goto out;
982 		}
983 	}
984 
985 	printf("virt:\ttest hmac throughput SUCCESS.\n\n");
986 
987 	/* Test dma_fd hmac */
988 	for (i = 0; i < ARRAY_SIZE(test_hmac_tbl); i++) {
989 		res = test_hash_item_tp(false, true, test_hmac_tbl[i].algo,
990 					test_hmac_tbl[i].blocksize, input_fd, buffer_len);
991 		if (res) {
992 			printf("dma_fd:\ttest hmac throughput FAILED!!!\n");
993 			goto out;
994 		}
995 	}
996 
997 	printf("dma_fd:\ttest hmac throughput SUCCESS.\n\n");
998 
999 out:
1000 	if (input_fd)
1001 		rk_crypto_mem_free(input_fd);
1002 
1003 	if (input_virt)
1004 		free(input_virt);
1005 
1006 	rk_crypto_deinit();
1007 
1008 	return 0;
1009 }
1010 
test_rsa_item_tp(uint32_t nbits)1011 static int test_rsa_item_tp(uint32_t nbits)
1012 {
1013 	uint8_t *data_plain = NULL, *data_enc = NULL, *data_dec = NULL;
1014 	uint32_t nbytes = nbits / 8;
1015 	rk_rsa_pub_key_pack pub_key;
1016 	rk_rsa_priv_key_pack priv_key;
1017 	struct timespec t1, t2, t3;
1018 	uint64_t priv_cost, pub_cost;
1019 	uint32_t out_len = 0;
1020 	RK_RES res;
1021 
1022 	data_plain = malloc(nbytes);
1023 	if (!data_plain) {
1024 		printf("malloc data_plain %uByte error!\n", nbytes);
1025 		res = RK_CRYPTO_ERR_OUT_OF_MEMORY;
1026 		goto exit;
1027 	}
1028 
1029 	data_enc = malloc(nbytes);
1030 	if (!data_enc) {
1031 		printf("malloc data_enc %uByte error!\n", nbytes);
1032 		res = RK_CRYPTO_ERR_OUT_OF_MEMORY;
1033 		goto exit;
1034 	}
1035 
1036 	data_dec = malloc(nbytes);
1037 	if (!data_dec) {
1038 		printf("malloc data_dec %uByte error!\n", nbytes);
1039 		res = RK_CRYPTO_ERR_OUT_OF_MEMORY;
1040 		goto exit;
1041 	}
1042 
1043 	res = rk_get_random(data_plain, nbytes);
1044 	if (res) {
1045 		printf("failed to get random data.");
1046 		goto exit;
1047 	}
1048 
1049 	/* make sure data_plain is less than n */
1050 	data_plain[0] = 0x00;
1051 
1052 	memset(data_enc, 0x00, nbytes);
1053 
1054 	test_init_pubkey(&pub_key, nbits);
1055 	test_init_privkey(&priv_key, nbits);
1056 
1057 	clock_gettime(CLOCK_REALTIME, &t1);
1058 
1059 	res = rk_rsa_priv_encrypt(&priv_key, RK_RSA_CRYPT_PADDING_NONE,
1060 				  data_plain, nbytes, data_enc, &out_len);
1061 	if (res) {
1062 		if (res != RK_CRYPTO_ERR_NOT_SUPPORTED)
1063 			printf("rk_rsa_priv_encrypt failed %x\n", res);
1064 		goto exit;
1065 	}
1066 
1067 	clock_gettime(CLOCK_REALTIME, &t2);
1068 
1069 	res = rk_rsa_pub_decrypt(&pub_key, RK_RSA_CRYPT_PADDING_NONE,
1070 				 data_enc, out_len, data_dec, &out_len);
1071 	if (res) {
1072 		printf("rk_rsa_pub_decrypt failed %x\n", res);
1073 		goto exit;
1074 	}
1075 
1076 	clock_gettime(CLOCK_REALTIME, &t3);
1077 
1078 	if (nbytes != out_len || memcmp(data_dec, data_plain, nbytes)) {
1079 		printf("rk_rsa_pub_decrypt compare failed\n");
1080 		test_dump_hex("result", data_dec, out_len);
1081 		test_dump_hex("expect", data_plain, nbytes);
1082 		res = RK_CRYPTO_ERR_GENERIC;
1083 		goto exit;
1084 	}
1085 
1086 	priv_cost = (t2.tv_sec - t1.tv_sec) * 1000000000 +
1087 		    (t2.tv_nsec - t1.tv_nsec);
1088 
1089 	pub_cost = (t3.tv_sec - t2.tv_sec) * 1000000000 +
1090 		   (t3.tv_nsec - t2.tv_nsec);
1091 
1092 
1093 	printf("virt:\t[RSA-%u]\tPRIV\tENCRYPT\t%lums.\n",
1094 	       nbits, (unsigned long)(priv_cost / 1000000));
1095 
1096 	printf("virt:\t[RSA-%u]\tPUB\tDECRYPT\t%lums.\n",
1097 	       nbits, (unsigned long)(pub_cost / 1000000));
1098 
1099 exit:
1100 	if (data_plain)
1101 		free(data_plain);
1102 
1103 	if (data_enc)
1104 		free(data_enc);
1105 
1106 	if (data_dec)
1107 		free(data_dec);
1108 
1109 	return (res == RK_CRYPTO_SUCCESS) ? 0 : -1;
1110 }
1111 
test_rsa_tp(void)1112 static int test_rsa_tp(void)
1113 {
1114 	int res;
1115 	uint32_t i;
1116 	uint32_t rsa_bits_tbl[] = {
1117 		RSA_BITS_1024,
1118 		RSA_BITS_2048,
1119 		RSA_BITS_3072,
1120 		RSA_BITS_4096,
1121 	};
1122 
1123 	if (rk_crypto_init()) {
1124 		printf("rk_crypto_init error!\n");
1125 		return -1;
1126 	}
1127 
1128 	for (i = 0; i < ARRAY_SIZE(rsa_bits_tbl); i++) {
1129 		res = test_rsa_item_tp(rsa_bits_tbl[i]);
1130 		if (res) {
1131 			printf("test rsa-%u throughput FAIL.\n\n", rsa_bits_tbl[i]);
1132 			goto out;
1133 		}
1134 	}
1135 
1136 	printf("test rsa throughput SUCCESS.\n\n");
1137 
1138 out:
1139 	rk_crypto_deinit();
1140 
1141 	return 0;
1142 }
1143 
test_throughput(void)1144 RK_RES test_throughput(void)
1145 {
1146 	if (test_otp_key_tp())
1147 		printf("Test otp key throughput FAILED.\n\n");
1148 
1149 	if (test_cipher_tp())
1150 		printf("Test cipher throughput FAILED.\n\n");
1151 
1152 	if (test_ae_tp())
1153 		printf("Test ae throughput FAILED.\n\n");
1154 
1155 	if (test_hash_tp())
1156 		printf("Test hash throughput FAILED.\n\n");
1157 
1158 	if (test_rsa_tp())
1159 		printf("Test rsa throughput FAILED.\n\n");
1160 
1161 	printf("Test throughput SUCCESS.\n");
1162 
1163 	return RK_CRYPTO_SUCCESS;
1164 }
1165