From f4797bae00502b9fd3db0bae80cd933f69b33060 Mon Sep 17 00:00:00 2001 From: Damian Nowak Date: Tue, 19 Mar 2019 10:43:48 +0100 Subject: [PATCH] examples/fips_validation: support plain SHA This patch enables plain SHA algorithm CAVP test support in fips_validation sample application. Signed-off-by: Damian Nowak Acked-by: Fan Zhang Acked-by: Marko Kovacevic --- examples/fips_validation/Makefile | 1 + examples/fips_validation/fips_validation.c | 17 +++ examples/fips_validation/fips_validation.h | 17 ++- .../fips_validation/fips_validation_sha.c | 110 +++++++++++++++ examples/fips_validation/main.c | 127 ++++++++++++++++++ examples/fips_validation/meson.build | 1 + 6 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 examples/fips_validation/fips_validation_sha.c diff --git a/examples/fips_validation/Makefile b/examples/fips_validation/Makefile index 923d0be6e4..2120cd9655 100644 --- a/examples/fips_validation/Makefile +++ b/examples/fips_validation/Makefile @@ -12,6 +12,7 @@ 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 += fips_validation_sha.c SRCS-y += fips_dev_self_test.c SRCS-y += main.c diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c index a835cc3fa6..2f8314fcc0 100644 --- a/examples/fips_validation/fips_validation.c +++ b/examples/fips_validation/fips_validation.c @@ -136,6 +136,11 @@ fips_test_parse_header(void) ret = parse_test_tdes_init(); if (ret < 0) return 0; + } else if (strstr(info.vec[i], "SHA-")) { + info.algo = FIPS_TEST_ALGO_SHA; + ret = parse_test_sha_init(); + if (ret < 0) + return ret; } tmp = strstr(info.vec[i], "# Config info for "); @@ -186,6 +191,18 @@ fips_test_parse_header(void) continue; } + tmp = strstr(info.vec[i], "\" information for \""); + if (tmp != NULL) { + char tmp_output[128] = {0}; + + strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1); + + fprintf(info.fp_wr, "%s%s%s\n", tmp_output, + "\" information for DPDK Cryptodev ", + info.device_name); + continue; + } + if (i == info.nb_vec_lines - 1) { /** update the time as current time, write to file */ fprintf(info.fp_wr, "%s%s\n", "# Generated on ", diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h index 3e291bc365..b604db9ec2 100644 --- a/examples/fips_validation/fips_validation.h +++ b/examples/fips_validation/fips_validation.h @@ -14,6 +14,7 @@ #define MAX_NB_TESTS 10240 #define MAX_BUF_SIZE 2048 #define MAX_STRING_SIZE 64 +#define MAX_DIGEST_SIZE 64 #define POSITIVE_TEST 0 #define NEGATIVE_TEST -1 @@ -29,6 +30,7 @@ enum fips_test_algorithms { FIPS_TEST_ALGO_AES_CCM, FIPS_TEST_ALGO_HMAC, FIPS_TEST_ALGO_TDES, + FIPS_TEST_ALGO_SHA, FIPS_TEST_ALGO_MAX }; @@ -111,6 +113,11 @@ enum fips_ccm_test_types { CCM_DVPT, /* Decryption-Verification Process Test */ }; +enum fips_sha_test_types { + SHA_KAT = 0, + SHA_MCT +}; + struct aesavs_interim_data { enum fips_aesavs_test_types test_type; uint32_t cipher_algo; @@ -135,6 +142,11 @@ struct ccm_interim_data { uint32_t iv_len; }; +struct sha_interim_data { + enum fips_sha_test_types test_type; + enum rte_crypto_auth_algorithm algo; +}; + struct fips_test_interim_info { FILE *fp_rd; FILE *fp_wr; @@ -150,7 +162,7 @@ struct fips_test_interim_info { struct hmac_interim_data hmac_data; struct tdes_interim_data tdes_data; struct ccm_interim_data ccm_data; - + struct sha_interim_data sha_data; } interim_info; enum fips_test_op op; @@ -200,6 +212,9 @@ parse_test_cmac_init(void); int parse_test_ccm_init(void); +int +parse_test_sha_init(void); + int parser_read_uint8_hex(uint8_t *value, const char *p); diff --git a/examples/fips_validation/fips_validation_sha.c b/examples/fips_validation/fips_validation_sha.c new file mode 100644 index 0000000000..2cca9cecc5 --- /dev/null +++ b/examples/fips_validation/fips_validation_sha.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Intel Corporation + */ + +#include +#include +#include + +#include + +#include "fips_validation.h" + +#define ALGO_PREFIX "[L = " +#define MSGLEN_STR "Len = " +#define MSG_STR "Msg = " +#define MD_STR "MD = " +#define SEED_STR "Seed = " +#define MCT_STR "Monte" + +struct plain_hash_size_conversion { + const char *str; + enum rte_crypto_auth_algorithm algo; +} phsc[] = { + {"20", RTE_CRYPTO_AUTH_SHA1}, + {"28", RTE_CRYPTO_AUTH_SHA224}, + {"32", RTE_CRYPTO_AUTH_SHA256}, + {"48", RTE_CRYPTO_AUTH_SHA384}, + {"64", RTE_CRYPTO_AUTH_SHA512}, +}; + +static int +parse_interim_algo(__attribute__((__unused__)) const char *key, + char *text, + __attribute__((__unused__)) struct fips_val *val) +{ + uint32_t i; + + for (i = 0; i < RTE_DIM(phsc); i++) { + if (strstr(text, phsc[i].str)) { + info.interim_info.sha_data.algo = phsc[i].algo; + parser_read_uint32_val(ALGO_PREFIX, + text, &vec.cipher_auth.digest); + break; + } + } + + if (i == RTE_DIM(phsc)) + return -1; + + return 0; +} + +struct fips_test_callback sha_tests_vectors[] = { + {MSGLEN_STR, parser_read_uint32_bit_val, &vec.pt}, + {MSG_STR, parse_uint8_known_len_hex_str, &vec.pt}, + {SEED_STR, parse_uint8_hex_str, &vec.cipher_auth.digest}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback sha_tests_interim_vectors[] = { + {ALGO_PREFIX, parse_interim_algo, NULL}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +static int +parse_test_sha_writeback(struct fips_val *val) // ! +{ + struct fips_val val_local; + + fprintf(info.fp_wr, "%s", MD_STR); + + val_local.val = val->val + vec.pt.len; + val_local.len = vec.cipher_auth.digest.len; + + parse_write_hex_str(&val_local); + return 0; +} + +static int +rsp_test_sha_check(struct fips_val *val) +{ + if (memcmp(val->val + vec.pt.len, vec.cipher_auth.digest.val, + vec.cipher_auth.digest.len) == 0) + fprintf(info.fp_wr, "Success\n"); + else + fprintf(info.fp_wr, "Failed\n"); + + return 0; +} + +int +parse_test_sha_init(void) +{ + uint32_t i; + + info.interim_info.sha_data.test_type = SHA_KAT; + for (i = 0; i < info.nb_vec_lines; i++) { + char *line = info.vec[i]; + if (strstr(line, MCT_STR)) + info.interim_info.sha_data.test_type = SHA_MCT; + } + + info.op = FIPS_TEST_ENC_AUTH_GEN; + info.parse_writeback = parse_test_sha_writeback; + info.callbacks = sha_tests_vectors; + info.interim_callbacks = sha_tests_interim_vectors; + info.writeback_callbacks = NULL; + info.kat_check = rsp_test_sha_check; + return 0; +} diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c index 32d06dd14d..5e3d5baa8f 100644 --- a/examples/fips_validation/main.c +++ b/examples/fips_validation/main.c @@ -887,6 +887,41 @@ prepare_ccm_xform(struct rte_crypto_sym_xform *xform) return 0; } +static int +prepare_sha_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_auth_xform *auth_xform = &xform->auth; + + xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + + auth_xform->algo = info.interim_info.sha_data.algo; + auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform->digest_length = vec.cipher_auth.digest.len; + + cap_idx.algo.auth = auth_xform->algo; + cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; + + 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_auth(cap, + auth_xform->key.length, + auth_xform->digest_length, 0) != 0) { + RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", + info.device_name, auth_xform->key.length, + auth_xform->digest_length); + return -EPERM; + } + + return 0; +} + static void get_writeback_data(struct fips_val *val) { @@ -1217,6 +1252,90 @@ fips_mct_aes_test(void) return 0; } +static int +fips_mct_sha_test(void) +{ +#define SHA_EXTERN_ITER 100 +#define SHA_INTERN_ITER 1000 +#define SHA_MD_BLOCK 3 + struct fips_val val, md[SHA_MD_BLOCK]; + char temp[MAX_DIGEST_SIZE*2]; + int ret; + uint32_t i, j; + + val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); + for (i = 0; i < SHA_MD_BLOCK; i++) + md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); + + rte_free(vec.pt.val); + vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); + + fips_test_write_one_case(); + fprintf(info.fp_wr, "\n"); + + for (j = 0; j < SHA_EXTERN_ITER; j++) { + + memcpy(md[0].val, vec.cipher_auth.digest.val, + vec.cipher_auth.digest.len); + md[0].len = vec.cipher_auth.digest.len; + memcpy(md[1].val, vec.cipher_auth.digest.val, + vec.cipher_auth.digest.len); + md[1].len = vec.cipher_auth.digest.len; + memcpy(md[2].val, vec.cipher_auth.digest.val, + vec.cipher_auth.digest.len); + md[2].len = vec.cipher_auth.digest.len; + + for (i = 0; i < (SHA_INTERN_ITER); i++) { + + memcpy(vec.pt.val, md[0].val, + (size_t)md[0].len); + memcpy((vec.pt.val + md[0].len), md[1].val, + (size_t)md[1].len); + memcpy((vec.pt.val + md[0].len + md[1].len), + md[2].val, + (size_t)md[2].len); + vec.pt.len = md[0].len + md[1].len + md[2].len; + + ret = fips_run_test(); + if (ret < 0) { + if (ret == -EPERM) { + fprintf(info.fp_wr, "Bypass\n\n"); + return 0; + } + return ret; + } + + get_writeback_data(&val); + + memcpy(md[0].val, md[1].val, md[1].len); + md[0].len = md[1].len; + memcpy(md[1].val, md[2].val, md[2].len); + md[1].len = md[2].len; + + memcpy(md[2].val, (val.val + vec.pt.len), + vec.cipher_auth.digest.len); + md[2].len = vec.cipher_auth.digest.len; + } + + memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); + vec.cipher_auth.digest.len = md[2].len; + + fprintf(info.fp_wr, "COUNT = %u\n", j); + + writeback_hex_str("", temp, &vec.cipher_auth.digest); + + fprintf(info.fp_wr, "MD = %s\n\n", temp); + } + + for (i = 0; i < (SHA_MD_BLOCK); i++) + rte_free(md[i].val); + + rte_free(vec.pt.val); + + return 0; +} + + static int init_test_ops(void) { @@ -1257,6 +1376,14 @@ init_test_ops(void) test_ops.prepare_xform = prepare_ccm_xform; test_ops.test = fips_generic_test; break; + case FIPS_TEST_ALGO_SHA: + test_ops.prepare_op = prepare_auth_op; + test_ops.prepare_xform = prepare_sha_xform; + if (info.interim_info.sha_data.test_type == SHA_MCT) + test_ops.test = fips_mct_sha_test; + else + 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 20f33f4954..6dd63082ca 100644 --- a/examples/fips_validation/meson.build +++ b/examples/fips_validation/meson.build @@ -16,6 +16,7 @@ sources = files( 'fips_validation_gcm.c', 'fips_validation_cmac.c', 'fips_validation_ccm.c', + 'fips_validation_sha.c', 'fips_dev_self_test.c', 'main.c' )