]> git.droids-corp.org - dpdk.git/commitdiff
crypto/openssl: update DSA routine with 3.0 EVP API
authorKai Ji <kai.ji@intel.com>
Tue, 21 Jun 2022 15:42:14 +0000 (23:42 +0800)
committerAkhil Goyal <gakhil@marvell.com>
Tue, 21 Jun 2022 18:04:50 +0000 (20:04 +0200)
This patch updates asymmetric DSA routine in crypto openssl pmd
to adopt openssl 3.0 EVP apis. Divided the single combined DSA sign
test to two individual DSA sign and DSA verfiy tests.

Signed-off-by: Kai Ji <kai.ji@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Akhil Goyal <gakhil@marvell.com>
app/test/test_cryptodev_asym.c
doc/guides/rel_notes/release_22_07.rst
drivers/crypto/openssl/compat.h
drivers/crypto/openssl/openssl_pmd_private.h
drivers/crypto/openssl/rte_openssl_pmd.c
drivers/crypto/openssl/rte_openssl_pmd_ops.c

index 41e9e58346c4283a8b9069a895a6e89299358c51..e4b3c211df3e67ac9f300a968f2bad03ec92bdd4 100644 (file)
@@ -1640,7 +1640,7 @@ test_dh_keygenration(void)
 }
 
 static int
-test_dsa_sign(void)
+test_dsa_sign(struct rte_crypto_dsa_op_param *dsa_op)
 {
        struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
        struct rte_mempool *op_mpool = ts_params->op_mpool;
@@ -1650,9 +1650,6 @@ test_dsa_sign(void)
        struct rte_crypto_op *op = NULL, *result_op = NULL;
        void *sess = NULL;
        int status = TEST_SUCCESS;
-       uint8_t r[TEST_DH_MOD_LEN];
-       uint8_t s[TEST_DH_MOD_LEN];
-       uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
        int ret;
 
        ret = rte_cryptodev_asym_session_create(dev_id, &dsa_xform, sess_mpool, &sess);
@@ -1674,6 +1671,7 @@ test_dsa_sign(void)
                goto error_exit;
        }
        asym_op = op->asym;
+       asym_op->dsa = *dsa_op;
 
        debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
                        dsa_xform.dsa.p.length);
@@ -1687,13 +1685,6 @@ test_dsa_sign(void)
        /* attach asymmetric crypto session to crypto operations */
        rte_crypto_op_attach_asym_session(op, sess);
        asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
-       asym_op->dsa.message.data = dgst;
-       asym_op->dsa.message.length = sizeof(dgst);
-       asym_op->dsa.r.length = sizeof(r);
-       asym_op->dsa.r.data = r;
-       asym_op->dsa.s.length = sizeof(s);
-       asym_op->dsa.s.data = s;
-
        RTE_LOG(DEBUG, USER1, "Process ASYM operation");
 
        /* Process crypto operation */
@@ -1717,12 +1708,71 @@ test_dsa_sign(void)
        }
 
        asym_op = result_op->asym;
+       dsa_op->r.length = asym_op->dsa.r.length;
+       dsa_op->s.length = asym_op->dsa.s.length;
 
        debug_hexdump(stdout, "r:",
                        asym_op->dsa.r.data, asym_op->dsa.r.length);
        debug_hexdump(stdout, "s:",
                        asym_op->dsa.s.data, asym_op->dsa.s.length);
+error_exit:
+       if (sess != NULL)
+               rte_cryptodev_asym_session_free(dev_id, sess);
+       if (op != NULL)
+               rte_crypto_op_free(op);
+       return status;
+}
+
+static int
+test_dsa_verify(struct rte_crypto_dsa_op_param *dsa_op)
+{
+       struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+       struct rte_mempool *op_mpool = ts_params->op_mpool;
+       struct rte_mempool *sess_mpool = ts_params->session_mpool;
+       uint8_t dev_id = ts_params->valid_devs[0];
+       struct rte_crypto_asym_op *asym_op = NULL;
+       struct rte_crypto_op *op = NULL, *result_op = NULL;
+       void *sess = NULL;
+       int status = TEST_SUCCESS;
+       int ret;
 
+       ret = rte_cryptodev_asym_session_create(dev_id, &dsa_xform, sess_mpool, &sess);
+       if (ret < 0) {
+               RTE_LOG(ERR, USER1,
+                                "line %u FAILED: %s", __LINE__,
+                               "Session creation failed");
+               status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+               goto error_exit;
+       }
+       /* set up crypto op data structure */
+       op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+       if (!op) {
+               RTE_LOG(ERR, USER1,
+                       "line %u FAILED: %s",
+                       __LINE__, "Failed to allocate asymmetric crypto "
+                       "operation struct");
+               status = TEST_FAILED;
+               goto error_exit;
+       }
+       asym_op = op->asym;
+       asym_op->dsa = *dsa_op;
+
+       debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
+                       dsa_xform.dsa.p.length);
+       debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data,
+                       dsa_xform.dsa.q.length);
+       debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data,
+                       dsa_xform.dsa.g.length);
+
+       /* attach asymmetric crypto session to crypto operations */
+       rte_crypto_op_attach_asym_session(op, sess);
+
+       debug_hexdump(stdout, "r:",
+                       asym_op->dsa.r.data, asym_op->dsa.r.length);
+       debug_hexdump(stdout, "s:",
+                       asym_op->dsa.s.data, asym_op->dsa.s.length);
+
+       RTE_LOG(DEBUG, USER1, "Process ASYM verify operation");
        /* Test PMD DSA sign verification using signer public key */
        asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
 
@@ -1768,8 +1818,22 @@ static int
 test_dsa(void)
 {
        int status;
-       status = test_dsa_sign();
-       TEST_ASSERT_EQUAL(status, 0, "Test failed");
+       uint8_t r[TEST_DH_MOD_LEN];
+       uint8_t s[TEST_DH_MOD_LEN];
+       struct rte_crypto_dsa_op_param dsa_op;
+       uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
+
+       dsa_op.message.data = dgst;
+       dsa_op.message.length = sizeof(dgst);
+       dsa_op.r.data = r;
+       dsa_op.s.data = s;
+       dsa_op.r.length = sizeof(r);
+       dsa_op.s.length = sizeof(s);
+
+       status = test_dsa_sign(&dsa_op);
+       TEST_ASSERT_EQUAL(status, 0, "DSA sign test failed");
+       status = test_dsa_verify(&dsa_op);
+       TEST_ASSERT_EQUAL(status, 0, "DSA verify test failed");
        return status;
 }
 
index e64e9b8e08b9ad03c471d59bf41c4f95fe452769..4d50aa2c028e884aabb621209a983bdf14baf62c 100644 (file)
@@ -177,6 +177,11 @@ New Features
   Added support for Elliptic Curve Diffie Hellman (ECDH) asymmetric
   algorithm in cryptodev.
 
+* **Updated OpenSSL crypto driver with 3.0 EVP API.**
+
+  Updated OpenSSL driver to support OpenSSL v3.0 EVP API.
+  Backward compatibility with OpenSSL v1.1.1 is also maintained.
+
 * **Updated Marvell cnxk crypto driver.**
 
   * Added AH mode support in lookaside protocol (IPsec) for CN9K & CN10K.
index eecb7d36989b91e6a31a10d2ee0ff52231baefa6..9f9167c4f1faac0cf9d25fd79baee67af68a3729 100644 (file)
@@ -104,6 +104,18 @@ get_dsa_priv_key(DSA *dsa, BIGNUM **priv_key)
        *priv_key = dsa->priv_key;
 }
 
+#elif (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+static __rte_always_inline void
+set_dsa_sign(DSA_SIG *sign, BIGNUM *r, BIGNUM *s)
+{
+       DSA_SIG_set0(sign, r, s);
+}
+
+static __rte_always_inline void
+get_dsa_sign(DSA_SIG *sign, const BIGNUM **r, const BIGNUM **s)
+{
+       DSA_SIG_get0(sign, r, s);
+}
 #else
 
 static __rte_always_inline int
index b952188c9d250e61d1d372d2e45fe743c36bccfd..5963a67a0889143a9a90a299bbc034820cc6141b 100644 (file)
@@ -184,6 +184,9 @@ struct openssl_asym_session {
                } dh;
                struct {
                        DSA *dsa;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+                       OSSL_PARAM_BLD * param_bld;
+#endif
                } s;
        } u;
 } __rte_cache_aligned;
index 375dc9cfdc4a43d48c2b790fdd58af0920fa2e93..84bca8689423edb351b7511cf0e9403153ebaa2d 100644 (file)
@@ -2,8 +2,6 @@
  * Copyright(c) 2016-2017 Intel Corporation
  */
 
-#define OPENSSL_API_COMPAT 0x10100000L
-
 #include <rte_common.h>
 #include <rte_hexdump.h>
 #include <rte_cryptodev.h>
@@ -1764,6 +1762,171 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 }
 
 /* process dsa sign operation */
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+static int
+process_openssl_dsa_sign_op_evp(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+       EVP_PKEY_CTX *dsa_ctx = NULL;
+       EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
+       EVP_PKEY *pkey = NULL;
+       OSSL_PARAM_BLD *param_bld = sess->u.s.param_bld;
+       OSSL_PARAM *params = NULL;
+
+       size_t outlen;
+       unsigned char *dsa_sign_data;
+       const unsigned char *dsa_sign_data_p;
+
+       cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+       params = OSSL_PARAM_BLD_to_param(param_bld);
+       if (!params) {
+               OSSL_PARAM_BLD_free(param_bld);
+               return -1;
+       }
+
+       if (key_ctx == NULL
+               || EVP_PKEY_fromdata_init(key_ctx) <= 0
+               || EVP_PKEY_fromdata(key_ctx, &pkey,
+                                               EVP_PKEY_PUBLIC_KEY, params) <= 0)
+               goto err_dsa_sign;
+
+       dsa_ctx = EVP_PKEY_CTX_new(pkey, NULL);
+       if (!dsa_ctx)
+               goto err_dsa_sign;
+
+       if (EVP_PKEY_sign_init(dsa_ctx) <= 0)
+               goto err_dsa_sign;
+
+       if (EVP_PKEY_sign(dsa_ctx, NULL, &outlen, op->message.data,
+                                               op->message.length) <= 0)
+               goto err_dsa_sign;
+
+       if (outlen <= 0)
+               goto err_dsa_sign;
+
+       dsa_sign_data = OPENSSL_malloc(outlen);
+       if (!dsa_sign_data)
+               goto err_dsa_sign;
+
+       if (EVP_PKEY_sign(dsa_ctx, dsa_sign_data, &outlen, op->message.data,
+                                               op->message.length) <= 0) {
+               free(dsa_sign_data);
+               goto err_dsa_sign;
+       }
+
+       dsa_sign_data_p = (const unsigned char *)dsa_sign_data;
+       DSA_SIG *sign = d2i_DSA_SIG(NULL, &dsa_sign_data_p, outlen);
+       if (!sign) {
+               OPENSSL_LOG(ERR, "%s:%d\n", __func__, __LINE__);
+               free(dsa_sign_data);
+               goto err_dsa_sign;
+       } else {
+               const BIGNUM *r = NULL, *s = NULL;
+               get_dsa_sign(sign, &r, &s);
+
+               op->r.length = BN_bn2bin(r, op->r.data);
+               op->s.length = BN_bn2bin(s, op->s.data);
+               cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+       }
+
+       DSA_SIG_free(sign);
+       free(dsa_sign_data);
+       return 0;
+
+err_dsa_sign:
+       if (params)
+               OSSL_PARAM_free(params);
+       if (key_ctx)
+               EVP_PKEY_CTX_free(key_ctx);
+       if (dsa_ctx)
+               EVP_PKEY_CTX_free(dsa_ctx);
+       return -1;
+}
+
+/* process dsa verify operation */
+static int
+process_openssl_dsa_verify_op_evp(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+       DSA_SIG *sign = DSA_SIG_new();
+       BIGNUM *r = NULL, *s = NULL;
+       BIGNUM *pub_key = NULL;
+       OSSL_PARAM_BLD *param_bld = sess->u.s.param_bld;
+       OSSL_PARAM *params = NULL;
+       EVP_PKEY *pkey = NULL;
+       EVP_PKEY_CTX *dsa_ctx = NULL;
+       EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
+       unsigned char *dsa_sig = NULL;
+       size_t sig_len;
+       int ret = -1;
+
+       cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+       if (!param_bld) {
+               OPENSSL_LOG(ERR, " %s:%d\n", __func__, __LINE__);
+               return -1;
+       }
+
+       r = BN_bin2bn(op->r.data, op->r.length, r);
+       s = BN_bin2bn(op->s.data, op->s.length, s);
+       pub_key = BN_bin2bn(op->y.data, op->y.length, pub_key);
+       if (!r || !s || !pub_key) {
+               BN_free(r);
+               BN_free(s);
+               BN_free(pub_key);
+               OSSL_PARAM_BLD_free(param_bld);
+               goto err_dsa_verify;
+       }
+
+       set_dsa_sign(sign, r, s);
+       if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key)) {
+               OSSL_PARAM_BLD_free(param_bld);
+               goto err_dsa_verify;
+       }
+
+       params = OSSL_PARAM_BLD_to_param(param_bld);
+       if (!params) {
+               OSSL_PARAM_BLD_free(param_bld);
+               goto err_dsa_verify;
+       }
+
+       if (key_ctx == NULL
+               || EVP_PKEY_fromdata_init(key_ctx) <= 0
+               || EVP_PKEY_fromdata(key_ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+               goto err_dsa_verify;
+
+       dsa_ctx = EVP_PKEY_CTX_new(pkey, NULL);
+       if (!dsa_ctx)
+               goto err_dsa_verify;
+
+       if (!sign)
+               goto err_dsa_verify;
+
+       sig_len = i2d_DSA_SIG(sign, &dsa_sig);
+       if (EVP_PKEY_verify_init(dsa_ctx) <= 0)
+               goto err_dsa_verify;
+
+       ret = EVP_PKEY_verify(dsa_ctx, dsa_sig, sig_len,
+                                       op->message.data, op->message.length);
+       if (ret == 1) {
+               cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+               ret = 0;
+       }
+
+err_dsa_verify:
+       if (sign)
+               DSA_SIG_free(sign);
+       if (params)
+               OSSL_PARAM_free(params);
+       if (key_ctx)
+               EVP_PKEY_CTX_free(key_ctx);
+       if (dsa_ctx)
+               EVP_PKEY_CTX_free(dsa_ctx);
+
+       return ret;
+}
+#else
 static int
 process_openssl_dsa_sign_op(struct rte_crypto_op *cop,
                struct openssl_asym_session *sess)
@@ -1845,6 +2008,7 @@ process_openssl_dsa_verify_op(struct rte_crypto_op *cop,
 
        return 0;
 }
+#endif
 
 /* process dh operation */
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -2501,6 +2665,14 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 #endif
                break;
        case RTE_CRYPTO_ASYM_XFORM_DSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+                       retval = process_openssl_dsa_sign_op_evp(op, sess);
+               else if (op->asym->dsa.op_type ==
+                               RTE_CRYPTO_ASYM_OP_VERIFY)
+                       retval =
+                               process_openssl_dsa_verify_op_evp(op, sess);
+#else
                if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
                        retval = process_openssl_dsa_sign_op(op, sess);
                else if (op->asym->dsa.op_type ==
@@ -2509,6 +2681,7 @@ 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;
        default:
                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
index 6f5267a63a3abdf24e2815e6df1561b4b9355996..8d1f8e834a77ea9df71046b42573c23e6e27a63a 100644 (file)
@@ -812,13 +812,13 @@ static int openssl_set_asym_session_parameters(
                struct openssl_asym_session *asym_session,
                struct rte_crypto_asym_xform *xform)
 {
-       int ret = 0;
+       int ret = -1;
 
        if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) &&
                (xform->next != NULL)) {
                OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
                        rte_crypto_asym_xform_strings[xform->xform_type]);
-               return -1;
+               return ret;
        }
 
        switch (xform->xform_type) {
@@ -1003,7 +1003,7 @@ static int openssl_set_asym_session_parameters(
                if (ret) {
                        OPENSSL_LOG(ERR, "Failed to load rsa keys\n");
                        RSA_free(rsa);
-                       return -1;
+                       return ret;
                }
                asym_session->u.r.rsa = rsa;
                asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA;
@@ -1029,7 +1029,7 @@ err_rsa:
                if (ctx == NULL) {
                        OPENSSL_LOG(ERR,
                                " failed to allocate resources\n");
-                       return -1;
+                       return ret;
                }
                BN_CTX_start(ctx);
                BIGNUM *mod = BN_CTX_get(ctx);
@@ -1037,7 +1037,7 @@ err_rsa:
                if (mod == NULL || exp == NULL) {
                        BN_CTX_end(ctx);
                        BN_CTX_free(ctx);
-                       return -1;
+                       return ret;
                }
 
                mod = BN_bin2bn((const unsigned char *)
@@ -1060,14 +1060,14 @@ err_rsa:
                if (ctx == NULL) {
                        OPENSSL_LOG(ERR,
                                " failed to allocate resources\n");
-                       return -1;
+                       return ret;
                }
                BN_CTX_start(ctx);
                BIGNUM *mod = BN_CTX_get(ctx);
                if (mod == NULL) {
                        BN_CTX_end(ctx);
                        BN_CTX_free(ctx);
-                       return -1;
+                       return ret;
                }
 
                mod = BN_bin2bn((const unsigned char *)
@@ -1158,6 +1158,56 @@ err_dh:
        }
        case RTE_CRYPTO_ASYM_XFORM_DSA:
        {
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               BIGNUM *p = NULL, *g = NULL;
+               BIGNUM *q = NULL, *priv_key = NULL;
+               BIGNUM *pub_key = BN_new();
+               BN_zero(pub_key);
+               OSSL_PARAM_BLD *param_bld = NULL;
+
+               p = BN_bin2bn((const unsigned char *)
+                               xform->dsa.p.data,
+                               xform->dsa.p.length,
+                               p);
+
+               g = BN_bin2bn((const unsigned char *)
+                               xform->dsa.g.data,
+                               xform->dsa.g.length,
+                               g);
+
+               q = BN_bin2bn((const unsigned char *)
+                               xform->dsa.q.data,
+                               xform->dsa.q.length,
+                               q);
+               if (!p || !q || !g)
+                       goto err_dsa;
+
+               priv_key = BN_bin2bn((const unsigned char *)
+                               xform->dsa.x.data,
+                               xform->dsa.x.length,
+                               priv_key);
+               if (priv_key == NULL)
+                       goto err_dsa;
+
+               param_bld = OSSL_PARAM_BLD_new();
+               if (!param_bld) {
+                       OPENSSL_LOG(ERR, "failed to allocate resources\n");
+                       goto err_dsa;
+               }
+
+               if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p)
+                       || !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g)
+                       || !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q)
+                       || !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key)) {
+                       OSSL_PARAM_BLD_free(param_bld);
+                       OPENSSL_LOG(ERR, "failed to allocate resources\n");
+                       goto err_dsa;
+               }
+               asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
+               asym_session->u.s.param_bld = param_bld;
+
+               break;
+#else
                BIGNUM *p = NULL, *g = NULL;
                BIGNUM *q = NULL, *priv_key = NULL;
                BIGNUM *pub_key = BN_new();
@@ -1217,7 +1267,7 @@ err_dh:
                asym_session->u.s.dsa = dsa;
                asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
                break;
-
+#endif
 err_dsa:
                BN_free(p);
                BN_free(q);
@@ -1227,7 +1277,7 @@ err_dsa:
                return -1;
        }
        default:
-               return -1;
+               return ret;
        }
 
        return 0;
@@ -1310,8 +1360,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #endif
                break;
        case RTE_CRYPTO_ASYM_XFORM_DSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               sess->u.s.param_bld = NULL;
+#else
                if (sess->u.s.dsa)
                        DSA_free(sess->u.s.dsa);
+#endif
                break;
        default:
                break;