examples/fips_validation: support plain SHA
authorDamian Nowak <damianx.nowak@intel.com>
Tue, 19 Mar 2019 09:43:48 +0000 (10:43 +0100)
committerAkhil Goyal <akhil.goyal@nxp.com>
Fri, 22 Mar 2019 14:54:24 +0000 (15:54 +0100)
This patch enables plain SHA algorithm CAVP test support
in fips_validation sample application.

Signed-off-by: Damian Nowak <damianx.nowak@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
examples/fips_validation/Makefile
examples/fips_validation/fips_validation.c
examples/fips_validation/fips_validation.h
examples/fips_validation/fips_validation_sha.c [new file with mode: 0644]
examples/fips_validation/main.c
examples/fips_validation/meson.build

index 923d0be..2120cd9 100644 (file)
@@ -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
 
index a835cc3..2f8314f 100644 (file)
@@ -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 ",
index 3e291bc..b604db9 100644 (file)
@@ -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 (file)
index 0000000..2cca9ce
--- /dev/null
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#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;
+}
index 32d06dd..5e3d5ba 100644 (file)
@@ -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;
        }
index 20f33f4..6dd6308 100644 (file)
@@ -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'
 )