DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v2 0/3] SM2 crypto algorithm support
@ 2023-05-26  9:12 Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm Gowrishankar Muthukrishnan
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-05-26  9:12 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Gowrishankar Muthukrishnan

This patch series adds SM2 crypto algorithm support, along with tests
verified using Openssl.

v2:
 - addressed suggestions in v1.

Gowrishankar Muthukrishnan (3):
  cryptodev: add SM2 asymmetric crypto algorithm
  test/crypto: add asymmetric SM2 test cases
  crypto/openssl: add SM2 asymmetric crypto support

 app/test/test_cryptodev_asym.c               | 504 +++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h   | 120 +++++
 doc/guides/cryptodevs/features/default.ini   |   1 +
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 doc/guides/cryptodevs/openssl.rst            |   1 +
 doc/guides/rel_notes/release_23_07.rst       |   9 +
 drivers/crypto/openssl/openssl_pmd_private.h |   7 +
 drivers/crypto/openssl/rte_openssl_pmd.c     | 245 +++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 101 ++++
 lib/cryptodev/rte_crypto_asym.h              |  77 +++
 lib/cryptodev/rte_cryptodev.c                |   1 +
 11 files changed, 1067 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm
  2023-05-26  9:12 [PATCH v2 0/3] SM2 crypto algorithm support Gowrishankar Muthukrishnan
@ 2023-05-26  9:12 ` Gowrishankar Muthukrishnan
  2023-05-28 17:43   ` Kusztal, ArkadiuszX
  2023-05-26  9:12 ` [PATCH v2 2/3] test/crypto: add asymmetric SM2 test cases Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 3/3] crypto/openssl: add SM2 asymmetric crypto support Gowrishankar Muthukrishnan
  2 siblings, 1 reply; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-05-26  9:12 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Gowrishankar Muthukrishnan

ShangMi 2 (SM2) is a encryption and digital signature algorithm
used in the Chinese National Standard.

Added support for asymmetric SM2 in cryptodev along with prime
field curve, as referenced in RFC:
https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/rel_notes/release_23_07.rst     |  5 ++
 lib/cryptodev/rte_crypto_asym.h            | 77 ++++++++++++++++++++++
 lib/cryptodev/rte_cryptodev.c              |  1 +
 4 files changed, 84 insertions(+)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index 523da0cfa8..a69967bb9e 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -125,6 +125,7 @@ Diffie-hellman          =
 ECDSA                   =
 ECPM                    =
 ECDH                    =
+SM2                     =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst
index a9b1293689..8b8e69d619 100644
--- a/doc/guides/rel_notes/release_23_07.rst
+++ b/doc/guides/rel_notes/release_23_07.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added SM2 asymmetric algorithm in cryptodev.**
+
+  Added support for ShamMi 2 (SM2) asymmetric crypto algorithm
+  along with prime field curve support.
+
 
 Removed Items
 -------------
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 989f38323f..35fa2c0a6d 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -119,6 +119,11 @@ enum rte_crypto_asym_xform_type {
 	/**< Elliptic Curve Point Multiplication */
 	RTE_CRYPTO_ASYM_XFORM_ECFPM,
 	/**< Elliptic Curve Fixed Point Multiplication */
+	RTE_CRYPTO_ASYM_XFORM_SM2,
+	/**< ShangMi 2
+	 * Performs Encrypt, Decrypt, Sign and Verify.
+	 * Refer to rte_crypto_asym_op_type.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -382,6 +387,20 @@ struct rte_crypto_ec_xform {
 	/**< Pre-defined ec groups */
 };
 
+/**
+ * Asymmetric SM2 transform data
+ *
+ * Structure describing SM2 xform params
+ *
+ */
+struct rte_crypto_sm2_xform {
+	rte_crypto_uint pkey;
+	/**< Private key of the signer for signature generation. */
+
+	struct rte_crypto_ec_point q;
+	/**< Public key of the signer for verification. */
+};
+
 /**
  * Operations params for modular operations:
  * exponentiation and multiplicative inverse
@@ -637,9 +656,66 @@ struct rte_crypto_asym_xform {
 		/**< EC xform parameters, used by elliptic curve based
 		 * operations.
 		 */
+
+		struct rte_crypto_sm2_xform sm2;
+		/**< SM2 xform parameters */
 	};
 };
 
+/**
+ * SM2 operation params
+ */
+struct rte_crypto_sm2_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**<
+	 * Pointer to input data
+	 * - to be encrypted for SM2 public encrypt.
+	 * - to be signed for SM2 sign generation.
+	 * - to be authenticated for SM2 sign verification.
+	 *
+	 * Pointer to output data
+	 * - for SM2 private decrypt.
+	 * In this case the underlying array should have been
+	 * allocated with enough memory to hold plaintext output
+	 * (at least encrypted text length). The message.length field
+	 * will be overwritten by the PMD with the decrypted length.
+	 */
+
+	rte_crypto_param cipher;
+	/**<
+	 * Pointer to input data
+	 * - to be decrypted for SM2 private decrypt.
+	 *
+	 * Pointer to output data
+	 * - for SM2 public encrypt.
+	 * In this case the underlying array should have been allocated
+	 * with enough memory to hold ciphertext output (at least X bytes
+	 * for prime field curve of N bytes and for message M bytes,
+	 * where X = (C1 + C2 + C3) and computed based on SM2 RFC as
+	 * C1 (1 + N + N), C2 = M, C3 = N. The cipher.length field will
+	 * be overwritten by the PMD with the encrypted length.
+	 */
+
+	rte_crypto_uint id;
+	/**< The SM2 id used by signer and verifier and is in interval (1, n-1). */
+
+	rte_crypto_uint r;
+	/**< r component of elliptic curve signature
+	 *     output : for signature generation (of at least N bytes
+	 *              where prime field length is N bytes)
+	 *     input  : for signature verification
+	 */
+	rte_crypto_uint s;
+	/**< s component of elliptic curve signature
+	 *     output : for signature generation (of at least N bytes
+	 *              where prime field length is N bytes)
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Asymmetric Cryptographic Operation.
  *
@@ -665,6 +741,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_dsa_op_param dsa;
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
+		struct rte_crypto_sm2_op_param sm2;
 	};
 	uint16_t flags;
 	/**<
diff --git a/lib/cryptodev/rte_cryptodev.c b/lib/cryptodev/rte_cryptodev.c
index a96114b2da..21cabc3ffd 100644
--- a/lib/cryptodev/rte_cryptodev.c
+++ b/lib/cryptodev/rte_cryptodev.c
@@ -299,6 +299,7 @@ crypto_asym_xform_strings[] = {
 	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
 	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
 	[RTE_CRYPTO_ASYM_XFORM_ECPM]	= "ecpm",
+	[RTE_CRYPTO_ASYM_XFORM_SM2]	= "sm2",
 };
 
 /**
-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] test/crypto: add asymmetric SM2 test cases
  2023-05-26  9:12 [PATCH v2 0/3] SM2 crypto algorithm support Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2023-05-26  9:12 ` Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 3/3] crypto/openssl: add SM2 asymmetric crypto support Gowrishankar Muthukrishnan
  2 siblings, 0 replies; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-05-26  9:12 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Gowrishankar Muthukrishnan

Added test cases and test vectors for asymmetric SM2 crypto verification.
Cases are added for sign/verify/encrypt/decrypt.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c             | 504 +++++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h | 120 +++++
 2 files changed, 624 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 9236817650..68029c9910 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -21,6 +21,7 @@
 #include "test_cryptodev_ecpm_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
+#include "test_cryptodev_sm2_test_vectors.h"
 #include "test_cryptodev_asym_util.h"
 #include "test.h"
 
@@ -2196,6 +2197,505 @@ test_ecpm_all_curve(void)
 	return overall_status;
 }
 
+static int
+test_sm2_sign(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct crypto_testsuite_sm2_params input_params = sm2_param_fp256;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	uint8_t output_buf_s[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
+	xform.sm2.pkey.data = input_params.pkey.data;
+	xform.sm2.pkey.length = input_params.pkey.length;
+	xform.sm2.q.x.data = input_params.pubkey_qx.data;
+	xform.sm2.q.x.length = input_params.pubkey_qx.length;
+	xform.sm2.q.y.data = input_params.pubkey_qy.data;
+	xform.sm2.q.y.length = input_params.pubkey_qy.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	op->asym->sm2.message.data = input_params.message.data;
+	op->asym->sm2.message.length = input_params.message.length;
+	op->asym->sm2.id.data = input_params.id.data;
+	op->asym->sm2.id.length = input_params.id.length;
+
+	/* Init out buf */
+	op->asym->sm2.r.data = output_buf_r;
+	op->asym->sm2.s.data = output_buf_s;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "r:",
+			asym_op->sm2.r.data, asym_op->sm2.r.length);
+	debug_hexdump(stdout, "s:",
+			asym_op->sm2.s.data, asym_op->sm2.s.length);
+
+	/* Verify sign (in roundtrip).
+	 * Due to random number used per message, sign op
+	 * would produce different output for same message
+	 * everytime. Hence, we can't have expected output
+	 * to match, instead reverse op to verify.
+	 */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+
+	/* Enqueue sign result for verify */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		status = TEST_FAILED;
+		goto exit;
+	}
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"SM2 verify failed.\n");
+		goto exit;
+	}
+
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_sm2_verify(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct crypto_testsuite_sm2_params input_params = sm2_param_fp256;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
+	xform.sm2.q.x.data = input_params.pubkey_qx.data;
+	xform.sm2.q.x.length = input_params.pubkey_qx.length;
+	xform.sm2.q.y.data = input_params.pubkey_qy.data;
+	xform.sm2.q.y.length = input_params.pubkey_qy.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Verify given sign */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	op->asym->sm2.message.data = input_params.message.data;
+	op->asym->sm2.message.length = input_params.message.length;
+	op->asym->sm2.r.data = input_params.sign_r.data;
+	op->asym->sm2.r.length = input_params.sign_r.length;
+	op->asym->sm2.s.data = input_params.sign_s.data;
+	op->asym->sm2.s.length = input_params.sign_s.length;
+	op->asym->sm2.id.data = input_params.id.data;
+	op->asym->sm2.id.length = input_params.id.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_sm2_encrypt(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct crypto_testsuite_sm2_params input_params = sm2_param_fp256;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t output_buf[TEST_DATA_SIZE], *pbuf = NULL;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
+	xform.sm2.pkey.data = input_params.pkey.data;
+	xform.sm2.pkey.length = input_params.pkey.length;
+	xform.sm2.q.x.data = input_params.pubkey_qx.data;
+	xform.sm2.q.x.length = input_params.pubkey_qx.length;
+	xform.sm2.q.y.data = input_params.pubkey_qy.data;
+	xform.sm2.q.y.length = input_params.pubkey_qy.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute encrypt */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
+	op->asym->sm2.message.data = input_params.message.data;
+	op->asym->sm2.message.length = input_params.message.length;
+
+	/* Init out buf */
+	op->asym->sm2.cipher.data = output_buf;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "cipher:",
+			asym_op->sm2.cipher.data, asym_op->sm2.cipher.length);
+
+	/* Verify cipher (in roundtrip).
+	 * Due to random number used per message, encrypt op
+	 * would produce different output for same message
+	 * everytime. Hence, we can't have expected output
+	 * to match, instead reverse op to decrypt.
+	 */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT;
+	pbuf = rte_malloc(NULL, TEST_DATA_SIZE, 0);
+	op->asym->sm2.message.data = pbuf;
+	op->asym->sm2.message.length = TEST_DATA_SIZE;
+
+	/* Enqueue cipher result for decrypt */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		status = TEST_FAILED;
+		goto exit;
+	}
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"SM2 encrypt failed.\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+	if (memcmp(input_params.message.data, asym_op->sm2.message.data,
+			   asym_op->sm2.message.length) != 0) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"SM2 encrypt failed.\n");
+		goto exit;
+	}
+exit:
+	if (pbuf != NULL)
+		rte_free(pbuf);
+
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_sm2_decrypt(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct crypto_testsuite_sm2_params input_params = sm2_param_fp256;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_m[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
+	xform.sm2.pkey.data = input_params.pkey.data;
+	xform.sm2.pkey.length = input_params.pkey.length;
+	xform.sm2.q.x.data = input_params.pubkey_qx.data;
+	xform.sm2.q.x.length = input_params.pubkey_qx.length;
+	xform.sm2.q.y.data = input_params.pubkey_qy.data;
+	xform.sm2.q.y.length = input_params.pubkey_qy.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute decrypt */
+
+	/* Populate op with operational details */
+	op->asym->sm2.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT;
+	op->asym->sm2.cipher.data = input_params.cipher.data;
+	op->asym->sm2.cipher.length = input_params.cipher.length;
+
+	/* Init out buf */
+	op->asym->sm2.message.data = output_buf_m;
+	op->asym->sm2.message.length = RTE_DIM(output_buf_m);
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "message:",
+			asym_op->sm2.message.data, asym_op->sm2.message.length);
+
+	if (memcmp(input_params.message.data, asym_op->sm2.message.data,
+			op->asym->sm2.message.length)) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"SM2 decrypt failed.\n");
+		goto exit;
+	}
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 	.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
 	.setup = testsuite_setup,
@@ -2205,6 +2705,10 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_dsa),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_dh_keygenration),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_sm2_encrypt),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_sm2_sign),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_sm2_verify),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_sm2_decrypt),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_rsa_enc_dec),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_rsa_sign_verify),
diff --git a/app/test/test_cryptodev_sm2_test_vectors.h b/app/test/test_cryptodev_sm2_test_vectors.h
new file mode 100644
index 0000000000..d70d3ccaa0
--- /dev/null
+++ b/app/test/test_cryptodev_sm2_test_vectors.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_SM2_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_SM2_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+struct crypto_testsuite_sm2_params {
+	rte_crypto_param pubkey_qx;
+	rte_crypto_param pubkey_qy;
+	rte_crypto_param pkey;
+	rte_crypto_param sign_r;
+	rte_crypto_param sign_s;
+	rte_crypto_param id;
+	rte_crypto_param cipher;
+	rte_crypto_param message;
+};
+
+static uint8_t fp256_pkey[] = {
+	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
+	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
+	0xec, 0x35, 0xee, 0x3b, 0x76, 0xc2, 0x34, 0x08,
+	0xd9, 0x4a, 0x22, 0x0d, 0x7f, 0xf6, 0xc6, 0x90
+};
+
+static uint8_t fp256_qx[] = {
+	0x7b, 0x24, 0xa3, 0x03, 0xcf, 0xb2, 0x22, 0xfa,
+	0x4c, 0xb3, 0x88, 0x54, 0xf9, 0x30, 0xd1, 0x4d,
+	0xe3, 0x50, 0xda, 0xba, 0xe6, 0xa7, 0x0b, 0x91,
+	0x4c, 0x04, 0x0d, 0x5c, 0xe0, 0x8e, 0x86, 0xc5
+};
+
+static uint8_t fp256_qy[] = {
+	0xbc, 0x39, 0xe3, 0x19, 0x4e, 0xd2, 0x29, 0x22,
+	0x5b, 0x37, 0x2d, 0xeb, 0xcc, 0x05, 0x52, 0x8d,
+	0xb9, 0x40, 0xa3, 0xab, 0x3c, 0xbe, 0x16, 0x30,
+	0x1c, 0xe4, 0xe8, 0x7f, 0xba, 0x6e, 0x0b, 0xae
+};
+
+static uint8_t fp256_sign_r[] = {
+	0xf3, 0x26, 0x10, 0xde, 0xfb, 0xbf, 0x13, 0xd4,
+	0x73, 0xb1, 0xc2, 0x80, 0x51, 0x06, 0x29, 0xf9,
+	0xfb, 0xc8, 0x11, 0xa7, 0x8d, 0x2c, 0xcb, 0x09,
+	0x7c, 0xb2, 0xcf, 0x58, 0x0b, 0x5e, 0x25, 0xff
+};
+
+static uint8_t fp256_sign_s[] = {
+	0x8d, 0x8d, 0xb5, 0x40, 0xe3, 0xfb, 0x98, 0xf9,
+	0x8c, 0xe4, 0x58, 0x60, 0xf2, 0x78, 0x8f, 0xd9,
+	0xbf, 0xb8, 0x47, 0x73, 0x88, 0xc1, 0xd1, 0xcd,
+	0x2d, 0xdb, 0xe3, 0xc1, 0x44, 0x30, 0x25, 0x86
+};
+
+static uint8_t fp256_id[] = {
+	0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8
+};
+
+static uint8_t fp256_message[] = {
+	0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
+	0x64, 0x69, 0x67, 0x65, 0x73, 0x74
+};
+
+static uint8_t fp256_cipher[] = {
+	0x30, 0x78, 0x02, 0x21, 0x00, 0xAB, 0xBD, 0xE8,
+	0xE8, 0x80, 0x93, 0x36, 0x77, 0xB6, 0x44, 0x47,
+	0x6D, 0x00, 0xF6, 0x51, 0xC8, 0x80, 0x9C, 0x9E,
+	0xD9, 0xEC, 0x36, 0x8A, 0x60, 0x8E, 0x26, 0x2D,
+	0x71, 0x31, 0xB7, 0xC1, 0x38, 0x02, 0x21, 0x00,
+	0xE1, 0xBF, 0x4C, 0x13, 0x7A, 0x87, 0x40, 0x32,
+	0xF5, 0xA1, 0xE2, 0xA1, 0x3B, 0x83, 0xBF, 0x6B,
+	0x3F, 0xFB, 0xC8, 0x13, 0x01, 0xDE, 0xCF, 0xC0,
+	0xF4, 0x24, 0x66, 0x52, 0x89, 0xDA, 0x6D, 0x7A,
+	0x04, 0x20, 0x8E, 0xFD, 0x52, 0x77, 0xC9, 0xE7,
+	0x90, 0xD1, 0x17, 0x75, 0xDE, 0xEE, 0xF3, 0xE5,
+	0x11, 0x0C, 0x5D, 0xE1, 0x3A, 0xB6, 0x2B, 0x72,
+	0x60, 0xE5, 0xD5, 0xF3, 0x0F, 0xE2, 0x44, 0xDB,
+	0xBC, 0x66, 0x04, 0x0E, 0x78, 0x2D, 0xC0, 0x3D,
+	0x38, 0xA2, 0x42, 0xA4, 0x8E, 0x8B, 0xF5, 0x06,
+	0x32, 0xFA
+};
+
+/** SM2 Fp256 elliptic curve test params */
+struct crypto_testsuite_sm2_params sm2_param_fp256 = {
+	.pubkey_qx = {
+		.data = fp256_qx,
+		.length = sizeof(fp256_qx),
+	},
+	.pubkey_qy = {
+		.data = fp256_qy,
+		.length = sizeof(fp256_qy),
+	},
+	.sign_r = {
+		.data = fp256_sign_r,
+		.length = sizeof(fp256_sign_r),
+	},
+	.sign_s = {
+		.data = fp256_sign_s,
+		.length = sizeof(fp256_sign_s),
+	},
+	.id = {
+		.data = fp256_id,
+		.length = sizeof(fp256_id),
+	},
+	.pkey = {
+		.data = fp256_pkey,
+		.length = sizeof(fp256_pkey),
+	},
+	.message = {
+		.data = fp256_message,
+		.length = sizeof(fp256_message),
+	},
+	.cipher = {
+		.data = fp256_cipher,
+		.length = sizeof(fp256_cipher),
+	}
+};
+
+#endif /* __TEST_CRYPTODEV_SM2_TEST_VECTORS_H__ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] crypto/openssl: add SM2 asymmetric crypto support
  2023-05-26  9:12 [PATCH v2 0/3] SM2 crypto algorithm support Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2023-05-26  9:12 ` [PATCH v2 2/3] test/crypto: add asymmetric SM2 test cases Gowrishankar Muthukrishnan
@ 2023-05-26  9:12 ` Gowrishankar Muthukrishnan
  2 siblings, 0 replies; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-05-26  9:12 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Gowrishankar Muthukrishnan

Add SM2 asymmetric algorithm support in openssl PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 doc/guides/cryptodevs/openssl.rst            |   1 +
 doc/guides/rel_notes/release_23_07.rst       |   4 +
 drivers/crypto/openssl/openssl_pmd_private.h |   7 +
 drivers/crypto/openssl/rte_openssl_pmd.c     | 245 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 101 ++++++++
 6 files changed, 359 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index 4b0f9b162e..b64c8ec4a5 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -65,6 +65,7 @@ DSA = Y
 Modular Exponentiation = Y
 Modular Inversion = Y
 Diffie-hellman = Y
+SM2 = Y
 
 ;
 ; Supported Operating systems of the 'openssl' crypto driver.
diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst
index 03041ceda1..ff21d21b23 100644
--- a/doc/guides/cryptodevs/openssl.rst
+++ b/doc/guides/cryptodevs/openssl.rst
@@ -53,6 +53,7 @@ Supported Asymmetric Crypto algorithms:
 * ``RTE_CRYPTO_ASYM_XFORM_DH``
 * ``RTE_CRYPTO_ASYM_XFORM_MODINV``
 * ``RTE_CRYPTO_ASYM_XFORM_MODEX``
+* ``RTE_CRYPTO_ASYM_XFORM_SM2``
 
 
 Installation
diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst
index 8b8e69d619..aeebcffb60 100644
--- a/doc/guides/rel_notes/release_23_07.rst
+++ b/doc/guides/rel_notes/release_23_07.rst
@@ -61,6 +61,10 @@ New Features
   along with prime field curve support.
 
 
+* **Updated OpenSSL crypto driver for SM2 support.**
+
+  Added SM2 algorithm support in asymmetric crypto operations.
+
 Removed Items
 -------------
 
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index ed6841e460..d7990c8333 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -12,6 +12,7 @@
 #include <openssl/rsa.h>
 #include <openssl/dh.h>
 #include <openssl/dsa.h>
+#include <openssl/ec.h>
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 #include <openssl/provider.h>
 #include <openssl/core_names.h>
@@ -200,6 +201,12 @@ struct openssl_asym_session {
 			OSSL_PARAM_BLD * param_bld;
 #endif
 		} s;
+		struct {
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM *key_params;
+			OSSL_PARAM *enc_params;
+#endif
+		} sm2;
 	} u;
 } __rte_cache_aligned;
 /** 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 384d262621..25feb88ac3 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -13,6 +13,7 @@
 #include <openssl/cmac.h>
 #include <openssl/hmac.h>
 #include <openssl/evp.h>
+#include <openssl/ec.h>
 
 #include "openssl_pmd_private.h"
 #include "compat.h"
@@ -2662,6 +2663,234 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 	return ret;
 
 }
+
+static int
+process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	OSSL_PARAM *kparams = sess->u.sm2.key_params;
+	struct rte_crypto_asym_op *op = cop->asym;
+	EVP_PKEY *pkey = NULL;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	if (!kparams)
+		return ret;
+
+	switch (op->sm2.op_type) {
+	case RTE_CRYPTO_ASYM_OP_ENCRYPT:
+		{
+			OSSL_PARAM *eparams = sess->u.sm2.enc_params;
+			size_t output_len;
+
+			kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL);
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0)
+				goto err_sm2;
+
+			cctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!cctx)
+				goto err_sm2;
+
+			if (!EVP_PKEY_encrypt_init(cctx))
+				goto err_sm2;
+
+			if (!EVP_PKEY_CTX_set_params(cctx, eparams))
+				goto err_sm2;
+
+			if (!EVP_PKEY_encrypt(cctx, op->sm2.cipher.data, &output_len,
+								 op->sm2.message.data,
+								 op->sm2.message.length))
+				goto err_sm2;
+			op->sm2.cipher.length = output_len;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_DECRYPT:
+		{
+			OSSL_PARAM *eparams = sess->u.sm2.enc_params;
+
+			kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL);
+			if (kctx == NULL
+				|| EVP_PKEY_fromdata_init(kctx) <= 0
+				|| EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0)
+				goto err_sm2;
+
+			cctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!cctx)
+				goto err_sm2;
+
+			if (!EVP_PKEY_decrypt_init(cctx))
+				goto err_sm2;
+
+			if (!EVP_PKEY_CTX_set_params(cctx, eparams))
+				goto err_sm2;
+
+			if (!EVP_PKEY_decrypt(cctx, op->sm2.message.data, &op->sm2.message.length,
+					op->sm2.cipher.data, op->sm2.cipher.length))
+				goto err_sm2;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			unsigned char signbuf[128] = {0};
+			const unsigned char *signptr = signbuf;
+			EVP_MD_CTX *md_ctx = NULL;
+			const BIGNUM *r, *s;
+			ECDSA_SIG *ec_sign;
+			EVP_MD *check_md;
+			size_t signlen;
+
+			kctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL);
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0)
+				goto err_sm2;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_sm2;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_sm2;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+			check_md = EVP_MD_fetch(NULL, "sm3", NULL);
+			if (!check_md)
+				goto err_sm2;
+
+			if (!EVP_DigestSignInit(md_ctx, NULL, check_md, NULL, pkey))
+				goto err_sm2;
+
+			if (EVP_PKEY_CTX_set1_id(sctx, op->sm2.id.data, op->sm2.id.length) <= 0)
+				goto err_sm2;
+
+			if (!EVP_DigestSignUpdate(md_ctx, op->sm2.message.data,
+					op->sm2.message.length))
+				goto err_sm2;
+
+			if (!EVP_DigestSignFinal(md_ctx, NULL, &signlen))
+				goto err_sm2;
+
+			if (!EVP_DigestSignFinal(md_ctx, signbuf, &signlen))
+				goto err_sm2;
+
+			ec_sign = d2i_ECDSA_SIG(NULL, &signptr, signlen);
+			if (!ec_sign)
+				goto err_sm2;
+
+			r = ECDSA_SIG_get0_r(ec_sign);
+			s = ECDSA_SIG_get0_s(ec_sign);
+			if (!r || !s)
+				goto err_sm2;
+
+			op->sm2.r.length = BN_num_bytes(r);
+			op->sm2.s.length = BN_num_bytes(s);
+			BN_bn2bin(r, op->sm2.r.data);
+			BN_bn2bin(s, op->sm2.s.data);
+
+			ECDSA_SIG_free(ec_sign);
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			unsigned char signbuf[128] = {0};
+			EVP_MD_CTX *md_ctx = NULL;
+			BIGNUM *r = NULL, *s = NULL;
+			ECDSA_SIG *ec_sign;
+			EVP_MD *check_md;
+			size_t signlen;
+
+			kctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL);
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, kparams) <= 0)
+				goto err_sm2;
+
+			if (!EVP_PKEY_is_a(pkey, "SM2"))
+				goto err_sm2;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_sm2;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_sm2;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+			check_md = EVP_MD_fetch(NULL, "sm3", NULL);
+			if (!check_md)
+				goto err_sm2;
+
+			if (!EVP_DigestVerifyInit(md_ctx, NULL, check_md, NULL, pkey))
+				goto err_sm2;
+
+			if (EVP_PKEY_CTX_set1_id(sctx, op->sm2.id.data, op->sm2.id.length) <= 0)
+				goto err_sm2;
+
+			if (!EVP_DigestVerifyUpdate(md_ctx, op->sm2.message.data,
+					op->sm2.message.length))
+				goto err_sm2;
+
+			ec_sign = ECDSA_SIG_new();
+			if (!ec_sign)
+				goto err_sm2;
+
+			r = BN_bin2bn(op->sm2.r.data, op->sm2.r.length, r);
+			s = BN_bin2bn(op->sm2.s.data, op->sm2.s.length, s);
+			if (!r || !s)
+				goto err_sm2;
+
+			if (!ECDSA_SIG_set0(ec_sign, r, s)) {
+				BN_free(r);
+				BN_free(s);
+				goto err_sm2;
+			}
+
+			r = NULL;
+			s = NULL;
+
+			signlen = i2d_ECDSA_SIG(ec_sign, (unsigned char **)&signbuf);
+			if (signlen <= 0)
+				goto err_sm2;
+
+			if (!EVP_DigestVerifyFinal(md_ctx, signbuf, signlen))
+				goto err_sm2;
+
+			BN_free(r);
+			BN_free(s);
+			ECDSA_SIG_free(ec_sign);
+	}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_sm2;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_sm2:
+	if (kctx)
+		EVP_PKEY_CTX_free(kctx);
+
+	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,
@@ -2761,6 +2990,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 
 	return 0;
 }
+
+static int
+process_openssl_sm2_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -2809,6 +3047,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_SM2:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_sm2_op_evp(op, sess);
+#else
+		retval = process_openssl_sm2_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 29ad1b9505..7a1e1e8e8c 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -1282,6 +1282,102 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		BIGNUM *pkey = NULL;
+		uint8_t pubkey[64];
+		size_t len = 0;
+		int ret = -1;
+
+		pkey = BN_bin2bn((const unsigned char *)xform->sm2.pkey.data,
+				 xform->sm2.pkey.length, pkey);
+
+		memset(pubkey, 0, RTE_DIM(pubkey));
+		pubkey[0] = 0x04;
+		len += 1;
+		memcpy(&pubkey[len], xform->sm2.q.x.data, xform->sm2.q.x.length);
+		len += xform->sm2.q.x.length;
+		memcpy(&pubkey[len], xform->sm2.q.y.data, xform->sm2.q.y.length);
+		len += xform->sm2.q.y.length;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_sm2;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+				OSSL_PKEY_PARAM_GROUP_NAME, "SM2", 0);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_sm2;
+		}
+
+		ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, pkey);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_sm2;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+									 pubkey, len);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_sm2;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_sm2;
+		}
+
+		asym_session->u.sm2.key_params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_sm2;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+				OSSL_ASYM_CIPHER_PARAM_DIGEST, "SM3", 0);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_sm2;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to h params\n");
+			goto err_sm2;
+		}
+
+		asym_session->u.sm2.enc_params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_SM2;
+		break;
+err_sm2:
+		if (pkey)
+			BN_free(pkey);
+
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.sm2.key_params)
+			OSSL_PARAM_free(asym_session->u.sm2.key_params);
+
+		if (asym_session->u.sm2.enc_params)
+			OSSL_PARAM_free(asym_session->u.sm2.enc_params);
+
+		return -1;
+#endif
+	}
 	default:
 		return ret;
 	}
@@ -1366,6 +1462,11 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 			DSA_free(sess->u.s.dsa);
 #endif
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_SM2:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_free(sess->u.sm2.key_params);
+		OSSL_PARAM_free(sess->u.sm2.enc_params);
+#endif
 	default:
 		break;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm
  2023-05-26  9:12 ` [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2023-05-28 17:43   ` Kusztal, ArkadiuszX
  2023-05-29  7:28     ` Gowrishankar Muthukrishnan
  0 siblings, 1 reply; 7+ messages in thread
From: Kusztal, ArkadiuszX @ 2023-05-28 17:43 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev; +Cc: anoobj, Akhil Goyal, Fan Zhang

Hi Gowrishankar,

> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Friday, May 26, 2023 11:12 AM
> To: dev@dpdk.org
> Cc: anoobj@marvell.com; Akhil Goyal <gakhil@marvell.com>; Fan Zhang
> <fanzhang.oss@gmail.com>; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>
> Subject: [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm
> 
> ShangMi 2 (SM2) is a encryption and digital signature algorithm used in the
> Chinese National Standard.

It is more of a set of public-key cryptography algorithms based on elliptic curves.

> 
> Added support for asymmetric SM2 in cryptodev along with prime field curve, as
> referenced in RFC:
> https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>  doc/guides/cryptodevs/features/default.ini |  1 +
>  doc/guides/rel_notes/release_23_07.rst     |  5 ++
>  lib/cryptodev/rte_crypto_asym.h            | 77 ++++++++++++++++++++++
>  lib/cryptodev/rte_cryptodev.c              |  1 +
>  4 files changed, 84 insertions(+)
> 
> diff --git a/doc/guides/cryptodevs/features/default.ini
> b/doc/guides/cryptodevs/features/default.ini
> index 523da0cfa8..a69967bb9e 100644
> --- a/doc/guides/cryptodevs/features/default.ini
> +++ b/doc/guides/cryptodevs/features/default.ini
> @@ -125,6 +125,7 @@ Diffie-hellman          =
>  ECDSA                   =
>  ECPM                    =
>  ECDH                    =
> +SM2                     =
> 
>  ;
>  ; Supported Operating systems of a default crypto driver.
> diff --git a/doc/guides/rel_notes/release_23_07.rst
> b/doc/guides/rel_notes/release_23_07.rst
> index a9b1293689..8b8e69d619 100644
> --- a/doc/guides/rel_notes/release_23_07.rst
> +++ b/doc/guides/rel_notes/release_23_07.rst
> @@ -55,6 +55,11 @@ New Features
>       Also, make sure to start the actual text at the margin.
>       =======================================================
> 
> +* **Added SM2 asymmetric algorithm in cryptodev.**
> +
> +  Added support for ShamMi 2 (SM2) asymmetric crypto algorithm  along
> + with prime field curve support.
> +
> 
>  Removed Items
>  -------------
> diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
> index 989f38323f..35fa2c0a6d 100644
> --- a/lib/cryptodev/rte_crypto_asym.h
> +++ b/lib/cryptodev/rte_crypto_asym.h
> @@ -119,6 +119,11 @@ enum rte_crypto_asym_xform_type {
>  	/**< Elliptic Curve Point Multiplication */
>  	RTE_CRYPTO_ASYM_XFORM_ECFPM,
>  	/**< Elliptic Curve Fixed Point Multiplication */
> +	RTE_CRYPTO_ASYM_XFORM_SM2,
> +	/**< ShangMi 2
> +	 * Performs Encrypt, Decrypt, Sign and Verify.
> +	 * Refer to rte_crypto_asym_op_type.
> +	 */
>  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
>  	/**< End of list */
>  };
> @@ -382,6 +387,20 @@ struct rte_crypto_ec_xform {
>  	/**< Pre-defined ec groups */
>  };
> 
> +/**
> + * Asymmetric SM2 transform data
> + *
> + * Structure describing SM2 xform params
> + *
> + */
> +struct rte_crypto_sm2_xform {
> +	rte_crypto_uint pkey;
> +	/**< Private key of the signer for signature generation. */
> +
> +	struct rte_crypto_ec_point q;
> +	/**< Public key of the signer for verification. */ };
> +
>  /**
>   * Operations params for modular operations:
>   * exponentiation and multiplicative inverse @@ -637,9 +656,66 @@ struct
> rte_crypto_asym_xform {
>  		/**< EC xform parameters, used by elliptic curve based
>  		 * operations.
>  		 */
> +
> +		struct rte_crypto_sm2_xform sm2;
> +		/**< SM2 xform parameters */
>  	};
>  };
> 
> +/**
> + * SM2 operation params
> + */
> +struct rte_crypto_sm2_op_param {

There is no random value 'k'. And SM2 is also using it for encryption.
There is no key exchange or point multiplication option in this op, therefore, I would rather have all SM2 algorithms in separate ops.
We also could abandon finally '_param' suffix, it does not add clarity but extends struct tags, which are very long already.

> +	enum rte_crypto_asym_op_type op_type;
> +	/**< Signature generation or verification */
> +
> +	rte_crypto_param message;
> +	/**<
> +	 * Pointer to input data
> +	 * - to be encrypted for SM2 public encrypt.
> +	 * - to be signed for SM2 sign generation.
> +	 * - to be authenticated for SM2 sign verification.

Is 'message' in signature case here plaintext or hash?
If 'plaintext' it is inconsistent with other signature algorithms, and most likely not all HW devices will support that.
Additionally or hash function should be specified as an argument by the user, or the function used should be defined
in the API information. I see it is not directly said in this draft what function it ought be, although most likely
SM3 would be the one.	

> +	 *
> +	 * Pointer to output data
> +	 * - for SM2 private decrypt.
> +	 * In this case the underlying array should have been
> +	 * allocated with enough memory to hold plaintext output
> +	 * (at least encrypted text length). The message.length field
> +	 * will be overwritten by the PMD with the decrypted length.
> +	 */
> +
> +	rte_crypto_param cipher;
> +	/**<
> +	 * Pointer to input data
> +	 * - to be decrypted for SM2 private decrypt.
> +	 *
> +	 * Pointer to output data
> +	 * - for SM2 public encrypt.
> +	 * In this case the underlying array should have been allocated
> +	 * with enough memory to hold ciphertext output (at least X bytes
> +	 * for prime field curve of N bytes and for message M bytes,
> +	 * where X = (C1 + C2 + C3) and computed based on SM2 RFC as
> +	 * C1 (1 + N + N), C2 = M, C3 = N. The cipher.length field will
> +	 * be overwritten by the PMD with the encrypted length.
> +	 */
> +
> +	rte_crypto_uint id;
> +	/**< The SM2 id used by signer and verifier and is in interval (1,
> +n-1). */

What is this parameter exactly, is it an ID prepended to the signature input?

> +
> +	rte_crypto_uint r;
> +	/**< r component of elliptic curve signature
> +	 *     output : for signature generation (of at least N bytes
> +	 *              where prime field length is N bytes)
> +	 *     input  : for signature verification
> +	 */
> +	rte_crypto_uint s;
> +	/**< s component of elliptic curve signature
> +	 *     output : for signature generation (of at least N bytes
> +	 *              where prime field length is N bytes)
> +	 *     input  : for signature verification
> +	 */
> +};
> +
>  /**
>   * Asymmetric Cryptographic Operation.
>   *
> @@ -665,6 +741,7 @@ struct rte_crypto_asym_op {
>  		struct rte_crypto_dsa_op_param dsa;
>  		struct rte_crypto_ecdsa_op_param ecdsa;
>  		struct rte_crypto_ecpm_op_param ecpm;
> +		struct rte_crypto_sm2_op_param sm2;
>  	};
>  	uint16_t flags;
>  	/**<
> diff --git a/lib/cryptodev/rte_cryptodev.c b/lib/cryptodev/rte_cryptodev.c index
> a96114b2da..21cabc3ffd 100644
> --- a/lib/cryptodev/rte_cryptodev.c
> +++ b/lib/cryptodev/rte_cryptodev.c
> @@ -299,6 +299,7 @@ crypto_asym_xform_strings[] = {
>  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
>  	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
>  	[RTE_CRYPTO_ASYM_XFORM_ECPM]	= "ecpm",
> +	[RTE_CRYPTO_ASYM_XFORM_SM2]	= "sm2",
>  };
> 
>  /**
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm
  2023-05-28 17:43   ` Kusztal, ArkadiuszX
@ 2023-05-29  7:28     ` Gowrishankar Muthukrishnan
  2023-06-04  9:47       ` Gowrishankar Muthukrishnan
  0 siblings, 1 reply; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-05-29  7:28 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, dev; +Cc: Anoob Joseph, Akhil Goyal, Fan Zhang

Hi ArkadiuszX,

> > ShangMi 2 (SM2) is a encryption and digital signature algorithm used
> > in the Chinese National Standard.
> 
> It is more of a set of public-key cryptography algorithms based on elliptic curves.
Ok I ll rephrase it.

> 
> >
...
> > ---
> >  doc/guides/cryptodevs/features/default.ini |  1 +
> >  doc/guides/rel_notes/release_23_07.rst     |  5 ++
> >  lib/cryptodev/rte_crypto_asym.h            | 77 ++++++++++++++++++++++
> >  lib/cryptodev/rte_cryptodev.c              |  1 +
> >  4 files changed, 84 insertions(+)
> >
> > diff --git a/doc/guides/cryptodevs/features/default.ini
> > b/doc/guides/cryptodevs/features/default.ini
> > index 523da0cfa8..a69967bb9e 100644
> > --- a/doc/guides/cryptodevs/features/default.ini
> > +++ b/doc/guides/cryptodevs/features/default.ini
> > @@ -125,6 +125,7 @@ Diffie-hellman          =
> >  ECDSA                   =
> >  ECPM                    =
> >  ECDH                    =
> > +SM2                     =
> >
> >  ;
> >  ; Supported Operating systems of a default crypto driver.
> > diff --git a/doc/guides/rel_notes/release_23_07.rst
> > b/doc/guides/rel_notes/release_23_07.rst
> > index a9b1293689..8b8e69d619 100644
> > --- a/doc/guides/rel_notes/release_23_07.rst
> > +++ b/doc/guides/rel_notes/release_23_07.rst
> > @@ -55,6 +55,11 @@ New Features
> >       Also, make sure to start the actual text at the margin.
> >       =======================================================
> >
> > +* **Added SM2 asymmetric algorithm in cryptodev.**
> > +
> > +  Added support for ShamMi 2 (SM2) asymmetric crypto algorithm  along
> > + with prime field curve support.
> > +
> >
> >  Removed Items
> >  -------------
> > diff --git a/lib/cryptodev/rte_crypto_asym.h
> > b/lib/cryptodev/rte_crypto_asym.h index 989f38323f..35fa2c0a6d 100644
> > --- a/lib/cryptodev/rte_crypto_asym.h
> > +++ b/lib/cryptodev/rte_crypto_asym.h
> > @@ -119,6 +119,11 @@ enum rte_crypto_asym_xform_type {
> >  	/**< Elliptic Curve Point Multiplication */
> >  	RTE_CRYPTO_ASYM_XFORM_ECFPM,
> >  	/**< Elliptic Curve Fixed Point Multiplication */
> > +	RTE_CRYPTO_ASYM_XFORM_SM2,
> > +	/**< ShangMi 2
> > +	 * Performs Encrypt, Decrypt, Sign and Verify.
> > +	 * Refer to rte_crypto_asym_op_type.
> > +	 */
> >  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> >  	/**< End of list */
> >  };
> > @@ -382,6 +387,20 @@ struct rte_crypto_ec_xform {
> >  	/**< Pre-defined ec groups */
> >  };
> >
> > +/**
> > + * Asymmetric SM2 transform data
> > + *
> > + * Structure describing SM2 xform params
> > + *
> > + */
> > +struct rte_crypto_sm2_xform {
> > +	rte_crypto_uint pkey;
> > +	/**< Private key of the signer for signature generation. */
> > +
> > +	struct rte_crypto_ec_point q;
> > +	/**< Public key of the signer for verification. */ };
> > +
> >  /**
> >   * Operations params for modular operations:
> >   * exponentiation and multiplicative inverse @@ -637,9 +656,66 @@
> > struct rte_crypto_asym_xform {
> >  		/**< EC xform parameters, used by elliptic curve based
> >  		 * operations.
> >  		 */
> > +
> > +		struct rte_crypto_sm2_xform sm2;
> > +		/**< SM2 xform parameters */
> >  	};
> >  };
> >
> > +/**
> > + * SM2 operation params
> > + */
> > +struct rte_crypto_sm2_op_param {
> 
> There is no random value 'k'. And SM2 is also using it for encryption.

Agreed. But if we see openSSL kind of SW library, it does not take this param from app. 
(for eg sign/encrypt), instead it generates on its own (still through RNG as I see).
so, shall we support either way meaning extern_scalar or inbuilt_scalar ? I am thinking
we can add enum like below:
- RTE_EC_SCALAR_INBUILT 
- RTE_EC_SCALAR_EXTERNAL

With inbuilt scalar, this k value in param can be ignored by PMD, while in external case,
pass it to HW.

> There is no key exchange or point multiplication option in this op, therefore, I
> would rather have all SM2 algorithms in separate ops.
You mean, we shall have structs rte_crypto_sm2_sign_op, rte_crypto_sm2_verify_op etc 
dedicated for each op ?

> We also could abandon finally '_param' suffix, it does not add clarity but extends
> struct tags, which are very long already.
Only for SM2 or for all algorithms ?

> 
> > +	enum rte_crypto_asym_op_type op_type;
> > +	/**< Signature generation or verification */

I need to add correction here. Op type can also be encrypt or decrypt.
> > +
> > +	rte_crypto_param message;
> > +	/**<
> > +	 * Pointer to input data
> > +	 * - to be encrypted for SM2 public encrypt.
> > +	 * - to be signed for SM2 sign generation.
> > +	 * - to be authenticated for SM2 sign verification.
> 
> Is 'message' in signature case here plaintext or hash?
As per RFC draft, it seems plain text, because we add prefix to it and then H256().

> If 'plaintext' it is inconsistent with other signature algorithms, and most likely
> not all HW devices will support that.
It is just another EC right ? Even in EC op param, we don't distinguish plaintext/hash message.

> Additionally or hash function should be specified as an argument by the user, or
> the function used should be defined in the API information. I see it is not directly
> said in this draft what function it ought be, although most likely
> SM3 would be the one.

Agree, SM2 sign implementation would need to know which hash algo to pick.
Hence, we can add hash function as param. RFC does not list options but quotes that
Algorithm should have been approved by Chinese Commercial Cryptography Administration Office.
So I am not too sure if we could add SHA3/SHAKE apart from SHA256 if it is approved.
 - SM3
 - SHA256
 - SHA3_256
 - SHAKE_256

May be PMD could evaluate it and return -ENOTSUP accordingly ?
> 
> > +	 *
> > +	 * Pointer to output data
> > +	 * - for SM2 private decrypt.
> > +	 * In this case the underlying array should have been
> > +	 * allocated with enough memory to hold plaintext output
> > +	 * (at least encrypted text length). The message.length field
> > +	 * will be overwritten by the PMD with the decrypted length.
> > +	 */
> > +
> > +	rte_crypto_param cipher;
> > +	/**<
> > +	 * Pointer to input data
> > +	 * - to be decrypted for SM2 private decrypt.
> > +	 *
> > +	 * Pointer to output data
> > +	 * - for SM2 public encrypt.
> > +	 * In this case the underlying array should have been allocated
> > +	 * with enough memory to hold ciphertext output (at least X bytes
> > +	 * for prime field curve of N bytes and for message M bytes,
> > +	 * where X = (C1 + C2 + C3) and computed based on SM2 RFC as
> > +	 * C1 (1 + N + N), C2 = M, C3 = N. The cipher.length field will
> > +	 * be overwritten by the PMD with the encrypted length.
> > +	 */
> > +
> > +	rte_crypto_uint id;
> > +	/**< The SM2 id used by signer and verifier and is in interval (1,
> > +n-1). */
> 
> What is this parameter exactly, is it an ID prepended to the signature input?
> 
This is signer identifier as per RFC. This gets concatenated with other EC params:
  ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)

ZA is then once again added with message before one more hash on entire thing.
> > +
> > +	rte_crypto_uint r;
> > +	/**< r component of elliptic curve signature
> > +	 *     output : for signature generation (of at least N bytes
> > +	 *              where prime field length is N bytes)
> > +	 *     input  : for signature verification
> > +	 */
> > +	rte_crypto_uint s;
> > +	/**< s component of elliptic curve signature
> > +	 *     output : for signature generation (of at least N bytes
> > +	 *              where prime field length is N bytes)
> > +	 *     input  : for signature verification
> > +	 */
> > +};
> > +
> >  /**
> >   * Asymmetric Cryptographic Operation.
> >   *
> > @@ -665,6 +741,7 @@ struct rte_crypto_asym_op {
> >  		struct rte_crypto_dsa_op_param dsa;
> >  		struct rte_crypto_ecdsa_op_param ecdsa;
> >  		struct rte_crypto_ecpm_op_param ecpm;
> > +		struct rte_crypto_sm2_op_param sm2;
> >  	};
> >  	uint16_t flags;
> >  	/**<
> > diff --git a/lib/cryptodev/rte_cryptodev.c
> > b/lib/cryptodev/rte_cryptodev.c index a96114b2da..21cabc3ffd 100644
> > --- a/lib/cryptodev/rte_cryptodev.c
> > +++ b/lib/cryptodev/rte_cryptodev.c
> > @@ -299,6 +299,7 @@ crypto_asym_xform_strings[] = {
> >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> >  	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> >  	[RTE_CRYPTO_ASYM_XFORM_ECPM]	= "ecpm",
> > +	[RTE_CRYPTO_ASYM_XFORM_SM2]	= "sm2",
> >  };
> >
> >  /**
> > --
> > 2.25.1

Thanks for the review,
Gowrishankar

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm
  2023-05-29  7:28     ` Gowrishankar Muthukrishnan
@ 2023-06-04  9:47       ` Gowrishankar Muthukrishnan
  0 siblings, 0 replies; 7+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-06-04  9:47 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, dev; +Cc: Anoob Joseph, Akhil Goyal, Fan Zhang

Hi,
I have simplified sm2 xform to only have hash algo and rest in crypto op. Please review v3 and let me know if changes are good.
Also, I need to test plain scalar k value but I don't have support in openSSL to do that. So, I will meanwhile get back once I am
done with that part as well, but v3 is good to go for openSSL pmd.

Thanks,
Gowrishankar

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-06-04  9:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-26  9:12 [PATCH v2 0/3] SM2 crypto algorithm support Gowrishankar Muthukrishnan
2023-05-26  9:12 ` [PATCH v2 1/3] cryptodev: add SM2 asymmetric crypto algorithm Gowrishankar Muthukrishnan
2023-05-28 17:43   ` Kusztal, ArkadiuszX
2023-05-29  7:28     ` Gowrishankar Muthukrishnan
2023-06-04  9:47       ` Gowrishankar Muthukrishnan
2023-05-26  9:12 ` [PATCH v2 2/3] test/crypto: add asymmetric SM2 test cases Gowrishankar Muthukrishnan
2023-05-26  9:12 ` [PATCH v2 3/3] crypto/openssl: add SM2 asymmetric crypto support Gowrishankar Muthukrishnan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).