]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2018 Intel Corporation | |
3 | */ | |
4 | ||
5 | #include <sys/stat.h> | |
6 | #include <getopt.h> | |
7 | #include <dirent.h> | |
8 | ||
9 | #include <rte_cryptodev.h> | |
10 | #include <rte_cryptodev_pmd.h> | |
11 | #include <rte_mempool.h> | |
12 | #include <rte_mbuf.h> | |
13 | #include <rte_string_fns.h> | |
14 | ||
15 | #include "fips_validation.h" | |
16 | #include "fips_dev_self_test.h" | |
17 | ||
18 | #define REQ_FILE_PATH_KEYWORD "req-file" | |
19 | #define RSP_FILE_PATH_KEYWORD "rsp-file" | |
20 | #define FOLDER_KEYWORD "path-is-folder" | |
21 | #define CRYPTODEV_KEYWORD "cryptodev" | |
22 | #define CRYPTODEV_ID_KEYWORD "cryptodev-id" | |
23 | #define CRYPTODEV_ST_KEYWORD "self-test" | |
24 | #define CRYPTODEV_BK_ID_KEYWORD "broken-test-id" | |
25 | #define CRYPTODEV_BK_DIR_KEY "broken-test-dir" | |
26 | #define CRYPTODEV_ENC_KEYWORD "enc" | |
27 | #define CRYPTODEV_DEC_KEYWORD "dec" | |
28 | ||
29 | struct fips_test_vector vec; | |
30 | struct fips_test_interim_info info; | |
31 | ||
32 | struct cryptodev_fips_validate_env { | |
33 | const char *req_path; | |
34 | const char *rsp_path; | |
35 | uint32_t is_path_folder; | |
36 | uint32_t dev_id; | |
37 | struct rte_mempool *mpool; | |
38 | struct rte_mempool *sess_mpool; | |
39 | struct rte_mempool *sess_priv_mpool; | |
40 | struct rte_mempool *op_pool; | |
41 | struct rte_mbuf *mbuf; | |
42 | struct rte_crypto_op *op; | |
43 | struct rte_cryptodev_sym_session *sess; | |
44 | uint32_t self_test; | |
45 | struct fips_dev_broken_test_config *broken_test_config; | |
46 | } env; | |
47 | ||
48 | static int | |
49 | cryptodev_fips_validate_app_int(void) | |
50 | { | |
f67539c2 | 51 | struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0}; |
9f95a23c TL |
52 | struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL}; |
53 | uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size( | |
54 | env.dev_id); | |
55 | int ret; | |
56 | ||
57 | if (env.self_test) { | |
58 | ret = fips_dev_self_test(env.dev_id, env.broken_test_config); | |
59 | if (ret < 0) { | |
60 | struct rte_cryptodev *cryptodev = | |
61 | rte_cryptodev_pmd_get_dev(env.dev_id); | |
62 | ||
63 | rte_cryptodev_pmd_destroy(cryptodev); | |
64 | ||
65 | return ret; | |
66 | } | |
67 | } | |
68 | ||
69 | ret = rte_cryptodev_configure(env.dev_id, &conf); | |
70 | if (ret < 0) | |
71 | return ret; | |
72 | ||
73 | env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", 128, 0, 0, | |
74 | UINT16_MAX, rte_socket_id()); | |
75 | if (!env.mpool) | |
76 | return ret; | |
77 | ||
78 | ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, | |
79 | rte_socket_id()); | |
80 | if (ret < 0) | |
81 | return ret; | |
82 | ||
83 | ret = -ENOMEM; | |
84 | ||
85 | env.sess_mpool = rte_cryptodev_sym_session_pool_create( | |
86 | "FIPS_SESS_MEMPOOL", 16, 0, 0, 0, rte_socket_id()); | |
87 | if (!env.sess_mpool) | |
88 | goto error_exit; | |
89 | ||
90 | env.sess_priv_mpool = rte_mempool_create("FIPS_SESS_PRIV_MEMPOOL", | |
91 | 16, sess_sz, 0, 0, NULL, NULL, NULL, | |
92 | NULL, rte_socket_id(), 0); | |
93 | if (!env.sess_priv_mpool) | |
94 | goto error_exit; | |
95 | ||
96 | env.op_pool = rte_crypto_op_pool_create( | |
97 | "FIPS_OP_POOL", | |
98 | RTE_CRYPTO_OP_TYPE_SYMMETRIC, | |
99 | 1, 0, | |
100 | 16, | |
101 | rte_socket_id()); | |
102 | if (!env.op_pool) | |
103 | goto error_exit; | |
104 | ||
105 | env.mbuf = rte_pktmbuf_alloc(env.mpool); | |
106 | if (!env.mbuf) | |
107 | goto error_exit; | |
108 | ||
109 | env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); | |
110 | if (!env.op) | |
111 | goto error_exit; | |
112 | ||
113 | qp_conf.mp_session = env.sess_mpool; | |
114 | qp_conf.mp_session_private = env.sess_priv_mpool; | |
115 | ||
116 | ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, | |
117 | rte_socket_id()); | |
118 | if (ret < 0) | |
119 | goto error_exit; | |
120 | ||
121 | return 0; | |
122 | ||
123 | error_exit: | |
124 | ||
125 | rte_mempool_free(env.mpool); | |
126 | if (env.sess_mpool) | |
127 | rte_mempool_free(env.sess_mpool); | |
128 | if (env.sess_priv_mpool) | |
129 | rte_mempool_free(env.sess_priv_mpool); | |
130 | if (env.op_pool) | |
131 | rte_mempool_free(env.op_pool); | |
132 | ||
133 | return ret; | |
134 | } | |
135 | ||
136 | static void | |
137 | cryptodev_fips_validate_app_uninit(void) | |
138 | { | |
139 | rte_pktmbuf_free(env.mbuf); | |
140 | rte_crypto_op_free(env.op); | |
141 | rte_cryptodev_sym_session_clear(env.dev_id, env.sess); | |
142 | rte_cryptodev_sym_session_free(env.sess); | |
143 | rte_mempool_free(env.mpool); | |
144 | rte_mempool_free(env.sess_mpool); | |
145 | rte_mempool_free(env.sess_priv_mpool); | |
146 | rte_mempool_free(env.op_pool); | |
147 | } | |
148 | ||
149 | static int | |
150 | fips_test_one_file(void); | |
151 | ||
152 | static int | |
153 | parse_cryptodev_arg(char *arg) | |
154 | { | |
155 | int id = rte_cryptodev_get_dev_id(arg); | |
156 | ||
157 | if (id < 0) { | |
158 | RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", | |
159 | id, arg); | |
160 | return id; | |
161 | } | |
162 | ||
163 | env.dev_id = (uint32_t)id; | |
164 | ||
165 | return 0; | |
166 | } | |
167 | ||
168 | static int | |
169 | parse_cryptodev_id_arg(char *arg) | |
170 | { | |
171 | uint32_t cryptodev_id; | |
172 | ||
173 | if (parser_read_uint32(&cryptodev_id, arg) < 0) { | |
174 | RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", | |
175 | -EINVAL, arg); | |
176 | return -1; | |
177 | } | |
178 | ||
179 | ||
180 | if (!rte_cryptodev_pmd_is_valid_dev(cryptodev_id)) { | |
181 | RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", | |
182 | cryptodev_id, arg); | |
183 | return -1; | |
184 | } | |
185 | ||
186 | env.dev_id = (uint32_t)cryptodev_id; | |
187 | ||
188 | return 0; | |
189 | } | |
190 | ||
191 | static void | |
192 | cryptodev_fips_validate_usage(const char *prgname) | |
193 | { | |
194 | printf("%s [EAL options] --\n" | |
195 | " --%s: REQUEST-FILE-PATH\n" | |
196 | " --%s: RESPONSE-FILE-PATH\n" | |
197 | " --%s: indicating both paths are folders\n" | |
198 | " --%s: CRYPTODEV-NAME\n" | |
199 | " --%s: CRYPTODEV-ID-NAME\n" | |
200 | " --%s: self test indicator\n" | |
201 | " --%s: self broken test ID\n" | |
202 | " --%s: self broken test direction\n", | |
203 | prgname, REQ_FILE_PATH_KEYWORD, RSP_FILE_PATH_KEYWORD, | |
204 | FOLDER_KEYWORD, CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD, | |
205 | CRYPTODEV_ST_KEYWORD, CRYPTODEV_BK_ID_KEYWORD, | |
206 | CRYPTODEV_BK_DIR_KEY); | |
207 | } | |
208 | ||
209 | static int | |
210 | cryptodev_fips_validate_parse_args(int argc, char **argv) | |
211 | { | |
212 | int opt, ret; | |
213 | char *prgname = argv[0]; | |
214 | char **argvopt; | |
215 | int option_index; | |
216 | struct option lgopts[] = { | |
217 | {REQ_FILE_PATH_KEYWORD, required_argument, 0, 0}, | |
218 | {RSP_FILE_PATH_KEYWORD, required_argument, 0, 0}, | |
219 | {FOLDER_KEYWORD, no_argument, 0, 0}, | |
220 | {CRYPTODEV_KEYWORD, required_argument, 0, 0}, | |
221 | {CRYPTODEV_ID_KEYWORD, required_argument, 0, 0}, | |
222 | {CRYPTODEV_ST_KEYWORD, no_argument, 0, 0}, | |
223 | {CRYPTODEV_BK_ID_KEYWORD, required_argument, 0, 0}, | |
224 | {CRYPTODEV_BK_DIR_KEY, required_argument, 0, 0}, | |
225 | {NULL, 0, 0, 0} | |
226 | }; | |
227 | ||
228 | argvopt = argv; | |
229 | ||
230 | while ((opt = getopt_long(argc, argvopt, "s:", | |
231 | lgopts, &option_index)) != EOF) { | |
232 | ||
233 | switch (opt) { | |
234 | case 0: | |
235 | if (strcmp(lgopts[option_index].name, | |
236 | REQ_FILE_PATH_KEYWORD) == 0) | |
237 | env.req_path = optarg; | |
238 | else if (strcmp(lgopts[option_index].name, | |
239 | RSP_FILE_PATH_KEYWORD) == 0) | |
240 | env.rsp_path = optarg; | |
241 | else if (strcmp(lgopts[option_index].name, | |
242 | FOLDER_KEYWORD) == 0) | |
243 | env.is_path_folder = 1; | |
244 | else if (strcmp(lgopts[option_index].name, | |
245 | CRYPTODEV_KEYWORD) == 0) { | |
246 | ret = parse_cryptodev_arg(optarg); | |
247 | if (ret < 0) { | |
248 | cryptodev_fips_validate_usage(prgname); | |
249 | return -EINVAL; | |
250 | } | |
251 | } else if (strcmp(lgopts[option_index].name, | |
252 | CRYPTODEV_ID_KEYWORD) == 0) { | |
253 | ret = parse_cryptodev_id_arg(optarg); | |
254 | if (ret < 0) { | |
255 | cryptodev_fips_validate_usage(prgname); | |
256 | return -EINVAL; | |
257 | } | |
258 | } else if (strcmp(lgopts[option_index].name, | |
259 | CRYPTODEV_ST_KEYWORD) == 0) { | |
260 | env.self_test = 1; | |
261 | } else if (strcmp(lgopts[option_index].name, | |
262 | CRYPTODEV_BK_ID_KEYWORD) == 0) { | |
263 | if (!env.broken_test_config) { | |
264 | env.broken_test_config = rte_malloc( | |
265 | NULL, | |
266 | sizeof(*env.broken_test_config), | |
267 | 0); | |
268 | if (!env.broken_test_config) | |
269 | return -ENOMEM; | |
270 | ||
271 | env.broken_test_config->expect_fail_dir = | |
272 | self_test_dir_enc_auth_gen; | |
273 | } | |
274 | ||
275 | if (parser_read_uint32( | |
276 | &env.broken_test_config->expect_fail_test_idx, | |
277 | optarg) < 0) { | |
278 | rte_free(env.broken_test_config); | |
279 | cryptodev_fips_validate_usage(prgname); | |
280 | return -EINVAL; | |
281 | } | |
282 | } else if (strcmp(lgopts[option_index].name, | |
283 | CRYPTODEV_BK_DIR_KEY) == 0) { | |
284 | if (!env.broken_test_config) { | |
285 | env.broken_test_config = rte_malloc( | |
286 | NULL, | |
287 | sizeof(*env.broken_test_config), | |
288 | 0); | |
289 | if (!env.broken_test_config) | |
290 | return -ENOMEM; | |
291 | ||
292 | env.broken_test_config-> | |
293 | expect_fail_test_idx = 0; | |
294 | } | |
295 | ||
296 | if (strcmp(optarg, CRYPTODEV_ENC_KEYWORD) == 0) | |
297 | env.broken_test_config->expect_fail_dir = | |
298 | self_test_dir_enc_auth_gen; | |
299 | else if (strcmp(optarg, CRYPTODEV_DEC_KEYWORD) | |
300 | == 0) | |
301 | env.broken_test_config->expect_fail_dir = | |
302 | self_test_dir_dec_auth_verify; | |
303 | else { | |
304 | rte_free(env.broken_test_config); | |
305 | cryptodev_fips_validate_usage(prgname); | |
306 | return -EINVAL; | |
307 | } | |
308 | } else { | |
309 | cryptodev_fips_validate_usage(prgname); | |
310 | return -EINVAL; | |
311 | } | |
312 | break; | |
313 | default: | |
314 | return -1; | |
315 | } | |
316 | } | |
317 | ||
318 | if (env.req_path == NULL || env.rsp_path == NULL || | |
319 | env.dev_id == UINT32_MAX) { | |
320 | cryptodev_fips_validate_usage(prgname); | |
321 | return -EINVAL; | |
322 | } | |
323 | ||
324 | return 0; | |
325 | } | |
326 | ||
327 | int | |
328 | main(int argc, char *argv[]) | |
329 | { | |
330 | int ret; | |
331 | ||
332 | ret = rte_eal_init(argc, argv); | |
333 | if (ret < 0) { | |
334 | RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); | |
335 | return -1; | |
336 | } | |
337 | ||
338 | argc -= ret; | |
339 | argv += ret; | |
340 | ||
341 | ret = cryptodev_fips_validate_parse_args(argc, argv); | |
342 | if (ret < 0) | |
343 | rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); | |
344 | ||
345 | ret = cryptodev_fips_validate_app_int(); | |
346 | if (ret < 0) { | |
347 | RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); | |
348 | return -1; | |
349 | } | |
350 | ||
351 | if (!env.is_path_folder) { | |
352 | printf("Processing file %s... ", env.req_path); | |
353 | ||
354 | ret = fips_test_init(env.req_path, env.rsp_path, | |
355 | rte_cryptodev_name_get(env.dev_id)); | |
356 | if (ret < 0) { | |
357 | RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", | |
358 | ret, env.req_path); | |
359 | goto exit; | |
360 | } | |
361 | ||
362 | ||
363 | ret = fips_test_one_file(); | |
364 | if (ret < 0) { | |
365 | RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", | |
366 | ret, env.req_path); | |
367 | goto exit; | |
368 | } | |
369 | ||
370 | printf("Done\n"); | |
371 | ||
372 | } else { | |
373 | struct dirent *dir; | |
374 | DIR *d_req, *d_rsp; | |
375 | char req_path[1024]; | |
376 | char rsp_path[1024]; | |
377 | ||
378 | d_req = opendir(env.req_path); | |
379 | if (!d_req) { | |
380 | RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", | |
381 | -EINVAL, env.req_path); | |
382 | goto exit; | |
383 | } | |
384 | ||
385 | d_rsp = opendir(env.rsp_path); | |
386 | if (!d_rsp) { | |
387 | ret = mkdir(env.rsp_path, 0700); | |
388 | if (ret == 0) | |
389 | d_rsp = opendir(env.rsp_path); | |
390 | else { | |
391 | RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", | |
392 | -EINVAL, env.rsp_path); | |
393 | goto exit; | |
394 | } | |
395 | } | |
396 | closedir(d_rsp); | |
397 | ||
398 | while ((dir = readdir(d_req)) != NULL) { | |
399 | if (strstr(dir->d_name, "req") == NULL) | |
400 | continue; | |
401 | ||
402 | snprintf(req_path, 1023, "%s/%s", env.req_path, | |
403 | dir->d_name); | |
404 | snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, | |
405 | dir->d_name); | |
406 | strlcpy(strstr(rsp_path, "req"), "rsp", 4); | |
407 | ||
408 | printf("Processing file %s... ", req_path); | |
409 | ||
410 | ret = fips_test_init(req_path, rsp_path, | |
411 | rte_cryptodev_name_get(env.dev_id)); | |
412 | if (ret < 0) { | |
413 | RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", | |
414 | ret, req_path); | |
415 | break; | |
416 | } | |
417 | ||
418 | ret = fips_test_one_file(); | |
419 | if (ret < 0) { | |
420 | RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", | |
421 | ret, req_path); | |
422 | break; | |
423 | } | |
424 | ||
425 | printf("Done\n"); | |
426 | } | |
427 | ||
428 | closedir(d_req); | |
429 | } | |
430 | ||
431 | ||
432 | exit: | |
433 | fips_test_clear(); | |
434 | cryptodev_fips_validate_app_uninit(); | |
435 | ||
436 | return ret; | |
437 | ||
438 | } | |
439 | ||
440 | #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) | |
441 | #define CRYPTODEV_FIPS_MAX_RETRIES 16 | |
442 | ||
443 | typedef int (*fips_test_one_case_t)(void); | |
444 | typedef int (*fips_prepare_op_t)(void); | |
445 | typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *); | |
446 | ||
447 | struct fips_test_ops { | |
448 | fips_prepare_xform_t prepare_xform; | |
449 | fips_prepare_op_t prepare_op; | |
450 | fips_test_one_case_t test; | |
451 | } test_ops; | |
452 | ||
453 | static int | |
454 | prepare_cipher_op(void) | |
455 | { | |
456 | struct rte_crypto_sym_op *sym = env.op->sym; | |
457 | uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); | |
458 | ||
459 | __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); | |
460 | rte_pktmbuf_reset(env.mbuf); | |
461 | ||
462 | sym->m_src = env.mbuf; | |
463 | sym->cipher.data.offset = 0; | |
464 | ||
465 | memcpy(iv, vec.iv.val, vec.iv.len); | |
466 | ||
467 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
468 | uint8_t *pt; | |
469 | ||
470 | if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { | |
471 | RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); | |
472 | return -EPERM; | |
473 | } | |
474 | ||
475 | pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len); | |
476 | ||
477 | if (!pt) { | |
478 | RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", | |
479 | -ENOMEM); | |
480 | return -ENOMEM; | |
481 | } | |
482 | ||
483 | memcpy(pt, vec.pt.val, vec.pt.len); | |
484 | sym->cipher.data.length = vec.pt.len; | |
485 | ||
486 | } else { | |
487 | uint8_t *ct; | |
488 | ||
489 | if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { | |
490 | RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); | |
491 | return -EPERM; | |
492 | } | |
493 | ||
494 | ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); | |
495 | ||
496 | if (!ct) { | |
497 | RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", | |
498 | -ENOMEM); | |
499 | return -ENOMEM; | |
500 | } | |
501 | ||
502 | memcpy(ct, vec.ct.val, vec.ct.len); | |
503 | sym->cipher.data.length = vec.ct.len; | |
504 | } | |
505 | ||
506 | rte_crypto_op_attach_sym_session(env.op, env.sess); | |
507 | ||
508 | return 0; | |
509 | } | |
510 | ||
511 | static int | |
512 | prepare_auth_op(void) | |
513 | { | |
514 | struct rte_crypto_sym_op *sym = env.op->sym; | |
f67539c2 | 515 | uint8_t *pt; |
9f95a23c TL |
516 | |
517 | __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); | |
518 | rte_pktmbuf_reset(env.mbuf); | |
519 | ||
520 | sym->m_src = env.mbuf; | |
521 | sym->auth.data.offset = 0; | |
522 | ||
f67539c2 TL |
523 | pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len + |
524 | vec.cipher_auth.digest.len); | |
9f95a23c | 525 | |
f67539c2 TL |
526 | if (!pt) { |
527 | RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", | |
528 | -ENOMEM); | |
529 | return -ENOMEM; | |
530 | } | |
9f95a23c | 531 | |
f67539c2 TL |
532 | sym->auth.data.length = vec.pt.len; |
533 | sym->auth.digest.data = pt + vec.pt.len; | |
534 | sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( | |
535 | env.mbuf, vec.pt.len); | |
9f95a23c | 536 | |
f67539c2 | 537 | memcpy(pt, vec.pt.val, vec.pt.len); |
9f95a23c | 538 | |
f67539c2 TL |
539 | if (info.op == FIPS_TEST_DEC_AUTH_VERIF) |
540 | memcpy(pt + vec.pt.len, vec.cipher_auth.digest.val, | |
541 | vec.cipher_auth.digest.len); | |
9f95a23c TL |
542 | |
543 | rte_crypto_op_attach_sym_session(env.op, env.sess); | |
544 | ||
545 | return 0; | |
546 | } | |
547 | ||
548 | static int | |
549 | prepare_aead_op(void) | |
550 | { | |
551 | struct rte_crypto_sym_op *sym = env.op->sym; | |
552 | uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); | |
553 | ||
554 | __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); | |
555 | rte_pktmbuf_reset(env.mbuf); | |
556 | ||
557 | if (info.algo == FIPS_TEST_ALGO_AES_CCM) | |
558 | memcpy(iv + 1, vec.iv.val, vec.iv.len); | |
559 | else | |
560 | memcpy(iv, vec.iv.val, vec.iv.len); | |
561 | ||
562 | sym->m_src = env.mbuf; | |
563 | sym->aead.data.offset = 0; | |
564 | sym->aead.aad.data = vec.aead.aad.val; | |
565 | sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); | |
566 | ||
567 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
568 | uint8_t *pt; | |
569 | ||
570 | if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { | |
571 | RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); | |
572 | return -EPERM; | |
573 | } | |
574 | ||
575 | pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, | |
576 | vec.pt.len + vec.aead.digest.len); | |
577 | ||
578 | if (!pt) { | |
579 | RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", | |
580 | -ENOMEM); | |
581 | return -ENOMEM; | |
582 | } | |
583 | ||
584 | memcpy(pt, vec.pt.val, vec.pt.len); | |
585 | sym->aead.data.length = vec.pt.len; | |
586 | sym->aead.digest.data = pt + vec.pt.len; | |
587 | sym->aead.digest.phys_addr = rte_pktmbuf_mtophys_offset( | |
588 | env.mbuf, vec.pt.len); | |
589 | } else { | |
590 | uint8_t *ct; | |
591 | ||
592 | if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { | |
593 | RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); | |
594 | return -EPERM; | |
595 | } | |
596 | ||
597 | ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); | |
598 | ||
599 | if (!ct) { | |
600 | RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", | |
601 | -ENOMEM); | |
602 | return -ENOMEM; | |
603 | } | |
604 | ||
605 | memcpy(ct, vec.ct.val, vec.ct.len); | |
606 | sym->aead.data.length = vec.ct.len; | |
607 | sym->aead.digest.data = vec.aead.digest.val; | |
608 | sym->aead.digest.phys_addr = rte_malloc_virt2iova( | |
609 | sym->aead.digest.data); | |
610 | } | |
611 | ||
612 | rte_crypto_op_attach_sym_session(env.op, env.sess); | |
613 | ||
614 | return 0; | |
615 | } | |
616 | ||
617 | static int | |
618 | prepare_aes_xform(struct rte_crypto_sym_xform *xform) | |
619 | { | |
620 | const struct rte_cryptodev_symmetric_capability *cap; | |
621 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
622 | struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; | |
623 | ||
624 | xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; | |
625 | ||
f67539c2 TL |
626 | if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) |
627 | cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; | |
628 | else | |
629 | cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB; | |
630 | ||
9f95a23c TL |
631 | cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? |
632 | RTE_CRYPTO_CIPHER_OP_ENCRYPT : | |
633 | RTE_CRYPTO_CIPHER_OP_DECRYPT; | |
634 | cipher_xform->key.data = vec.cipher_auth.key.val; | |
635 | cipher_xform->key.length = vec.cipher_auth.key.len; | |
f67539c2 TL |
636 | if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC) { |
637 | cipher_xform->iv.length = vec.iv.len; | |
638 | cipher_xform->iv.offset = IV_OFF; | |
639 | } else { | |
640 | cipher_xform->iv.length = 0; | |
641 | cipher_xform->iv.offset = 0; | |
642 | } | |
643 | cap_idx.algo.cipher = cipher_xform->algo; | |
9f95a23c TL |
644 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; |
645 | ||
646 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
647 | if (!cap) { | |
648 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
649 | env.dev_id); | |
650 | return -EINVAL; | |
651 | } | |
652 | ||
653 | if (rte_cryptodev_sym_capability_check_cipher(cap, | |
654 | cipher_xform->key.length, | |
655 | cipher_xform->iv.length) != 0) { | |
656 | RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", | |
657 | info.device_name, cipher_xform->key.length, | |
658 | cipher_xform->iv.length); | |
659 | return -EPERM; | |
660 | } | |
661 | ||
662 | return 0; | |
663 | } | |
664 | ||
665 | static int | |
666 | prepare_tdes_xform(struct rte_crypto_sym_xform *xform) | |
667 | { | |
668 | const struct rte_cryptodev_symmetric_capability *cap; | |
669 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
670 | struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; | |
671 | ||
672 | xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; | |
673 | ||
f67539c2 TL |
674 | if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) |
675 | cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; | |
676 | else | |
677 | cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB; | |
9f95a23c TL |
678 | cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? |
679 | RTE_CRYPTO_CIPHER_OP_ENCRYPT : | |
680 | RTE_CRYPTO_CIPHER_OP_DECRYPT; | |
681 | cipher_xform->key.data = vec.cipher_auth.key.val; | |
682 | cipher_xform->key.length = vec.cipher_auth.key.len; | |
9f95a23c | 683 | |
f67539c2 TL |
684 | if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) { |
685 | cipher_xform->iv.length = vec.iv.len; | |
686 | cipher_xform->iv.offset = IV_OFF; | |
687 | } else { | |
688 | cipher_xform->iv.length = 0; | |
689 | cipher_xform->iv.offset = 0; | |
690 | } | |
691 | cap_idx.algo.cipher = cipher_xform->algo; | |
9f95a23c TL |
692 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; |
693 | ||
694 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
695 | if (!cap) { | |
696 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
697 | env.dev_id); | |
698 | return -EINVAL; | |
699 | } | |
700 | ||
701 | if (rte_cryptodev_sym_capability_check_cipher(cap, | |
702 | cipher_xform->key.length, | |
703 | cipher_xform->iv.length) != 0) { | |
704 | RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", | |
705 | info.device_name, cipher_xform->key.length, | |
706 | cipher_xform->iv.length); | |
707 | return -EPERM; | |
708 | } | |
709 | ||
710 | return 0; | |
711 | } | |
712 | ||
713 | static int | |
714 | prepare_hmac_xform(struct rte_crypto_sym_xform *xform) | |
715 | { | |
716 | const struct rte_cryptodev_symmetric_capability *cap; | |
717 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
718 | struct rte_crypto_auth_xform *auth_xform = &xform->auth; | |
719 | ||
720 | xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
721 | ||
722 | auth_xform->algo = info.interim_info.hmac_data.algo; | |
723 | auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; | |
724 | auth_xform->digest_length = vec.cipher_auth.digest.len; | |
725 | auth_xform->key.data = vec.cipher_auth.key.val; | |
726 | auth_xform->key.length = vec.cipher_auth.key.len; | |
727 | ||
728 | cap_idx.algo.auth = auth_xform->algo; | |
729 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
730 | ||
731 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
732 | if (!cap) { | |
733 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
734 | env.dev_id); | |
735 | return -EINVAL; | |
736 | } | |
737 | ||
738 | if (rte_cryptodev_sym_capability_check_auth(cap, | |
739 | auth_xform->key.length, | |
740 | auth_xform->digest_length, 0) != 0) { | |
741 | RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", | |
742 | info.device_name, auth_xform->key.length, | |
743 | auth_xform->digest_length); | |
744 | return -EPERM; | |
745 | } | |
746 | ||
747 | return 0; | |
748 | } | |
749 | ||
750 | static int | |
751 | prepare_gcm_xform(struct rte_crypto_sym_xform *xform) | |
752 | { | |
753 | const struct rte_cryptodev_symmetric_capability *cap; | |
754 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
755 | struct rte_crypto_aead_xform *aead_xform = &xform->aead; | |
756 | ||
757 | xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; | |
758 | ||
759 | aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; | |
760 | aead_xform->aad_length = vec.aead.aad.len; | |
761 | aead_xform->digest_length = vec.aead.digest.len; | |
762 | aead_xform->iv.offset = IV_OFF; | |
763 | aead_xform->iv.length = vec.iv.len; | |
764 | aead_xform->key.data = vec.aead.key.val; | |
765 | aead_xform->key.length = vec.aead.key.len; | |
766 | aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? | |
767 | RTE_CRYPTO_AEAD_OP_ENCRYPT : | |
768 | RTE_CRYPTO_AEAD_OP_DECRYPT; | |
769 | ||
770 | cap_idx.algo.aead = aead_xform->algo; | |
771 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; | |
772 | ||
773 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
774 | if (!cap) { | |
775 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
776 | env.dev_id); | |
777 | return -EINVAL; | |
778 | } | |
779 | ||
780 | if (rte_cryptodev_sym_capability_check_aead(cap, | |
781 | aead_xform->key.length, | |
782 | aead_xform->digest_length, aead_xform->aad_length, | |
783 | aead_xform->iv.length) != 0) { | |
784 | RTE_LOG(ERR, USER1, | |
785 | "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", | |
786 | info.device_name, aead_xform->key.length, | |
787 | aead_xform->digest_length, | |
788 | aead_xform->aad_length, | |
789 | aead_xform->iv.length); | |
790 | return -EPERM; | |
791 | } | |
792 | ||
793 | return 0; | |
794 | } | |
795 | ||
796 | static int | |
797 | prepare_cmac_xform(struct rte_crypto_sym_xform *xform) | |
798 | { | |
799 | const struct rte_cryptodev_symmetric_capability *cap; | |
800 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
801 | struct rte_crypto_auth_xform *auth_xform = &xform->auth; | |
802 | ||
803 | xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
804 | ||
805 | auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; | |
806 | auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? | |
807 | RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; | |
808 | auth_xform->digest_length = vec.cipher_auth.digest.len; | |
809 | auth_xform->key.data = vec.cipher_auth.key.val; | |
810 | auth_xform->key.length = vec.cipher_auth.key.len; | |
811 | ||
812 | cap_idx.algo.auth = auth_xform->algo; | |
813 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
814 | ||
815 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
816 | if (!cap) { | |
817 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
818 | env.dev_id); | |
819 | return -EINVAL; | |
820 | } | |
821 | ||
822 | if (rte_cryptodev_sym_capability_check_auth(cap, | |
823 | auth_xform->key.length, | |
824 | auth_xform->digest_length, 0) != 0) { | |
825 | RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", | |
826 | info.device_name, auth_xform->key.length, | |
827 | auth_xform->digest_length); | |
828 | return -EPERM; | |
829 | } | |
830 | ||
831 | return 0; | |
832 | } | |
833 | ||
834 | static int | |
835 | prepare_ccm_xform(struct rte_crypto_sym_xform *xform) | |
836 | { | |
837 | const struct rte_cryptodev_symmetric_capability *cap; | |
838 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
839 | struct rte_crypto_aead_xform *aead_xform = &xform->aead; | |
840 | ||
841 | xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; | |
842 | ||
843 | aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; | |
844 | aead_xform->aad_length = vec.aead.aad.len; | |
845 | aead_xform->digest_length = vec.aead.digest.len; | |
846 | aead_xform->iv.offset = IV_OFF; | |
847 | aead_xform->iv.length = vec.iv.len; | |
848 | aead_xform->key.data = vec.aead.key.val; | |
849 | aead_xform->key.length = vec.aead.key.len; | |
850 | aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? | |
851 | RTE_CRYPTO_AEAD_OP_ENCRYPT : | |
852 | RTE_CRYPTO_AEAD_OP_DECRYPT; | |
853 | ||
854 | cap_idx.algo.aead = aead_xform->algo; | |
855 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; | |
856 | ||
857 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
858 | if (!cap) { | |
859 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
860 | env.dev_id); | |
861 | return -EINVAL; | |
862 | } | |
863 | ||
864 | if (rte_cryptodev_sym_capability_check_aead(cap, | |
865 | aead_xform->key.length, | |
866 | aead_xform->digest_length, aead_xform->aad_length, | |
867 | aead_xform->iv.length) != 0) { | |
868 | RTE_LOG(ERR, USER1, | |
869 | "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", | |
870 | info.device_name, aead_xform->key.length, | |
871 | aead_xform->digest_length, | |
872 | aead_xform->aad_length, | |
873 | aead_xform->iv.length); | |
874 | return -EPERM; | |
875 | } | |
876 | ||
877 | return 0; | |
878 | } | |
879 | ||
880 | static int | |
881 | prepare_sha_xform(struct rte_crypto_sym_xform *xform) | |
882 | { | |
883 | const struct rte_cryptodev_symmetric_capability *cap; | |
884 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
885 | struct rte_crypto_auth_xform *auth_xform = &xform->auth; | |
886 | ||
887 | xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
888 | ||
889 | auth_xform->algo = info.interim_info.sha_data.algo; | |
890 | auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; | |
891 | auth_xform->digest_length = vec.cipher_auth.digest.len; | |
892 | ||
893 | cap_idx.algo.auth = auth_xform->algo; | |
894 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; | |
895 | ||
896 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
897 | if (!cap) { | |
898 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
899 | env.dev_id); | |
900 | return -EINVAL; | |
901 | } | |
902 | ||
903 | if (rte_cryptodev_sym_capability_check_auth(cap, | |
904 | auth_xform->key.length, | |
905 | auth_xform->digest_length, 0) != 0) { | |
906 | RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", | |
907 | info.device_name, auth_xform->key.length, | |
908 | auth_xform->digest_length); | |
909 | return -EPERM; | |
910 | } | |
911 | ||
912 | return 0; | |
913 | } | |
914 | ||
f67539c2 TL |
915 | static int |
916 | prepare_xts_xform(struct rte_crypto_sym_xform *xform) | |
917 | { | |
918 | const struct rte_cryptodev_symmetric_capability *cap; | |
919 | struct rte_cryptodev_sym_capability_idx cap_idx; | |
920 | struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; | |
921 | ||
922 | xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; | |
923 | ||
924 | cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; | |
925 | cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? | |
926 | RTE_CRYPTO_CIPHER_OP_ENCRYPT : | |
927 | RTE_CRYPTO_CIPHER_OP_DECRYPT; | |
928 | cipher_xform->key.data = vec.cipher_auth.key.val; | |
929 | cipher_xform->key.length = vec.cipher_auth.key.len; | |
930 | cipher_xform->iv.length = vec.iv.len; | |
931 | cipher_xform->iv.offset = IV_OFF; | |
932 | ||
933 | cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; | |
934 | cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; | |
935 | ||
936 | cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); | |
937 | if (!cap) { | |
938 | RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", | |
939 | env.dev_id); | |
940 | return -EINVAL; | |
941 | } | |
942 | ||
943 | if (rte_cryptodev_sym_capability_check_cipher(cap, | |
944 | cipher_xform->key.length, | |
945 | cipher_xform->iv.length) != 0) { | |
946 | RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", | |
947 | info.device_name, cipher_xform->key.length, | |
948 | cipher_xform->iv.length); | |
949 | return -EPERM; | |
950 | } | |
951 | ||
952 | return 0; | |
953 | } | |
954 | ||
9f95a23c TL |
955 | static void |
956 | get_writeback_data(struct fips_val *val) | |
957 | { | |
958 | val->val = rte_pktmbuf_mtod(env.mbuf, uint8_t *); | |
959 | val->len = rte_pktmbuf_pkt_len(env.mbuf); | |
960 | } | |
961 | ||
962 | static int | |
963 | fips_run_test(void) | |
964 | { | |
965 | struct rte_crypto_sym_xform xform = {0}; | |
966 | uint16_t n_deqd; | |
967 | int ret; | |
968 | ||
969 | ret = test_ops.prepare_xform(&xform); | |
970 | if (ret < 0) | |
971 | return ret; | |
972 | ||
973 | env.sess = rte_cryptodev_sym_session_create(env.sess_mpool); | |
974 | if (!env.sess) | |
975 | return -ENOMEM; | |
976 | ||
977 | ret = rte_cryptodev_sym_session_init(env.dev_id, | |
978 | env.sess, &xform, env.sess_priv_mpool); | |
979 | if (ret < 0) { | |
980 | RTE_LOG(ERR, USER1, "Error %i: Init session\n", | |
981 | ret); | |
982 | goto exit; | |
983 | } | |
984 | ||
985 | ret = test_ops.prepare_op(); | |
986 | if (ret < 0) { | |
987 | RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", | |
988 | ret); | |
989 | goto exit; | |
990 | } | |
991 | ||
992 | if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { | |
993 | RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); | |
994 | ret = -1; | |
995 | goto exit; | |
996 | } | |
997 | ||
998 | do { | |
999 | struct rte_crypto_op *deqd_op; | |
1000 | ||
1001 | n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, | |
1002 | 1); | |
1003 | } while (n_deqd == 0); | |
1004 | ||
1005 | vec.status = env.op->status; | |
1006 | ||
1007 | exit: | |
1008 | rte_cryptodev_sym_session_clear(env.dev_id, env.sess); | |
1009 | rte_cryptodev_sym_session_free(env.sess); | |
1010 | env.sess = NULL; | |
1011 | ||
1012 | return ret; | |
1013 | } | |
1014 | ||
1015 | static int | |
1016 | fips_generic_test(void) | |
1017 | { | |
1018 | struct fips_val val; | |
1019 | int ret; | |
1020 | ||
1021 | fips_test_write_one_case(); | |
1022 | ||
1023 | ret = fips_run_test(); | |
1024 | if (ret < 0) { | |
1025 | if (ret == -EPERM) { | |
1026 | fprintf(info.fp_wr, "Bypass\n\n"); | |
1027 | return 0; | |
1028 | } | |
1029 | ||
1030 | return ret; | |
1031 | } | |
1032 | ||
1033 | get_writeback_data(&val); | |
1034 | ||
1035 | switch (info.file_type) { | |
1036 | case FIPS_TYPE_REQ: | |
1037 | case FIPS_TYPE_RSP: | |
1038 | if (info.parse_writeback == NULL) | |
1039 | return -EPERM; | |
1040 | ret = info.parse_writeback(&val); | |
1041 | if (ret < 0) | |
1042 | return ret; | |
1043 | break; | |
1044 | case FIPS_TYPE_FAX: | |
1045 | if (info.kat_check == NULL) | |
1046 | return -EPERM; | |
1047 | ret = info.kat_check(&val); | |
1048 | if (ret < 0) | |
1049 | return ret; | |
1050 | break; | |
1051 | } | |
1052 | ||
1053 | fprintf(info.fp_wr, "\n"); | |
1054 | ||
1055 | return 0; | |
1056 | } | |
1057 | ||
1058 | static int | |
1059 | fips_mct_tdes_test(void) | |
1060 | { | |
1061 | #define TDES_BLOCK_SIZE 8 | |
1062 | #define TDES_EXTERN_ITER 400 | |
1063 | #define TDES_INTERN_ITER 10000 | |
1064 | struct fips_val val, val_key; | |
1065 | uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; | |
1066 | uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; | |
1067 | uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; | |
1068 | uint32_t i, j, k; | |
1069 | int ret; | |
f67539c2 | 1070 | int test_mode = info.interim_info.tdes_data.test_mode; |
9f95a23c TL |
1071 | |
1072 | for (i = 0; i < TDES_EXTERN_ITER; i++) { | |
1073 | if (i != 0) | |
1074 | update_info_vec(i); | |
1075 | ||
1076 | fips_test_write_one_case(); | |
1077 | ||
1078 | for (j = 0; j < TDES_INTERN_ITER; j++) { | |
1079 | ret = fips_run_test(); | |
1080 | if (ret < 0) { | |
1081 | if (ret == -EPERM) { | |
1082 | fprintf(info.fp_wr, "Bypass\n"); | |
1083 | return 0; | |
1084 | } | |
9f95a23c TL |
1085 | return ret; |
1086 | } | |
1087 | ||
1088 | get_writeback_data(&val); | |
1089 | ||
1090 | if (info.op == FIPS_TEST_DEC_AUTH_VERIF) | |
1091 | memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); | |
1092 | ||
1093 | if (j == 0) { | |
1094 | memcpy(prev_out, val.val, TDES_BLOCK_SIZE); | |
1095 | ||
1096 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
f67539c2 TL |
1097 | if (test_mode == TDES_MODE_ECB) { |
1098 | memcpy(vec.pt.val, val.val, | |
1099 | TDES_BLOCK_SIZE); | |
1100 | } else { | |
1101 | memcpy(vec.pt.val, vec.iv.val, | |
1102 | TDES_BLOCK_SIZE); | |
1103 | memcpy(vec.iv.val, val.val, | |
1104 | TDES_BLOCK_SIZE); | |
1105 | } | |
1106 | ||
9f95a23c | 1107 | } else { |
f67539c2 TL |
1108 | if (test_mode == TDES_MODE_ECB) { |
1109 | memcpy(vec.ct.val, val.val, | |
1110 | TDES_BLOCK_SIZE); | |
1111 | } else { | |
1112 | memcpy(vec.iv.val, vec.ct.val, | |
1113 | TDES_BLOCK_SIZE); | |
1114 | memcpy(vec.ct.val, val.val, | |
1115 | TDES_BLOCK_SIZE); | |
1116 | } | |
9f95a23c TL |
1117 | } |
1118 | continue; | |
1119 | } | |
1120 | ||
1121 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
f67539c2 TL |
1122 | if (test_mode == TDES_MODE_ECB) { |
1123 | memcpy(vec.pt.val, val.val, | |
1124 | TDES_BLOCK_SIZE); | |
1125 | } else { | |
1126 | memcpy(vec.iv.val, val.val, | |
1127 | TDES_BLOCK_SIZE); | |
1128 | memcpy(vec.pt.val, prev_out, | |
1129 | TDES_BLOCK_SIZE); | |
1130 | } | |
9f95a23c | 1131 | } else { |
f67539c2 TL |
1132 | if (test_mode == TDES_MODE_ECB) { |
1133 | memcpy(vec.ct.val, val.val, | |
1134 | TDES_BLOCK_SIZE); | |
1135 | } else { | |
1136 | memcpy(vec.iv.val, vec.ct.val, | |
1137 | TDES_BLOCK_SIZE); | |
1138 | memcpy(vec.ct.val, val.val, | |
1139 | TDES_BLOCK_SIZE); | |
1140 | } | |
9f95a23c TL |
1141 | } |
1142 | ||
1143 | if (j == TDES_INTERN_ITER - 1) | |
1144 | continue; | |
1145 | ||
1146 | memcpy(prev_out, val.val, TDES_BLOCK_SIZE); | |
1147 | ||
1148 | if (j == TDES_INTERN_ITER - 3) | |
1149 | memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE); | |
1150 | } | |
1151 | ||
1152 | info.parse_writeback(&val); | |
1153 | fprintf(info.fp_wr, "\n"); | |
1154 | ||
1155 | if (i == TDES_EXTERN_ITER - 1) | |
1156 | continue; | |
1157 | ||
1158 | /** update key */ | |
1159 | memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); | |
1160 | ||
1161 | if (info.interim_info.tdes_data.nb_keys == 0) { | |
1162 | if (memcmp(val_key.val, val_key.val + 8, 8) == 0) | |
1163 | info.interim_info.tdes_data.nb_keys = 1; | |
1164 | else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) | |
1165 | info.interim_info.tdes_data.nb_keys = 2; | |
1166 | else | |
1167 | info.interim_info.tdes_data.nb_keys = 3; | |
1168 | ||
1169 | } | |
1170 | ||
1171 | for (k = 0; k < TDES_BLOCK_SIZE; k++) { | |
1172 | ||
1173 | switch (info.interim_info.tdes_data.nb_keys) { | |
1174 | case 3: | |
1175 | val_key.val[k] ^= val.val[k]; | |
1176 | val_key.val[k + 8] ^= prev_out[k]; | |
1177 | val_key.val[k + 16] ^= prev_prev_out[k]; | |
1178 | break; | |
1179 | case 2: | |
1180 | val_key.val[k] ^= val.val[k]; | |
1181 | val_key.val[k + 8] ^= prev_out[k]; | |
1182 | val_key.val[k + 16] ^= val.val[k]; | |
1183 | break; | |
1184 | default: /* case 1 */ | |
1185 | val_key.val[k] ^= val.val[k]; | |
1186 | val_key.val[k + 8] ^= val.val[k]; | |
1187 | val_key.val[k + 16] ^= val.val[k]; | |
1188 | break; | |
1189 | } | |
1190 | ||
1191 | } | |
1192 | ||
1193 | for (k = 0; k < 24; k++) | |
1194 | val_key.val[k] = (__builtin_popcount(val_key.val[k]) & | |
1195 | 0x1) ? | |
1196 | val_key.val[k] : (val_key.val[k] ^ 0x1); | |
1197 | ||
1198 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
f67539c2 TL |
1199 | if (test_mode == TDES_MODE_ECB) { |
1200 | memcpy(vec.pt.val, val.val, TDES_BLOCK_SIZE); | |
1201 | } else { | |
1202 | memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); | |
1203 | memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); | |
1204 | } | |
9f95a23c | 1205 | } else { |
f67539c2 TL |
1206 | if (test_mode == TDES_MODE_ECB) { |
1207 | memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); | |
1208 | } else { | |
1209 | memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); | |
1210 | memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); | |
1211 | } | |
9f95a23c TL |
1212 | } |
1213 | } | |
1214 | ||
1215 | return 0; | |
1216 | } | |
1217 | ||
f67539c2 TL |
1218 | static int |
1219 | fips_mct_aes_ecb_test(void) | |
1220 | { | |
1221 | #define AES_BLOCK_SIZE 16 | |
1222 | #define AES_EXTERN_ITER 100 | |
1223 | #define AES_INTERN_ITER 1000 | |
1224 | struct fips_val val, val_key; | |
1225 | uint8_t prev_out[AES_BLOCK_SIZE] = {0}; | |
1226 | uint32_t i, j, k; | |
1227 | int ret; | |
1228 | ||
1229 | for (i = 0; i < AES_EXTERN_ITER; i++) { | |
1230 | if (i != 0) | |
1231 | update_info_vec(i); | |
1232 | ||
1233 | fips_test_write_one_case(); | |
1234 | ||
1235 | for (j = 0; j < AES_INTERN_ITER; j++) { | |
1236 | ret = fips_run_test(); | |
1237 | if (ret < 0) { | |
1238 | if (ret == -EPERM) { | |
1239 | fprintf(info.fp_wr, "Bypass\n"); | |
1240 | return 0; | |
1241 | } | |
1242 | ||
1243 | return ret; | |
1244 | } | |
1245 | ||
1246 | get_writeback_data(&val); | |
1247 | ||
1248 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) | |
1249 | memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); | |
1250 | else | |
1251 | memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); | |
1252 | ||
1253 | if (j == AES_INTERN_ITER - 1) | |
1254 | continue; | |
1255 | ||
1256 | memcpy(prev_out, val.val, AES_BLOCK_SIZE); | |
1257 | } | |
1258 | ||
1259 | info.parse_writeback(&val); | |
1260 | fprintf(info.fp_wr, "\n"); | |
1261 | ||
1262 | if (i == AES_EXTERN_ITER - 1) | |
1263 | continue; | |
1264 | ||
1265 | /** update key */ | |
1266 | memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); | |
1267 | for (k = 0; k < vec.cipher_auth.key.len; k++) { | |
1268 | switch (vec.cipher_auth.key.len) { | |
1269 | case 16: | |
1270 | val_key.val[k] ^= val.val[k]; | |
1271 | break; | |
1272 | case 24: | |
1273 | if (k < 8) | |
1274 | val_key.val[k] ^= prev_out[k + 8]; | |
1275 | else | |
1276 | val_key.val[k] ^= val.val[k - 8]; | |
1277 | break; | |
1278 | case 32: | |
1279 | if (k < 16) | |
1280 | val_key.val[k] ^= prev_out[k]; | |
1281 | else | |
1282 | val_key.val[k] ^= val.val[k - 16]; | |
1283 | break; | |
1284 | default: | |
1285 | return -1; | |
1286 | } | |
1287 | } | |
1288 | } | |
1289 | ||
1290 | return 0; | |
1291 | } | |
9f95a23c TL |
1292 | static int |
1293 | fips_mct_aes_test(void) | |
1294 | { | |
1295 | #define AES_BLOCK_SIZE 16 | |
1296 | #define AES_EXTERN_ITER 100 | |
1297 | #define AES_INTERN_ITER 1000 | |
1298 | struct fips_val val, val_key; | |
1299 | uint8_t prev_out[AES_BLOCK_SIZE] = {0}; | |
1300 | uint8_t prev_in[AES_BLOCK_SIZE] = {0}; | |
1301 | uint32_t i, j, k; | |
1302 | int ret; | |
1303 | ||
f67539c2 TL |
1304 | if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) |
1305 | return fips_mct_aes_ecb_test(); | |
1306 | ||
9f95a23c TL |
1307 | for (i = 0; i < AES_EXTERN_ITER; i++) { |
1308 | if (i != 0) | |
1309 | update_info_vec(i); | |
1310 | ||
1311 | fips_test_write_one_case(); | |
1312 | ||
1313 | for (j = 0; j < AES_INTERN_ITER; j++) { | |
1314 | ret = fips_run_test(); | |
1315 | if (ret < 0) { | |
1316 | if (ret == -EPERM) { | |
1317 | fprintf(info.fp_wr, "Bypass\n"); | |
1318 | return 0; | |
1319 | } | |
1320 | ||
1321 | return ret; | |
1322 | } | |
1323 | ||
1324 | get_writeback_data(&val); | |
1325 | ||
1326 | if (info.op == FIPS_TEST_DEC_AUTH_VERIF) | |
1327 | memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); | |
1328 | ||
1329 | if (j == 0) { | |
1330 | memcpy(prev_out, val.val, AES_BLOCK_SIZE); | |
1331 | ||
1332 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
1333 | memcpy(vec.pt.val, vec.iv.val, | |
1334 | AES_BLOCK_SIZE); | |
1335 | memcpy(vec.iv.val, val.val, | |
1336 | AES_BLOCK_SIZE); | |
1337 | } else { | |
1338 | memcpy(vec.ct.val, vec.iv.val, | |
1339 | AES_BLOCK_SIZE); | |
1340 | memcpy(vec.iv.val, prev_in, | |
1341 | AES_BLOCK_SIZE); | |
1342 | } | |
1343 | continue; | |
1344 | } | |
1345 | ||
1346 | if (info.op == FIPS_TEST_ENC_AUTH_GEN) { | |
1347 | memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); | |
1348 | memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); | |
1349 | } else { | |
1350 | memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); | |
1351 | memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); | |
1352 | } | |
1353 | ||
1354 | if (j == AES_INTERN_ITER - 1) | |
1355 | continue; | |
1356 | ||
1357 | memcpy(prev_out, val.val, AES_BLOCK_SIZE); | |
1358 | } | |
1359 | ||
1360 | info.parse_writeback(&val); | |
1361 | fprintf(info.fp_wr, "\n"); | |
1362 | ||
1363 | if (i == AES_EXTERN_ITER - 1) | |
1364 | continue; | |
1365 | ||
1366 | /** update key */ | |
1367 | memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); | |
1368 | for (k = 0; k < vec.cipher_auth.key.len; k++) { | |
1369 | switch (vec.cipher_auth.key.len) { | |
1370 | case 16: | |
1371 | val_key.val[k] ^= val.val[k]; | |
1372 | break; | |
1373 | case 24: | |
1374 | if (k < 8) | |
1375 | val_key.val[k] ^= prev_out[k + 8]; | |
1376 | else | |
1377 | val_key.val[k] ^= val.val[k - 8]; | |
1378 | break; | |
1379 | case 32: | |
1380 | if (k < 16) | |
1381 | val_key.val[k] ^= prev_out[k]; | |
1382 | else | |
1383 | val_key.val[k] ^= val.val[k - 16]; | |
1384 | break; | |
1385 | default: | |
1386 | return -1; | |
1387 | } | |
1388 | } | |
1389 | ||
1390 | if (info.op == FIPS_TEST_DEC_AUTH_VERIF) | |
1391 | memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); | |
1392 | } | |
1393 | ||
1394 | return 0; | |
1395 | } | |
1396 | ||
1397 | static int | |
1398 | fips_mct_sha_test(void) | |
1399 | { | |
1400 | #define SHA_EXTERN_ITER 100 | |
1401 | #define SHA_INTERN_ITER 1000 | |
1402 | #define SHA_MD_BLOCK 3 | |
1403 | struct fips_val val, md[SHA_MD_BLOCK]; | |
1404 | char temp[MAX_DIGEST_SIZE*2]; | |
1405 | int ret; | |
1406 | uint32_t i, j; | |
1407 | ||
1408 | val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); | |
1409 | for (i = 0; i < SHA_MD_BLOCK; i++) | |
1410 | md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); | |
1411 | ||
1412 | rte_free(vec.pt.val); | |
1413 | vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); | |
1414 | ||
1415 | fips_test_write_one_case(); | |
1416 | fprintf(info.fp_wr, "\n"); | |
1417 | ||
1418 | for (j = 0; j < SHA_EXTERN_ITER; j++) { | |
1419 | ||
1420 | memcpy(md[0].val, vec.cipher_auth.digest.val, | |
1421 | vec.cipher_auth.digest.len); | |
1422 | md[0].len = vec.cipher_auth.digest.len; | |
1423 | memcpy(md[1].val, vec.cipher_auth.digest.val, | |
1424 | vec.cipher_auth.digest.len); | |
1425 | md[1].len = vec.cipher_auth.digest.len; | |
1426 | memcpy(md[2].val, vec.cipher_auth.digest.val, | |
1427 | vec.cipher_auth.digest.len); | |
1428 | md[2].len = vec.cipher_auth.digest.len; | |
1429 | ||
1430 | for (i = 0; i < (SHA_INTERN_ITER); i++) { | |
1431 | ||
1432 | memcpy(vec.pt.val, md[0].val, | |
1433 | (size_t)md[0].len); | |
1434 | memcpy((vec.pt.val + md[0].len), md[1].val, | |
1435 | (size_t)md[1].len); | |
1436 | memcpy((vec.pt.val + md[0].len + md[1].len), | |
1437 | md[2].val, | |
1438 | (size_t)md[2].len); | |
1439 | vec.pt.len = md[0].len + md[1].len + md[2].len; | |
1440 | ||
1441 | ret = fips_run_test(); | |
1442 | if (ret < 0) { | |
1443 | if (ret == -EPERM) { | |
1444 | fprintf(info.fp_wr, "Bypass\n\n"); | |
1445 | return 0; | |
1446 | } | |
1447 | return ret; | |
1448 | } | |
1449 | ||
1450 | get_writeback_data(&val); | |
1451 | ||
1452 | memcpy(md[0].val, md[1].val, md[1].len); | |
1453 | md[0].len = md[1].len; | |
1454 | memcpy(md[1].val, md[2].val, md[2].len); | |
1455 | md[1].len = md[2].len; | |
1456 | ||
1457 | memcpy(md[2].val, (val.val + vec.pt.len), | |
1458 | vec.cipher_auth.digest.len); | |
1459 | md[2].len = vec.cipher_auth.digest.len; | |
1460 | } | |
1461 | ||
1462 | memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); | |
1463 | vec.cipher_auth.digest.len = md[2].len; | |
1464 | ||
1465 | fprintf(info.fp_wr, "COUNT = %u\n", j); | |
1466 | ||
1467 | writeback_hex_str("", temp, &vec.cipher_auth.digest); | |
1468 | ||
1469 | fprintf(info.fp_wr, "MD = %s\n\n", temp); | |
1470 | } | |
1471 | ||
1472 | for (i = 0; i < (SHA_MD_BLOCK); i++) | |
1473 | rte_free(md[i].val); | |
1474 | ||
1475 | rte_free(vec.pt.val); | |
1476 | ||
1477 | return 0; | |
1478 | } | |
1479 | ||
1480 | ||
1481 | static int | |
1482 | init_test_ops(void) | |
1483 | { | |
1484 | switch (info.algo) { | |
1485 | case FIPS_TEST_ALGO_AES: | |
1486 | test_ops.prepare_op = prepare_cipher_op; | |
1487 | test_ops.prepare_xform = prepare_aes_xform; | |
1488 | if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) | |
1489 | test_ops.test = fips_mct_aes_test; | |
1490 | else | |
1491 | test_ops.test = fips_generic_test; | |
1492 | break; | |
1493 | case FIPS_TEST_ALGO_HMAC: | |
1494 | test_ops.prepare_op = prepare_auth_op; | |
1495 | test_ops.prepare_xform = prepare_hmac_xform; | |
1496 | test_ops.test = fips_generic_test; | |
1497 | break; | |
1498 | case FIPS_TEST_ALGO_TDES: | |
1499 | test_ops.prepare_op = prepare_cipher_op; | |
1500 | test_ops.prepare_xform = prepare_tdes_xform; | |
1501 | if (info.interim_info.tdes_data.test_type == TDES_MCT) | |
1502 | test_ops.test = fips_mct_tdes_test; | |
1503 | else | |
1504 | test_ops.test = fips_generic_test; | |
1505 | break; | |
1506 | case FIPS_TEST_ALGO_AES_GCM: | |
1507 | test_ops.prepare_op = prepare_aead_op; | |
1508 | test_ops.prepare_xform = prepare_gcm_xform; | |
1509 | test_ops.test = fips_generic_test; | |
1510 | break; | |
1511 | case FIPS_TEST_ALGO_AES_CMAC: | |
1512 | test_ops.prepare_op = prepare_auth_op; | |
1513 | test_ops.prepare_xform = prepare_cmac_xform; | |
1514 | test_ops.test = fips_generic_test; | |
1515 | break; | |
1516 | case FIPS_TEST_ALGO_AES_CCM: | |
1517 | test_ops.prepare_op = prepare_aead_op; | |
1518 | test_ops.prepare_xform = prepare_ccm_xform; | |
1519 | test_ops.test = fips_generic_test; | |
1520 | break; | |
1521 | case FIPS_TEST_ALGO_SHA: | |
1522 | test_ops.prepare_op = prepare_auth_op; | |
1523 | test_ops.prepare_xform = prepare_sha_xform; | |
1524 | if (info.interim_info.sha_data.test_type == SHA_MCT) | |
1525 | test_ops.test = fips_mct_sha_test; | |
1526 | else | |
1527 | test_ops.test = fips_generic_test; | |
1528 | break; | |
f67539c2 TL |
1529 | case FIPS_TEST_ALGO_AES_XTS: |
1530 | test_ops.prepare_op = prepare_cipher_op; | |
1531 | test_ops.prepare_xform = prepare_xts_xform; | |
1532 | test_ops.test = fips_generic_test; | |
1533 | break; | |
9f95a23c | 1534 | default: |
f67539c2 TL |
1535 | if (strstr(info.file_name, "TECB") || |
1536 | strstr(info.file_name, "TCBC")) { | |
1537 | info.algo = FIPS_TEST_ALGO_TDES; | |
1538 | test_ops.prepare_op = prepare_cipher_op; | |
1539 | test_ops.prepare_xform = prepare_tdes_xform; | |
1540 | if (info.interim_info.tdes_data.test_type == TDES_MCT) | |
1541 | test_ops.test = fips_mct_tdes_test; | |
1542 | else | |
1543 | test_ops.test = fips_generic_test; | |
1544 | break; | |
1545 | } | |
9f95a23c TL |
1546 | return -1; |
1547 | } | |
1548 | ||
1549 | return 0; | |
1550 | } | |
1551 | ||
1552 | static void | |
1553 | print_test_block(void) | |
1554 | { | |
1555 | uint32_t i; | |
1556 | ||
1557 | for (i = 0; i < info.nb_vec_lines; i++) | |
1558 | printf("%s\n", info.vec[i]); | |
1559 | ||
1560 | printf("\n"); | |
1561 | } | |
1562 | ||
1563 | static int | |
1564 | fips_test_one_file(void) | |
1565 | { | |
1566 | int fetch_ret = 0, ret; | |
1567 | ||
1568 | ||
1569 | ret = init_test_ops(); | |
1570 | if (ret < 0) { | |
1571 | RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); | |
1572 | return ret; | |
1573 | } | |
1574 | ||
1575 | while (ret >= 0 && fetch_ret == 0) { | |
1576 | fetch_ret = fips_test_fetch_one_block(); | |
1577 | if (fetch_ret < 0) { | |
1578 | RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", | |
1579 | fetch_ret); | |
1580 | ret = fetch_ret; | |
1581 | goto error_one_case; | |
1582 | } | |
1583 | ||
1584 | if (info.nb_vec_lines == 0) { | |
1585 | if (fetch_ret == -EOF) | |
1586 | break; | |
1587 | ||
1588 | fprintf(info.fp_wr, "\n"); | |
1589 | continue; | |
1590 | } | |
1591 | ||
1592 | ret = fips_test_parse_one_case(); | |
1593 | switch (ret) { | |
1594 | case 0: | |
1595 | ret = test_ops.test(); | |
1596 | if (ret == 0) | |
1597 | break; | |
1598 | RTE_LOG(ERR, USER1, "Error %i: test block\n", | |
1599 | ret); | |
1600 | goto error_one_case; | |
1601 | case 1: | |
1602 | break; | |
1603 | default: | |
1604 | RTE_LOG(ERR, USER1, "Error %i: Parse block\n", | |
1605 | ret); | |
1606 | goto error_one_case; | |
1607 | } | |
1608 | ||
1609 | continue; | |
1610 | error_one_case: | |
1611 | print_test_block(); | |
1612 | } | |
1613 | ||
1614 | fips_test_clear(); | |
1615 | ||
1616 | return ret; | |
1617 | ||
1618 | } |