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