Skip to contentSkip to conversation

SM2 crypto algorithm support

PATCH Superseded Gowrishankar Muthukrishnan 2 participants 10 messages Apr 28, 2023 – May 26, 2023 Crypto API

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

cover SM2 crypto algorithm support

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

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

 app/test/test_cryptodev_asym.c               | 506 +++++++++++++++++++
 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       |   7 +
 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              |  76 +++
 lib/cryptodev/rte_cryptodev.c                |   1 +
 11 files changed, 1066 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
Signature · 1 line
2.25.1
#1 lore raw

PATCH 1/3 cryptodev: add SM2 asymmetric crypto algorithm

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

---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/rel_notes/release_23_07.rst     |  3 +
 lib/cryptodev/rte_crypto_asym.h            | 76 ++++++++++++++++++++++
 lib/cryptodev/rte_cryptodev.c              |  1 +
 4 files changed, 81 insertions(+)
doc/guides/cryptodevs/features/default.ini +1 -0
index 523da0cfa8..a69967bb9e 100644
@@ -125,6 +125,7 @@ Diffie-hellman          =
 ECDSA                   =
 ECPM                    =
 ECDH                    =
+SM2                     =
 
 ;
 ; Supported Operating systems of a default crypto driver.
doc/guides/rel_notes/release_23_07.rst +3 -0
index a9b1293689..b920840038 100644
@@ -55,6 +55,9 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added SM2 algorithm in cryptodev library.**
+
+  Added SM2 algorithm with prime field curve support.
 
 Removed Items
 -------------
lib/cryptodev/rte_crypto_asym.h +76 -0

103 lines not on this page · raw message

lib/cryptodev/rte_cryptodev.c +1 -0
index a96114b2da..fd7b6b92b5 100644
@@ -282,6 +282,7 @@ const char *rte_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",
 };
 
 /**
Signature · 1 line
2.25.1
#2 lore raw

RE: [v1, 1/3] cryptodev: add SM2 asymmetric crypto algorithm

Quoted 4 lines

Subject: [v1, 1/3] cryptodev: add SM2 asymmetric crypto algorithm

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

ShangMi 2 (SM2) is an encryption and digital signature algorithm used in the Chinese National Standard.
Added support for asymmetric SM2 in cryptodev along with prime field curve.

Can you also add link for RFC in patch description here as it is mentioned in the comments of the structure.

Quoted 28 lines
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/rel_notes/release_23_07.rst     |  3 +
 lib/cryptodev/rte_crypto_asym.h            | 76 ++++++++++++++++++++++
 lib/cryptodev/rte_cryptodev.c              |  1 +
 4 files changed, 81 insertions(+)
doc/guides/cryptodevs/features/default.ini +1 -0
index 523da0cfa8..a69967bb9e 100644
@@ -125,6 +125,7 @@ Diffie-hellman          =
 ECDSA                   =
 ECPM                    =
 ECDH                    =
+SM2                     =
 
 ;
 ; Supported Operating systems of a default crypto driver.
doc/guides/rel_notes/release_23_07.rst +0 -0
index a9b1293689..b920840038 100644

doc/guides/rel_notes/release_23_07.rst New Features · line 60

Quoted 6 lines
doc/guides/rel_notes/release_23_07.rst +3 -0
@@ -55,6 +55,9 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added SM2 algorithm in cryptodev library.**
+
+  Added SM2 algorithm with prime field curve support.

* **Added SM2 asymmetric algorithm in cryptodev.**

Added support for ShamMi 2 (SM2) asymmetric crypto algorithm along with prime field curve support.

lib/cryptodev/rte_crypto_asym.h enum rte_crypto_asym_xform_type { · line 123

Quoted 13 lines
doc/guides/rel_notes/release_23_07.rst +0 -0
 Removed Items
 -------------
lib/cryptodev/rte_crypto_asym.h +2 -0
index 989f38323f..c91a8dee4d 100644
@@ -119,6 +119,8 @@ 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. */

/**< ShangMi 2.
* Performs Encrypt, Decrypt, Sign and Verify.
* Refer to rte_crypto_asym_op_type.
*/

Quoted 9 lines
lib/cryptodev/rte_crypto_asym.h +2 -0
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -382,6 +384,20 @@ struct rte_crypto_ec_xform {
 	/**< Pre-defined ec groups */
 };
 
+/**
+ * Asymmetric SM2 transform data

lib/cryptodev/rte_crypto_asym.h struct rte_crypto_ec_xform { · line 398

Quoted 10 lines
lib/cryptodev/rte_crypto_asym.h +10 -0
+ *
+ * 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 */

Please add dots at end of sentences.

Quoted 46 lines
lib/cryptodev/rte_crypto_asym.h +36 -0
+};
+
 /**
  * Operations params for modular operations:
  * exponentiation and multiplicative inverse
@@ -637,9 +653,68 @@ 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
+	 * (atleast 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 (atleast X bytes

lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform { · line 702

Quoted 10 lines
lib/cryptodev/rte_crypto_asym.h +10 -0
+	 * 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).
+	 */

This can be a single line comment.

Quoted 40 lines
lib/cryptodev/rte_crypto_asym.h +16 -0
+
+	rte_crypto_uint r;
+	/**< r component of elliptic curve signature
+	 *     output : for signature generation (of atleast 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 atleast N bytes
+	 *              where prime field length is N bytes)
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Asymmetric Cryptographic Operation.
  *
@@ -665,6 +740,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;
 	/**<
lib/cryptodev/rte_cryptodev.c +1 -1
index a96114b2da..fd7b6b92b5 100644
@@ -282,6 +282,7 @@ const char *rte_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

#3 lore raw

PATCH 2/3 test/test_cryptodev_asym: add SM2 tests

In reply to Gowrishankar Muthukrishnan

Add SM2 tests.

---
 app/test/test_cryptodev_asym.c             | 506 +++++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h | 120 +++++
 2 files changed, 626 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
app/test/test_cryptodev_asym.c +506 -0
index 9236817650..bfaeedee27 100644
@@ -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,507 @@ 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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* 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) */
+
+	/* 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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* 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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* 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) */
+
+	/* 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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* 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 +2707,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),
app/test/test_cryptodev_sm2_test_vectors.h new file +120 -0

120 lines not on this page · raw message

Signature · 1 line
2.25.1
#4 lore raw

RE: [v1, 2/3] test/test_cryptodev_asym: add SM2 tests

Hi Gowri,

Quoted 2 lines

Subject: [v1, 2/3] test/test_cryptodev_asym: add SM2 tests

Title should be
test/crypto: add asymmetric SM2 cases

Quoted 1 line

Add SM2 tests.

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

If you have the reference from where the vectors are taken it can also be mentioned.

Quoted 34 lines
---
 app/test/test_cryptodev_asym.c             | 506 +++++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h | 120 +++++
 2 files changed, 626 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
app/test/test_cryptodev_asym.c +10 -0
index 9236817650..bfaeedee27 100644
@@ -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,507 @@ 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;

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2219

Quoted 10 lines
app/test/test_cryptodev_asym.c +10 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);

dev_info is being unused. Not checking for capabilities?

Quoted 53 lines
app/test/test_cryptodev_asym.c +51 -0
+
+	/* 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 */

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2279

Quoted 10 lines
app/test/test_cryptodev_asym.c +10 -0
+	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();

Shouldn't this be a finite loop and mark test as failed after some retries?

Quoted 246 lines
app/test/test_cryptodev_asym.c +65 -0
+
+	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) */
+
+	/* 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;

app/test/test_cryptodev_asym.c +14 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool,

RTE_CRYPTO_OP_TYPE_ASYMMETRIC);

app/test/test_cryptodev_asym.c +18 -0
+	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);

app/test/test_cryptodev_asym.c +66 -0
+	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;

app/test/test_cryptodev_asym.c +16 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool,

RTE_CRYPTO_OP_TYPE_ASYMMETRIC);

app/test/test_cryptodev_asym.c +21 -0
+	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);

app/test/test_cryptodev_asym.c +40 -0
+	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;

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2529

Quoted 10 lines
app/test/test_cryptodev_asym.c +10 -0
+		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;
+	}

Shouldn't we do content comparison of the cipher text with vectors here as well? Content is matched only after round trip which will not catch the hardware bug during encryption.

Quoted 327 lines
app/test/test_cryptodev_asym.c +5 -0
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "cipher:",
+			asym_op->sm2.cipher.data, asym_op-
Quoted 1 line

sm2.cipher.length);

app/test/test_cryptodev_asym.c +35 -0
+
+	/* Verify cipher (in roundtrip) */
+
+	/* 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-
Quoted 1 line

sm2.message.data,

app/test/test_cryptodev_asym.c +22 -0
+			   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;

app/test/test_cryptodev_asym.c +16 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool,

RTE_CRYPTO_OP_TYPE_ASYMMETRIC);

app/test/test_cryptodev_asym.c +21 -0
+	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);

app/test/test_cryptodev_asym.c +56 -0
+	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-
Quoted 1 line

sm2.message.length);

app/test/test_cryptodev_asym.c +2 -0
+
+	if (memcmp(input_params.message.data, asym_op-
Quoted 1 line

sm2.message.data,

app/test/test_cryptodev_asym.c +17 -0
+			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 +2707,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),

app/test/test_cryptodev_asym.c +1 -0
+		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),

app/test/test_cryptodev_asym.c +0 -0
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_rsa_sign_verify),
app/test/test_cryptodev_sm2_test_vectors.h new file +120 -1
new file mode 100644
index 0000000000..d70d3ccaa0
@@ -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

#5 lore raw

RE: [v1, 2/3] test/test_cryptodev_asym: add SM2 tests

Hi Akhil,

Quoted 4 lines

If you have the reference from where the vectors are taken it can also be mentioned.

I generated these test vectors in online. There are no reference test vectors quoted In RFC except for recommended curve parameters, at the end.
https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02

Quoted 38 lines
Quoted 38 lines
---
 app/test/test_cryptodev_asym.c             | 506 +++++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h | 120 +++++
 2 files changed, 626 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
(quoted diff) +0 -0

b/app/test/test_cryptodev_asym.c index 9236817650..bfaeedee27 100644

app/test/test_cryptodev_asym.c +14 -0
@@ -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,507 @@ 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;
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2218

Quoted 6 lines
app/test/test_cryptodev_asym.c +6 -0
+	struct rte_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);

dev_info is being unused. Not checking for capabilities?

It is the same case in other algorithms as well. Shall I collectively address this ?

Quoted 57 lines
Quoted 57 lines
app/test/test_cryptodev_asym.c +55 -0
+
+	/* 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");
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2279

Quoted 6 lines
app/test/test_cryptodev_asym.c +6 -0
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();

Shouldn't this be a finite loop and mark test as failed after some retries?

It is the same case in other algorithms as well. Shall I collectively address this ?

Quoted 10 lines
Quoted 10 lines
app/test/test_cryptodev_asym.c +9 -0
+
+	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;
+	}
+

...
<cut>
...

Quoted 92 lines
Quoted 92 lines
app/test/test_cryptodev_asym.c +5 -0
+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;

app/test/test_cryptodev_asym.c +16 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool,

RTE_CRYPTO_OP_TYPE_ASYMMETRIC);

app/test/test_cryptodev_asym.c +21 -0
+	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);

app/test/test_cryptodev_asym.c +47 -0
+	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");
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2229

Quoted 3 lines
app/test/test_cryptodev_asym.c +3 -0
+		status = TEST_FAILED;
+		goto exit;
+	}

Shouldn't we do content comparison of the cipher text with vectors here as well?
Content is matched only after round trip which will not catch the hardware bug during encryption.

Due to random scalar value used (and known only to driver), we can't have expected cipher string. I ll wait for review on current openssl driver implementation whether to introduce this scalar value in crypto op param like in EC. Based on this, we could address this suggestion.

Thanks.

Quoted 1 line
#6 lore raw

RE: [v1, 2/3] test/test_cryptodev_asym: add SM2 tests

Quoted 10 lines

Hi Akhil,

Quoted 4 lines

If you have the reference from where the vectors are taken it can also be mentioned.

I generated these test vectors in online. There are no reference test vectors quoted
In RFC except for recommended curve parameters, at the end.
https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02

ok

Quoted 47 lines
Quoted 38 lines
Quoted 38 lines
---
 app/test/test_cryptodev_asym.c             | 506 +++++++++++++++++++++
 app/test/test_cryptodev_sm2_test_vectors.h | 120 +++++
 2 files changed, 626 insertions(+)
 create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
(quoted diff) +0 -0

b/app/test/test_cryptodev_asym.c index 9236817650..bfaeedee27 100644

app/test/test_cryptodev_asym.c +14 -0
@@ -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,507 @@ 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;
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2218

Quoted 6 lines
app/test/test_cryptodev_asym.c +6 -0
+	struct rte_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);

dev_info is being unused. Not checking for capabilities?

Quoted 1 line

It is the same case in other algorithms as well. Shall I collectively address this ?

You can remove this dev_info get from here and add capability check in a separate patch for all cases.

Quoted 66 lines
Quoted 57 lines
Quoted 57 lines
app/test/test_cryptodev_asym.c +55 -0
+
+	/* 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");
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2279

Quoted 6 lines
app/test/test_cryptodev_asym.c +6 -0
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();

Shouldn't this be a finite loop and mark test as failed after some retries?

Quoted 1 line

It is the same case in other algorithms as well. Shall I collectively address this ?

Ok you can submit a separate patch for it.

Quoted 114 lines
Quoted 10 lines
Quoted 10 lines
app/test/test_cryptodev_asym.c +9 -0
+
+	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;
+	}
+

...
<cut>
...

Quoted 92 lines
Quoted 92 lines
app/test/test_cryptodev_asym.c +5 -0
+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;

app/test/test_cryptodev_asym.c +16 -0
+	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_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_SUCCESS;
+	void *sess = NULL;
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool,

RTE_CRYPTO_OP_TYPE_ASYMMETRIC);

app/test/test_cryptodev_asym.c +21 -0
+	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);

app/test/test_cryptodev_asym.c +47 -0
+	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");
Quoted 8 lines

app/test/test_cryptodev_asym.c test_ecpm_all_curve(void) · line 2229

Quoted 3 lines
app/test/test_cryptodev_asym.c +3 -0
+		status = TEST_FAILED;
+		goto exit;
+	}

Shouldn't we do content comparison of the cipher text with vectors here as well?
Content is matched only after round trip which will not catch the hardware bug during encryption.

Quoted 8 lines

Due to random scalar value used (and known only to driver), we can't have expected
cipher string. I ll wait for review on current openssl driver implementation whether
to introduce this scalar value in crypto op param like in EC. Based on this, we could
address this suggestion.

You can add a comment here in the code to explain this thing.

#7 lore raw

PATCH 3/3 crypto/openssl: add SM2 asymmetric crypto support

In reply to Gowrishankar Muthukrishnan

Add SM2 asymmetric algorithm support in openssl PMD.

---
 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(+)
doc/guides/cryptodevs/features/openssl.ini +1 -0
index 4b0f9b162e..b64c8ec4a5 100644
@@ -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.
doc/guides/cryptodevs/openssl.rst +1 -0
index 03041ceda1..ff21d21b23 100644
@@ -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
doc/guides/rel_notes/release_23_07.rst +4 -0
index b920840038..8868b0bb32 100644
@@ -59,6 +59,10 @@ New Features
 
   Added SM2 algorithm with prime field curve support.
 
+* **Updated OpenSSL crypto driver for SM2 support.**
+
+  Added SM2 algorithm support in asymmetric crypto operations.
+
 Removed Items
 -------------
 
drivers/crypto/openssl/openssl_pmd_private.h +7 -0
index ed6841e460..d7990c8333 100644
@@ -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 */
drivers/crypto/openssl/rte_openssl_pmd.c +245 -0

269 lines not on this page · raw message

drivers/crypto/openssl/rte_openssl_pmd_ops.c +101 -0

113 lines not on this page · raw message

Signature · 1 line
2.25.1