> Subject: [PATCH v2 5/8] crypto/openssl: add RSA-OAEP support for OpenSSL PMD Rename to crypto/openssl: support RSA-OAEP
> > Add support for RSA OAEP padding in the OpenSSL PMD OpenSSL 3.x > implementation. > > Store OAEP configuration parameters in the RSA asymmetric session, > including the OAEP hash, MGF1 hash, and optional label. Configure > these parameters on the EVP_PKEY context during RSA encrypt and > decrypt operations, and default the MGF1 hash to the OAEP hash when > not specified by the application. > > Validate OAEP-specific usage, restrict it to encrypt/decrypt > operations, and add proper cleanup of allocated label resources on > error and session teardown paths. > > Signed-off-by: Sucharitha Sarananaga <[email protected]> > --- > drivers/crypto/openssl/openssl_pmd_private.h | 5 ++ > drivers/crypto/openssl/rte_openssl_pmd.c | 53 ++++++++++++ > drivers/crypto/openssl/rte_openssl_pmd_ops.c | 90 ++++++++++++++++++++ > 3 files changed, 148 insertions(+) > > diff --git a/drivers/crypto/openssl/openssl_pmd_private.h > b/drivers/crypto/openssl/openssl_pmd_private.h > index ab40012d61..8704e1915a 100644 > --- a/drivers/crypto/openssl/openssl_pmd_private.h > +++ b/drivers/crypto/openssl/openssl_pmd_private.h > @@ -181,6 +181,11 @@ struct __rte_cache_aligned openssl_asym_session { > RSA *rsa; > uint32_t pad; > EVP_PKEY_CTX * ctx; > + const EVP_MD *oaep_md; > + const EVP_MD *mgf1_md; > + Remove extra line > + uint8_t *label; > + uint32_t label_len; > } r; > struct exp { > BIGNUM *exp; > diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c > b/drivers/crypto/openssl/rte_openssl_pmd.c > index 2319c7cfa9..4fbbb73bfa 100644 > --- a/drivers/crypto/openssl/rte_openssl_pmd.c > +++ b/drivers/crypto/openssl/rte_openssl_pmd.c > @@ -2292,6 +2292,41 @@ process_openssl_modexp_op(struct rte_crypto_op > *cop, > return 0; > } > > +/** > + * Configure RSA-OAEP parameters on an initialized EVP_PKEY_CTX. > + * Must be called after EVP_PKEY_encrypt_init() or EVP_PKEY_decrypt_init(). > + * > + * @return 0 on success, -1 on failure. > + */ > +static int > +openssl_rsa_set_oaep_params(EVP_PKEY_CTX *ctx, > + const struct openssl_asym_session *sess) > +{ > + if (sess->u.r.pad != RTE_CRYPTO_RSA_PADDING_OAEP) > + return 0; > + > + if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, sess->u.r.oaep_md) <= 0) > + return -1; > + > + if (EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sess->u.r.mgf1_md) <= 0) > + return -1; > + > + if (sess->u.r.label_len > 0) { > + void *label = OPENSSL_memdup(sess->u.r.label, sess- > >u.r.label_len); > + > + if (label == NULL) > + return -1; > + > + if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label, sess- > >u.r.label_len) <= 0) { > + OPENSSL_free(label); > + return -1; > + } > + } > + /* Empty label is default; set0_rsa_oaep_label(NULL,0) fails on OpenSSL > 3. */ > + > + return 0; > +} > + > /* process rsa operations */ > static int > process_openssl_rsa_op_evp(struct rte_crypto_op *cop, > @@ -2308,6 +2343,15 @@ process_openssl_rsa_op_evp(struct rte_crypto_op > *cop, > if (!rsa_ctx) > return ret; > > + /* OAEP is only valid for encrypt/decrypt */ > + if (sess->u.r.pad == RTE_CRYPTO_RSA_PADDING_OAEP && > + op->rsa.op_type != RTE_CRYPTO_ASYM_OP_ENCRYPT > && > + op->rsa.op_type != RTE_CRYPTO_ASYM_OP_DECRYPT) > { > + OPENSSL_LOG(ERR, "OAEP supports encrypt/decrypt only"); > + cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; > + return ret; > + } > + > switch (pad) { > case RTE_CRYPTO_RSA_PADDING_PKCS1_5: > pad = RSA_PKCS1_PADDING; > @@ -2315,6 +2359,9 @@ process_openssl_rsa_op_evp(struct rte_crypto_op > *cop, > case RTE_CRYPTO_RSA_PADDING_NONE: > pad = RSA_NO_PADDING; > break; > + case RTE_CRYPTO_RSA_PADDING_OAEP: > + pad = RSA_PKCS1_OAEP_PADDING; > + break; > default: > cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; > OPENSSL_LOG(ERR, > @@ -2330,6 +2377,9 @@ process_openssl_rsa_op_evp(struct rte_crypto_op > *cop, > if (EVP_PKEY_CTX_set_rsa_padding(rsa_ctx, pad) <= 0) > goto err_rsa; > > + if (openssl_rsa_set_oaep_params(rsa_ctx, sess) < 0) > + goto err_rsa; > + > if (EVP_PKEY_encrypt(rsa_ctx, NULL, &outlen, > op->rsa.message.data, > op->rsa.message.length) <= 0) > @@ -2355,6 +2405,9 @@ process_openssl_rsa_op_evp(struct rte_crypto_op > *cop, > if (EVP_PKEY_CTX_set_rsa_padding(rsa_ctx, pad) <= 0) > goto err_rsa; > > + if (openssl_rsa_set_oaep_params(rsa_ctx, sess) < 0) > + goto err_rsa; > + > if (EVP_PKEY_decrypt(rsa_ctx, NULL, &outlen, > op->rsa.cipher.data, > op->rsa.cipher.length) <= 0) > diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c > b/drivers/crypto/openssl/rte_openssl_pmd_ops.c > index 60d33f3474..902b46918d 100644 > --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c > +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c > @@ -2,6 +2,7 @@ > * Copyright(c) 2016-2017 Intel Corporation > */ > > +#include <limits.h> > #include <string.h> > > #include <rte_common.h> > @@ -1208,6 +1209,33 @@ openssl_pmd_sym_session_configure(struct > rte_cryptodev *dev, > return 0; > } > > +static const EVP_MD * > +openssl_get_md(enum rte_crypto_auth_algorithm alg) > +{ > + switch (alg) { > + case RTE_CRYPTO_AUTH_SHA1: > + return EVP_sha1(); > + case RTE_CRYPTO_AUTH_SHA224: > + return EVP_sha224(); > + case RTE_CRYPTO_AUTH_SHA256: > + return EVP_sha256(); > + case RTE_CRYPTO_AUTH_SHA384: > + return EVP_sha384(); > + case RTE_CRYPTO_AUTH_SHA512: > + return EVP_sha512(); > + case RTE_CRYPTO_AUTH_SHA3_224: > + return EVP_sha3_224(); > + case RTE_CRYPTO_AUTH_SHA3_256: > + return EVP_sha3_256(); > + case RTE_CRYPTO_AUTH_SHA3_384: > + return EVP_sha3_384(); > + case RTE_CRYPTO_AUTH_SHA3_512: > + return EVP_sha3_512(); > + default: > + return NULL; > + } > +} > + > static int openssl_set_asym_session_parameters( > struct openssl_asym_session *asym_session, > struct rte_crypto_asym_xform *xform) > @@ -1229,6 +1257,7 @@ static int openssl_set_asym_session_parameters( > BIGNUM *d = NULL; > BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL; > BIGNUM *iqmp = NULL, *dmq1 = NULL; > + uint32_t label_len = 0; > > /* copy xfrm data into rsa struct */ > n = BN_bin2bn((const unsigned char *)xform->rsa.n.data, > @@ -1240,6 +1269,57 @@ static int openssl_set_asym_session_parameters( > goto err_rsa; > > asym_session->u.r.pad = xform->rsa.padding.type; > + if (xform->rsa.padding.type == > RTE_CRYPTO_RSA_PADDING_OAEP) { > + asym_session->u.r.oaep_md = openssl_get_md(xform- > >rsa.padding.hash); > + > + if (asym_session->u.r.oaep_md == NULL) { > + OPENSSL_LOG(ERR, > + "Unsupported OAEP hash algorithm > %u", > + xform->rsa.padding.hash); > + goto err_rsa; > + } > + > + enum rte_crypto_auth_algorithm mgf1 = xform- > >rsa.padding.mgf1hash; Move the definitions at start of functions. I see there are 3-4 such instances in this and subsequent patches. > + > + if (mgf1 == 0) > + mgf1 = xform->rsa.padding.hash; > + > + asym_session->u.r.mgf1_md = openssl_get_md(mgf1); > + if (asym_session->u.r.mgf1_md == NULL) { > + OPENSSL_LOG(ERR, > + "Unsupported OAEP MGF1 hash > algorithm %u", mgf1); > + goto err_rsa; > + } > + > + if (xform->rsa.padding.oaep_label.length > > (size_t)INT_MAX) { > + OPENSSL_LOG(ERR, > + "OAEP label length %zu is too large", > + xform->rsa.padding.oaep_label.length); > + goto err_rsa; > + } > + > + label_len = (uint32_t)xform- > >rsa.padding.oaep_label.length; > + if (label_len > 0) { > + if (xform->rsa.padding.oaep_label.data == > NULL) { > + OPENSSL_LOG(ERR, > + "OAEP label length is non-zero > but data is NULL"); > + goto err_rsa; > + } > + > + asym_session->u.r.label = > OPENSSL_zalloc(label_len); > + if (asym_session->u.r.label == NULL) > + goto err_rsa; > + > + rte_memcpy(asym_session->u.r.label, > + xform->rsa.padding.oaep_label.data, > + label_len); I think you can use memcpy instead of rte_memcpy. > + asym_session->u.r.label_len = label_len; > + } else { > + asym_session->u.r.label_len = 0; > + asym_session->u.r.label = NULL; > + } > + } > + > OSSL_PARAM_BLD * param_bld = OSSL_PARAM_BLD_new(); > if (!param_bld) { > OPENSSL_LOG(ERR, "failed to allocate resources"); > @@ -1342,6 +1422,11 @@ static int openssl_set_asym_session_parameters( > ret = 0; > > err_rsa: > + if (ret != 0 && asym_session->u.r.label) { > + OPENSSL_free(asym_session->u.r.label); > + asym_session->u.r.label = NULL; > + asym_session->u.r.label_len = 0; > + } > BN_clear_free(n); > BN_clear_free(e); > BN_clear_free(d); > @@ -1817,6 +1902,11 @@ static void openssl_reset_asym_session(struct > openssl_asym_session *sess) > switch (sess->xfrm_type) { > case RTE_CRYPTO_ASYM_XFORM_RSA: > EVP_PKEY_CTX_free(sess->u.r.ctx); > + if (sess->u.r.label_len > 0) { > + OPENSSL_free(sess->u.r.label); > + sess->u.r.label = NULL; > + sess->u.r.label_len = 0; > + } > break; > case RTE_CRYPTO_ASYM_XFORM_MODEX: > if (sess->u.e.ctx) { > -- > 2.54.0

