[PATCH v6 2/6] crypto/openssl: support EDDSA
Kusztal, ArkadiuszX
arkadiuszx.kusztal at intel.com
Mon Oct 7 18:27:34 CEST 2024
Hi Gowrishankar,
> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn at marvell.com>
> Sent: Friday, October 4, 2024 10:26 AM
> To: dev at dpdk.org; Ji, Kai <kai.ji at intel.com>
> Cc: Anoob Joseph <anoobj at marvell.com>; Richardson, Bruce
> <bruce.richardson at intel.com>; jerinj at marvell.com; fanzhang.oss at gmail.com;
> Kusztal, ArkadiuszX <arkadiuszx.kusztal at intel.com>; jack.bond-
> preston at foss.arm.com; Marchand, David <david.marchand at redhat.com>;
> hemant.agrawal at nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch at intel.com>; Trahe, Fiona <fiona.trahe at intel.com>;
> Doherty, Declan <declan.doherty at intel.com>; matan at nvidia.com;
> ruifeng.wang at arm.com; Akhil Goyal <gakhil at marvell.com>; Gowrishankar
> Muthukrishnan <gmuthukrishn at marvell.com>
> Subject: [PATCH v6 2/6] crypto/openssl: support EDDSA
>
> Support EDDSA crypto algorithm in OpenSSL PMD.
>
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn at marvell.com>
> ---
> doc/guides/cryptodevs/features/openssl.ini | 1 +
> drivers/crypto/openssl/openssl_pmd_private.h | 13 ++
> drivers/crypto/openssl/rte_openssl_pmd.c | 223 +++++++++++++++++++
> drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
> 4 files changed, 368 insertions(+)
>
> diff --git a/doc/guides/cryptodevs/features/openssl.ini
> b/doc/guides/cryptodevs/features/openssl.ini
> index b64c8ec4a5..0540c075dc 100644
> --- a/doc/guides/cryptodevs/features/openssl.ini
> +++ b/doc/guides/cryptodevs/features/openssl.ini
> @@ -66,6 +66,7 @@ Modular Exponentiation = Y Modular Inversion = Y Diffie-
> hellman = Y
> SM2 = Y
> +EDDSA = Y
>
> ;
> ; Supported Operating systems of the 'openssl' crypto driver.
> diff --git a/drivers/crypto/openssl/openssl_pmd_private.h
> b/drivers/crypto/openssl/openssl_pmd_private.h
> index 0282b3d829..7dd97f1c72 100644
> --- a/drivers/crypto/openssl/openssl_pmd_private.h
> +++ b/drivers/crypto/openssl/openssl_pmd_private.h
> @@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
> #endif
> } s;
> struct {
> + uint8_t curve_id;
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> + EC_GROUP * group;
> + BIGNUM *priv_key;
> +#endif
> + } ec;
> + struct {
> #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> OSSL_PARAM * params;
> #endif
> } sm2;
> + struct {
> + uint8_t curve_id;
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> + OSSL_PARAM * params;
> +#endif
> + } eddsa;
> } u;
> };
> /** Set and validate OPENSSL crypto session parameters */ diff --git
> a/drivers/crypto/openssl/rte_openssl_pmd.c
> b/drivers/crypto/openssl/rte_openssl_pmd.c
> index e10a172f46..4e4d06403b 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> @@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op
> *cop,
>
> }
>
> +static int
> +process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
> + struct openssl_asym_session *sess)
> +{
> + const EC_GROUP *ecgrp = sess->u.ec.group;
> + EC_POINT *ecpt = NULL;
> + BN_CTX *ctx = NULL;
> + BIGNUM *n = NULL;
> + int ret = -1;
> +
> + n = BN_bin2bn((const unsigned char *)
> + cop->asym->ecpm.scalar.data,
> + cop->asym->ecpm.scalar.length,
> + BN_new());
> +
> + ctx = BN_CTX_new();
> + if (!ctx)
> + goto err_ecfpm;
> +
> + if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
> + goto err_ecfpm;
> +
> + if (cop->asym->flags &
> RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
> + unsigned char *buf = cop->asym->ecpm.r.x.data;
> + size_t sz;
> +
> + sz = EC_POINT_point2oct(ecgrp, ecpt,
> POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
> + if (!sz)
> + goto err_ecfpm;
> +
> + cop->asym->ecpm.r.x.length = sz;
> + }
> +
> +err_ecfpm:
> + BN_CTX_free(ctx);
> + BN_free(n);
> + return ret;
> +}
> +
> static int
> process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
> struct openssl_asym_session *sess)
> @@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct
> rte_crypto_op *cop,
> return ret;
> }
>
> +static int
> +process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
> + struct openssl_asym_session *sess)
> +{
> + static const char * const instance[] = {"Ed25519", "Ed25519ctx",
> "Ed25519ph",
> + "Ed448", "Ed448ph"};
> + EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
> + const uint8_t curve_id = sess->u.eddsa.curve_id;
> + struct rte_crypto_asym_op *op = cop->asym;
> + OSSL_PARAM *params = sess->u.eddsa.params;
> + OSSL_PARAM_BLD *iparam_bld = NULL;
> + OSSL_PARAM *iparams = NULL;
> + uint8_t signbuf[128] = {0};
> + EVP_MD_CTX *md_ctx = NULL;
> + EVP_PKEY *pkey = NULL;
> + size_t signlen;
> + int ret = -1;
> +
> + cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
> +
> + iparam_bld = OSSL_PARAM_BLD_new();
> + if (!iparam_bld)
> + goto err_eddsa;
> +
> + if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
> + OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-
> string",
> + op->eddsa.context.data, op->eddsa.context.length);
> +
> + }
> +
> + OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
> + instance[op->eddsa.instance], strlen(instance[op-
> >eddsa.instance]));
> +
> + iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
> + if (!iparams)
> + goto err_eddsa;
> +
> + switch (op->eddsa.op_type) {
> + case RTE_CRYPTO_ASYM_OP_SIGN:
> + {
> + if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
> + kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED25519", NULL);
I see this is a pattern in this PMD, but there are plenty of operations that should be done in session instead on the datapath.
EVP_PKEY_CTX_new_from_name
EVP_PKEY_fromdata
EVP_MD_CTX_new
EVP_MD_CTX_set_pkey_ctx
Should rather be done once per session than per every operation in with-session case.
> + else
> + kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED448", NULL);
> +
> + if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0
> ||
> + EVP_PKEY_fromdata(kctx, &pkey,
> EVP_PKEY_KEYPAIR, params) <= 0)
> + goto err_eddsa;
> +
> + md_ctx = EVP_MD_CTX_new();
> + if (!md_ctx)
> + goto err_eddsa;
> +
> + sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey,
> NULL);
> + if (!sctx)
> + goto err_eddsa;
> +
> + EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
> +
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> + if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL,
> NULL, pkey, iparams))
> + goto err_eddsa;
> +#else
> + if (op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_25519 ||
> + op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_448) {
> + if (!EVP_DigestSignInit(md_ctx, NULL, NULL,
> NULL, pkey))
> + goto err_eddsa;
> + } else
> + goto err_eddsa;
> +#endif
> +
> + if (!EVP_DigestSign(md_ctx, NULL, &signlen, op-
> >eddsa.message.data,
> + op->eddsa.message.length))
> + goto err_eddsa;
> +
> + if (signlen > RTE_DIM(signbuf))
> + goto err_eddsa;
> +
> + if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op-
> >eddsa.message.data,
> + op->eddsa.message.length))
> + goto err_eddsa;
> +
> + memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
> + op->eddsa.sign.length = signlen;
> + }
> + break;
> + case RTE_CRYPTO_ASYM_OP_VERIFY:
> + {
> + if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
> + kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED25519", NULL);
> + else
> + kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED448", NULL);
> +
> + if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0
> ||
> + EVP_PKEY_fromdata(kctx, &pkey,
> EVP_PKEY_PUBLIC_KEY, params) <= 0)
> + goto err_eddsa;
> +
> + md_ctx = EVP_MD_CTX_new();
> + if (!md_ctx)
> + goto err_eddsa;
> +
> + sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey,
> NULL);
> + if (!sctx)
> + goto err_eddsa;
> +
> + EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
> +
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> + if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL,
> NULL, NULL, pkey, iparams))
> + goto err_eddsa;
> +#else
> + if (op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_25519 ||
> + op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_448) {
> + if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL,
> NULL, pkey))
> + goto err_eddsa;
> + } else
> + goto err_eddsa;
> +#endif
> +
> + signlen = op->eddsa.sign.length;
> + memcpy(&signbuf[0], op->eddsa.sign.data, op-
> >eddsa.sign.length);
> +
> + ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op-
> >eddsa.message.data,
> + op->eddsa.message.length);
> + if (ret == 0)
> + goto err_eddsa;
> + }
> + break;
> + default:
> + /* allow ops with invalid args to be pushed to
> + * completion queue
> + */
> + cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> + goto err_eddsa;
> + }
> +
> + ret = 0;
> + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +err_eddsa:
> + OSSL_PARAM_BLD_free(iparam_bld);
> +
> + if (sctx)
> + EVP_PKEY_CTX_free(sctx);
> +
> + if (cctx)
> + EVP_PKEY_CTX_free(cctx);
> +
> + if (pkey)
> + EVP_PKEY_free(pkey);
> +
> + return ret;
> +}
> #else
> static int
> process_openssl_rsa_op(struct rte_crypto_op *cop, @@ -3174,6 +3365,15 @@
> process_openssl_rsa_op(struct rte_crypto_op *cop,
> return 0;
> }
>
> +static int
> +process_openssl_ecfpm_op(struct rte_crypto_op *cop,
> + struct openssl_asym_session *sess)
> +{
> + RTE_SET_USED(cop);
> + RTE_SET_USED(sess);
> + return -ENOTSUP;
> +}
> +
> static int
> process_openssl_sm2_op(struct rte_crypto_op *cop,
> struct openssl_asym_session *sess)
> @@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op
> *cop,
> RTE_SET_USED(sess);
> return -ENOTSUP;
> }
> +
> +static int
> +process_openssl_eddsa_op(struct rte_crypto_op *cop,
> + struct openssl_asym_session *sess)
> +{
> + RTE_SET_USED(cop);
> + RTE_SET_USED(sess);
> + return -ENOTSUP;
> +}
> #endif
>
> static int
> @@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct
> rte_crypto_op *op,
> process_openssl_dsa_verify_op(op, sess);
> else
> op->status =
> RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> +#endif
> + break;
> + case RTE_CRYPTO_ASYM_XFORM_ECFPM:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> + retval = process_openssl_ecfpm_op_evp(op, sess); #else
> + retval = process_openssl_ecfpm_op(op, sess);
> #endif
> break;
> case RTE_CRYPTO_ASYM_XFORM_SM2:
> @@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct
> rte_crypto_op *op,
> retval = process_openssl_sm2_op_evp(op, sess); #else
> retval = process_openssl_sm2_op(op, sess);
> +#endif
> + break;
> + case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> + retval = process_openssl_eddsa_op_evp(op, sess); #else
> + retval = process_openssl_eddsa_op(op, sess);
> #endif
> break;
> default:
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> index b7b612fc57..0725184653 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> @@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities
> openssl_pmd_capabilities[] = {
> },
> }
> },
> + { /* ECFPM */
> + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> + {.asym = {
> + .xform_capa = {
> + .xform_type =
> RTE_CRYPTO_ASYM_XFORM_ECFPM,
> + .op_types = 0
> + }
> + }
> + }
> + },
> { /* SM2 */
> .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> {.asym = {
> @@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities
> openssl_pmd_capabilities[] = {
> }
> }
> },
> + { /* EDDSA */
> + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> + {.asym = {
> + .xform_capa = {
> + .xform_type =
> RTE_CRYPTO_ASYM_XFORM_EDDSA,
> + .hash_algos = (1 <<
> RTE_CRYPTO_AUTH_SHA512 |
> + 1 <<
> RTE_CRYPTO_AUTH_SHAKE_256),
> + .op_types =
> + ((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
> + (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
> + }
> + }
> + }
> + },
>
> RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> };
> @@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
> BN_free(pub_key);
> return -1;
> }
> + case RTE_CRYPTO_ASYM_XFORM_ECFPM:
> + {
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> + EC_GROUP *ecgrp = NULL;
> +
> + asym_session->xfrm_type = xform->xform_type;
> +
> + switch (xform->ec.curve_id) {
> + case RTE_CRYPTO_EC_GROUP_SECP192R1:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp192k1);
> + break;
> + case RTE_CRYPTO_EC_GROUP_SECP224R1:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp224r1);
> + break;
> + case RTE_CRYPTO_EC_GROUP_SECP256R1:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp256k1);
> + break;
> + case RTE_CRYPTO_EC_GROUP_SECP384R1:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp384r1);
> + break;
> + case RTE_CRYPTO_EC_GROUP_SECP521R1:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp521r1);
> + break;
> + case RTE_CRYPTO_EC_GROUP_ED25519:
> + ecgrp =
> EC_GROUP_new_by_curve_name(NID_ED25519);
> + break;
> + case RTE_CRYPTO_EC_GROUP_ED448:
> + ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
> + break;
> + default:
> + break;
> + }
> +
> + asym_session->u.ec.curve_id = xform->ec.curve_id;
> + asym_session->u.ec.group = ecgrp;
> + break;
> +#else
> + OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL
> Version < 3.0");
> + return -ENOTSUP;
> +#endif
> + }
> case RTE_CRYPTO_ASYM_XFORM_SM2:
> {
> #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) @@ -1440,6 +1505,66 @@
> static int openssl_set_asym_session_parameters(
> #else
> OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL
> Version < 3.0");
> return -ENOTSUP;
> +#endif
> + }
> + case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> + {
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> + OSSL_PARAM_BLD *param_bld = NULL;
> + OSSL_PARAM *params = NULL;
> + int ret = -1;
> +
> + asym_session->u.eddsa.curve_id = xform->ec.curve_id;
> +
> + param_bld = OSSL_PARAM_BLD_new();
> + if (!param_bld) {
> + OPENSSL_LOG(ERR, "failed to allocate params");
> + goto err_eddsa;
> + }
> +
> + ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
> + OSSL_PKEY_PARAM_GROUP_NAME, "ED25519",
> sizeof("ED25519"));
> + if (!ret) {
> + OPENSSL_LOG(ERR, "failed to push params");
> + goto err_eddsa;
> + }
> +
> + ret = OSSL_PARAM_BLD_push_octet_string(param_bld,
> OSSL_PKEY_PARAM_PRIV_KEY,
> + xform->ec.pkey.data, xform->ec.pkey.length);
> + if (!ret) {
> + OPENSSL_LOG(ERR, "failed to push params");
> + goto err_eddsa;
> + }
> +
> + ret = OSSL_PARAM_BLD_push_octet_string(param_bld,
> OSSL_PKEY_PARAM_PUB_KEY,
> + xform->ec.q.x.data, xform->ec.q.x.length);
> + if (!ret) {
> + OPENSSL_LOG(ERR, "failed to push params");
> + goto err_eddsa;
> + }
> +
> + params = OSSL_PARAM_BLD_to_param(param_bld);
> + if (!params) {
> + OPENSSL_LOG(ERR, "failed to push params");
> + goto err_eddsa;
> + }
> +
> + asym_session->u.eddsa.params = params;
> + OSSL_PARAM_BLD_free(param_bld);
> +
> + asym_session->xfrm_type =
> RTE_CRYPTO_ASYM_XFORM_EDDSA;
> + break;
> +err_eddsa:
> + if (param_bld)
> + OSSL_PARAM_BLD_free(param_bld);
> +
> + if (asym_session->u.eddsa.params)
> + OSSL_PARAM_free(asym_session->u.eddsa.params);
> +
> + return -1;
> +#else
> + OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL
> Version < 3.3");
> + return -ENOTSUP;
> #endif
> }
> default:
> @@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct
> openssl_asym_session *sess) #if (OPENSSL_VERSION_NUMBER >=
> 0x30000000L)
> OSSL_PARAM_free(sess->u.sm2.params);
> #endif
> + break;
> + case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> + OSSL_PARAM_free(sess->u.eddsa.params);
> +#endif
> + break;
> default:
> break;
> }
> --
> 2.21.0
More information about the dev
mailing list