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