xref: /OK3568_Linux_fs/external/security/librkcrypto/test/test_cipher.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
3  */
4 #include <stdlib.h>
5 #include <string.h>
6 #include <time.h>
7 #include <unistd.h>
8 #include "rkcrypto_core.h"
9 #include "rkcrypto_mem.h"
10 #include "rkcrypto_trace.h"
11 #include "cmode_adapter.h"
12 #include "test_cipher.h"
13 #include "test_utils.h"
14 
15 #define DATA_BUTT	0xFFFFFFFF
16 #define TEST_DATA_MAX	(1024 * 1024)
17 #define MULTI_BLOCKSIZE	(256 * 1024)
18 
19 struct test_cipher_item {
20 	uint32_t algo;
21 	uint32_t modes[RK_CIPHER_MODE_MAX];
22 	uint32_t key_lens[4];
23 	uint32_t iv_len;
24 };
25 
26 static struct test_cipher_item test_item_tbl[] = {
27 {
28 	.algo  = RK_ALGO_DES,
29 	.modes = {
30 		RK_CIPHER_MODE_ECB,
31 		RK_CIPHER_MODE_CBC,
32 		RK_CIPHER_MODE_CFB,
33 		RK_CIPHER_MODE_OFB,
34 		DATA_BUTT,
35 	},
36 	.key_lens = {8},
37 	.iv_len   = DES_BLOCK_SIZE,
38 },
39 
40 {
41 	.algo  = RK_ALGO_TDES,
42 	.modes = {
43 		RK_CIPHER_MODE_ECB,
44 		RK_CIPHER_MODE_CBC,
45 		RK_CIPHER_MODE_CFB,
46 		RK_CIPHER_MODE_OFB,
47 		DATA_BUTT,
48 	},
49 	.key_lens = {24},
50 	.iv_len   = DES_BLOCK_SIZE,
51 },
52 
53 {
54 	.algo  = RK_ALGO_AES,
55 	.modes = {
56 		RK_CIPHER_MODE_ECB,
57 		RK_CIPHER_MODE_CBC,
58 		RK_CIPHER_MODE_CTS,
59 		RK_CIPHER_MODE_CTR,
60 		RK_CIPHER_MODE_CFB,
61 		RK_CIPHER_MODE_OFB,
62 		RK_CIPHER_MODE_XTS,
63 		DATA_BUTT,
64 	},
65 	.key_lens = {16, 24, 32},
66 	.iv_len   = AES_BLOCK_SIZE,
67 },
68 
69 {
70 	.algo  = RK_ALGO_SM4,
71 	.modes = {
72 		RK_CIPHER_MODE_ECB,
73 		RK_CIPHER_MODE_CBC,
74 		RK_CIPHER_MODE_CTS,
75 		RK_CIPHER_MODE_CTR,
76 		RK_CIPHER_MODE_CFB,
77 		RK_CIPHER_MODE_OFB,
78 		RK_CIPHER_MODE_XTS,
79 		DATA_BUTT,
80 	},
81 	.key_lens = {16},
82 	.iv_len   = SM4_BLOCK_SIZE,
83 },
84 
85 };
86 
test_cipher_item_virt(const struct test_cipher_item * item,int verbose)87 static RK_RES test_cipher_item_virt(const struct test_cipher_item *item, int verbose)
88 {
89 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
90 	uint32_t i, j, k;
91 	uint32_t ops[] = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC};
92 	uint32_t data_len = TEST_DATA_MAX;
93 	rk_handle cipher_hdl = 0;
94 	rk_cipher_config cipher_cfg;
95 	uint8_t *plain = NULL, *cipher_soft = NULL, *cipher_hard = NULL;
96 	uint32_t algo = 0, mode = 0, key_len, iv_len, operation;
97 	uint32_t loop_nbytes, tmp_len;
98 	uint8_t *tmp_data_in, *tmp_data_out;
99 	uint8_t iv_tmp[AES_BLOCK_SIZE];
100 	size_t page_size = getpagesize();
101 
102 	if (posix_memalign((void *)&plain, page_size, data_len) || !plain) {
103 		E_TRACE("plain malloc %uByte error!\n", data_len);
104 		goto exit;
105 	}
106 
107 	if (posix_memalign((void *)&cipher_soft, page_size, data_len) || !cipher_soft) {
108 		E_TRACE("cipher_soft malloc %uByte error!\n", data_len);
109 		goto exit;
110 	}
111 
112 	if (posix_memalign((void *)&cipher_hard, page_size, data_len) || !cipher_hard) {
113 		E_TRACE("cipher_hard malloc %uByte error!\n", data_len);
114 		goto exit;
115 	}
116 
117 	test_get_rng(plain, data_len);
118 
119 	memset(cipher_soft, 0x00, data_len);
120 	memset(cipher_hard, 0x00, data_len);
121 
122 	for (i = 0; i < ARRAY_SIZE(item->modes); i++) {
123 		algo = item->algo;
124 		mode = item->modes[i];
125 
126 		if (mode == DATA_BUTT)
127 			break;
128 
129 		for (j = 0; j < ARRAY_SIZE(item->key_lens); j++) {
130 			key_len = item->key_lens[j];
131 			iv_len  = item->iv_len;
132 
133 			if (key_len == 0)
134 				break;
135 
136 			if (mode == RK_CIPHER_MODE_XTS)
137 				key_len *= 2;
138 
139 			for (k = 0; k < ARRAY_SIZE(ops); k++) {
140 				operation = ops[k];
141 
142 				memset(&cipher_cfg, 0x00, sizeof(cipher_cfg));
143 				cipher_cfg.algo      = algo;
144 				cipher_cfg.mode      = mode;
145 				cipher_cfg.operation = operation;
146 				cipher_cfg.key_len   = key_len;
147 
148 				test_get_rng(cipher_cfg.key, key_len);
149 				test_get_rng(cipher_cfg.iv, iv_len);
150 				memcpy(iv_tmp, cipher_cfg.iv, iv_len);
151 
152 				res = rk_cipher_init(&cipher_cfg, &cipher_hdl);
153 				if (res) {
154 					if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
155 						E_TRACE("rk_cipher_init error[%x]\n", res);
156 						goto exit;
157 					}
158 
159 					if (verbose)
160 						printf("virt:\t[%s-%u]\t%s\t%s\tN/A\n",
161 						       test_algo_name(algo), key_len * 8,
162 						       test_mode_name(mode),
163 						       test_op_name(operation));
164 					res = RK_CRYPTO_SUCCESS;
165 					continue;
166 				}
167 
168 				if (is_no_multi_blocksize(mode))
169 					data_len = TEST_DATA_MAX - 3;
170 				else
171 					data_len = TEST_DATA_MAX;
172 
173 				/* chain multi crypt */
174 				loop_nbytes  = data_len;
175 				tmp_data_in  = plain;
176 				tmp_data_out = cipher_hard;
177 
178 				while (loop_nbytes) {
179 
180 					tmp_len = loop_nbytes > MULTI_BLOCKSIZE ? MULTI_BLOCKSIZE : loop_nbytes;
181 
182 					res = rk_cipher_crypt_virt(cipher_hdl, tmp_data_in,
183 								   tmp_data_out, tmp_len);
184 					if (res) {
185 						rk_cipher_final(cipher_hdl);
186 						E_TRACE("rk_cipher_crypt_virt error[%x]\n", res);
187 						goto exit;
188 					}
189 
190 					tmp_data_in  += tmp_len;
191 					tmp_data_out += tmp_len;
192 					loop_nbytes  -= tmp_len;
193 				}
194 
195 				rk_cipher_final(cipher_hdl);
196 				cipher_hdl = 0;
197 
198 				res = soft_cipher(algo, mode, operation,
199 						  cipher_cfg.key, cipher_cfg.key_len, iv_tmp,
200 						  plain, data_len, cipher_soft);
201 				if (res) {
202 					E_TRACE("soft_cipher error[%x]\n", res);
203 					goto exit;
204 				}
205 
206 				/* Verify the result */
207 				if (memcmp(cipher_hard, cipher_soft, data_len) != 0) {
208 					E_TRACE("rkcrypto_test_cipher_virt compare failed.\n");
209 //					test_dump_hex("cipher_hard", cipher_hard, data_len);
210 //					test_dump_hex("cipher_soft", cipher_soft, data_len);
211 					res = RK_CRYPTO_ERR_GENERIC;
212 					goto exit;
213 				}
214 
215 				if (verbose)
216 					printf("virt:\t[%s-%u]\t%s\t%s\tPASS\n",
217 					       test_algo_name(algo), key_len * 8,
218 					       test_mode_name(mode), test_op_name(operation));
219 			}
220 		}
221 	}
222 
223 	res = RK_CRYPTO_SUCCESS;
224 exit:
225 	if (plain)
226 		free(plain);
227 
228 	if (cipher_soft)
229 		free(cipher_soft);
230 
231 	if (cipher_hard)
232 		free(cipher_hard);
233 
234 	if (res)
235 		printf("virt:\t[%s-%u]\t%s\t%s\tFAIL\n",
236 		       test_algo_name(algo), key_len * 8,
237 		       test_mode_name(mode), test_op_name(operation));
238 
239 	return res;
240 }
241 
test_cipher_item_fd(const struct test_cipher_item * item,int verbose)242 static RK_RES test_cipher_item_fd(const struct test_cipher_item *item, int verbose)
243 {
244 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
245 	uint32_t i, j, k;
246 	uint32_t ops[] = {RK_OP_CIPHER_ENC, RK_OP_CIPHER_DEC};
247 	uint32_t data_len = TEST_DATA_MAX;
248 	rk_handle cipher_hdl = 0;
249 	rk_cipher_config cipher_cfg;
250 	rk_crypto_mem *plain = NULL, *cipher_soft = NULL, *cipher_hard = NULL;
251 	uint32_t algo = 0, mode = 0, key_len = 0, iv_len, operation;
252 	uint8_t iv_tmp[AES_BLOCK_SIZE];
253 
254 	plain = rk_crypto_mem_alloc(data_len);
255 	if (!plain) {
256 		E_TRACE("plain malloc %uByte error!\n", data_len);
257 		goto exit;
258 	}
259 
260 	cipher_soft = rk_crypto_mem_alloc(data_len);
261 	if (!cipher_soft) {
262 		E_TRACE("cipher_soft malloc %uByte error!\n", data_len);
263 		goto exit;
264 	}
265 
266 	cipher_hard = rk_crypto_mem_alloc(data_len);
267 	if (!cipher_hard) {
268 		E_TRACE("cipher_hard malloc %uByte error!\n", data_len);
269 		goto exit;
270 	}
271 
272 	test_get_rng(plain->vaddr, data_len);
273 
274 	for (i = 0; i < ARRAY_SIZE(item->modes); i++) {
275 		algo = item->algo;
276 		mode = item->modes[i];
277 
278 		if (mode == DATA_BUTT)
279 			break;
280 
281 		for (j = 0; j < ARRAY_SIZE(item->key_lens); j++) {
282 			key_len = item->key_lens[j];
283 			iv_len  = item->iv_len;
284 
285 			if (key_len == 0)
286 				break;
287 
288 			if (mode == RK_CIPHER_MODE_XTS)
289 				key_len *= 2;
290 
291 			for (k = 0; k < ARRAY_SIZE(ops); k++) {
292 				operation = ops[k];
293 
294 				memset(&cipher_cfg, 0x00, sizeof(cipher_cfg));
295 				cipher_cfg.algo      = algo;
296 				cipher_cfg.mode      = mode;
297 				cipher_cfg.operation = operation;
298 				cipher_cfg.key_len   = key_len;
299 
300 				test_get_rng(cipher_cfg.key, key_len);
301 				test_get_rng(cipher_cfg.iv, iv_len);
302 				memcpy(iv_tmp, cipher_cfg.iv, iv_len);
303 
304 				res = rk_cipher_init(&cipher_cfg, &cipher_hdl);
305 				if (res) {
306 					if (res != RK_CRYPTO_ERR_NOT_SUPPORTED) {
307 						E_TRACE("rk_cipher_init error[%x]\n", res);
308 						goto exit;
309 					}
310 
311 					if (verbose)
312 						printf("dma_fd:\t[%s-%u]\t%s\t%s\tN/A\n",
313 						       test_algo_name(algo), key_len * 8,
314 						       test_mode_name(mode), test_op_name(operation));
315 					res = RK_CRYPTO_SUCCESS;
316 					continue;
317 				}
318 
319 				if (is_no_multi_blocksize(mode))
320 					data_len = TEST_DATA_MAX - 7;
321 				else
322 					data_len = TEST_DATA_MAX;
323 
324 				res = rk_cipher_crypt(cipher_hdl, plain->dma_fd,
325 						      cipher_hard->dma_fd, data_len);
326 				if (res) {
327 					rk_cipher_final(cipher_hdl);
328 					E_TRACE("rk_cipher_crypt error[%x]\n", res);
329 					goto exit;
330 				}
331 
332 				rk_cipher_final(cipher_hdl);
333 				cipher_hdl = 0;
334 
335 				res = soft_cipher(algo, mode, operation,
336 						  cipher_cfg.key, cipher_cfg.key_len, iv_tmp,
337 						  plain->vaddr, data_len, cipher_soft->vaddr);
338 				if (res) {
339 					E_TRACE("soft_cipher error[%x]\n", res);
340 					goto exit;
341 				}
342 
343 				/* Verify the result */
344 				if (memcmp(cipher_hard->vaddr, cipher_soft->vaddr, data_len) != 0) {
345 					E_TRACE("rkcrypto_test_cipher compare failed.\n");
346 //					test_dump_hex("cipher_hard", cipher_hard->vaddr, data_len);
347 //					test_dump_hex("cipher_soft", cipher_soft->vaddr, data_len);
348 					res = RK_CRYPTO_ERR_GENERIC;
349 					goto exit;
350 				}
351 
352 				if (verbose)
353 					printf("dma_fd:\t[%s-%u]\t%s\t%s\tPASS\n",
354 					       test_algo_name(algo), key_len * 8,
355 					       test_mode_name(mode), test_op_name(operation));
356 			}
357 		}
358 	}
359 
360 	res = RK_CRYPTO_SUCCESS;
361 exit:
362 	rk_crypto_mem_free(plain);
363 	rk_crypto_mem_free(cipher_soft);
364 	rk_crypto_mem_free(cipher_hard);
365 
366 	if (res && key_len)
367 		printf("dma_fd:\t[%s-%u]\t%s\t%s\tFAIL\n",
368 		       test_algo_name(algo), key_len * 8,
369 		       test_mode_name(mode), test_op_name(operation));
370 
371 	return res;
372 }
373 
test_cipher(int verbose)374 RK_RES test_cipher(int verbose)
375 {
376 	RK_RES res = RK_CRYPTO_ERR_GENERIC;
377 	uint32_t i;
378 
379 	res = rk_crypto_init();
380 	if (res) {
381 		printf("rk_crypto_init error %08x\n", res);
382 		return res;
383 	}
384 
385 	for (i = 0; i < ARRAY_SIZE(test_item_tbl); i++) {
386 		res = test_cipher_item_virt(&test_item_tbl[i], verbose);
387 		if (res)
388 			goto exit;
389 
390 		res = test_cipher_item_fd(&test_item_tbl[i], verbose);
391 		if (res)
392 			goto exit;
393 		if (verbose)
394 			printf("\n");
395 	}
396 exit:
397 	rk_crypto_deinit();
398 	return res;
399 }
400 
401