1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
9 #include <rte_cryptodev.h>
10 #include <rte_cryptodev_pmd.h>
11 #include <rte_mempool.h>
13 #include <rte_string_fns.h>
15 #include "fips_validation.h"
16 #include "fips_dev_self_test.h"
18 #define REQ_FILE_PATH_KEYWORD "req-file"
19 #define RSP_FILE_PATH_KEYWORD "rsp-file"
20 #define FOLDER_KEYWORD "path-is-folder"
21 #define CRYPTODEV_KEYWORD "cryptodev"
22 #define CRYPTODEV_ID_KEYWORD "cryptodev-id"
23 #define CRYPTODEV_ST_KEYWORD "self-test"
24 #define CRYPTODEV_BK_ID_KEYWORD "broken-test-id"
25 #define CRYPTODEV_BK_DIR_KEY "broken-test-dir"
26 #define CRYPTODEV_ENC_KEYWORD "enc"
27 #define CRYPTODEV_DEC_KEYWORD "dec"
29 struct fips_test_vector vec
;
30 struct fips_test_interim_info info
;
32 struct cryptodev_fips_validate_env
{
35 uint32_t is_path_folder
;
37 struct rte_mempool
*mpool
;
38 struct rte_mempool
*sess_mpool
;
39 struct rte_mempool
*sess_priv_mpool
;
40 struct rte_mempool
*op_pool
;
41 struct rte_mbuf
*mbuf
;
42 struct rte_crypto_op
*op
;
43 struct rte_cryptodev_sym_session
*sess
;
45 struct fips_dev_broken_test_config
*broken_test_config
;
49 cryptodev_fips_validate_app_int(void)
51 struct rte_cryptodev_config conf
= {rte_socket_id(), 1};
52 struct rte_cryptodev_qp_conf qp_conf
= {128, NULL
, NULL
};
53 uint32_t sess_sz
= rte_cryptodev_sym_get_private_session_size(
58 ret
= fips_dev_self_test(env
.dev_id
, env
.broken_test_config
);
60 struct rte_cryptodev
*cryptodev
=
61 rte_cryptodev_pmd_get_dev(env
.dev_id
);
63 rte_cryptodev_pmd_destroy(cryptodev
);
69 ret
= rte_cryptodev_configure(env
.dev_id
, &conf
);
73 env
.mpool
= rte_pktmbuf_pool_create("FIPS_MEMPOOL", 128, 0, 0,
74 UINT16_MAX
, rte_socket_id());
78 ret
= rte_cryptodev_queue_pair_setup(env
.dev_id
, 0, &qp_conf
,
85 env
.sess_mpool
= rte_cryptodev_sym_session_pool_create(
86 "FIPS_SESS_MEMPOOL", 16, 0, 0, 0, rte_socket_id());
90 env
.sess_priv_mpool
= rte_mempool_create("FIPS_SESS_PRIV_MEMPOOL",
91 16, sess_sz
, 0, 0, NULL
, NULL
, NULL
,
92 NULL
, rte_socket_id(), 0);
93 if (!env
.sess_priv_mpool
)
96 env
.op_pool
= rte_crypto_op_pool_create(
98 RTE_CRYPTO_OP_TYPE_SYMMETRIC
,
105 env
.mbuf
= rte_pktmbuf_alloc(env
.mpool
);
109 env
.op
= rte_crypto_op_alloc(env
.op_pool
, RTE_CRYPTO_OP_TYPE_SYMMETRIC
);
113 qp_conf
.mp_session
= env
.sess_mpool
;
114 qp_conf
.mp_session_private
= env
.sess_priv_mpool
;
116 ret
= rte_cryptodev_queue_pair_setup(env
.dev_id
, 0, &qp_conf
,
125 rte_mempool_free(env
.mpool
);
127 rte_mempool_free(env
.sess_mpool
);
128 if (env
.sess_priv_mpool
)
129 rte_mempool_free(env
.sess_priv_mpool
);
131 rte_mempool_free(env
.op_pool
);
137 cryptodev_fips_validate_app_uninit(void)
139 rte_pktmbuf_free(env
.mbuf
);
140 rte_crypto_op_free(env
.op
);
141 rte_cryptodev_sym_session_clear(env
.dev_id
, env
.sess
);
142 rte_cryptodev_sym_session_free(env
.sess
);
143 rte_mempool_free(env
.mpool
);
144 rte_mempool_free(env
.sess_mpool
);
145 rte_mempool_free(env
.sess_priv_mpool
);
146 rte_mempool_free(env
.op_pool
);
150 fips_test_one_file(void);
153 parse_cryptodev_arg(char *arg
)
155 int id
= rte_cryptodev_get_dev_id(arg
);
158 RTE_LOG(ERR
, USER1
, "Error %i: invalid cryptodev name %s\n",
163 env
.dev_id
= (uint32_t)id
;
169 parse_cryptodev_id_arg(char *arg
)
171 uint32_t cryptodev_id
;
173 if (parser_read_uint32(&cryptodev_id
, arg
) < 0) {
174 RTE_LOG(ERR
, USER1
, "Error %i: invalid cryptodev id %s\n",
180 if (!rte_cryptodev_pmd_is_valid_dev(cryptodev_id
)) {
181 RTE_LOG(ERR
, USER1
, "Error %i: invalid cryptodev id %s\n",
186 env
.dev_id
= (uint32_t)cryptodev_id
;
192 cryptodev_fips_validate_usage(const char *prgname
)
194 printf("%s [EAL options] --\n"
195 " --%s: REQUEST-FILE-PATH\n"
196 " --%s: RESPONSE-FILE-PATH\n"
197 " --%s: indicating both paths are folders\n"
198 " --%s: CRYPTODEV-NAME\n"
199 " --%s: CRYPTODEV-ID-NAME\n"
200 " --%s: self test indicator\n"
201 " --%s: self broken test ID\n"
202 " --%s: self broken test direction\n",
203 prgname
, REQ_FILE_PATH_KEYWORD
, RSP_FILE_PATH_KEYWORD
,
204 FOLDER_KEYWORD
, CRYPTODEV_KEYWORD
, CRYPTODEV_ID_KEYWORD
,
205 CRYPTODEV_ST_KEYWORD
, CRYPTODEV_BK_ID_KEYWORD
,
206 CRYPTODEV_BK_DIR_KEY
);
210 cryptodev_fips_validate_parse_args(int argc
, char **argv
)
213 char *prgname
= argv
[0];
216 struct option lgopts
[] = {
217 {REQ_FILE_PATH_KEYWORD
, required_argument
, 0, 0},
218 {RSP_FILE_PATH_KEYWORD
, required_argument
, 0, 0},
219 {FOLDER_KEYWORD
, no_argument
, 0, 0},
220 {CRYPTODEV_KEYWORD
, required_argument
, 0, 0},
221 {CRYPTODEV_ID_KEYWORD
, required_argument
, 0, 0},
222 {CRYPTODEV_ST_KEYWORD
, no_argument
, 0, 0},
223 {CRYPTODEV_BK_ID_KEYWORD
, required_argument
, 0, 0},
224 {CRYPTODEV_BK_DIR_KEY
, required_argument
, 0, 0},
230 while ((opt
= getopt_long(argc
, argvopt
, "s:",
231 lgopts
, &option_index
)) != EOF
) {
235 if (strcmp(lgopts
[option_index
].name
,
236 REQ_FILE_PATH_KEYWORD
) == 0)
237 env
.req_path
= optarg
;
238 else if (strcmp(lgopts
[option_index
].name
,
239 RSP_FILE_PATH_KEYWORD
) == 0)
240 env
.rsp_path
= optarg
;
241 else if (strcmp(lgopts
[option_index
].name
,
242 FOLDER_KEYWORD
) == 0)
243 env
.is_path_folder
= 1;
244 else if (strcmp(lgopts
[option_index
].name
,
245 CRYPTODEV_KEYWORD
) == 0) {
246 ret
= parse_cryptodev_arg(optarg
);
248 cryptodev_fips_validate_usage(prgname
);
251 } else if (strcmp(lgopts
[option_index
].name
,
252 CRYPTODEV_ID_KEYWORD
) == 0) {
253 ret
= parse_cryptodev_id_arg(optarg
);
255 cryptodev_fips_validate_usage(prgname
);
258 } else if (strcmp(lgopts
[option_index
].name
,
259 CRYPTODEV_ST_KEYWORD
) == 0) {
261 } else if (strcmp(lgopts
[option_index
].name
,
262 CRYPTODEV_BK_ID_KEYWORD
) == 0) {
263 if (!env
.broken_test_config
) {
264 env
.broken_test_config
= rte_malloc(
266 sizeof(*env
.broken_test_config
),
268 if (!env
.broken_test_config
)
271 env
.broken_test_config
->expect_fail_dir
=
272 self_test_dir_enc_auth_gen
;
275 if (parser_read_uint32(
276 &env
.broken_test_config
->expect_fail_test_idx
,
278 rte_free(env
.broken_test_config
);
279 cryptodev_fips_validate_usage(prgname
);
282 } else if (strcmp(lgopts
[option_index
].name
,
283 CRYPTODEV_BK_DIR_KEY
) == 0) {
284 if (!env
.broken_test_config
) {
285 env
.broken_test_config
= rte_malloc(
287 sizeof(*env
.broken_test_config
),
289 if (!env
.broken_test_config
)
292 env
.broken_test_config
->
293 expect_fail_test_idx
= 0;
296 if (strcmp(optarg
, CRYPTODEV_ENC_KEYWORD
) == 0)
297 env
.broken_test_config
->expect_fail_dir
=
298 self_test_dir_enc_auth_gen
;
299 else if (strcmp(optarg
, CRYPTODEV_DEC_KEYWORD
)
301 env
.broken_test_config
->expect_fail_dir
=
302 self_test_dir_dec_auth_verify
;
304 rte_free(env
.broken_test_config
);
305 cryptodev_fips_validate_usage(prgname
);
309 cryptodev_fips_validate_usage(prgname
);
318 if (env
.req_path
== NULL
|| env
.rsp_path
== NULL
||
319 env
.dev_id
== UINT32_MAX
) {
320 cryptodev_fips_validate_usage(prgname
);
328 main(int argc
, char *argv
[])
332 ret
= rte_eal_init(argc
, argv
);
334 RTE_LOG(ERR
, USER1
, "Error %i: Failed init\n", ret
);
341 ret
= cryptodev_fips_validate_parse_args(argc
, argv
);
343 rte_exit(EXIT_FAILURE
, "Failed to parse arguments!\n");
345 ret
= cryptodev_fips_validate_app_int();
347 RTE_LOG(ERR
, USER1
, "Error %i: Failed init\n", ret
);
351 if (!env
.is_path_folder
) {
352 printf("Processing file %s... ", env
.req_path
);
354 ret
= fips_test_init(env
.req_path
, env
.rsp_path
,
355 rte_cryptodev_name_get(env
.dev_id
));
357 RTE_LOG(ERR
, USER1
, "Error %i: Failed test %s\n",
363 ret
= fips_test_one_file();
365 RTE_LOG(ERR
, USER1
, "Error %i: Failed test %s\n",
378 d_req
= opendir(env
.req_path
);
380 RTE_LOG(ERR
, USER1
, "Error %i: Path %s not exist\n",
381 -EINVAL
, env
.req_path
);
385 d_rsp
= opendir(env
.rsp_path
);
387 ret
= mkdir(env
.rsp_path
, 0700);
389 d_rsp
= opendir(env
.rsp_path
);
391 RTE_LOG(ERR
, USER1
, "Error %i: Invalid %s\n",
392 -EINVAL
, env
.rsp_path
);
398 while ((dir
= readdir(d_req
)) != NULL
) {
399 if (strstr(dir
->d_name
, "req") == NULL
)
402 snprintf(req_path
, 1023, "%s/%s", env
.req_path
,
404 snprintf(rsp_path
, 1023, "%s/%s", env
.rsp_path
,
406 strlcpy(strstr(rsp_path
, "req"), "rsp", 4);
408 printf("Processing file %s... ", req_path
);
410 ret
= fips_test_init(req_path
, rsp_path
,
411 rte_cryptodev_name_get(env
.dev_id
));
413 RTE_LOG(ERR
, USER1
, "Error %i: Failed test %s\n",
418 ret
= fips_test_one_file();
420 RTE_LOG(ERR
, USER1
, "Error %i: Failed test %s\n",
434 cryptodev_fips_validate_app_uninit();
440 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
441 #define CRYPTODEV_FIPS_MAX_RETRIES 16
443 typedef int (*fips_test_one_case_t
)(void);
444 typedef int (*fips_prepare_op_t
)(void);
445 typedef int (*fips_prepare_xform_t
)(struct rte_crypto_sym_xform
*);
447 struct fips_test_ops
{
448 fips_prepare_xform_t prepare_xform
;
449 fips_prepare_op_t prepare_op
;
450 fips_test_one_case_t test
;
454 prepare_cipher_op(void)
456 struct rte_crypto_sym_op
*sym
= env
.op
->sym
;
457 uint8_t *iv
= rte_crypto_op_ctod_offset(env
.op
, uint8_t *, IV_OFF
);
459 __rte_crypto_op_reset(env
.op
, RTE_CRYPTO_OP_TYPE_SYMMETRIC
);
460 rte_pktmbuf_reset(env
.mbuf
);
462 sym
->m_src
= env
.mbuf
;
463 sym
->cipher
.data
.offset
= 0;
465 memcpy(iv
, vec
.iv
.val
, vec
.iv
.len
);
467 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
470 if (vec
.pt
.len
> RTE_MBUF_MAX_NB_SEGS
) {
471 RTE_LOG(ERR
, USER1
, "PT len %u\n", vec
.pt
.len
);
475 pt
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
, vec
.pt
.len
);
478 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
483 memcpy(pt
, vec
.pt
.val
, vec
.pt
.len
);
484 sym
->cipher
.data
.length
= vec
.pt
.len
;
489 if (vec
.ct
.len
> RTE_MBUF_MAX_NB_SEGS
) {
490 RTE_LOG(ERR
, USER1
, "CT len %u\n", vec
.ct
.len
);
494 ct
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
, vec
.ct
.len
);
497 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
502 memcpy(ct
, vec
.ct
.val
, vec
.ct
.len
);
503 sym
->cipher
.data
.length
= vec
.ct
.len
;
506 rte_crypto_op_attach_sym_session(env
.op
, env
.sess
);
512 prepare_auth_op(void)
514 struct rte_crypto_sym_op
*sym
= env
.op
->sym
;
516 __rte_crypto_op_reset(env
.op
, RTE_CRYPTO_OP_TYPE_SYMMETRIC
);
517 rte_pktmbuf_reset(env
.mbuf
);
519 sym
->m_src
= env
.mbuf
;
520 sym
->auth
.data
.offset
= 0;
522 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
525 if (vec
.pt
.len
> RTE_MBUF_MAX_NB_SEGS
) {
526 RTE_LOG(ERR
, USER1
, "PT len %u\n", vec
.pt
.len
);
530 pt
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
, vec
.pt
.len
+
531 vec
.cipher_auth
.digest
.len
);
534 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
539 memcpy(pt
, vec
.pt
.val
, vec
.pt
.len
);
540 sym
->auth
.data
.length
= vec
.pt
.len
;
541 sym
->auth
.digest
.data
= pt
+ vec
.pt
.len
;
542 sym
->auth
.digest
.phys_addr
= rte_pktmbuf_mtophys_offset(
543 env
.mbuf
, vec
.pt
.len
);
548 if (vec
.ct
.len
> RTE_MBUF_MAX_NB_SEGS
) {
549 RTE_LOG(ERR
, USER1
, "CT len %u\n", vec
.ct
.len
);
553 ct
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
,
554 vec
.ct
.len
+ vec
.cipher_auth
.digest
.len
);
557 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
562 memcpy(ct
, vec
.ct
.val
, vec
.ct
.len
);
563 sym
->auth
.data
.length
= vec
.ct
.len
;
564 sym
->auth
.digest
.data
= vec
.cipher_auth
.digest
.val
;
565 sym
->auth
.digest
.phys_addr
= rte_malloc_virt2iova(
566 sym
->auth
.digest
.data
);
569 rte_crypto_op_attach_sym_session(env
.op
, env
.sess
);
575 prepare_aead_op(void)
577 struct rte_crypto_sym_op
*sym
= env
.op
->sym
;
578 uint8_t *iv
= rte_crypto_op_ctod_offset(env
.op
, uint8_t *, IV_OFF
);
580 __rte_crypto_op_reset(env
.op
, RTE_CRYPTO_OP_TYPE_SYMMETRIC
);
581 rte_pktmbuf_reset(env
.mbuf
);
583 if (info
.algo
== FIPS_TEST_ALGO_AES_CCM
)
584 memcpy(iv
+ 1, vec
.iv
.val
, vec
.iv
.len
);
586 memcpy(iv
, vec
.iv
.val
, vec
.iv
.len
);
588 sym
->m_src
= env
.mbuf
;
589 sym
->aead
.data
.offset
= 0;
590 sym
->aead
.aad
.data
= vec
.aead
.aad
.val
;
591 sym
->aead
.aad
.phys_addr
= rte_malloc_virt2iova(sym
->aead
.aad
.data
);
593 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
596 if (vec
.pt
.len
> RTE_MBUF_MAX_NB_SEGS
) {
597 RTE_LOG(ERR
, USER1
, "PT len %u\n", vec
.pt
.len
);
601 pt
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
,
602 vec
.pt
.len
+ vec
.aead
.digest
.len
);
605 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
610 memcpy(pt
, vec
.pt
.val
, vec
.pt
.len
);
611 sym
->aead
.data
.length
= vec
.pt
.len
;
612 sym
->aead
.digest
.data
= pt
+ vec
.pt
.len
;
613 sym
->aead
.digest
.phys_addr
= rte_pktmbuf_mtophys_offset(
614 env
.mbuf
, vec
.pt
.len
);
618 if (vec
.ct
.len
> RTE_MBUF_MAX_NB_SEGS
) {
619 RTE_LOG(ERR
, USER1
, "CT len %u\n", vec
.ct
.len
);
623 ct
= (uint8_t *)rte_pktmbuf_append(env
.mbuf
, vec
.ct
.len
);
626 RTE_LOG(ERR
, USER1
, "Error %i: MBUF too small\n",
631 memcpy(ct
, vec
.ct
.val
, vec
.ct
.len
);
632 sym
->aead
.data
.length
= vec
.ct
.len
;
633 sym
->aead
.digest
.data
= vec
.aead
.digest
.val
;
634 sym
->aead
.digest
.phys_addr
= rte_malloc_virt2iova(
635 sym
->aead
.digest
.data
);
638 rte_crypto_op_attach_sym_session(env
.op
, env
.sess
);
644 prepare_aes_xform(struct rte_crypto_sym_xform
*xform
)
646 const struct rte_cryptodev_symmetric_capability
*cap
;
647 struct rte_cryptodev_sym_capability_idx cap_idx
;
648 struct rte_crypto_cipher_xform
*cipher_xform
= &xform
->cipher
;
650 xform
->type
= RTE_CRYPTO_SYM_XFORM_CIPHER
;
652 cipher_xform
->algo
= RTE_CRYPTO_CIPHER_AES_CBC
;
653 cipher_xform
->op
= (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) ?
654 RTE_CRYPTO_CIPHER_OP_ENCRYPT
:
655 RTE_CRYPTO_CIPHER_OP_DECRYPT
;
656 cipher_xform
->key
.data
= vec
.cipher_auth
.key
.val
;
657 cipher_xform
->key
.length
= vec
.cipher_auth
.key
.len
;
658 cipher_xform
->iv
.length
= vec
.iv
.len
;
659 cipher_xform
->iv
.offset
= IV_OFF
;
661 cap_idx
.algo
.cipher
= RTE_CRYPTO_CIPHER_AES_CBC
;
662 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_CIPHER
;
664 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
666 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
671 if (rte_cryptodev_sym_capability_check_cipher(cap
,
672 cipher_xform
->key
.length
,
673 cipher_xform
->iv
.length
) != 0) {
674 RTE_LOG(ERR
, USER1
, "PMD %s key length %u IV length %u\n",
675 info
.device_name
, cipher_xform
->key
.length
,
676 cipher_xform
->iv
.length
);
684 prepare_tdes_xform(struct rte_crypto_sym_xform
*xform
)
686 const struct rte_cryptodev_symmetric_capability
*cap
;
687 struct rte_cryptodev_sym_capability_idx cap_idx
;
688 struct rte_crypto_cipher_xform
*cipher_xform
= &xform
->cipher
;
690 xform
->type
= RTE_CRYPTO_SYM_XFORM_CIPHER
;
692 cipher_xform
->algo
= RTE_CRYPTO_CIPHER_3DES_CBC
;
693 cipher_xform
->op
= (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) ?
694 RTE_CRYPTO_CIPHER_OP_ENCRYPT
:
695 RTE_CRYPTO_CIPHER_OP_DECRYPT
;
696 cipher_xform
->key
.data
= vec
.cipher_auth
.key
.val
;
697 cipher_xform
->key
.length
= vec
.cipher_auth
.key
.len
;
698 cipher_xform
->iv
.length
= vec
.iv
.len
;
699 cipher_xform
->iv
.offset
= IV_OFF
;
701 cap_idx
.algo
.cipher
= RTE_CRYPTO_CIPHER_3DES_CBC
;
702 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_CIPHER
;
704 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
706 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
711 if (rte_cryptodev_sym_capability_check_cipher(cap
,
712 cipher_xform
->key
.length
,
713 cipher_xform
->iv
.length
) != 0) {
714 RTE_LOG(ERR
, USER1
, "PMD %s key length %u IV length %u\n",
715 info
.device_name
, cipher_xform
->key
.length
,
716 cipher_xform
->iv
.length
);
724 prepare_hmac_xform(struct rte_crypto_sym_xform
*xform
)
726 const struct rte_cryptodev_symmetric_capability
*cap
;
727 struct rte_cryptodev_sym_capability_idx cap_idx
;
728 struct rte_crypto_auth_xform
*auth_xform
= &xform
->auth
;
730 xform
->type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
732 auth_xform
->algo
= info
.interim_info
.hmac_data
.algo
;
733 auth_xform
->op
= RTE_CRYPTO_AUTH_OP_GENERATE
;
734 auth_xform
->digest_length
= vec
.cipher_auth
.digest
.len
;
735 auth_xform
->key
.data
= vec
.cipher_auth
.key
.val
;
736 auth_xform
->key
.length
= vec
.cipher_auth
.key
.len
;
738 cap_idx
.algo
.auth
= auth_xform
->algo
;
739 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
741 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
743 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
748 if (rte_cryptodev_sym_capability_check_auth(cap
,
749 auth_xform
->key
.length
,
750 auth_xform
->digest_length
, 0) != 0) {
751 RTE_LOG(ERR
, USER1
, "PMD %s key length %u IV length %u\n",
752 info
.device_name
, auth_xform
->key
.length
,
753 auth_xform
->digest_length
);
761 prepare_gcm_xform(struct rte_crypto_sym_xform
*xform
)
763 const struct rte_cryptodev_symmetric_capability
*cap
;
764 struct rte_cryptodev_sym_capability_idx cap_idx
;
765 struct rte_crypto_aead_xform
*aead_xform
= &xform
->aead
;
767 xform
->type
= RTE_CRYPTO_SYM_XFORM_AEAD
;
769 aead_xform
->algo
= RTE_CRYPTO_AEAD_AES_GCM
;
770 aead_xform
->aad_length
= vec
.aead
.aad
.len
;
771 aead_xform
->digest_length
= vec
.aead
.digest
.len
;
772 aead_xform
->iv
.offset
= IV_OFF
;
773 aead_xform
->iv
.length
= vec
.iv
.len
;
774 aead_xform
->key
.data
= vec
.aead
.key
.val
;
775 aead_xform
->key
.length
= vec
.aead
.key
.len
;
776 aead_xform
->op
= (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) ?
777 RTE_CRYPTO_AEAD_OP_ENCRYPT
:
778 RTE_CRYPTO_AEAD_OP_DECRYPT
;
780 cap_idx
.algo
.aead
= aead_xform
->algo
;
781 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_AEAD
;
783 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
785 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
790 if (rte_cryptodev_sym_capability_check_aead(cap
,
791 aead_xform
->key
.length
,
792 aead_xform
->digest_length
, aead_xform
->aad_length
,
793 aead_xform
->iv
.length
) != 0) {
795 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
796 info
.device_name
, aead_xform
->key
.length
,
797 aead_xform
->digest_length
,
798 aead_xform
->aad_length
,
799 aead_xform
->iv
.length
);
807 prepare_cmac_xform(struct rte_crypto_sym_xform
*xform
)
809 const struct rte_cryptodev_symmetric_capability
*cap
;
810 struct rte_cryptodev_sym_capability_idx cap_idx
;
811 struct rte_crypto_auth_xform
*auth_xform
= &xform
->auth
;
813 xform
->type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
815 auth_xform
->algo
= RTE_CRYPTO_AUTH_AES_CMAC
;
816 auth_xform
->op
= (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) ?
817 RTE_CRYPTO_AUTH_OP_GENERATE
: RTE_CRYPTO_AUTH_OP_VERIFY
;
818 auth_xform
->digest_length
= vec
.cipher_auth
.digest
.len
;
819 auth_xform
->key
.data
= vec
.cipher_auth
.key
.val
;
820 auth_xform
->key
.length
= vec
.cipher_auth
.key
.len
;
822 cap_idx
.algo
.auth
= auth_xform
->algo
;
823 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
825 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
827 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
832 if (rte_cryptodev_sym_capability_check_auth(cap
,
833 auth_xform
->key
.length
,
834 auth_xform
->digest_length
, 0) != 0) {
835 RTE_LOG(ERR
, USER1
, "PMD %s key length %u IV length %u\n",
836 info
.device_name
, auth_xform
->key
.length
,
837 auth_xform
->digest_length
);
845 prepare_ccm_xform(struct rte_crypto_sym_xform
*xform
)
847 const struct rte_cryptodev_symmetric_capability
*cap
;
848 struct rte_cryptodev_sym_capability_idx cap_idx
;
849 struct rte_crypto_aead_xform
*aead_xform
= &xform
->aead
;
851 xform
->type
= RTE_CRYPTO_SYM_XFORM_AEAD
;
853 aead_xform
->algo
= RTE_CRYPTO_AEAD_AES_CCM
;
854 aead_xform
->aad_length
= vec
.aead
.aad
.len
;
855 aead_xform
->digest_length
= vec
.aead
.digest
.len
;
856 aead_xform
->iv
.offset
= IV_OFF
;
857 aead_xform
->iv
.length
= vec
.iv
.len
;
858 aead_xform
->key
.data
= vec
.aead
.key
.val
;
859 aead_xform
->key
.length
= vec
.aead
.key
.len
;
860 aead_xform
->op
= (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) ?
861 RTE_CRYPTO_AEAD_OP_ENCRYPT
:
862 RTE_CRYPTO_AEAD_OP_DECRYPT
;
864 cap_idx
.algo
.aead
= aead_xform
->algo
;
865 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_AEAD
;
867 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
869 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
874 if (rte_cryptodev_sym_capability_check_aead(cap
,
875 aead_xform
->key
.length
,
876 aead_xform
->digest_length
, aead_xform
->aad_length
,
877 aead_xform
->iv
.length
) != 0) {
879 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
880 info
.device_name
, aead_xform
->key
.length
,
881 aead_xform
->digest_length
,
882 aead_xform
->aad_length
,
883 aead_xform
->iv
.length
);
891 prepare_sha_xform(struct rte_crypto_sym_xform
*xform
)
893 const struct rte_cryptodev_symmetric_capability
*cap
;
894 struct rte_cryptodev_sym_capability_idx cap_idx
;
895 struct rte_crypto_auth_xform
*auth_xform
= &xform
->auth
;
897 xform
->type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
899 auth_xform
->algo
= info
.interim_info
.sha_data
.algo
;
900 auth_xform
->op
= RTE_CRYPTO_AUTH_OP_GENERATE
;
901 auth_xform
->digest_length
= vec
.cipher_auth
.digest
.len
;
903 cap_idx
.algo
.auth
= auth_xform
->algo
;
904 cap_idx
.type
= RTE_CRYPTO_SYM_XFORM_AUTH
;
906 cap
= rte_cryptodev_sym_capability_get(env
.dev_id
, &cap_idx
);
908 RTE_LOG(ERR
, USER1
, "Failed to get capability for cdev %u\n",
913 if (rte_cryptodev_sym_capability_check_auth(cap
,
914 auth_xform
->key
.length
,
915 auth_xform
->digest_length
, 0) != 0) {
916 RTE_LOG(ERR
, USER1
, "PMD %s key length %u digest length %u\n",
917 info
.device_name
, auth_xform
->key
.length
,
918 auth_xform
->digest_length
);
926 get_writeback_data(struct fips_val
*val
)
928 val
->val
= rte_pktmbuf_mtod(env
.mbuf
, uint8_t *);
929 val
->len
= rte_pktmbuf_pkt_len(env
.mbuf
);
935 struct rte_crypto_sym_xform xform
= {0};
939 ret
= test_ops
.prepare_xform(&xform
);
943 env
.sess
= rte_cryptodev_sym_session_create(env
.sess_mpool
);
947 ret
= rte_cryptodev_sym_session_init(env
.dev_id
,
948 env
.sess
, &xform
, env
.sess_priv_mpool
);
950 RTE_LOG(ERR
, USER1
, "Error %i: Init session\n",
955 ret
= test_ops
.prepare_op();
957 RTE_LOG(ERR
, USER1
, "Error %i: Prepare op\n",
962 if (rte_cryptodev_enqueue_burst(env
.dev_id
, 0, &env
.op
, 1) < 1) {
963 RTE_LOG(ERR
, USER1
, "Error: Failed enqueue\n");
969 struct rte_crypto_op
*deqd_op
;
971 n_deqd
= rte_cryptodev_dequeue_burst(env
.dev_id
, 0, &deqd_op
,
973 } while (n_deqd
== 0);
975 vec
.status
= env
.op
->status
;
978 rte_cryptodev_sym_session_clear(env
.dev_id
, env
.sess
);
979 rte_cryptodev_sym_session_free(env
.sess
);
986 fips_generic_test(void)
991 fips_test_write_one_case();
993 ret
= fips_run_test();
996 fprintf(info
.fp_wr
, "Bypass\n\n");
1003 get_writeback_data(&val
);
1005 switch (info
.file_type
) {
1008 if (info
.parse_writeback
== NULL
)
1010 ret
= info
.parse_writeback(&val
);
1015 if (info
.kat_check
== NULL
)
1017 ret
= info
.kat_check(&val
);
1023 fprintf(info
.fp_wr
, "\n");
1029 fips_mct_tdes_test(void)
1031 #define TDES_BLOCK_SIZE 8
1032 #define TDES_EXTERN_ITER 400
1033 #define TDES_INTERN_ITER 10000
1034 struct fips_val val
, val_key
;
1035 uint8_t prev_out
[TDES_BLOCK_SIZE
] = {0};
1036 uint8_t prev_prev_out
[TDES_BLOCK_SIZE
] = {0};
1037 uint8_t prev_in
[TDES_BLOCK_SIZE
] = {0};
1041 for (i
= 0; i
< TDES_EXTERN_ITER
; i
++) {
1045 fips_test_write_one_case();
1047 for (j
= 0; j
< TDES_INTERN_ITER
; j
++) {
1048 ret
= fips_run_test();
1050 if (ret
== -EPERM
) {
1051 fprintf(info
.fp_wr
, "Bypass\n");
1058 get_writeback_data(&val
);
1060 if (info
.op
== FIPS_TEST_DEC_AUTH_VERIF
)
1061 memcpy(prev_in
, vec
.ct
.val
, TDES_BLOCK_SIZE
);
1064 memcpy(prev_out
, val
.val
, TDES_BLOCK_SIZE
);
1066 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
1067 memcpy(vec
.pt
.val
, vec
.iv
.val
,
1069 memcpy(vec
.iv
.val
, val
.val
,
1072 memcpy(vec
.iv
.val
, vec
.ct
.val
,
1074 memcpy(vec
.ct
.val
, val
.val
,
1080 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
1081 memcpy(vec
.iv
.val
, val
.val
, TDES_BLOCK_SIZE
);
1082 memcpy(vec
.pt
.val
, prev_out
, TDES_BLOCK_SIZE
);
1084 memcpy(vec
.iv
.val
, vec
.ct
.val
, TDES_BLOCK_SIZE
);
1085 memcpy(vec
.ct
.val
, val
.val
, TDES_BLOCK_SIZE
);
1088 if (j
== TDES_INTERN_ITER
- 1)
1091 memcpy(prev_out
, val
.val
, TDES_BLOCK_SIZE
);
1093 if (j
== TDES_INTERN_ITER
- 3)
1094 memcpy(prev_prev_out
, val
.val
, TDES_BLOCK_SIZE
);
1097 info
.parse_writeback(&val
);
1098 fprintf(info
.fp_wr
, "\n");
1100 if (i
== TDES_EXTERN_ITER
- 1)
1104 memcpy(&val_key
, &vec
.cipher_auth
.key
, sizeof(val_key
));
1106 if (info
.interim_info
.tdes_data
.nb_keys
== 0) {
1107 if (memcmp(val_key
.val
, val_key
.val
+ 8, 8) == 0)
1108 info
.interim_info
.tdes_data
.nb_keys
= 1;
1109 else if (memcmp(val_key
.val
, val_key
.val
+ 16, 8) == 0)
1110 info
.interim_info
.tdes_data
.nb_keys
= 2;
1112 info
.interim_info
.tdes_data
.nb_keys
= 3;
1116 for (k
= 0; k
< TDES_BLOCK_SIZE
; k
++) {
1118 switch (info
.interim_info
.tdes_data
.nb_keys
) {
1120 val_key
.val
[k
] ^= val
.val
[k
];
1121 val_key
.val
[k
+ 8] ^= prev_out
[k
];
1122 val_key
.val
[k
+ 16] ^= prev_prev_out
[k
];
1125 val_key
.val
[k
] ^= val
.val
[k
];
1126 val_key
.val
[k
+ 8] ^= prev_out
[k
];
1127 val_key
.val
[k
+ 16] ^= val
.val
[k
];
1129 default: /* case 1 */
1130 val_key
.val
[k
] ^= val
.val
[k
];
1131 val_key
.val
[k
+ 8] ^= val
.val
[k
];
1132 val_key
.val
[k
+ 16] ^= val
.val
[k
];
1138 for (k
= 0; k
< 24; k
++)
1139 val_key
.val
[k
] = (__builtin_popcount(val_key
.val
[k
]) &
1141 val_key
.val
[k
] : (val_key
.val
[k
] ^ 0x1);
1143 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
1144 memcpy(vec
.iv
.val
, val
.val
, TDES_BLOCK_SIZE
);
1145 memcpy(vec
.pt
.val
, prev_out
, TDES_BLOCK_SIZE
);
1147 memcpy(vec
.iv
.val
, prev_out
, TDES_BLOCK_SIZE
);
1148 memcpy(vec
.ct
.val
, val
.val
, TDES_BLOCK_SIZE
);
1156 fips_mct_aes_test(void)
1158 #define AES_BLOCK_SIZE 16
1159 #define AES_EXTERN_ITER 100
1160 #define AES_INTERN_ITER 1000
1161 struct fips_val val
, val_key
;
1162 uint8_t prev_out
[AES_BLOCK_SIZE
] = {0};
1163 uint8_t prev_in
[AES_BLOCK_SIZE
] = {0};
1167 for (i
= 0; i
< AES_EXTERN_ITER
; i
++) {
1171 fips_test_write_one_case();
1173 for (j
= 0; j
< AES_INTERN_ITER
; j
++) {
1174 ret
= fips_run_test();
1176 if (ret
== -EPERM
) {
1177 fprintf(info
.fp_wr
, "Bypass\n");
1184 get_writeback_data(&val
);
1186 if (info
.op
== FIPS_TEST_DEC_AUTH_VERIF
)
1187 memcpy(prev_in
, vec
.ct
.val
, AES_BLOCK_SIZE
);
1190 memcpy(prev_out
, val
.val
, AES_BLOCK_SIZE
);
1192 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
1193 memcpy(vec
.pt
.val
, vec
.iv
.val
,
1195 memcpy(vec
.iv
.val
, val
.val
,
1198 memcpy(vec
.ct
.val
, vec
.iv
.val
,
1200 memcpy(vec
.iv
.val
, prev_in
,
1206 if (info
.op
== FIPS_TEST_ENC_AUTH_GEN
) {
1207 memcpy(vec
.iv
.val
, val
.val
, AES_BLOCK_SIZE
);
1208 memcpy(vec
.pt
.val
, prev_out
, AES_BLOCK_SIZE
);
1210 memcpy(vec
.iv
.val
, prev_in
, AES_BLOCK_SIZE
);
1211 memcpy(vec
.ct
.val
, prev_out
, AES_BLOCK_SIZE
);
1214 if (j
== AES_INTERN_ITER
- 1)
1217 memcpy(prev_out
, val
.val
, AES_BLOCK_SIZE
);
1220 info
.parse_writeback(&val
);
1221 fprintf(info
.fp_wr
, "\n");
1223 if (i
== AES_EXTERN_ITER
- 1)
1227 memcpy(&val_key
, &vec
.cipher_auth
.key
, sizeof(val_key
));
1228 for (k
= 0; k
< vec
.cipher_auth
.key
.len
; k
++) {
1229 switch (vec
.cipher_auth
.key
.len
) {
1231 val_key
.val
[k
] ^= val
.val
[k
];
1235 val_key
.val
[k
] ^= prev_out
[k
+ 8];
1237 val_key
.val
[k
] ^= val
.val
[k
- 8];
1241 val_key
.val
[k
] ^= prev_out
[k
];
1243 val_key
.val
[k
] ^= val
.val
[k
- 16];
1250 if (info
.op
== FIPS_TEST_DEC_AUTH_VERIF
)
1251 memcpy(vec
.iv
.val
, val
.val
, AES_BLOCK_SIZE
);
1258 fips_mct_sha_test(void)
1260 #define SHA_EXTERN_ITER 100
1261 #define SHA_INTERN_ITER 1000
1262 #define SHA_MD_BLOCK 3
1263 struct fips_val val
, md
[SHA_MD_BLOCK
];
1264 char temp
[MAX_DIGEST_SIZE
*2];
1268 val
.val
= rte_malloc(NULL
, (MAX_DIGEST_SIZE
*SHA_MD_BLOCK
), 0);
1269 for (i
= 0; i
< SHA_MD_BLOCK
; i
++)
1270 md
[i
].val
= rte_malloc(NULL
, (MAX_DIGEST_SIZE
*2), 0);
1272 rte_free(vec
.pt
.val
);
1273 vec
.pt
.val
= rte_malloc(NULL
, (MAX_DIGEST_SIZE
*SHA_MD_BLOCK
), 0);
1275 fips_test_write_one_case();
1276 fprintf(info
.fp_wr
, "\n");
1278 for (j
= 0; j
< SHA_EXTERN_ITER
; j
++) {
1280 memcpy(md
[0].val
, vec
.cipher_auth
.digest
.val
,
1281 vec
.cipher_auth
.digest
.len
);
1282 md
[0].len
= vec
.cipher_auth
.digest
.len
;
1283 memcpy(md
[1].val
, vec
.cipher_auth
.digest
.val
,
1284 vec
.cipher_auth
.digest
.len
);
1285 md
[1].len
= vec
.cipher_auth
.digest
.len
;
1286 memcpy(md
[2].val
, vec
.cipher_auth
.digest
.val
,
1287 vec
.cipher_auth
.digest
.len
);
1288 md
[2].len
= vec
.cipher_auth
.digest
.len
;
1290 for (i
= 0; i
< (SHA_INTERN_ITER
); i
++) {
1292 memcpy(vec
.pt
.val
, md
[0].val
,
1294 memcpy((vec
.pt
.val
+ md
[0].len
), md
[1].val
,
1296 memcpy((vec
.pt
.val
+ md
[0].len
+ md
[1].len
),
1299 vec
.pt
.len
= md
[0].len
+ md
[1].len
+ md
[2].len
;
1301 ret
= fips_run_test();
1303 if (ret
== -EPERM
) {
1304 fprintf(info
.fp_wr
, "Bypass\n\n");
1310 get_writeback_data(&val
);
1312 memcpy(md
[0].val
, md
[1].val
, md
[1].len
);
1313 md
[0].len
= md
[1].len
;
1314 memcpy(md
[1].val
, md
[2].val
, md
[2].len
);
1315 md
[1].len
= md
[2].len
;
1317 memcpy(md
[2].val
, (val
.val
+ vec
.pt
.len
),
1318 vec
.cipher_auth
.digest
.len
);
1319 md
[2].len
= vec
.cipher_auth
.digest
.len
;
1322 memcpy(vec
.cipher_auth
.digest
.val
, md
[2].val
, md
[2].len
);
1323 vec
.cipher_auth
.digest
.len
= md
[2].len
;
1325 fprintf(info
.fp_wr
, "COUNT = %u\n", j
);
1327 writeback_hex_str("", temp
, &vec
.cipher_auth
.digest
);
1329 fprintf(info
.fp_wr
, "MD = %s\n\n", temp
);
1332 for (i
= 0; i
< (SHA_MD_BLOCK
); i
++)
1333 rte_free(md
[i
].val
);
1335 rte_free(vec
.pt
.val
);
1344 switch (info
.algo
) {
1345 case FIPS_TEST_ALGO_AES
:
1346 test_ops
.prepare_op
= prepare_cipher_op
;
1347 test_ops
.prepare_xform
= prepare_aes_xform
;
1348 if (info
.interim_info
.aes_data
.test_type
== AESAVS_TYPE_MCT
)
1349 test_ops
.test
= fips_mct_aes_test
;
1351 test_ops
.test
= fips_generic_test
;
1353 case FIPS_TEST_ALGO_HMAC
:
1354 test_ops
.prepare_op
= prepare_auth_op
;
1355 test_ops
.prepare_xform
= prepare_hmac_xform
;
1356 test_ops
.test
= fips_generic_test
;
1358 case FIPS_TEST_ALGO_TDES
:
1359 test_ops
.prepare_op
= prepare_cipher_op
;
1360 test_ops
.prepare_xform
= prepare_tdes_xform
;
1361 if (info
.interim_info
.tdes_data
.test_type
== TDES_MCT
)
1362 test_ops
.test
= fips_mct_tdes_test
;
1364 test_ops
.test
= fips_generic_test
;
1366 case FIPS_TEST_ALGO_AES_GCM
:
1367 test_ops
.prepare_op
= prepare_aead_op
;
1368 test_ops
.prepare_xform
= prepare_gcm_xform
;
1369 test_ops
.test
= fips_generic_test
;
1371 case FIPS_TEST_ALGO_AES_CMAC
:
1372 test_ops
.prepare_op
= prepare_auth_op
;
1373 test_ops
.prepare_xform
= prepare_cmac_xform
;
1374 test_ops
.test
= fips_generic_test
;
1376 case FIPS_TEST_ALGO_AES_CCM
:
1377 test_ops
.prepare_op
= prepare_aead_op
;
1378 test_ops
.prepare_xform
= prepare_ccm_xform
;
1379 test_ops
.test
= fips_generic_test
;
1381 case FIPS_TEST_ALGO_SHA
:
1382 test_ops
.prepare_op
= prepare_auth_op
;
1383 test_ops
.prepare_xform
= prepare_sha_xform
;
1384 if (info
.interim_info
.sha_data
.test_type
== SHA_MCT
)
1385 test_ops
.test
= fips_mct_sha_test
;
1387 test_ops
.test
= fips_generic_test
;
1397 print_test_block(void)
1401 for (i
= 0; i
< info
.nb_vec_lines
; i
++)
1402 printf("%s\n", info
.vec
[i
]);
1408 fips_test_one_file(void)
1410 int fetch_ret
= 0, ret
;
1413 ret
= init_test_ops();
1415 RTE_LOG(ERR
, USER1
, "Error %i: Init test op\n", ret
);
1419 while (ret
>= 0 && fetch_ret
== 0) {
1420 fetch_ret
= fips_test_fetch_one_block();
1421 if (fetch_ret
< 0) {
1422 RTE_LOG(ERR
, USER1
, "Error %i: Fetch block\n",
1425 goto error_one_case
;
1428 if (info
.nb_vec_lines
== 0) {
1429 if (fetch_ret
== -EOF
)
1432 fprintf(info
.fp_wr
, "\n");
1436 ret
= fips_test_parse_one_case();
1439 ret
= test_ops
.test();
1442 RTE_LOG(ERR
, USER1
, "Error %i: test block\n",
1444 goto error_one_case
;
1448 RTE_LOG(ERR
, USER1
, "Error %i: Parse block\n",
1450 goto error_one_case
;