From patchwork Thu Sep 5 13:39:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gowrishankar Muthukrishnan X-Patchwork-Id: 143663 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 5B0C24590E; Thu, 5 Sep 2024 15:40:29 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8123042E8C; Thu, 5 Sep 2024 15:40:24 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 33CD542E82 for ; Thu, 5 Sep 2024 15:40:22 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 485AWPL8018437; Thu, 5 Sep 2024 06:40:19 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=5 gs742lis4AH+Ii/teLfmdlUUMMlwW5LzDYc7Hi29Tg=; b=jt76TKfWtYkBpwnaw AAq7bfUZG9qdb/6OajzJaxYwgS/UAbhVgrwGTVBEU70YmArt0VtNs6zcRr6/toaS iKPquGvujN1tduDKcepAXVkHDAFHWzBEYyKqPImp/HgpR12aGg9SHWIYrqHpNm5s UGcnx+nODD3tHsyh3BxkAIA7ErLcZTBNjc/YSAajK+ZWGlS/re1oJe1MamY4GzN3 aDBr6J1dLso6WRnw6S9EYvjGqVPd1Mu4ct36igSPdN5kl+x8kA06JUe+zp64Ixve 0KtQObZMK/8xptplovHC837lm1MyomMT0H+3rhTwEKzIWeGStidDPK66+MW96RpW Stxmw== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 41faywgnmq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 05 Sep 2024 06:40:19 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Thu, 5 Sep 2024 06:40:18 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Thu, 5 Sep 2024 06:40:18 -0700 Received: from BG-LT91401.marvell.com (BG-LT91401.marvell.com [10.28.168.34]) by maili.marvell.com (Postfix) with ESMTP id EDAE45B692A; Thu, 5 Sep 2024 06:40:11 -0700 (PDT) From: Gowrishankar Muthukrishnan To: , Brian Dooley , "Gowrishankar Muthukrishnan" CC: Anoob Joseph , , , , , , , , , , , , , , , Akhil Goyal Subject: [PATCH v2 5/6] examples/fips_validation: support EDDSA Date: Thu, 5 Sep 2024 19:09:30 +0530 Message-ID: <20240905133933.741-5-gmuthukrishn@marvell.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20240905133933.741-1-gmuthukrishn@marvell.com> References: <0ae6a1afadac64050d80b0fd7712c4a6a8599e2c.1701273963.git.gmuthukrishn@marvell.com> <20240905133933.741-1-gmuthukrishn@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: oqK0OXDTutSBTWm-BqRtjvrAz1k8Gy8Z X-Proofpoint-GUID: oqK0OXDTutSBTWm-BqRtjvrAz1k8Gy8Z X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-05_08,2024-09-04_01,2024-09-02_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 EDDSA support in fips_validation app. Signed-off-by: Gowrishankar Muthukrishnan --- examples/fips_validation/fips_validation.c | 2 + examples/fips_validation/fips_validation.h | 23 ++ .../fips_validation/fips_validation_eddsa.c | 307 +++++++++++++++++ examples/fips_validation/main.c | 323 ++++++++++++++++-- examples/fips_validation/meson.build | 1 + 5 files changed, 623 insertions(+), 33 deletions(-) create mode 100644 examples/fips_validation/fips_validation_eddsa.c diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c index c15178e55b..43d1e55532 100644 --- a/examples/fips_validation/fips_validation.c +++ b/examples/fips_validation/fips_validation.c @@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void) info.algo = FIPS_TEST_ALGO_RSA; else if (strstr(algo_str, "ECDSA")) info.algo = FIPS_TEST_ALGO_ECDSA; + else if (strstr(algo_str, "EDDSA")) + info.algo = FIPS_TEST_ALGO_EDDSA; else return -EINVAL; diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h index abc1d64742..795cf834e8 100644 --- a/examples/fips_validation/fips_validation.h +++ b/examples/fips_validation/fips_validation.h @@ -46,6 +46,7 @@ enum fips_test_algorithms { FIPS_TEST_ALGO_SHA, FIPS_TEST_ALGO_RSA, FIPS_TEST_ALGO_ECDSA, + FIPS_TEST_ALGO_EDDSA, FIPS_TEST_ALGO_MAX }; @@ -106,6 +107,12 @@ struct fips_test_vector { struct fips_val s; struct fips_val k; } ecdsa; + struct { + struct fips_val pkey; + struct fips_val q; + struct fips_val ctx; + struct fips_val sign; + } eddsa; struct fips_val pt; struct fips_val ct; @@ -177,6 +184,11 @@ enum fips_ecdsa_test_types { ECDSA_AFT = 0, }; +enum fips_eddsa_test_types { + EDDSA_AFT = 0, + EDDSA_BFT +}; + struct aesavs_interim_data { enum fips_aesavs_test_types test_type; uint32_t cipher_algo; @@ -241,6 +253,13 @@ struct ecdsa_interim_data { uint8_t pubkey_gen; }; +struct eddsa_interim_data { + enum rte_crypto_curve_id curve_id; + uint8_t curve_len; + uint8_t pubkey_gen; + bool prehash; +}; + #ifdef USE_JANSSON /* * Maximum length of buffer to hold any json string. @@ -288,6 +307,7 @@ struct fips_test_interim_info { struct xts_interim_data xts_data; struct rsa_interim_data rsa_data; struct ecdsa_interim_data ecdsa_data; + struct eddsa_interim_data eddsa_data; } interim_info; enum fips_test_op op; @@ -374,6 +394,9 @@ parse_test_rsa_json_init(void); int parse_test_ecdsa_json_init(void); +int +parse_test_eddsa_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_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c new file mode 100644 index 0000000000..8ccf7501bd --- /dev/null +++ b/examples/fips_validation/fips_validation_eddsa.c @@ -0,0 +1,307 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include +#include +#include +#include +#include + +#ifdef USE_OPENSSL +#include +#include +#endif /* USE_OPENSSL */ + +#include +#include + +#include "fips_validation.h" + +#define TESTTYPE_JSON_STR "testType" +#define CURVE_JSON_STR "curve" +#define PH_JSON_STR "preHash" + +#define MSG_JSON_STR "message" +#define CTX_JSON_STR "context" +#define Q_JSON_STR "q" +#define SIG_JSON_STR "signature" + +#ifdef USE_JANSSON +struct { + uint8_t type; + const char *desc; +} eddsa_test_types[] = { + {EDDSA_AFT, "AFT"}, + {EDDSA_BFT, "BFT"} +}; + +struct { + enum rte_crypto_curve_id curve_id; + const char *desc; +} eddsa_curve_ids[] = { + {RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"}, + {RTE_CRYPTO_EC_GROUP_ED448, "ED-448"}, +}; + +struct { + uint8_t curve_len; + const char *desc; +} eddsa_curve_len[] = { + {32, "ED-25519"}, + {64, "ED-448"}, +}; + +#ifdef USE_OPENSSL +#define MAX_TRIES 10 +static int +prepare_vec_eddsa(void) +{ + BIGNUM *pkey = NULL, *order = NULL; + int ret = -1, j; + unsigned long pid; + + /* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2). + */ + static const char * const orderstr[] = { + "7237005577332262213973186563042994240857116359379907606001950938285454250989", + "181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779", + }; + + pid = getpid(); + RAND_seed(&pid, sizeof(pid)); + + if (!RAND_status()) + return -1; + + order = BN_new(); + if (!order) + goto err; + + j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519; + 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.eddsa.pkey); + + ret = 0; +err: + BN_free(order); + BN_free(pkey); + return ret; +} +#else +static int +prepare_vec_eddsa(void) +{ + /* + * Generate EDDSA values. + */ + return -ENOTSUP; +} +#endif /* USE_OPENSSL */ + +static int +parse_test_eddsa_json_interim_writeback(struct fips_val *val) +{ + RTE_SET_USED(val); + + if (info.op == FIPS_TEST_ASYM_SIGGEN) { + /* For siggen tests, EDDSA values can be created soon after + * the test group data are parsed. + */ + if (vec.eddsa.pkey.val) { + rte_free(vec.eddsa.pkey.val); + vec.eddsa.pkey.val = NULL; + } + + if (prepare_vec_eddsa() < 0) + return -1; + + info.interim_info.eddsa_data.pubkey_gen = 1; + } + + return 0; +} + +static int +post_test_eddsa_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.eddsa.q); + obj = json_string(info.one_line_text); + json_object_set_new(json_info.json_write_group, "q", obj); + } + + return 0; +} + +static int +parse_test_eddsa_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.eddsa.sign); + obj = json_string(info.one_line_text); + json_object_set_new(json_info.json_write_case, "signature", obj); + } 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()); + } else if (info.op == FIPS_TEST_ASYM_KEYGEN) { + json_t *obj; + + writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey); + obj = json_string(info.one_line_text); + json_object_set_new(json_info.json_write_case, "d", obj); + + writeback_hex_str("", info.one_line_text, &vec.eddsa.q); + obj = json_string(info.one_line_text); + json_object_set_new(json_info.json_write_case, "q", obj); + } + + 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(eddsa_test_types); i++) + if (strstr(src, eddsa_test_types[i].desc)) { + info.parse_writeback = parse_test_eddsa_json_writeback; + break; + } + + if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types)) + return -EINVAL; + + } else if (strcmp(key, CURVE_JSON_STR) == 0) { + for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++) + if (strstr(src, eddsa_curve_ids[i].desc)) { + info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id; + info.interim_info.eddsa_data.curve_len = + eddsa_curve_len[i].curve_len; + break; + } + + if (i >= RTE_DIM(eddsa_curve_ids)) + return -EINVAL; + } else if (strcmp(key, PH_JSON_STR) == 0) { + info.interim_info.eddsa_data.prehash = false; + } else { + return -EINVAL; + } + + return 0; +} + +static int +parse_keygen_tc_str(const char *key, char *src, struct fips_val *val) +{ + RTE_SET_USED(key); + RTE_SET_USED(src); + RTE_SET_USED(val); + + if (info.op == FIPS_TEST_ASYM_KEYGEN) { + if (vec.eddsa.pkey.val) { + rte_free(vec.eddsa.pkey.val); + vec.eddsa.pkey.val = NULL; + } + + if (prepare_vec_eddsa() < 0) + return -1; + + info.interim_info.eddsa_data.pubkey_gen = 1; + } + + return 0; +} + +struct fips_test_callback eddsa_interim_json_vectors[] = { + {TESTTYPE_JSON_STR, parse_interim_str, NULL}, + {CURVE_JSON_STR, parse_interim_str, NULL}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback eddsa_siggen_json_vectors[] = { + {MSG_JSON_STR, parse_uint8_hex_str, &vec.pt}, + {CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback eddsa_sigver_json_vectors[] = { + {MSG_JSON_STR, parse_uint8_hex_str, &vec.pt}, + {Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q}, + {SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +struct fips_test_callback eddsa_keygen_json_vectors[] = { + {"tcId", parse_keygen_tc_str, &vec.pt}, + {NULL, NULL, NULL} /**< end pointer */ +}; + +int +parse_test_eddsa_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_callbacks = eddsa_interim_json_vectors; + info.post_interim_writeback = post_test_eddsa_json_interim_writeback; + info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback; + if (strcmp(mode_str, "sigGen") == 0) { + info.op = FIPS_TEST_ASYM_SIGGEN; + info.callbacks = eddsa_siggen_json_vectors; + } else if (strcmp(mode_str, "sigVer") == 0) { + info.op = FIPS_TEST_ASYM_SIGVER; + info.callbacks = eddsa_sigver_json_vectors; + } else if (strcmp(mode_str, "keyGen") == 0) { + info.op = FIPS_TEST_ASYM_KEYGEN; + info.callbacks = eddsa_keygen_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 7ae2c6c007..522373ac1d 100644 --- a/examples/fips_validation/main.c +++ b/examples/fips_validation/main.c @@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void) return 0; } +static int +prepare_eddsa_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->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; + asym->eddsa.message.data = msg.val; + asym->eddsa.message.length = msg.len; + asym->eddsa.context.data = vec.eddsa.ctx.val; + asym->eddsa.context.length = vec.eddsa.ctx.len; + + rte_free(vec.eddsa.sign.val); + + vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len; + vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0); + + asym->eddsa.sign.data = vec.eddsa.sign.val; + asym->eddsa.sign.length = 0; + } else if (info.op == FIPS_TEST_ASYM_SIGVER) { + asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; + asym->eddsa.message.data = msg.val; + asym->eddsa.message.length = msg.len; + asym->eddsa.sign.data = vec.eddsa.sign.val; + asym->eddsa.sign.length = vec.eddsa.sign.len; + } else { + RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); + return -EINVAL; + } + + if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) { + asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519; + if (info.interim_info.eddsa_data.prehash) + asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH; + if (vec.eddsa.ctx.len > 0) + asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX; + } else { + asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448; + if (info.interim_info.eddsa_data.prehash) + asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH; + } + rte_crypto_op_attach_asym_session(env.op, env.asym.sess); + + return 0; +} + static int prepare_ecfpm_op(void) { @@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void) return 0; } +static int +prepare_edfpm_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.eddsa.pkey.val; + asym->ecpm.scalar.length = vec.eddsa.pkey.len; + + rte_free(vec.eddsa.q.val); + + vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len; + vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0); + + asym->ecpm.r.x.data = vec.eddsa.q.val; + asym->ecpm.r.x.length = 0; + asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED; + + rte_crypto_op_attach_asym_session(env.op, env.asym.sess); + + return 0; +} + static int prepare_aes_xform(struct rte_crypto_sym_xform *xform) { @@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform) return 0; } +static int +prepare_eddsa_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_EDDSA; + 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; + } + + xform->ec.pkey.data = vec.eddsa.pkey.val; + xform->ec.pkey.length = vec.eddsa.pkey.len; + xform->ec.q.x.data = vec.eddsa.q.val; + xform->ec.q.x.length = vec.eddsa.q.len; + 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; + } + + xform->ec.q.x.data = vec.eddsa.q.val; + xform->ec.q.x.length = vec.eddsa.q.len; + break; + default: + break; + } + + xform->ec.curve_id = info.interim_info.eddsa_data.curve_id; + return 0; +} + static int prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform) { @@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform) return 0; } +static int +prepare_edfpm_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.eddsa_data.curve_id; + return 0; +} + static int get_writeback_data(struct fips_val *val) { @@ -1709,7 +1863,9 @@ fips_run_asym_test(void) struct rte_crypto_op *deqd_op; int ret; - if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) { + if (info.op == FIPS_TEST_ASYM_KEYGEN && + (info.algo != FIPS_TEST_ALGO_ECDSA && + info.algo != FIPS_TEST_ALGO_EDDSA)) { RTE_SET_USED(asym); ret = 0; goto exit; @@ -1758,53 +1914,140 @@ fips_run_test(void) { int ret; - env.op = env.sym.op; - if (env.is_asym_test) { - if (info.op == FIPS_TEST_ASYM_KEYGEN && - info.algo == FIPS_TEST_ALGO_ECDSA) { - env.op = env.asym.op; + env.op = NULL; + if (!env.is_asym_test) { + env.op = env.sym.op; + return fips_run_sym_test(); + } + + if (info.op == FIPS_TEST_ASYM_KEYGEN) { + if (info.algo == FIPS_TEST_ALGO_ECDSA) { 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.interim_info.ecdsa_data.pubkey_gen = 0; - return ret; + + } else if (info.algo == FIPS_TEST_ALGO_EDDSA) { + test_ops.prepare_asym_xform = prepare_edfpm_xform; + test_ops.prepare_asym_op = prepare_edfpm_op; + info.interim_info.eddsa_data.pubkey_gen = 0; } - vec.cipher_auth.digest.len = parse_test_sha_hash_size( - info.interim_info.rsa_data.auth); + env.op = env.asym.op; + return fips_run_asym_test(); + } + + if (info.algo == FIPS_TEST_ALGO_ECDSA) { + vec.cipher_auth.digest.len = + parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth); test_ops.prepare_sym_xform = prepare_sha_xform; test_ops.prepare_sym_op = prepare_auth_op; + + env.op = env.sym.op; ret = fips_run_sym_test(); if (ret < 0) return ret; - } else { - return fips_run_sym_test(); } env.op = env.asym.op; - 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; + if (info.op == FIPS_TEST_ASYM_SIGGEN) { + fips_prepare_asym_xform_t old_xform; + fips_prepare_op_t old_op; + + old_xform = test_ops.prepare_asym_xform; + old_op = test_ops.prepare_asym_op; + + if (info.algo == FIPS_TEST_ALGO_ECDSA && + info.interim_info.ecdsa_data.pubkey_gen == 1) { + info.op = FIPS_TEST_ASYM_KEYGEN; + test_ops.prepare_asym_xform = prepare_ecfpm_xform; + test_ops.prepare_asym_op = prepare_ecfpm_op; - info.post_interim_writeback(NULL); - info.interim_info.ecdsa_data.pubkey_gen = 0; + 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; + } else if (info.algo == FIPS_TEST_ALGO_EDDSA && + info.interim_info.eddsa_data.pubkey_gen == 1) { + info.op = FIPS_TEST_ASYM_KEYGEN; + test_ops.prepare_asym_xform = prepare_edfpm_xform; + test_ops.prepare_asym_op = prepare_edfpm_op; + + const struct rte_cryptodev_asymmetric_xform_capability *cap; + struct rte_cryptodev_asym_capability_idx cap_idx; + + cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA; + 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; + } + + if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) { + ret = fips_run_asym_test(); + if (ret < 0) + return ret; + } else { + /* Below is only a workaround by using known keys. */ + struct rte_crypto_asym_xform xform = {0}; + + prepare_edfpm_xform(&xform); + prepare_edfpm_op(); + uint8_t pkey25519[] = { + 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, + 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, + 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, + 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42 + }; + uint8_t q25519[] = { + 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, + 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34, + 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, + 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf + }; + uint8_t pkey448[] = { + 0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08, + 0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d, + 0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5, + 0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf, + 0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f, + 0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa, + 0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f, + 0x01 + }; + uint8_t q448[] = { + 0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80, + 0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a, + 0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd, + 0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a, + 0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd, + 0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5, + 0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f, + 0x00 + }; + if (info.interim_info.eddsa_data.curve_id == + RTE_CRYPTO_EC_GROUP_ED25519) { + memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519)); + vec.eddsa.pkey.len = 32; + memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519)); + vec.eddsa.q.len = 32; + } else { + memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448)); + vec.eddsa.pkey.len = 32; + memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448)); + vec.eddsa.q.len = 32; + } + } + info.post_interim_writeback(NULL); + info.interim_info.eddsa_data.pubkey_gen = 0; + + } + + test_ops.prepare_asym_xform = old_xform; + test_ops.prepare_asym_op = old_op; info.op = FIPS_TEST_ASYM_SIGGEN; ret = fips_run_asym_test(); } else { @@ -2536,6 +2779,17 @@ init_test_ops(void) test_ops.test = fips_generic_test; } break; + case FIPS_TEST_ALGO_EDDSA: + if (info.op == FIPS_TEST_ASYM_KEYGEN) { + test_ops.prepare_asym_op = prepare_edfpm_op; + test_ops.prepare_asym_xform = prepare_edfpm_xform; + test_ops.test = fips_generic_test; + } else { + test_ops.prepare_asym_op = prepare_eddsa_op; + test_ops.prepare_asym_xform = prepare_eddsa_xform; + test_ops.test = fips_generic_test; + } + break; default: if (strstr(info.file_name, "TECB") || strstr(info.file_name, "TCBC")) { @@ -2719,6 +2973,9 @@ fips_test_one_test_group(void) case FIPS_TEST_ALGO_ECDSA: ret = parse_test_ecdsa_json_init(); break; + case FIPS_TEST_ALGO_EDDSA: + ret = parse_test_eddsa_json_init(); + break; default: return -EINVAL; } diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build index 34d3c7c8ca..7d4e440c6c 100644 --- a/examples/fips_validation/meson.build +++ b/examples/fips_validation/meson.build @@ -20,6 +20,7 @@ sources = files( 'fips_validation_xts.c', 'fips_validation_rsa.c', 'fips_validation_ecdsa.c', + 'fips_validation_eddsa.c', 'fips_dev_self_test.c', 'main.c', )