SM2 crypto algorithm support
v3 cover SM2 crypto algorithm support
This patch series adds SM2 crypto algorithm support, along with tests verified using Openssl.
v3:
- sm2 xform contains hash param and key pair info moved into op.
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 | 581 +++++++++++++++++++ app/test/test_cryptodev_sm2_test_vectors.h | 129 ++++ 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 | 6 + drivers/crypto/openssl/rte_openssl_pmd.c | 297 ++++++++++ drivers/crypto/openssl/rte_openssl_pmd_ops.c | 48 ++ lib/cryptodev/rte_crypto_asym.h | 87 +++ lib/cryptodev/rte_cryptodev.c | 1 + 11 files changed, 1161 insertions(+) create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
Signature · 1 line
2.25.1
PATCH v3 1/3 cryptodev: add SM2 asymmetric crypto algorithm
ShangMi 2 (SM2) is 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
--- doc/guides/cryptodevs/features/default.ini | 1 + doc/guides/rel_notes/release_23_07.rst | 5 ++ lib/cryptodev/rte_crypto_asym.h | 87 ++++++++++++++++++++++ lib/cryptodev/rte_cryptodev.c | 1 + 4 files changed, 94 insertions(+)
doc/guides/cryptodevs/features/default.ini +1 -0
@@ -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 +5 -0
@@ -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 -------------
lib/cryptodev/rte_crypto_asym.h +87 -0
114 lines not on this page · raw message
lib/cryptodev/rte_cryptodev.c +1 -0
@@ -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", };/**
Signature · 1 line
2.25.1
RE: [PATCH v3 1/3] cryptodev: add SM2 asymmetric crypto algorithm
Some things will need to be changed before the next release (few of them I described below), but I will ack it. Especially that other algorithms have similar issues.
Quoted 108 lines
-----Original Message-----
From: Gowrishankar Muthukrishnan <[email protected]>
Sent: Sunday, June 4, 2023 11:43 AM
To: [email protected]
Cc: [email protected]; Akhil Goyal <[email protected]>; Kusztal, ArkadiuszX <[email protected]>; Fan Zhang <[email protected]>; Ji, Kai <[email protected]>; Gowrishankar Muthukrishnan <[email protected]>
Subject: [PATCH v3 1/3] cryptodev: add SM2 asymmetric crypto algorithmShangMi 2 (SM2) is 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-02Signed-off-by Gowrishankar Muthukrishnan <[email protected]>--- doc/guides/cryptodevs/features/default.ini | 1 + doc/guides/rel_notes/release_23_07.rst | 5 ++ lib/cryptodev/rte_crypto_asym.h | 87 ++++++++++++++++++++++ lib/cryptodev/rte_cryptodev.c | 1 + 4 files changed, 94 insertions(+)doc/guides/cryptodevs/features/default.ini +1
-0@@ -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 +5
-0@@ -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 -------------lib/cryptodev/rte_crypto_asym.h +15
-0@@ -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,17 @@ struct rte_crypto_ec_xform {/**< Pre-defined ec groups */ }; +/** +* Asymmetric SM2 transform data +* +* Structure describing SM2 xform params +* +*/ +struct rte_crypto_sm2_xform { +enum rte_crypto_auth_algorithm hash; +/**< Hash algorithm used in SM2 op. */ }; +/** * Operations params for modular operations: * exponentiation and multiplicative inverse @@ -637,9 +653,79 @@ struct
rte_crypto_asym_xform{lib/cryptodev/rte_crypto_asym.h +13
-0/**< 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_uint pkey; +/**< Private key for encryption or sign generation */ +
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform { · line 681
Quoted 10 lines
lib/cryptodev/rte_crypto_asym.h +10
-0+struct rte_crypto_ec_point q; +/**< Public key for decryption 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. +*
This repeats problems known to dsa/ecdsa. What will work on OpenSSL PMD will not work on the HW. Ironically, test will pass for both... We can extend this before the next release.
Quoted 12 lines
lib/cryptodev/rte_crypto_asym.h +12
-0+* 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.
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform { · line 703
Quoted 10 lines
lib/cryptodev/rte_crypto_asym.h +10
-0+* +* 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. +*/
I thought it was concatenation, not addition.
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform {
Quoted 4 lines
lib/cryptodev/rte_crypto_asym.h +4
-0+ +rte_crypto_uint id; +/**< The SM2 id used by signer and verifier and is in interval (1, +n-1). */
Where does the (1,n-1) limitation comes from? As it is a hashed prefix, should it have any mathematical interpretation at all?
Quoted 47 lines
lib/cryptodev/rte_crypto_asym.h +23
-0+ +rte_crypto_uint k; +/**< The SM2 per-message secret number, which is an integer +* in the interval (1, n-1). +* If the random number is generated by the PMD, +* the 'rte_crypto_param.data' parameter should be set to NULL. +*/ + +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 +751,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 index renamed from lib/cryptodev/rte_cryptodev.c +0
-0
a96114b2da..21cabc3ffd100644lib/cryptodev/rte_cryptodev.c +1
-1@@ -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
RE: [PATCH v3 1/3] cryptodev: add SM2 asymmetric crypto algorithm
Quoted 6 lines
Acked-by Arek Kusztal <[email protected]>Some things will need to be changed before the next release (few of them I described below), but I will ack it. Especially that other algorithms have similar issues.
Sure. I also thought any improvements can collectively addressed as it is another EC.
Quoted 39 lines
Quoted 39 lines
lib/cryptodev/rte_crypto_asym.h +10
-0+/** +* Asymmetric SM2 transform data +* +* Structure describing SM2 xform params +* +*/ +struct rte_crypto_sm2_xform { +enum rte_crypto_auth_algorithm hash; +/**< Hash algorithm used in SM2 op. */ }; +/** * Operations params for modular operations: * exponentiation and multiplicative inverse @@ -637,9 +653,79 @@ struct
rte_crypto_asym_xform{lib/cryptodev/rte_crypto_asym.h +19
-0/**< 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_uint pkey; +/**< Private key for encryption or sign generation */ + +struct rte_crypto_ec_point q; +/**< Public key for decryption or verification */ + +rte_crypto_param message; +/**< +* Pointer to input data
Quoted 8 lines
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform { · line 681
Quoted 4 lines
lib/cryptodev/rte_crypto_asym.h +4
-0+* - to be encrypted for SM2 public encrypt. +* - to be signed for SM2 sign generation. +* - to be authenticated for SM2 sign verification. +* This repeats problems known to dsa/ecdsa. What will work on OpenSSL PMD will not work on the HW. Ironically, test will pass for both...
We can extend this before the next release.
Ack
Quoted 16 lines
Quoted 16 lines
lib/cryptodev/rte_crypto_asym.h +15
-0+* 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.
Quoted 8 lines
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform { · line 703
Quoted 7 lines
lib/cryptodev/rte_crypto_asym.h +7
-0+* 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. +*/ I thought it was concatenation, not addition.
Typo I did. Yes it should have been ||.
Quoted 6 lines
lib/cryptodev/rte_crypto_asym.h struct rte_crypto_asym_xform {
Quoted 4 lines
lib/cryptodev/rte_crypto_asym.h +4
-0+ +rte_crypto_uint id; +/**< The SM2 id used by signer and verifier and is in interval (1, +n-1). */ Where does the (1,n-1) limitation comes from? As it is a hashed prefix, should it have any mathematical interpretation at all?
Yeah it is not necessarily limited wrt n. we can just phrase it:
/**< The SM2 id used by signer and verifier */
In fact, here could be another improvement (applicable to EC as well) to keep the params specific to op. Sign/verify only would need this param (and r , s below).
Quoted 22 lines
Quoted 22 lines
lib/cryptodev/rte_crypto_asym.h +22
-0+ +rte_crypto_uint k; +/**< The SM2 per-message secret number, which is an integer +* in the interval (1, n-1). +* If the random number is generated by the PMD, +* the 'rte_crypto_param.data' parameter should be set to NULL. +*/ + +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 +*/ +}; +
PATCH v3 2/3 test/crypto: add asymmetric SM2 test cases
In reply to Gowrishankar MuthukrishnanAdded test cases for asymmetric SM2 crypto validation. Test cases are added for sign/verify/encrypt/decrypt.
--- app/test/test_cryptodev_asym.c | 581 +++++++++++++++++++++ app/test/test_cryptodev_sm2_test_vectors.h | 129 +++++ 2 files changed, 710 insertions(+) create mode 100644 app/test/test_cryptodev_sm2_test_vectors.h
app/test/test_cryptodev_asym.c +581 -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,582 @@ test_ecpm_all_curve(void)return overall_status; } +static int +_test_sm2_sign (bool rnd_secret) +{ +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.hash =RTE_CRYPTO_AUTH_SM3 ; + + 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 */ + asym_op->sm2.op_type =RTE_CRYPTO_ASYM_OP_SIGN ; + asym_op->sm2.message.data = input_params.message.data; + asym_op->sm2.message.length = input_params.message.length; + asym_op->sm2.pkey.data = input_params.pkey.data; + asym_op->sm2.pkey.length = input_params.pkey.length; + asym_op->sm2.q.x.data = input_params.pubkey_qx.data; + asym_op->sm2.q.x.length = input_params.pubkey_qx.length; + asym_op->sm2.q.y.data = input_params.pubkey_qy.data; + asym_op->sm2.q.y.length = input_params.pubkey_qy.length; + asym_op->sm2.id.data = input_params.id.data; + asym_op->sm2.id.length = input_params.id.length; +if (rnd_secret) { + asym_op->sm2.k.data =NULL ; + asym_op->sm2.k.length =0 ; + }else { + asym_op->sm2.k.data = input_params.k.data; + asym_op->sm2.k.length = input_params.k.length; + } + +/* Init out buf */ + asym_op->sm2.r.data = output_buf_r; + asym_op->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); + +if (!rnd_secret) { +/* Verify sign (by comparison). */ +if (memcmp (input_params.sign_r.data, asym_op->sm2.r.data, + asym_op->sm2.r.length) !=0 ) { + status =TEST_FAILED ; +RTE_LOG (ERR ,USER1 , +"line %u FAILED: %s" , __LINE__, +"SM2 sign failed.\n" ); + goto exit; + } +if (memcmp (input_params.sign_s.data, asym_op->sm2.s.data, + asym_op->sm2.s.length) !=0 ) { + status =TEST_FAILED ; +RTE_LOG (ERR ,USER1 , +"line %u FAILED: %s" , __LINE__, +"SM2 sign failed.\n" ); + goto exit; + } + }else { +/* Verify sign (in roundtrip). +* Due to random number used per message, sign op +* would produce different output for same message +* every time. Hence, we can't have expected output +* to match, instead reverse op to verify. +*/ + +/* Populate op with operational details */ + asym_op->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_sign_rnd_secret (void ) +{ +return _test_sm2_sign (true); +} + +__rte_used static int +test_sm2_sign_plain_secret (void ) +{ +return _test_sm2_sign (false); +} + +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_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.hash =RTE_CRYPTO_AUTH_SM3 ; + + 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 */ + asym_op->sm2.op_type =RTE_CRYPTO_ASYM_OP_VERIFY ; + asym_op->sm2.message.data = input_params.message.data; + asym_op->sm2.message.length = input_params.message.length; + asym_op->sm2.pkey.data = input_params.pkey.data; + asym_op->sm2.pkey.length = input_params.pkey.length; + asym_op->sm2.q.x.data = input_params.pubkey_qx.data; + asym_op->sm2.q.x.length = input_params.pubkey_qx.length; + asym_op->sm2.q.y.data = input_params.pubkey_qy.data; + asym_op->sm2.q.y.length = input_params.pubkey_qy.length; + asym_op->sm2.r.data = input_params.sign_r.data; + asym_op->sm2.r.length = input_params.sign_r.length; + asym_op->sm2.s.data = input_params.sign_s.data; + asym_op->sm2.s.length = input_params.sign_s.length; + asym_op->sm2.id.data = input_params.id.data; + asym_op->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_enc (bool rnd_secret) +{ +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.hash =RTE_CRYPTO_AUTH_SM3 ; + + 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 */ + asym_op->sm2.op_type =RTE_CRYPTO_ASYM_OP_ENCRYPT ; + asym_op->sm2.message.data = input_params.message.data; + asym_op->sm2.message.length = input_params.message.length; + asym_op->sm2.pkey.data = input_params.pkey.data; + asym_op->sm2.pkey.length = input_params.pkey.length; + asym_op->sm2.q.x.data = input_params.pubkey_qx.data; + asym_op->sm2.q.x.length = input_params.pubkey_qx.length; + asym_op->sm2.q.y.data = input_params.pubkey_qy.data; + asym_op->sm2.q.y.length = input_params.pubkey_qy.length; +if (rnd_secret) { + asym_op->sm2.k.data =NULL ; + asym_op->sm2.k.length =0 ; + }else { + asym_op->sm2.k.data = input_params.k.data; + asym_op->sm2.k.length = input_params.k.length; + } + +/* Init out buf */ + asym_op->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); + +if (!rnd_secret) { +if (memcmp (input_params.cipher.data, asym_op->sm2.cipher.data, + asym_op->sm2.cipher.length) !=0 ) { + status =TEST_FAILED ; +RTE_LOG (ERR ,USER1 ,"line %u FAILED: %s" , __LINE__, +"SM2 encrypt failed.\n" ); + goto exit; + } + }else { +/* Verify cipher (in roundtrip). +* Due to random number used per message, encrypt op +* would produce different output for same message +* every time. 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_enc_rnd_secret (void ) +{ +return _test_sm2_enc (true); +} + +__rte_used static int +test_sm2_enc_plain_secret (void ) +{ +return _test_sm2_enc (false); +} + +static int +test_sm2_dec (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.hash =RTE_CRYPTO_AUTH_SM3 ; + + 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 */ + asym_op->sm2.op_type =RTE_CRYPTO_ASYM_OP_DECRYPT ; + asym_op->sm2.cipher.data = input_params.cipher.data; + asym_op->sm2.cipher.length = input_params.cipher.length; + asym_op->sm2.pkey.data = input_params.pkey.data; + asym_op->sm2.pkey.length = input_params.pkey.length; + asym_op->sm2.q.x.data = input_params.pubkey_qx.data; + asym_op->sm2.q.x.length = input_params.pubkey_qx.length; + asym_op->sm2.q.y.data = input_params.pubkey_qy.data; + asym_op->sm2.q.y.length = input_params.pubkey_qy.length; + +/* Init out buf */ + asym_op->sm2.message.data = output_buf_m; + asym_op->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 +2782,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_sign_rnd_secret), +TEST_CASE_ST (ut_setup_asym, ut_teardown_asym, test_sm2_verify), +TEST_CASE_ST (ut_setup_asym, ut_teardown_asym, test_sm2_enc_rnd_secret), +TEST_CASE_ST (ut_setup_asym, ut_teardown_asym, test_sm2_dec),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 +129 -0
129 lines not on this page · raw message
Signature · 1 line
2.25.1
PATCH v3 3/3 crypto/openssl: add SM2 asymmetric crypto support
In reply to Gowrishankar MuthukrishnanAdd 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 | 6 + drivers/crypto/openssl/rte_openssl_pmd.c | 297 +++++++++++++++++++ drivers/crypto/openssl/rte_openssl_pmd_ops.c | 48 +++ 6 files changed, 357 insertions(+)
doc/guides/cryptodevs/features/openssl.ini +1 -0
@@ -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
@@ -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
@@ -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 -------------
drivers/crypto/openssl/openssl_pmd_private.h +6 -0
@@ -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,11 @@ struct openssl_asym_session {OSSL_PARAM_BLD * param_bld;#endif } s; +struct { +#if (OPENSSL_VERSION_NUMBER >=0x30000000L ) +OSSL_PARAM * params; +#endif + } sm2; } u; } __rte_cache_aligned;/** Set and validate OPENSSL crypto session parameters */
drivers/crypto/openssl/rte_openssl_pmd.c +297 -0
321 lines not on this page · raw message
drivers/crypto/openssl/rte_openssl_pmd_ops.c +48 -0
60 lines not on this page · raw message
Signature · 1 line
2.25.1