* [v1 0/2] examples/fips_validation: add ECDSA tests @ 2022-09-27 7:30 Gowrishankar Muthukrishnan 2022-09-27 7:30 ` [v1 1/2] cryptodev: add enumeration in EC xform for FPM Gowrishankar Muthukrishnan 2022-09-27 7:30 ` [v1 2/2] examples/fips_validation: add ECDSA validation Gowrishankar Muthukrishnan 0 siblings, 2 replies; 8+ messages in thread From: Gowrishankar Muthukrishnan @ 2022-09-27 7:30 UTC (permalink / raw) To: dev Cc: Anoob Joseph, Fan Zhang, Brian Dooley, Akhil Goyal, jerinj, Gowrishankar Muthukrishnan This series adds ECDSA validation in fips_validation app. Depends-on: series-24851 ("FIPS asymmetric validation") Gowrishankar Muthukrishnan (2): cryptodev: add enumeration in EC xform for FPM examples/fips_validation: add ECDSA validation 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 + lib/cryptodev/rte_crypto_asym.h | 3 + 7 files changed, 672 insertions(+), 3 deletions(-) create mode 100644 examples/fips_validation/fips_validation_ecdsa.c -- 2.25.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [v1 1/2] cryptodev: add enumeration in EC xform for FPM 2022-09-27 7:30 [v1 0/2] examples/fips_validation: add ECDSA tests Gowrishankar Muthukrishnan @ 2022-09-27 7:30 ` Gowrishankar Muthukrishnan 2022-09-28 21:35 ` Ji, Kai 2022-09-27 7:30 ` [v1 2/2] examples/fips_validation: add ECDSA validation Gowrishankar Muthukrishnan 1 sibling, 1 reply; 8+ messages in thread From: Gowrishankar Muthukrishnan @ 2022-09-27 7:30 UTC (permalink / raw) To: dev Cc: Anoob Joseph, Fan Zhang, Brian Dooley, Akhil Goyal, jerinj, Gowrishankar Muthukrishnan, Kiran Kumar K Add enumeration in EC xform for FPM. Crypto driver would need this to xform point multiplication based on given type of EC curve. Signed-off-by: Kiran Kumar K <kirankumark@marvell.com> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> --- lib/cryptodev/rte_crypto_asym.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h index 8ae43d5f3d..da13a5e0c1 100644 --- a/lib/cryptodev/rte_crypto_asym.h +++ b/lib/cryptodev/rte_crypto_asym.h @@ -116,6 +116,9 @@ enum rte_crypto_asym_xform_type { /**< Elliptic Curve Diffie Hellman */ RTE_CRYPTO_ASYM_XFORM_ECPM, /**< Elliptic Curve Point Multiplication */ + + RTE_CRYPTO_ASYM_XFORM_ECFPM, + /**< Elliptic Curve Fixed Point Multiplication */ RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END /**< End of list */ }; -- 2.25.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [v1 1/2] cryptodev: add enumeration in EC xform for FPM 2022-09-27 7:30 ` [v1 1/2] cryptodev: add enumeration in EC xform for FPM Gowrishankar Muthukrishnan @ 2022-09-28 21:35 ` Ji, Kai 2022-09-30 18:08 ` Akhil Goyal 0 siblings, 1 reply; 8+ messages in thread From: Ji, Kai @ 2022-09-28 21:35 UTC (permalink / raw) To: Gowrishankar Muthukrishnan, dev Cc: Anoob Joseph, Zhang, Roy Fan, Dooley, Brian, Akhil Goyal, jerinj, Kiran Kumar K Acked-by: Kai Ji <kai.ji@intel.com> > -----Original Message----- > From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> > Sent: Tuesday, September 27, 2022 8:31 AM > To: dev@dpdk.org > Cc: Anoob Joseph <anoobj@marvell.com>; Zhang, Roy Fan > <roy.fan.zhang@intel.com>; Dooley, Brian <brian.dooley@intel.com>; Akhil > Goyal <gakhil@marvell.com>; jerinj@marvell.com; Gowrishankar > Muthukrishnan <gmuthukrishn@marvell.com>; Kiran Kumar K > <kirankumark@marvell.com> > Subject: [v1 1/2] cryptodev: add enumeration in EC xform for FPM > > Add enumeration in EC xform for FPM. Crypto driver would need this to > xform point multiplication based on given type of EC curve. > > Signed-off-by: Kiran Kumar K <kirankumark@marvell.com> > Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> > --- ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [v1 1/2] cryptodev: add enumeration in EC xform for FPM 2022-09-28 21:35 ` Ji, Kai @ 2022-09-30 18:08 ` Akhil Goyal 0 siblings, 0 replies; 8+ messages in thread From: Akhil Goyal @ 2022-09-30 18:08 UTC (permalink / raw) To: Ji, Kai, Gowrishankar Muthukrishnan, dev Cc: Anoob Joseph, Zhang, Roy Fan, Dooley, Brian, Jerin Jacob Kollanukkaran, Kiran Kumar Kokkilagadda > Acked-by: Kai Ji <kai.ji@intel.com> > > > Add enumeration in EC xform for FPM. Crypto driver would need this to > > xform point multiplication based on given type of EC curve. > > > > Signed-off-by: Kiran Kumar K <kirankumark@marvell.com> > > Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> > > --- This patch is applied to dpdk-next-crypto as we are approaching RC1 date. FIPS application patch is not acked and we can merge it in RC2. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [v1 2/2] examples/fips_validation: add ECDSA validation 2022-09-27 7:30 [v1 0/2] examples/fips_validation: add ECDSA tests Gowrishankar Muthukrishnan 2022-09-27 7:30 ` [v1 1/2] cryptodev: add enumeration in EC xform for FPM Gowrishankar Muthukrishnan @ 2022-09-27 7:30 ` Gowrishankar Muthukrishnan 2022-10-07 10:50 ` Akhil Goyal 2022-10-17 9:34 ` Dooley, Brian 1 sibling, 2 replies; 8+ messages in thread From: Gowrishankar Muthukrishnan @ 2022-09-27 7:30 UTC (permalink / raw) To: dev Cc: Anoob Joseph, Fan Zhang, Brian Dooley, Akhil Goyal, jerinj, Gowrishankar Muthukrishnan This patch adds support in fips_validation app to validate ECDSA. Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@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", + "", + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409" + }; + + /* 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 ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [v1 2/2] examples/fips_validation: add ECDSA validation 2022-09-27 7:30 ` [v1 2/2] examples/fips_validation: add ECDSA validation Gowrishankar Muthukrishnan @ 2022-10-07 10:50 ` Akhil Goyal 2022-10-17 9:34 ` Dooley, Brian 1 sibling, 0 replies; 8+ messages in thread From: Akhil Goyal @ 2022-10-07 10:50 UTC (permalink / raw) To: Gowrishankar Muthukrishnan, dev Cc: Anoob Joseph, Fan Zhang, Brian Dooley, Jerin Jacob Kollanukkaran, Gowrishankar Muthukrishnan Hi Brian, > 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 <gmuthukrishn@marvell.com> > --- Can you review this and ack? ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [v1 2/2] examples/fips_validation: add ECDSA validation 2022-09-27 7:30 ` [v1 2/2] examples/fips_validation: add ECDSA validation Gowrishankar Muthukrishnan 2022-10-07 10:50 ` Akhil Goyal @ 2022-10-17 9:34 ` Dooley, Brian 2022-10-21 15:48 ` Akhil Goyal 1 sibling, 1 reply; 8+ messages in thread From: Dooley, Brian @ 2022-10-17 9:34 UTC (permalink / raw) To: Gowrishankar Muthukrishnan, dev Cc: Anoob Joseph, Zhang, Roy Fan, Akhil Goyal, jerinj > -----Original Message----- > From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> > Sent: Tuesday, September 27, 2022 8:31 AM > To: dev@dpdk.org > Cc: Anoob Joseph <anoobj@marvell.com>; Zhang, Roy Fan > <roy.fan.zhang@intel.com>; Dooley, Brian <brian.dooley@intel.com>; Akhil > Goyal <gakhil@marvell.com>; jerinj@marvell.com; Gowrishankar > Muthukrishnan <gmuthukrishn@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 <gmuthukrishn@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.dooley@intel.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [v1 2/2] examples/fips_validation: add ECDSA validation 2022-10-17 9:34 ` Dooley, Brian @ 2022-10-21 15:48 ` Akhil Goyal 0 siblings, 0 replies; 8+ messages in thread From: Akhil Goyal @ 2022-10-21 15:48 UTC (permalink / raw) To: Dooley, Brian, Gowrishankar Muthukrishnan, dev Cc: Anoob Joseph, Zhang, Roy Fan, Jerin Jacob Kollanukkaran > > 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 <gmuthukrishn@marvell.com> > > Acked-by: Brian Dooley <brian.dooley@intel.com> Applied to dpdk-next-crypto Thanks. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-10-21 15:48 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-27 7:30 [v1 0/2] examples/fips_validation: add ECDSA tests Gowrishankar Muthukrishnan 2022-09-27 7:30 ` [v1 1/2] cryptodev: add enumeration in EC xform for FPM Gowrishankar Muthukrishnan 2022-09-28 21:35 ` Ji, Kai 2022-09-30 18:08 ` Akhil Goyal 2022-09-27 7:30 ` [v1 2/2] examples/fips_validation: add ECDSA validation Gowrishankar Muthukrishnan 2022-10-07 10:50 ` Akhil Goyal 2022-10-17 9:34 ` Dooley, Brian 2022-10-21 15:48 ` Akhil Goyal
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).