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