> -----Original Message----- > From: Gowrishankar Muthukrishnan <gmuthukri...@marvell.com> > Sent: Tuesday, September 27, 2022 8:31 AM > To: dev@dpdk.org > Cc: Anoob Joseph <ano...@marvell.com>; Zhang, Roy Fan > <roy.fan.zh...@intel.com>; Dooley, Brian <brian.doo...@intel.com>; Akhil > Goyal <gak...@marvell.com>; jer...@marvell.com; Gowrishankar > Muthukrishnan <gmuthukri...@marvell.com> > Subject: [v1 2/2] examples/fips_validation: add ECDSA validation > > This patch adds support in fips_validation app to validate ECDSA. > > Signed-off-by: Gowrishankar Muthukrishnan <gmuthukri...@marvell.com> > --- > doc/guides/sample_app_ug/fips_validation.rst | 1 + > examples/fips_validation/fips_validation.c | 2 + > examples/fips_validation/fips_validation.h | 27 ++ > .../fips_validation/fips_validation_ecdsa.c | 431 ++++++++++++++++++ > examples/fips_validation/main.c | 210 ++++++++- > examples/fips_validation/meson.build | 1 + > 6 files changed, 669 insertions(+), 3 deletions(-) create mode 100644 > examples/fips_validation/fips_validation_ecdsa.c > > diff --git a/doc/guides/sample_app_ug/fips_validation.rst > b/doc/guides/sample_app_ug/fips_validation.rst > index 5e9ad2d006..3a2357eaa9 100644 > --- a/doc/guides/sample_app_ug/fips_validation.rst > +++ b/doc/guides/sample_app_ug/fips_validation.rst > @@ -67,6 +67,7 @@ ACVP > * TDES-CBC - AFT, MCT > * TDES-ECB - AFT, MCT > * RSA > + * ECDSA > > > Application Information > diff --git a/examples/fips_validation/fips_validation.c > b/examples/fips_validation/fips_validation.c > index 5d485a2bd5..55f68a7ae0 100644 > --- a/examples/fips_validation/fips_validation.c > +++ b/examples/fips_validation/fips_validation.c > @@ -473,6 +473,8 @@ fips_test_parse_one_json_vector_set(void) > info.algo = FIPS_TEST_ALGO_TDES; > else if (strstr(algo_str, "RSA")) > info.algo = FIPS_TEST_ALGO_RSA; > + else if (strstr(algo_str, "ECDSA")) > + info.algo = FIPS_TEST_ALGO_ECDSA; > else > return -EINVAL; > > diff --git a/examples/fips_validation/fips_validation.h > b/examples/fips_validation/fips_validation.h > index 7cbbc1f084..f9dfbecd5d 100644 > --- a/examples/fips_validation/fips_validation.h > +++ b/examples/fips_validation/fips_validation.h > @@ -43,6 +43,7 @@ enum fips_test_algorithms { > FIPS_TEST_ALGO_TDES, > FIPS_TEST_ALGO_SHA, > FIPS_TEST_ALGO_RSA, > + FIPS_TEST_ALGO_ECDSA, > FIPS_TEST_ALGO_MAX > }; > > @@ -94,6 +95,15 @@ struct fips_test_vector { > struct fips_val dq; > struct fips_val qinv; > } rsa; > + struct { > + struct fips_val seed; > + struct fips_val pkey; > + struct fips_val qx; > + struct fips_val qy; > + struct fips_val r; > + struct fips_val s; > + struct fips_val k; > + } ecdsa; > > struct fips_val pt; > struct fips_val ct; > @@ -159,6 +169,10 @@ enum fips_rsa_test_types { > RSA_KAT > }; > > +enum fips_ecdsa_test_types { > + ECDSA_AFT = 0, > +}; > + > struct aesavs_interim_data { > enum fips_aesavs_test_types test_type; > uint32_t cipher_algo; > @@ -213,6 +227,14 @@ struct rsa_interim_data { > uint8_t random_msg; > }; > > +struct ecdsa_interim_data { > + enum rte_crypto_auth_algorithm auth; > + enum rte_crypto_curve_id curve_id; > + u_int8_t curve_len; > + uint8_t random_msg; > + uint8_t pubkey_gen; > +}; > + > #ifdef USE_JANSSON > /* > * Maximum length of buffer to hold any json string. > @@ -259,6 +281,7 @@ struct fips_test_interim_info { > struct gcm_interim_data gcm_data; > struct xts_interim_data xts_data; > struct rsa_interim_data rsa_data; > + struct ecdsa_interim_data ecdsa_data; > } interim_info; > > enum fips_test_op op; > @@ -268,6 +291,7 @@ struct fips_test_interim_info { > const struct fips_test_callback *writeback_callbacks; > > post_prcess_t parse_interim_writeback; > + post_prcess_t post_interim_writeback; > post_prcess_t parse_writeback; > post_prcess_t kat_check; > }; > @@ -338,6 +362,9 @@ parse_test_tdes_json_init(void); int > parse_test_rsa_json_init(void); > > +int > +parse_test_ecdsa_json_init(void); > + > int > fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand); > #endif /* USE_JANSSON */ diff --git > a/examples/fips_validation/fips_validation_ecdsa.c > b/examples/fips_validation/fips_validation_ecdsa.c > new file mode 100644 > index 0000000000..2bac348052 > --- /dev/null > +++ b/examples/fips_validation/fips_validation_ecdsa.c > @@ -0,0 +1,431 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2022 Marvell. > + */ > + > +#include <string.h> > +#include <time.h> > +#include <stdio.h> > +#include <sys/random.h> > +#include <sys/types.h> > +#include <unistd.h> > + > +#ifdef USE_OPENSSL > +#include <openssl/bn.h> > +#include <openssl/rand.h> > +#endif /* USE_OPENSSL */ > + > +#include <rte_cryptodev.h> > +#include <rte_malloc.h> > + > +#include "fips_validation.h" > + > +#define CONFORMANCE_JSON_STR "conformance" > +#define TESTTYPE_JSON_STR "testType" > +#define CURVE_JSON_STR "curve" > +#define HASH_JSON_STR "hashAlg" > +#define RV_JSON_STR "randomValue" > + > +#define MSG_JSON_STR "message" > +#define QX_JSON_STR "qx" > +#define QY_JSON_STR "qy" > +#define R_JSON_STR "r" > +#define S_JSON_STR "s" > + > +#define RV_BUF_LEN (1024/8) > +#define RV_BIT_LEN (256) > + > +#ifdef USE_JANSSON > +struct { > + uint8_t type; > + const char *desc; > +} ecdsa_test_types[] = { > + {ECDSA_AFT, "AFT"} > +}; > + > +struct { > + enum rte_crypto_auth_algorithm auth; > + const char *desc; > +} ecdsa_auth_algs[] = { > + {RTE_CRYPTO_AUTH_SHA1, "SHA-1"}, > + {RTE_CRYPTO_AUTH_SHA224, "SHA2-224"}, > + {RTE_CRYPTO_AUTH_SHA256, "SHA2-256"}, > + {RTE_CRYPTO_AUTH_SHA384, "SHA2-384"}, > + {RTE_CRYPTO_AUTH_SHA512, "SHA2-512"}, }; > + > +struct { > + enum rte_crypto_curve_id curve_id; > + const char *desc; > +} ecdsa_curve_ids[] = { > + {RTE_CRYPTO_EC_GROUP_SECP192R1, "P-192"}, > + {RTE_CRYPTO_EC_GROUP_SECP224R1, "P-224"}, > + {RTE_CRYPTO_EC_GROUP_SECP256R1, "P-256"}, > + {RTE_CRYPTO_EC_GROUP_SECP384R1, "P-384"}, > + {RTE_CRYPTO_EC_GROUP_SECP521R1, "P-521"}, }; > + > +struct { > + uint8_t curve_len; > + const char *desc; > +} ecdsa_curve_len[] = { > + {24, "P-192"}, > + {28, "P-224"}, > + {32, "P-256"}, > + {48, "P-384"}, > + {66, "P-521"}, > +}; > + > +#ifdef USE_OPENSSL > +#define MAX_TRIES 10 > +static int > +prepare_vec_ecdsa(void) > +{ > + BIGNUM *pkey = NULL, *order = NULL, *r = NULL; > + int ret = -1, j; > + unsigned long pid; > + > + /* For ECDSA prime fields, order of base points. > + * Below string array is indexed by starting with first supported > + * curve (SECP-192R1). > + */ > + static const char * const orderstr[] = { > + > "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", > + "", > + > "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", > + "", > + > "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2F > C632551", > + > "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F43 > 72DDF581A0DB248B0A77AECEC196ACCC52973", > + > "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > FFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E > 91386409" > + }; > + > + /* Seed PRNG */ > + if (vec.ecdsa.seed.val) { > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.seed); > + RAND_seed((char *)info.one_line_text, > strlen(info.one_line_text)); > + } else { > + pid = getpid(); > + RAND_seed(&pid, sizeof(pid)); > + } > + > + if (!RAND_status()) > + return -1; > + > + order = BN_new(); > + if (!order) > + goto err; > + > + j = info.interim_info.ecdsa_data.curve_id - > RTE_CRYPTO_EC_GROUP_SECP192R1; > + if (!BN_hex2bn(&order, orderstr[j])) > + goto err; > + > + pkey = BN_new(); > + if (!pkey) > + goto err; > + > + for (j = 0; j < MAX_TRIES; j++) { > + /* pkey should be in [1, order - 1] */ > + if (!BN_rand_range(pkey, order)) > + goto err; > + > + if (!BN_is_zero(pkey)) > + break; > + } > + > + if (j == MAX_TRIES) > + goto err; > + > + parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.ecdsa.pkey); > + > + r = BN_new(); > + if (!r) > + goto err; > + > + if (info.interim_info.ecdsa_data.random_msg) { > + if (!BN_rand(r, RV_BIT_LEN, 0, 0)) > + goto err; > + > + parse_uint8_hex_str("", BN_bn2hex(r), &vec.ecdsa.seed); > + } > + > + ret = 0; > +err: > + BN_free(order); > + BN_free(pkey); > + BN_free(r); > + return ret; > +} > + > +static int > +prepare_vec_ecdsa_k(void) > +{ > + BIGNUM *pkey = NULL, *k = NULL; > + int ret = -1; > + > + if (!vec.ecdsa.pkey.len) > + return -1; > + > + pkey = BN_new(); > + if (!pkey) > + goto err; > + > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.pkey); > + ret = BN_hex2bn(&pkey, info.one_line_text); > + if ((uint32_t)ret != strlen(info.one_line_text)) > + goto err; > + > + k = BN_new(); > + if (!k) > + goto err; > + > + if (!BN_sub(k, pkey, BN_value_one())) > + goto err; > + > + if (BN_is_zero(pkey)) { > + if (!BN_add(k, pkey, BN_value_one())) > + goto err; > + } > + > + parse_uint8_hex_str("", BN_bn2hex(k), &vec.ecdsa.k); > + ret = 0; > +err: > + BN_free(pkey); > + BN_free(k); > + return ret; > +} > + > +#else > +static int > +prepare_vec_ecdsa(void) > +{ > + /* > + * Generate ECDSA values. > + */ > + return -ENOTSUP; > +} > + > +static int > +prepare_vec_ecdsa_k(void) > +{ > + /* > + * Generate ECDSA values. > + */ > + return -ENOTSUP; > +} > +#endif /* USE_OPENSSL */ > + > +static int > +parse_test_ecdsa_json_interim_writeback(struct fips_val *val) { > + RTE_SET_USED(val); > + > + if (info.interim_info.ecdsa_data.random_msg) { > + json_object_set_new(json_info.json_write_group, > "conformance", > + json_string("SP800- > 106")); > + } > + > + if (info.op == FIPS_TEST_ASYM_SIGGEN) { > + /* For siggen tests, ECDSA values can be created soon after > + * the test group data are parsed. > + */ > + if (vec.ecdsa.pkey.val) { > + rte_free(vec.ecdsa.pkey.val); > + vec.ecdsa.pkey.val = NULL; > + } > + > + if (prepare_vec_ecdsa() < 0) > + return -1; > + > + info.interim_info.ecdsa_data.pubkey_gen = 1; > + } > + > + return 0; > +} > + > +static int > +post_test_ecdsa_json_interim_writeback(struct fips_val *val) { > + RTE_SET_USED(val); > + > + if (info.op == FIPS_TEST_ASYM_KEYGEN) { > + json_t *obj; > + > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.qx); > + obj = json_string(info.one_line_text); > + json_object_set_new(json_info.json_write_group, "qx", > obj); > + > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.qy); > + obj = json_string(info.one_line_text); > + json_object_set_new(json_info.json_write_group, "qy", > obj); > + } > + > + return 0; > +} > + > +static int > +parse_test_ecdsa_json_writeback(struct fips_val *val) { > + json_t *tcId; > + > + RTE_SET_USED(val); > + > + tcId = json_object_get(json_info.json_test_case, "tcId"); > + > + json_info.json_write_case = json_object(); > + json_object_set(json_info.json_write_case, "tcId", tcId); > + > + if (info.op == FIPS_TEST_ASYM_SIGGEN) { > + json_t *obj; > + > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.r); > + obj = json_string(info.one_line_text); > + json_object_set_new(json_info.json_write_case, "r", obj); > + > + writeback_hex_str("", info.one_line_text, &vec.ecdsa.s); > + obj = json_string(info.one_line_text); > + json_object_set_new(json_info.json_write_case, "s", obj); > + > + if (info.interim_info.ecdsa_data.random_msg) { > + writeback_hex_str("", info.one_line_text, > &vec.ecdsa.seed); > + obj = json_string(info.one_line_text); > + json_object_set_new(json_info.json_write_case, > "randomValue", obj); > + json_object_set_new(json_info.json_write_case, > "randomValueLen", > + json_integer(vec.ecdsa.seed.len * 8)); > + } > + } else if (info.op == FIPS_TEST_ASYM_SIGVER) { > + if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) > + json_object_set_new(json_info.json_write_case, > "testPassed", json_true()); > + else > + json_object_set_new(json_info.json_write_case, > "testPassed", json_false()); > + } > + > + return 0; > +} > + > +static int > +parse_interim_str(const char *key, char *src, struct fips_val *val) { > + uint32_t i; > + > + RTE_SET_USED(val); > + > + if (strcmp(key, TESTTYPE_JSON_STR) == 0) { > + for (i = 0; i < RTE_DIM(ecdsa_test_types); i++) > + if (strstr(src, ecdsa_test_types[i].desc)) { > + info.parse_writeback = > parse_test_ecdsa_json_writeback; > + break; > + } > + > + if (!info.parse_writeback || i >= > RTE_DIM(ecdsa_test_types)) > + return -EINVAL; > + > + } else if (strcmp(key, CURVE_JSON_STR) == 0) { > + for (i = 0; i < RTE_DIM(ecdsa_curve_ids); i++) > + if (strstr(src, ecdsa_curve_ids[i].desc)) { > + info.interim_info.ecdsa_data.curve_id = > ecdsa_curve_ids[i].curve_id; > + info.interim_info.ecdsa_data.curve_len = > + ecdsa_curve_len[i].curve_len; > + break; > + } > + > + if (i >= RTE_DIM(ecdsa_curve_ids)) > + return -EINVAL; > + } else if (strcmp(key, HASH_JSON_STR) == 0) { > + for (i = 0; i < RTE_DIM(ecdsa_auth_algs); i++) > + if (strstr(src, ecdsa_auth_algs[i].desc)) { > + info.interim_info.ecdsa_data.auth = > ecdsa_auth_algs[i].auth; > + break; > + } > + > + if (i >= RTE_DIM(ecdsa_auth_algs)) > + return -EINVAL; > + } else if (strcmp(key, CONFORMANCE_JSON_STR) == 0) { > + info.interim_info.ecdsa_data.random_msg = 1; > + } else { > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +parse_siggen_message_str(const char *key, char *src, struct fips_val > +*val) { > + int ret = 0; > + > + parse_uint8_hex_str(key, src, val); > + if (info.interim_info.ecdsa_data.random_msg) { > + ret = fips_test_randomize_message(val, &vec.ecdsa.seed); > + if (ret < 0) > + return ret; > + } > + > + if (vec.ecdsa.k.val) { > + rte_free(vec.ecdsa.k.val); > + vec.ecdsa.k.val = NULL; > + } > + > + ret = prepare_vec_ecdsa_k(); > + return ret; > +} > + > +static int > +parse_sigver_randomvalue_str(const char *key, char *src, struct > +fips_val *val) { > + int ret = 0; > + > + parse_uint8_hex_str(key, src, val); > + if (info.interim_info.ecdsa_data.random_msg) > + ret = fips_test_randomize_message(&vec.pt, val); > + > + return ret; > +} > + > +struct fips_test_callback ecdsa_interim_json_vectors[] = { > + {TESTTYPE_JSON_STR, parse_interim_str, NULL}, > + {CURVE_JSON_STR, parse_interim_str, NULL}, > + {HASH_JSON_STR, parse_interim_str, NULL}, > + {CONFORMANCE_JSON_STR, parse_interim_str, NULL}, > + {NULL, NULL, NULL} /**< end pointer */ }; > + > +struct fips_test_callback ecdsa_siggen_json_vectors[] = { > + {MSG_JSON_STR, parse_siggen_message_str, &vec.pt}, > + {NULL, NULL, NULL} /**< end pointer */ }; > + > +struct fips_test_callback ecdsa_sigver_json_vectors[] = { > + {MSG_JSON_STR, parse_uint8_hex_str, &vec.pt}, > + {QX_JSON_STR, parse_uint8_hex_str, &vec.ecdsa.qx}, > + {QY_JSON_STR, parse_uint8_hex_str, &vec.ecdsa.qy}, > + {R_JSON_STR, parse_uint8_hex_str, &vec.ecdsa.r}, > + {S_JSON_STR, parse_uint8_hex_str, &vec.ecdsa.s}, > + {RV_JSON_STR, parse_sigver_randomvalue_str, > &vec.ecdsa.seed}, > + {NULL, NULL, NULL} /**< end pointer */ }; > + > +int > +parse_test_ecdsa_json_init(void) > +{ > + json_t *mode_obj = json_object_get(json_info.json_vector_set, > "mode"); > + const char *mode_str = json_string_value(mode_obj); > + > + info.callbacks = NULL; > + info.parse_writeback = NULL; > + info.interim_info.ecdsa_data.random_msg = 0; > + > + info.interim_callbacks = ecdsa_interim_json_vectors; > + info.post_interim_writeback = > post_test_ecdsa_json_interim_writeback; > + info.parse_interim_writeback = > parse_test_ecdsa_json_interim_writeback; > + if (strcmp(mode_str, "sigGen") == 0) { > + info.op = FIPS_TEST_ASYM_SIGGEN; > + info.callbacks = ecdsa_siggen_json_vectors; > + } else if (strcmp(mode_str, "sigVer") == 0) { > + info.op = FIPS_TEST_ASYM_SIGVER; > + info.callbacks = ecdsa_sigver_json_vectors; > + } else { > + return -EINVAL; > + } > + > + return 0; > +} > +#endif /* USE_JANSSON */ > diff --git a/examples/fips_validation/main.c > b/examples/fips_validation/main.c index cfa01eae20..b4cb10a106 100644 > --- a/examples/fips_validation/main.c > +++ b/examples/fips_validation/main.c > @@ -977,6 +977,103 @@ prepare_rsa_op(void) > return 0; > } > > +static int > +prepare_ecdsa_op(void) > +{ > + struct rte_crypto_asym_op *asym; > + struct fips_val msg; > + > + __rte_crypto_op_reset(env.op, > RTE_CRYPTO_OP_TYPE_ASYMMETRIC); > + > + asym = env.op->asym; > + if (env.digest) { > + msg.val = env.digest; > + msg.len = env.digest_len; > + } else { > + msg.val = vec.pt.val; > + msg.len = vec.pt.len; > + } > + > + if (info.op == FIPS_TEST_ASYM_SIGGEN) { > + asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; > + asym->ecdsa.message.data = msg.val; > + asym->ecdsa.message.length = msg.len; > + asym->ecdsa.pkey.data = vec.ecdsa.pkey.val; > + asym->ecdsa.pkey.length = vec.ecdsa.pkey.len; > + asym->ecdsa.k.data = vec.ecdsa.k.val; > + asym->ecdsa.k.length = vec.ecdsa.k.len; > + > + if (vec.ecdsa.r.val) > + rte_free(vec.ecdsa.r.val); > + > + if (vec.ecdsa.s.val) > + rte_free(vec.ecdsa.s.val); > + > + vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len; > + vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0); > + > + vec.ecdsa.s.len = vec.ecdsa.r.len; > + vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0); > + > + asym->ecdsa.r.data = vec.ecdsa.r.val; > + asym->ecdsa.r.length = 0; > + asym->ecdsa.s.data = vec.ecdsa.s.val; > + asym->ecdsa.s.length = 0; > + } else if (info.op == FIPS_TEST_ASYM_SIGVER) { > + asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; > + asym->ecdsa.message.data = msg.val; > + asym->ecdsa.message.length = msg.len; > + asym->ecdsa.q.x.data = vec.ecdsa.qx.val; > + asym->ecdsa.q.x.length = vec.ecdsa.qx.len; > + asym->ecdsa.q.y.data = vec.ecdsa.qy.val; > + asym->ecdsa.q.y.length = vec.ecdsa.qy.len; > + asym->ecdsa.r.data = vec.ecdsa.r.val; > + asym->ecdsa.r.length = vec.ecdsa.r.len; > + asym->ecdsa.s.data = vec.ecdsa.s.val; > + asym->ecdsa.s.length = vec.ecdsa.s.len; > + } else { > + RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); > + return -EINVAL; > + } > + > + rte_crypto_op_attach_asym_session(env.op, env.asym.sess); > + > + return 0; > +} > + > +static int > +prepare_ecfpm_op(void) > +{ > + struct rte_crypto_asym_op *asym; > + > + __rte_crypto_op_reset(env.op, > RTE_CRYPTO_OP_TYPE_ASYMMETRIC); > + > + asym = env.op->asym; > + asym->ecpm.scalar.data = vec.ecdsa.pkey.val; > + asym->ecpm.scalar.length = vec.ecdsa.pkey.len; > + > + if (vec.ecdsa.qx.val) > + rte_free(vec.ecdsa.qx.val); > + > + if (vec.ecdsa.qy.val) > + rte_free(vec.ecdsa.qy.val); > + > + vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len; > + vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0); > + > + vec.ecdsa.qy.len = vec.ecdsa.qx.len; > + vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0); > + > + asym->ecpm.r.x.data = vec.ecdsa.qx.val; > + asym->ecpm.r.x.length = 0; > + asym->ecpm.r.y.data = vec.ecdsa.qy.val; > + asym->ecpm.r.y.length = 0; > + > + rte_crypto_op_attach_asym_session(env.op, env.asym.sess); > + > + return 0; > +} > + > static int > prepare_aes_xform(struct rte_crypto_sym_xform *xform) { @@ -1441,6 > +1538,69 @@ prepare_rsa_xform(struct rte_crypto_asym_xform *xform) > return 0; > } > > +static int > +prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform) { > + const struct rte_cryptodev_asymmetric_xform_capability *cap; > + struct rte_cryptodev_asym_capability_idx cap_idx; > + > + xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA; > + xform->next = NULL; > + > + cap_idx.type = xform->xform_type; > + cap = rte_cryptodev_asym_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; > + } > + > + switch (info.op) { > + case FIPS_TEST_ASYM_SIGGEN: > + if > (!rte_cryptodev_asym_xform_capability_check_optype(cap, > + RTE_CRYPTO_ASYM_OP_SIGN)) { > + RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", > + info.device_name, > RTE_CRYPTO_ASYM_OP_SIGN); > + return -EPERM; > + } > + break; > + case FIPS_TEST_ASYM_SIGVER: > + if > (!rte_cryptodev_asym_xform_capability_check_optype(cap, > + RTE_CRYPTO_ASYM_OP_VERIFY)) { > + RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", > + info.device_name, > RTE_CRYPTO_ASYM_OP_VERIFY); > + return -EPERM; > + } > + break; > + default: > + break; > + } > + > + xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; > + return 0; > +} > + > +static int > +prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform) { > + const struct rte_cryptodev_asymmetric_xform_capability *cap; > + struct rte_cryptodev_asym_capability_idx cap_idx; > + > + xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM; > + xform->next = NULL; > + > + cap_idx.type = xform->xform_type; > + cap = rte_cryptodev_asym_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; > + } > + > + xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; > + return 0; > +} > + > static int > get_writeback_data(struct fips_val *val) { @@ -1546,7 +1706,7 @@ > fips_run_asym_test(void) > struct rte_crypto_op *deqd_op; > int ret; > > - if (info.op == FIPS_TEST_ASYM_KEYGEN) { > + if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != > +FIPS_TEST_ALGO_ECDSA) { > RTE_SET_USED(asym); > ret = 0; > goto exit; > @@ -1606,7 +1766,33 @@ fips_run_test(void) > } > > env.op = env.asym.op; > - return fips_run_asym_test(); > + if (info.op == FIPS_TEST_ASYM_SIGGEN && > + info.algo == FIPS_TEST_ALGO_ECDSA && > + info.interim_info.ecdsa_data.pubkey_gen == 1) { > + fips_prepare_asym_xform_t ecdsa_xform; > + fips_prepare_op_t ecdsa_op; > + > + ecdsa_xform = test_ops.prepare_asym_xform; > + ecdsa_op = test_ops.prepare_asym_op; > + info.op = FIPS_TEST_ASYM_KEYGEN; > + test_ops.prepare_asym_xform = prepare_ecfpm_xform; > + test_ops.prepare_asym_op = prepare_ecfpm_op; > + ret = fips_run_asym_test(); > + if (ret < 0) > + return ret; > + > + info.post_interim_writeback(NULL); > + info.interim_info.ecdsa_data.pubkey_gen = 0; > + > + test_ops.prepare_asym_xform = ecdsa_xform; > + test_ops.prepare_asym_op = ecdsa_op; > + info.op = FIPS_TEST_ASYM_SIGGEN; > + ret = fips_run_asym_test(); > + } else { > + ret = fips_run_asym_test(); > + } > + > + return ret; > } > > static int > @@ -2235,6 +2421,17 @@ init_test_ops(void) > test_ops.prepare_asym_xform = prepare_rsa_xform; > test_ops.test = fips_generic_test; > break; > + case FIPS_TEST_ALGO_ECDSA: > + if (info.op == FIPS_TEST_ASYM_KEYGEN) { > + test_ops.prepare_asym_op = prepare_ecfpm_op; > + test_ops.prepare_asym_xform = > prepare_ecfpm_xform; > + test_ops.test = fips_generic_test; > + } else { > + test_ops.prepare_asym_op = prepare_ecdsa_op; > + test_ops.prepare_asym_xform = > prepare_ecdsa_xform; > + test_ops.test = fips_generic_test; > + } > + break; > default: > if (strstr(info.file_name, "TECB") || > strstr(info.file_name, "TCBC")) { > @@ -2409,6 +2606,9 @@ fips_test_one_test_group(void) > case FIPS_TEST_ALGO_RSA: > ret = parse_test_rsa_json_init(); > break; > + case FIPS_TEST_ALGO_ECDSA: > + ret = parse_test_ecdsa_json_init(); > + break; > default: > return -EINVAL; > } > @@ -2439,7 +2639,7 @@ static int > fips_test_one_vector_set(void) > { > int ret; > - json_t *test_groups, *write_groups, *write_version, *write_set; > + json_t *test_groups, *write_groups, *write_version, *write_set, > *mode; > size_t group_idx, num_groups; > > test_groups = json_object_get(json_info.json_vector_set, > "testGroups"); @@ -2458,6 +2658,10 @@ fips_test_one_vector_set(void) > json_object_get(json_info.json_vector_set, "vsId")); > json_object_set(write_set, "algorithm", > json_object_get(json_info.json_vector_set, "algorithm")); > + mode = json_object_get(json_info.json_vector_set, "mode"); > + if (mode != NULL) > + json_object_set_new(write_set, "mode", mode); > + > json_object_set(write_set, "revision", > json_object_get(json_info.json_vector_set, "revision")); > json_object_set_new(write_set, "isSample", diff --git > a/examples/fips_validation/meson.build > b/examples/fips_validation/meson.build > index d310093189..34d3c7c8ca 100644 > --- a/examples/fips_validation/meson.build > +++ b/examples/fips_validation/meson.build > @@ -19,6 +19,7 @@ sources = files( > 'fips_validation_sha.c', > 'fips_validation_xts.c', > 'fips_validation_rsa.c', > + 'fips_validation_ecdsa.c', > 'fips_dev_self_test.c', > 'main.c', > ) > -- > 2.25.1
Acked-by: Brian Dooley <brian.doo...@intel.com>