From: Marko Kovacevic Date: Fri, 2 Nov 2018 09:55:34 +0000 (+0000) Subject: examples/fips_validation: support CCM parsing X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=305921f4508d6a4c399ff99036e379e810455b9b;p=dpdk.git examples/fips_validation: support CCM parsing Added enablement for CCM parser, to allow the application to parser the ccm request files and to validate all test types supported. Signed-off-by: Marko Kovacevic Signed-off-by: Fan Zhang Acked-by: Arek Kusztal Reviewed-by: Akhil Goyal --- diff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst index 747c8c8a71..aeacfacb7c 100644 --- a/doc/guides/sample_app_ug/fips_validation.rst +++ b/doc/guides/sample_app_ug/fips_validation.rst @@ -42,6 +42,7 @@ Limitations * Supported test vectors * AES-CBC (128,192,256) - GFSbox, KeySbox, MCT, MMT * AES-GCM (128,192,256) - EncryptExtIV, Decrypt + * AES-CCM (128) - VADT, VNT, VPT, VTT, DVPT * AES-CMAC (128) - Generate, Verify * HMAC (SHA1, SHA224, SHA256, SHA384, SHA512) * TDES-CBC (1 Key, 2 Keys, 3 Keys) - MMT, Monte, Permop, Subkey, Varkey, diff --git a/examples/fips_validation/Makefile b/examples/fips_validation/Makefile index 77b15ae1f2..7b1fe34a68 100644 --- a/examples/fips_validation/Makefile +++ b/examples/fips_validation/Makefile @@ -11,6 +11,7 @@ SRCS-y += fips_validation_hmac.c SRCS-y += fips_validation_tdes.c SRCS-y += fips_validation_gcm.c SRCS-y += fips_validation_cmac.c +SRCS-y += fips_validation_ccm.c SRCS-y += main.c # Build using pkg-config variables if possible diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c index fdf6f640bd..a835cc3fa6 100644 --- a/examples/fips_validation/fips_validation.c +++ b/examples/fips_validation/fips_validation.c @@ -121,6 +121,11 @@ fips_test_parse_header(void) ret = parse_test_cmac_init(); if (ret < 0) return 0; + } else if (strstr(info.vec[i], "CCM")) { + info.algo = FIPS_TEST_ALGO_AES_CCM; + ret = parse_test_ccm_init(); + if (ret < 0) + return 0; } else if (strstr(info.vec[i], "HMAC")) { info.algo = FIPS_TEST_ALGO_HMAC; ret = parse_test_hmac_init(); diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h index 8dffe8ed18..3e291bc365 100644 --- a/examples/fips_validation/fips_validation.h +++ b/examples/fips_validation/fips_validation.h @@ -26,6 +26,7 @@ enum fips_test_algorithms { FIPS_TEST_ALGO_AES = 0, FIPS_TEST_ALGO_AES_GCM, FIPS_TEST_ALGO_AES_CMAC, + FIPS_TEST_ALGO_AES_CCM, FIPS_TEST_ALGO_HMAC, FIPS_TEST_ALGO_TDES, FIPS_TEST_ALGO_MAX @@ -102,6 +103,14 @@ enum fips_tdes_test_types { TDES_MMT /* Multi block Message Test */ }; +enum fips_ccm_test_types { + CCM_VADT = 1, /* Variable Associated Data Test */ + CCM_VPT, /* Variable Payload Test */ + CCM_VNT, /* Variable Nonce Test */ + CCM_VTT, /* Variable Tag Test */ + CCM_DVPT, /* Decryption-Verification Process Test */ +}; + struct aesavs_interim_data { enum fips_aesavs_test_types test_type; uint32_t cipher_algo; @@ -117,6 +126,15 @@ struct tdes_interim_data { uint32_t nb_keys; }; +struct ccm_interim_data { + enum fips_ccm_test_types test_type; + uint32_t aad_len; + uint32_t pt_len; + uint32_t digest_len; + uint32_t key_len; + uint32_t iv_len; +}; + struct fips_test_interim_info { FILE *fp_rd; FILE *fp_wr; @@ -131,6 +149,7 @@ struct fips_test_interim_info { struct aesavs_interim_data aes_data; struct hmac_interim_data hmac_data; struct tdes_interim_data tdes_data; + struct ccm_interim_data ccm_data; } interim_info; @@ -178,6 +197,9 @@ parse_test_gcm_init(void); int parse_test_cmac_init(void); +int +parse_test_ccm_init(void); + int parser_read_uint8_hex(uint8_t *value, const char *p); diff --git a/examples/fips_validation/fips_validation_ccm.c b/examples/fips_validation/fips_validation_ccm.c new file mode 100644 index 0000000000..632999c1e4 --- /dev/null +++ b/examples/fips_validation/fips_validation_ccm.c @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include + +#include +#include +#include + +#include "fips_validation.h" + +#define DVPT_STR "CCM-DVPT" +#define VADT_STR "CCM-VADT" +#define VPT_STR "CCM-VPT" +#define VNT_STR "CCM-VNT" +#define VTT_STR "CCM-VTT" + +#define PARAM_PREFIX "[" +#define ALEN_PREFIX "Alen = " +#define PLEN_PREFIX "Plen = " +#define IVLEN_PREFIX "Nlen = " +#define DIGESTL_PREFIX "Tlen = " + +#define COUNT_STR "Count = " +#define KEY_STR "Key = " +#define IV_STR "Nonce = " +#define PT_STR "Payload = " +#define CT_STR "CT = " +#define AAD_STR "Adata = " +#define POS_NEG_STR "Result = " + +#define POS_KEYWORD "Pass" +#define NEG_KEYWORD "Fail" + +static int +parser_dvpt_interim(const char *key, char *src, struct fips_val *val) +{ + char *tmp, c, value[10]; + char num_pattern[] = "0123456789"; + int i = 0; + + memset(value, 0, 10); + + tmp = strstr(src, key); + if (!tmp) + return -1; + + tmp += strlen(key); + + c = tmp[0]; + + while (strchr(num_pattern, c) && i < 10) { + value[i++] = c; + c = tmp[i]; + } + + return parser_read_uint32_val("", value, val); +} + +static int +parse_dvpt_ct_hex_str(const char *key, char *src, struct fips_val *val) +{ + int ret; + + val->len = vec.pt.len; + + ret = parse_uint8_known_len_hex_str(key, src, val); + if (ret < 0) + return ret; + + src += strlen(key) + val->len * 2; + + ret = parse_uint8_known_len_hex_str("", src, &vec.aead.digest); + if (ret < 0) { + rte_free(val->val); + memset(val, 0, sizeof(*val)); + return ret; + } + + return 0; +} + +static int +parse_uint8_ccm_aad_str(const char *key, char *src, struct fips_val *val) +{ + uint32_t len = val->len, j; + + src += strlen(key); + + /* CCM aad requires 18 bytes padding before the real content */ + val->val = rte_zmalloc(NULL, len + 18, 0); + if (!val->val) + return -1; + + for (j = 0; j < len; j++) { + char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'}; + + if (parser_read_uint8_hex(&val->val[j + 18], byte) < 0) { + rte_free(val->val); + memset(val, 0, sizeof(*val)); + return -EINVAL; + } + } + + return 0; +} + +struct fips_test_callback ccm_vnt_vec[] = { + {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, + {AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad}, + {PT_STR, parse_uint8_known_len_hex_str, &vec.pt}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vnt_interim_vec[] = { + {ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad}, + {PLEN_PREFIX, parser_read_uint32_val, &vec.pt}, + {DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest}, + {IVLEN_PREFIX, parser_read_uint32_val, &vec.iv}, + {KEY_STR, parse_uint8_hex_str, &vec.aead.key}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vtt_vec[] = { + {AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad}, + {PT_STR, parse_uint8_known_len_hex_str, &vec.pt}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vtt_interim_vec[] = { + {ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad}, + {PLEN_PREFIX, parser_read_uint32_val, &vec.pt}, + {IVLEN_PREFIX, parser_read_uint32_val, &vec.iv}, + {DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest}, + {KEY_STR, parse_uint8_hex_str, &vec.aead.key}, + {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vadt_vec[] = { + {AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad}, + {PT_STR, parse_uint8_known_len_hex_str, &vec.pt}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vadt_interim_vec[] = { + {PLEN_PREFIX, parser_read_uint32_val, &vec.pt}, + {IVLEN_PREFIX, parser_read_uint32_val, &vec.iv}, + {ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad}, + {DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest}, + {KEY_STR, parse_uint8_hex_str, &vec.aead.key}, + {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vpt_vec[] = { + {AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad}, + {PT_STR, parse_uint8_known_len_hex_str, &vec.pt}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_vpt_interim_vec[] = { + {ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad}, + {IVLEN_PREFIX, parser_read_uint32_val, &vec.iv}, + {DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest}, + {PLEN_PREFIX, parser_read_uint32_val, &vec.pt}, + {KEY_STR, parse_uint8_hex_str, &vec.aead.key}, + {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_dvpt_vec[] = { + {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, + {AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad}, + {CT_STR, parse_dvpt_ct_hex_str, &vec.ct}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback ccm_dvpt_interim_vec[] = { + {ALEN_PREFIX, parser_dvpt_interim, &vec.aead.aad}, + {PLEN_PREFIX, parser_dvpt_interim, &vec.pt}, + {IVLEN_PREFIX, parser_dvpt_interim, &vec.iv}, + {DIGESTL_PREFIX, parser_dvpt_interim, &vec.aead.digest}, + {KEY_STR, parse_uint8_hex_str, &vec.aead.key}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct ccm_test_types { + const char *str; + uint32_t type; + const struct fips_test_callback *cb; + const struct fips_test_callback *cb_interim; + enum fips_test_op op; +} ctt[] = { + {DVPT_STR, CCM_DVPT, ccm_dvpt_vec, ccm_dvpt_interim_vec, + FIPS_TEST_DEC_AUTH_VERIF}, + {VPT_STR, CCM_VPT, ccm_vpt_vec, ccm_vpt_interim_vec, + FIPS_TEST_ENC_AUTH_GEN}, + {VADT_STR, CCM_VADT, ccm_vadt_vec, ccm_vadt_interim_vec, + FIPS_TEST_ENC_AUTH_GEN}, + {VNT_STR, CCM_VNT, ccm_vnt_vec, ccm_vnt_interim_vec, + FIPS_TEST_ENC_AUTH_GEN}, + {VTT_STR, CCM_VTT, ccm_vtt_vec, ccm_vtt_interim_vec, + FIPS_TEST_ENC_AUTH_GEN}, +}; + +static int +parse_test_ccm_writeback(struct fips_val *val) +{ + struct fips_val tmp_val; + + switch (info.interim_info.ccm_data.test_type) { + case CCM_DVPT: + fprintf(info.fp_wr, "%s", POS_NEG_STR); + if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { + fprintf(info.fp_wr, "%s\n", POS_KEYWORD); + fprintf(info.fp_wr, "%s", PT_STR); + + tmp_val.val = val->val; + tmp_val.len = vec.pt.len; + + if (tmp_val.len == 0) + fprintf(info.fp_wr, "00\n"); + else + parse_write_hex_str(&tmp_val); + } else + fprintf(info.fp_wr, "%s\n", NEG_KEYWORD); + + break; + + case CCM_VADT: + case CCM_VNT: + case CCM_VPT: + case CCM_VTT: + fprintf(info.fp_wr, "%s", CT_STR); + + parse_write_hex_str(val); + + break; + + } + + return 0; +} + +int +parse_test_ccm_init(void) +{ + + uint32_t i; + + for (i = 0; i < info.nb_vec_lines; i++) { + char *line = info.vec[i]; + uint32_t j; + + for (j = 0; j < RTE_DIM(ctt); j++) + if (strstr(line, ctt[j].str)) { + info.interim_info.ccm_data.test_type = + ctt[j].type; + info.callbacks = ctt[j].cb; + info.interim_callbacks = ctt[j].cb_interim; + info.op = ctt[j].op; + break; + } + } + + info.parse_writeback = parse_test_ccm_writeback; + + return 0; +} diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c index e953f3e6d8..0a7e75fc89 100644 --- a/examples/fips_validation/main.c +++ b/examples/fips_validation/main.c @@ -470,7 +470,10 @@ prepare_aead_op(void) __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); rte_pktmbuf_reset(env.mbuf); - memcpy(iv, vec.iv.val, vec.iv.len); + if (info.algo == FIPS_TEST_ALGO_AES_CCM) + memcpy(iv + 1, vec.iv.val, vec.iv.len); + else + memcpy(iv, vec.iv.val, vec.iv.len); sym->m_src = env.mbuf; sym->aead.data.offset = 0; @@ -726,6 +729,52 @@ prepare_cmac_xform(struct rte_crypto_sym_xform *xform) return 0; } +static int +prepare_ccm_xform(struct rte_crypto_sym_xform *xform) +{ + const struct rte_cryptodev_symmetric_capability *cap; + struct rte_cryptodev_sym_capability_idx cap_idx; + struct rte_crypto_aead_xform *aead_xform = &xform->aead; + + xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; + + aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; + aead_xform->aad_length = vec.aead.aad.len; + aead_xform->digest_length = vec.aead.digest.len; + aead_xform->iv.offset = IV_OFF; + aead_xform->iv.length = vec.iv.len; + aead_xform->key.data = vec.aead.key.val; + aead_xform->key.length = vec.aead.key.len; + aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? + RTE_CRYPTO_AEAD_OP_ENCRYPT : + RTE_CRYPTO_AEAD_OP_DECRYPT; + + cap_idx.algo.aead = aead_xform->algo; + cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; + + cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); + if (!cap) { + RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", + env.dev_id); + return -EINVAL; + } + + if (rte_cryptodev_sym_capability_check_aead(cap, + aead_xform->key.length, + aead_xform->digest_length, aead_xform->aad_length, + aead_xform->iv.length) != 0) { + RTE_LOG(ERR, USER1, + "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", + info.device_name, aead_xform->key.length, + aead_xform->digest_length, + aead_xform->aad_length, + aead_xform->iv.length); + return -EPERM; + } + + return 0; +} + static void get_writeback_data(struct fips_val *val) { @@ -1091,6 +1140,11 @@ init_test_ops(void) test_ops.prepare_xform = prepare_cmac_xform; test_ops.test = fips_generic_test; break; + case FIPS_TEST_ALGO_AES_CCM: + test_ops.prepare_op = prepare_aead_op; + test_ops.prepare_xform = prepare_ccm_xform; + test_ops.test = fips_generic_test; + break; default: return -1; } diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build index a0d38fa4f7..498c9ba95b 100644 --- a/examples/fips_validation/meson.build +++ b/examples/fips_validation/meson.build @@ -15,5 +15,6 @@ sources = files( 'fips_validation_tdes.c', 'fips_validation_gcm.c', 'fips_validation_cmac.c', + 'fips_validation_ccm.c', 'main.c' )