From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0620EA0032; Fri, 18 Feb 2022 10:44:15 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C4B2240E28; Fri, 18 Feb 2022 10:44:14 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id 9EE0140395 for ; Fri, 18 Feb 2022 10:44:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645177453; x=1676713453; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=seSkIfPlZBhXiEvVNPjxi3JyYUVT8H1TVaMLIwMV8IU=; b=Z2255UqtS5kkulnsQ8/lcNG1kEPxEy7UaS0JLD6UM/CwUZFAcKbi8BfI smK7ErkQ+QQHuO4PfOrQ1EbwuAcHAuEdtrGhsGks3ZgXfo4cqT4dnQNhz qv7M/EyAA7twH3OwAbTrs58nabPtv1SyKciw0gSnfR+NJ1iNfRiYj67B7 f6qftihighz8BhkuSMGftsrVqV3lrOOUkbHqIh0PKjO9WuXG5QuIn5oQO d8MV42cD6KWGuJMNU1eLidlxHiK8Jz8tJ+kXdxNGs7/NRffJ6XkM0NBv5 ui1+wVS8GpwUTs71dTEzbw761dlWZc9dYWKPH/Zh6JPYhjNp5LuAQBsu2 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10261"; a="248690156" X-IronPort-AV: E=Sophos;i="5.88,378,1635231600"; d="scan'208";a="248690156" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2022 01:44:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,378,1635231600"; d="scan'208";a="637692046" Received: from silpixa00400465.ir.intel.com ([10.55.128.22]) by orsmga004.jf.intel.com with ESMTP; 18 Feb 2022 01:44:10 -0800 From: Kai Ji To: dev@dpdk.org Cc: gakhil@marvell.com, roy.fan.zhang@intel.com, Kai Ji Subject: [dpdk-dev v4] crypto/openssl: openssl 3.0 support on sym crypto routine Date: Fri, 18 Feb 2022 17:44:08 +0800 Message-Id: <20220218094408.49290-1-kai.ji@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220217174552.50903-1-kai.ji@intel.com> References: <20220217174552.50903-1-kai.ji@intel.com> 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 update the symmetric EVP routine in crypto openssl pmd to adopt openssl 3.0 library. Signed-off-by: Kai Ji v4: - code comments addressed v3: - rebase to 22.03-RC1 - enable openssl 3.0 lagacy library of DES - remove local ctx in combined op as EVP_CIPHER_CTX_copy refuse copy without a valid dup function pointer. v2: - minor code fix --- drivers/crypto/openssl/compat.h | 10 ++ drivers/crypto/openssl/openssl_pmd_private.h | 4 + drivers/crypto/openssl/rte_openssl_pmd.c | 177 +++++++++++++++++-- 3 files changed, 181 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/openssl/compat.h b/drivers/crypto/openssl/compat.h index eecb7d3698..0674dd6c5d 100644 --- a/drivers/crypto/openssl/compat.h +++ b/drivers/crypto/openssl/compat.h @@ -192,6 +192,16 @@ get_dsa_priv_key(DSA *dsa, const BIGNUM **priv_key) DSA_get0_key(dsa, NULL, priv_key); } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +/* Known DIGEST names (not a complete list) */ +#define OSSL_DIGEST_NAME_MD5 "MD5" +#define OSSL_DIGEST_NAME_MD5_SHA1 "MD5-SHA1" +#define OSSL_DIGEST_NAME_SHA1 "SHA1" +#define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224" +#define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256" +#define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384" +#define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512" +#endif #endif /* version < 10100000 */ #endif /* __RTA_COMPAT_H__ */ diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h index b2054b3754..86dc169aaf 100644 --- a/drivers/crypto/openssl/openssl_pmd_private.h +++ b/drivers/crypto/openssl/openssl_pmd_private.h @@ -134,8 +134,12 @@ struct openssl_session { /**< pointer to EVP key */ const EVP_MD *evp_algo; /**< pointer to EVP algorithm function */ +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC_CTX * ctx; +# else HMAC_CTX *ctx; /**< pointer to EVP context structure */ +# endif } hmac; }; diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index 5794ed8159..2c5dea8cd3 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -39,6 +39,57 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) } #endif +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include + +OSSL_PROVIDER *legacy; +OSSL_PROVIDER *deflt; + +static void ossl_load_legacy_provider(void) +{ + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) { + OPENSSL_LOG(ERR, "Failed to load Legacy provider\n"); + return -EINVAL; + } + + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + OPENSSL_LOG(ERR, "Failed to load Default provider\n"); + OSSL_PROVIDER_unload(legacy); + return -EINVAL; + } +} + +static void ossl_unload_legacy_provider(void) +{ + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); +} + +static __rte_always_inline const char * +get_digest_name(const struct rte_crypto_sym_xform *xform) +{ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_MD5_HMAC: + return OSSL_DIGEST_NAME_MD5; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + return OSSL_DIGEST_NAME_SHA1; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + return OSSL_DIGEST_NAME_SHA2_224; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + return OSSL_DIGEST_NAME_SHA2_256; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + return OSSL_DIGEST_NAME_SHA2_384; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + return OSSL_DIGEST_NAME_SHA2_512; + default: + return NULL; + } +} +#endif + static int cryptodev_openssl_remove(struct rte_vdev_device *vdev); /*----------------------------------------------------------------------------*/ @@ -580,6 +631,34 @@ openssl_set_session_auth_parameters(struct openssl_session *sess, sess->auth.auth.ctx = EVP_MD_CTX_create(); break; +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = OPENSSL_AUTH_AS_HMAC; + + OSSL_PARAM params[2]; + const char *algo = get_digest_name(xform); + EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL); + sess->auth.hmac.ctx = EVP_MAC_CTX_new(mac); + EVP_MAC_free(mac); + if (get_auth_algo(xform->auth.algo, + &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + + params[0] = OSSL_PARAM_construct_utf8_string("digest", + (char *)algo, 0); + params[1] = OSSL_PARAM_construct_end(); + if (EVP_MAC_init(sess->auth.hmac.ctx, + xform->auth.key.data, + xform->auth.key.length, + params) != 1) + return -EINVAL; + break; +# else case RTE_CRYPTO_AUTH_MD5_HMAC: case RTE_CRYPTO_AUTH_SHA1_HMAC: case RTE_CRYPTO_AUTH_SHA224_HMAC: @@ -598,7 +677,7 @@ openssl_set_session_auth_parameters(struct openssl_session *sess, sess->auth.hmac.evp_algo, NULL) != 1) return -EINVAL; break; - +# endif default: return -ENOTSUP; } @@ -723,7 +802,11 @@ openssl_reset_session(struct openssl_session *sess) break; case OPENSSL_AUTH_AS_HMAC: EVP_PKEY_free(sess->auth.hmac.pkey); +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC_CTX_free(sess->auth.hmac.ctx); +# else HMAC_CTX_free(sess->auth.hmac.ctx); +# endif break; default: break; @@ -1262,6 +1345,59 @@ process_openssl_auth(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, return -EINVAL; } +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +/** Process standard openssl auth algorithms with hmac */ +static int +process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, + int srclen, EVP_MAC_CTX *ctx) +{ + size_t dstlen; + struct rte_mbuf *m; + int l, n = srclen; + uint8_t *src; + + for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m); + m = m->next) + offset -= rte_pktmbuf_data_len(m); + + if (m == 0) + goto process_auth_err; + + src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset); + + l = rte_pktmbuf_data_len(m) - offset; + if (srclen <= l) { + if (EVP_MAC_update(ctx, (unsigned char *)src, srclen) != 1) + goto process_auth_err; + goto process_auth_final; + } + + if (EVP_MAC_update(ctx, (unsigned char *)src, l) != 1) + goto process_auth_err; + + n -= l; + + for (m = m->next; (m != NULL) && (n > 0); m = m->next) { + src = rte_pktmbuf_mtod(m, uint8_t *); + l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n; + if (EVP_MAC_update(ctx, (unsigned char *)src, l) != 1) + goto process_auth_err; + n -= l; + } + +process_auth_final: + if (EVP_MAC_final(ctx, dst, &dstlen, sizeof(dst)) != 1) + goto process_auth_err; + + EVP_MAC_CTX_free(ctx); + return 0; + +process_auth_err: + EVP_MAC_CTX_free(ctx); + OPENSSL_LOG(ERR, "Process openssl auth failed"); + return -EINVAL; +} +# else /** Process standard openssl auth algorithms with hmac */ static int process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, @@ -1314,7 +1450,7 @@ process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, OPENSSL_LOG(ERR, "Process openssl auth failed"); return -EINVAL; } - +# endif /*----------------------------------------------------------------------------*/ /** Process auth/cipher combined operation */ @@ -1328,7 +1464,6 @@ process_openssl_combined_op int srclen, aadlen, status = -1; uint32_t offset; uint8_t taglen; - EVP_CIPHER_CTX *ctx_copy; /* * Segmented destination buffer is not supported for @@ -1365,8 +1500,6 @@ process_openssl_combined_op } taglen = sess->auth.digest_length; - ctx_copy = EVP_CIPHER_CTX_new(); - EVP_CIPHER_CTX_copy(ctx_copy, sess->cipher.ctx); if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || @@ -1374,12 +1507,12 @@ process_openssl_combined_op status = process_openssl_auth_encryption_gcm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, ctx_copy); + dst, tag, sess->cipher.ctx); else status = process_openssl_auth_encryption_ccm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, taglen, ctx_copy); + dst, tag, taglen, sess->cipher.ctx); } else { if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC || @@ -1387,15 +1520,14 @@ process_openssl_combined_op status = process_openssl_auth_decryption_gcm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, ctx_copy); + dst, tag, sess->cipher.ctx); else status = process_openssl_auth_decryption_ccm( mbuf_src, offset, srclen, aad, aadlen, iv, - dst, tag, taglen, ctx_copy); + dst, tag, taglen, sess->cipher.ctx); } - EVP_CIPHER_CTX_free(ctx_copy); if (status != 0) { if (status == (-EFAULT) && sess->auth.operation == @@ -1557,7 +1689,12 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, uint8_t *dst; int srclen, status; EVP_MD_CTX *ctx_a; +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC_CTX *ctx_h; + EVP_MAC *mac; +# else HMAC_CTX *ctx_h; +# endif srclen = op->sym->auth.data.length; @@ -1573,12 +1710,22 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, EVP_MD_CTX_destroy(ctx_a); break; case OPENSSL_AUTH_AS_HMAC: +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + mac = EVP_MAC_fetch(NULL, "HMAC", NULL); + ctx_h = EVP_MAC_CTX_new(mac); + ctx_h = EVP_MAC_CTX_dup(sess->auth.hmac.ctx); + EVP_MAC_free(mac); + status = process_openssl_auth_hmac(mbuf_src, dst, + op->sym->auth.data.offset, srclen, + ctx_h); +# else ctx_h = HMAC_CTX_new(); HMAC_CTX_copy(ctx_h, sess->auth.hmac.ctx); status = process_openssl_auth_hmac(mbuf_src, dst, op->sym->auth.data.offset, srclen, ctx_h); HMAC_CTX_free(ctx_h); +# endif break; default: status = -1; @@ -2215,6 +2362,13 @@ cryptodev_openssl_create(const char *name, rte_cryptodev_pmd_probing_finish(dev); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + /* Load legacy provider + * Some algorithms are no longer available in earlier version of openssl, + * unless the legacy provider explicitly loaded. e.g. DES + */ + ossl_load_legacy_provider(); +# endif return 0; init_error: @@ -2263,6 +2417,9 @@ cryptodev_openssl_remove(struct rte_vdev_device *vdev) if (cryptodev == NULL) return -ENODEV; +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + ossl_unload_legacy_provider(); +# endif return rte_cryptodev_pmd_destroy(cryptodev); } -- 2.17.1