@@ -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;
@@ -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 */
new file mode 100644
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.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 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 */
@@ -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;
}
@@ -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',
)