From patchwork Tue Sep 27 07:30:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gowrishankar Muthukrishnan X-Patchwork-Id: 116946 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B582DA00C2; Tue, 27 Sep 2022 09:30:56 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 12648427F0; Tue, 27 Sep 2022 09:30:56 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 3169C427F0 for ; Tue, 27 Sep 2022 09:30:54 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 28R4Ucsw016232; Tue, 27 Sep 2022 00:30:53 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=CspLcgLsz33aoR/8wnOh9wFaFROAqbKLcOVTodVcFZ8=; b=IZrXgisZ3+zYuOdm4wJb4wP8VJBMQ6urh5f38leMFIDi/tgew4pQeoJiYjIMx5bj4Mrj YvLx+MPJgMQEyJbQBVorA8c4jo3Hdz9OqcWtKe3CEGy6hFJg+KiTRIRKiDNwx+OEtfw1 jx40FVzX9MBIjh5vpwHVwXJijAD7MipRuOpU4eSgrvjklWVKWabcUkSnpRsrbYD9Yyb0 iqbzqdO9o82yGKzLR5TqUMt9oSmR5bWmkU4zQYxllTlOv02jtMf+kfVrOdDOErOO8mSi padC8Lap5ECwert6zKFy5byqMT1B3NB6JjfJPT8avCrblbSPvcQoH9V0vZtY5bDpi6Jt EA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3jt1dp8x4r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 27 Sep 2022 00:30:53 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 27 Sep 2022 00:30:51 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Tue, 27 Sep 2022 00:30:51 -0700 Received: from localhost.localdomain (unknown [10.28.34.38]) by maili.marvell.com (Postfix) with ESMTP id A5A293F707B; Tue, 27 Sep 2022 00:30:48 -0700 (PDT) From: Gowrishankar Muthukrishnan To: CC: Anoob Joseph , Fan Zhang , Brian Dooley , Akhil Goyal , , Gowrishankar Muthukrishnan , Kiran Kumar K Subject: [v1 1/2] cryptodev: add enumeration in EC xform for FPM Date: Tue, 27 Sep 2022 13:00:42 +0530 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: I2J3Nm-zRTM_aIySTUNr1BVdx0rsTf39 X-Proofpoint-GUID: I2J3Nm-zRTM_aIySTUNr1BVdx0rsTf39 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-09-27_02,2022-09-22_02,2022-06-22_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 Signed-off-by: Gowrishankar Muthukrishnan Acked-by: Kai Ji --- 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 */ }; From patchwork Tue Sep 27 07:30:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gowrishankar Muthukrishnan X-Patchwork-Id: 116947 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B8EA9A00C2; Tue, 27 Sep 2022 09:31:02 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0DBF84281C; Tue, 27 Sep 2022 09:30:59 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 2B06B4280D for ; Tue, 27 Sep 2022 09:30:57 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 28R3pkEF031852; Tue, 27 Sep 2022 00:30:56 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=tSikGilDRHINaMTy4zhIrr5qm8g3bt0nJewxjKK5hKo=; b=Mkg4ff8/cSCSXre6PbdzWdDzN7hGeXNaOPsoXWKj8BV/tSWbcW77cxYTx+Y/Ux0f/6Z7 pS+4/mqYD3SiCKvIHOcmju2hpjDdzHIYLCySZG0WOflv6w8d6CC7/II8ddqLT4Z3bC+N V/Nb005LjWM4cdIi5Gz5VMT4K3iHX0YyiSejSbLZ7YHgwyULvc0t444C0vPvjMJietIJ RSu5tgw74Pi57HIgqZfjrvadc6ZgtH4C7IjcYDMrdokR0D6/K/joHMEv/kXZ6qkEalpd Ds4ClUhQBe7nBm/FPJNmI5FeYH2zOjwUR8IEF9W7Nt9OlGvgWdupKuBCTNr5y/vWx50A Rg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3jucsq36tf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 27 Sep 2022 00:30:56 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 27 Sep 2022 00:30:54 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Tue, 27 Sep 2022 00:30:54 -0700 Received: from localhost.localdomain (unknown [10.28.34.38]) by maili.marvell.com (Postfix) with ESMTP id E46DB3F7041; Tue, 27 Sep 2022 00:30:51 -0700 (PDT) From: Gowrishankar Muthukrishnan To: CC: Anoob Joseph , Fan Zhang , Brian Dooley , Akhil Goyal , , Gowrishankar Muthukrishnan Subject: [v1 2/2] examples/fips_validation: add ECDSA validation Date: Tue, 27 Sep 2022 13:00:43 +0530 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 X-Proofpoint-GUID: i2OTUipmuBdRbz63dBblL_MJr0U4HLX1 X-Proofpoint-ORIG-GUID: i2OTUipmuBdRbz63dBblL_MJr0U4HLX1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-09-27_02,2022-09-22_02,2022-06-22_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch adds support in fips_validation app to validate ECDSA. Signed-off-by: Gowrishankar Muthukrishnan Acked-by: Brian Dooley --- 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 +#include +#include +#include +#include +#include + +#ifdef USE_OPENSSL +#include +#include +#endif /* USE_OPENSSL */ + +#include +#include + +#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', )