From cdd997ce99eab8b834e78334f87eb968d67eb3f9 Mon Sep 17 00:00:00 2001 From: JiangShui <1175135535@qq.com> Date: Tue, 31 Oct 2023 16:32:18 +0800 Subject: [PATCH] Backport uadk engine build patch --- ...dk_prov_digest-merge-threshold-table.patch | 293 ++ 0012-uadk-add-uadk_prov_cipher.patch | 944 +++++ ...test-add-prov_cipher-for-openssl-3.0.patch | 63 + ...p-signed-unsigned-mix-with-relationa.patch | 431 +++ ...gine-fixup-variable-naming-conflicts.patch | 334 ++ 0016-digest-fixup-free-source-method.patch | 30 + ...ixup-free-source-method-inconsistent.patch | 30 + ...her-fixup-error-handling-in-ctx-init.patch | 79 + ...ify-setting-async-poll-state-process.patch | 40 + ...-fixup-release-source-of-private-key.patch | 223 ++ ...dd-pkey-method-null-pointer-judgment.patch | 125 + ...elease-source-when-new-kg-out-failed.patch | 31 + 0023-rsa-bugfix-repeated-source-release.patch | 39 + ...unreleased-source-in-data-conversion.patch | 368 ++ ...penssl-method-null-pointer-judgement.patch | 111 + ...e-cleanup-call-form-of-callback-func.patch | 169 + ...ine-cleanup-empty-body-warning-in-v1.patch | 36 + ...heck-version-for-openssl-version-3.0.patch | 43 + 0029-README-fix-openEuler-build-libdir.patch | 29 + ...igest-provider-default-may-not-exist.patch | 95 + ...der-iv_len-in-SM4_ECB-mode-must-be-0.patch | 32 + ...ad-default-provider-into-Global-libr.patch | 71 + ...ndle-the-async_poll_task_free-in-pro.patch | 84 + ...her-iv_len-in-SM4_ECB-mode-must-be-0.patch | 28 + ...cipher-add-handling-of-param-padding.patch | 38 + 0036-uadk_prov_cipher-fix-padding.patch | 605 ++++ 0037-uadk_prov_cipher-add-stream-mode.patch | 189 + ...-xts-mode-does-not-use-default-provi.patch | 44 + ...k_prov_cipher-handle-no-padding-case.patch | 129 + ...hange-provider-name-to-its-full-path.patch | 63 + ...-sanity_test-remove-default-provider.patch | 110 + ...-add-static-descriptor-to-uadk_prov_.patch | 29 + 0043-tentative-ctx-handle-handle.patch | 25 + ...dk-add-uadk_prov_rsa-for-openssl-3.0.patch | 3157 +++++++++++++++++ ...der-add-DOPENSSL_SUPPRESS_DEPRECATED.patch | 36 + 0046-uadk_prov_cipher-fix-build-warning.patch | 46 + ...ov_init-change-name-more-informative.patch | 92 + ...ssion-and-data-when-copy-evp-context.patch | 316 ++ uadk_engine.spec | 43 +- 39 files changed, 8649 insertions(+), 1 deletion(-) create mode 100644 0011-uadk_prov_digest-merge-threshold-table.patch create mode 100644 0012-uadk-add-uadk_prov_cipher.patch create mode 100644 0013-sanity_test-add-prov_cipher-for-openssl-3.0.patch create mode 100644 0014-uadk_engine-fixup-signed-unsigned-mix-with-relationa.patch create mode 100644 0015-uadk_engine-fixup-variable-naming-conflicts.patch create mode 100644 0016-digest-fixup-free-source-method.patch create mode 100644 0017-ecc-fixup-free-source-method-inconsistent.patch create mode 100644 0018-cipher-fixup-error-handling-in-ctx-init.patch create mode 100644 0019-uadk_engine-modify-setting-async-poll-state-process.patch create mode 100644 0020-dh-fixup-release-source-of-private-key.patch create mode 100644 0021-ecc-Add-pkey-method-null-pointer-judgment.patch create mode 100644 0022-rsa-release-source-when-new-kg-out-failed.patch create mode 100644 0023-rsa-bugfix-repeated-source-release.patch create mode 100644 0024-sm2-fixup-unreleased-source-in-data-conversion.patch create mode 100644 0025-ecc-add-openssl-method-null-pointer-judgement.patch create mode 100644 0026-uadk_engine-cleanup-call-form-of-callback-func.patch create mode 100644 0027-uadk_engine-cleanup-empty-body-warning-in-v1.patch create mode 100644 0028-sanity_test.sh-check-version-for-openssl-version-3.0.patch create mode 100644 0029-README-fix-openEuler-build-libdir.patch create mode 100644 0030-uadk_prov_digest-provider-default-may-not-exist.patch create mode 100644 0031-uadk_provider-iv_len-in-SM4_ECB-mode-must-be-0.patch create mode 100644 0032-uadk_provider-load-default-provider-into-Global-libr.patch create mode 100644 0033-uadk_provider-handle-the-async_poll_task_free-in-pro.patch create mode 100644 0034-uadk_cipher-iv_len-in-SM4_ECB-mode-must-be-0.patch create mode 100644 0035-uadk_prov_cipher-add-handling-of-param-padding.patch create mode 100644 0036-uadk_prov_cipher-fix-padding.patch create mode 100644 0037-uadk_prov_cipher-add-stream-mode.patch create mode 100644 0038-uadk_prov_cipher-xts-mode-does-not-use-default-provi.patch create mode 100644 0039-uadk_prov_cipher-handle-no-padding-case.patch create mode 100644 0040-sanity_test.sh-change-provider-name-to-its-full-path.patch create mode 100644 0041-sanity_test-remove-default-provider.patch create mode 100644 0042-uadk_prov_cipher-add-static-descriptor-to-uadk_prov_.patch create mode 100644 0043-tentative-ctx-handle-handle.patch create mode 100644 0044-uadk-add-uadk_prov_rsa-for-openssl-3.0.patch create mode 100644 0045-uadk_provider-add-DOPENSSL_SUPPRESS_DEPRECATED.patch create mode 100644 0046-uadk_prov_cipher-fix-build-warning.patch create mode 100644 0047-uadk_prov_init-change-name-more-informative.patch create mode 100644 0048-digest-alloc-session-and-data-when-copy-evp-context.patch diff --git a/0011-uadk_prov_digest-merge-threshold-table.patch b/0011-uadk_prov_digest-merge-threshold-table.patch new file mode 100644 index 0000000..2eadc2d --- /dev/null +++ b/0011-uadk_prov_digest-merge-threshold-table.patch @@ -0,0 +1,293 @@ +From 9ac731a7ab33306712c101f0c6c6d75dc97c2b87 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 21 Jun 2023 03:13:20 +0000 +Subject: [PATCH 11/48] uadk_prov_digest: merge threshold table + +Merge digest_pkt_threshold_table to digest_info_table +for simplicity. + +Modify func name with uadk_ prefix. + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_digest.c | 120 ++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 73 deletions(-) + +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index fd05753..5456d2d 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -57,11 +57,6 @@ enum sec_digest_state { + SEC_DIGEST_FINAL + }; + +-struct digest_threshold_table { +- int nid; +- int threshold; +-}; +- + struct digest_prov { + int pid; + }; +@@ -104,29 +99,27 @@ struct digest_info { + enum wd_digest_mode mode; + enum wd_digest_type alg; + __u32 out_len; +-}; +- +-static struct digest_threshold_table digest_pkt_threshold_table[] = { +- { NID_sm3, SM3_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_md5, MD5_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_sha1, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_sha224, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_sha256, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_sha384, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, +- { NID_sha512, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT }, ++ __u32 threshold; + }; + + static struct digest_info digest_info_table[] = { +- {NID_md5, WD_DIGEST_NORMAL, WD_DIGEST_MD5, 16}, +- {NID_sm3, WD_DIGEST_NORMAL, WD_DIGEST_SM3, 32}, +- {NID_sha1, WD_DIGEST_NORMAL, WD_DIGEST_SHA1, 20}, +- {NID_sha224, WD_DIGEST_NORMAL, WD_DIGEST_SHA224, 28}, +- {NID_sha256, WD_DIGEST_NORMAL, WD_DIGEST_SHA256, 32}, +- {NID_sha384, WD_DIGEST_NORMAL, WD_DIGEST_SHA384, 48}, +- {NID_sha512, WD_DIGEST_NORMAL, WD_DIGEST_SHA512, 64}, ++ {NID_md5, WD_DIGEST_NORMAL, WD_DIGEST_MD5, ++ 16, MD5_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sm3, WD_DIGEST_NORMAL, WD_DIGEST_SM3, ++ 32, SM3_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sha1, WD_DIGEST_NORMAL, WD_DIGEST_SHA1, ++ 20, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sha224, WD_DIGEST_NORMAL, WD_DIGEST_SHA224, ++ 28, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sha256, WD_DIGEST_NORMAL, WD_DIGEST_SHA256, ++ 32, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sha384, WD_DIGEST_NORMAL, WD_DIGEST_SHA384, ++ 48, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, ++ {NID_sha512, WD_DIGEST_NORMAL, WD_DIGEST_SHA512, ++ 64, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, + }; + +-static int uadk_e_digests_soft_md(struct digest_priv_ctx *priv) ++static int uadk_digests_soft_md(struct digest_priv_ctx *priv) + { + if (priv->soft_md) + return 1; +@@ -163,31 +156,17 @@ static int uadk_e_digests_soft_md(struct digest_priv_ctx *priv) + return 1; + } + +-static uint32_t sec_digest_get_sw_threshold(int n_id) +-{ +- int threshold_table_size = ARRAY_SIZE(digest_pkt_threshold_table); +- int i = 0; +- +- do { +- if (digest_pkt_threshold_table[i].nid == n_id) +- return digest_pkt_threshold_table[i].threshold; +- } while (++i < threshold_table_size); +- +- fprintf(stderr, "nid %d not found in digest threshold table", n_id); +- return 0; +-} +- +-static int digest_soft_init(struct digest_priv_ctx *priv) ++static int uadk_digest_soft_init(struct digest_priv_ctx *priv) + { + return EVP_DigestInit(priv->soft_ctx, priv->soft_md); + } + +-static int digest_soft_update(EVP_MD_CTX *ctx, const void *data, size_t len) ++static int uadk_digest_soft_update(EVP_MD_CTX *ctx, const void *data, size_t len) + { + return EVP_DigestUpdate(ctx, data, len); + } + +-static int digest_soft_final(struct digest_priv_ctx *priv, unsigned char *digest) ++static int uadk_digest_soft_final(struct digest_priv_ctx *priv, unsigned char *digest) + { + unsigned int digest_length = EVP_MD_get_size(priv->soft_md); + +@@ -213,21 +192,21 @@ static void digest_soft_cleanup(struct digest_priv_ctx *priv) + } + } + +-static int uadk_e_digest_soft_work(struct digest_priv_ctx *priv, int len, ++static int uadk_digest_soft_work(struct digest_priv_ctx *priv, int len, + unsigned char *digest) + { +- digest_soft_init(priv); ++ uadk_digest_soft_init(priv); + + if (len != 0) +- digest_soft_update(priv->soft_ctx, priv->data, len); ++ uadk_digest_soft_update(priv->soft_ctx, priv->data, len); + +- digest_soft_final(priv, digest); ++ uadk_digest_soft_final(priv, digest); + digest_soft_cleanup(priv); + + return 1; + } + +-static int uadk_e_digest_env_poll(void *ctx) ++static int uadk_digest_env_poll(void *ctx) + { + __u64 rx_cnt = 0; + __u32 recv = 0; +@@ -262,7 +241,7 @@ static int uadk_digest_init(struct digest_priv_ctx *priv) + goto soft_init; + } + prov.pid = getpid(); +- async_register_poll_fn(ASYNC_TASK_DIGEST, uadk_e_digest_env_poll); ++ async_register_poll_fn(ASYNC_TASK_DIGEST, uadk_digest_env_poll); + } + pthread_mutex_unlock(&digest_mutex); + +@@ -272,6 +251,7 @@ static int uadk_digest_init(struct digest_priv_ctx *priv) + priv->setup.mode = digest_info_table[i].mode; + priv->req.out_buf_bytes = MAX_DIGEST_LENGTH; + priv->req.out_bytes = digest_info_table[i].out_len; ++ priv->switch_threshold = digest_info_table[i].threshold; + break; + } + } +@@ -294,35 +274,29 @@ static int uadk_digest_init(struct digest_priv_ctx *priv) + return 0; + } + +- if (uadk_e_digests_soft_md(priv)) +- priv->switch_threshold = sec_digest_get_sw_threshold(nid); ++ uadk_digests_soft_md(priv); + + return 1; + + soft_init: + pthread_mutex_unlock(&digest_mutex); + fprintf(stderr, "uadk failed to initialize digest.\n"); +- return digest_soft_init(priv); ++ return uadk_digest_soft_init(priv); + } + +-static void digest_update_out_length(struct digest_priv_ctx *priv) ++static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *data, size_t data_len) + { ++ const unsigned char *tmpdata = (const unsigned char *)data; ++ size_t left_len = data_len; ++ int copy_to_bufflen; ++ int ret; ++ + /* Sha224 and Sha384 need full length mac buffer as doing long hash */ + if (priv->e_nid == NID_sha224) + priv->req.out_bytes = WD_DIGEST_SHA224_FULL_LEN; + + if (priv->e_nid == NID_sha384) + priv->req.out_bytes = WD_DIGEST_SHA384_FULL_LEN; +-} +- +-static int digest_update_inner(struct digest_priv_ctx *priv, const void *data, size_t data_len) +-{ +- const unsigned char *tmpdata = (const unsigned char *)data; +- size_t left_len = data_len; +- int copy_to_bufflen; +- int ret; +- +- digest_update_out_length(priv); + + priv->req.has_next = DIGEST_DOING; + +@@ -363,13 +337,13 @@ do_soft_digest: + && priv->data + && priv->last_update_bufflen != 0) { + priv->switch_flag = UADK_DO_SOFT; +- digest_soft_init(priv); +- ret = digest_soft_update(priv->soft_ctx, ++ uadk_digest_soft_init(priv); ++ ret = uadk_digest_soft_update(priv->soft_ctx, + priv->data, priv->last_update_bufflen); + if (ret != 1) + return ret; + +- return digest_soft_update(priv->soft_ctx, ++ return uadk_digest_soft_update(priv->soft_ctx, + tmpdata, left_len); + } + +@@ -388,13 +362,13 @@ static int uadk_digest_update(struct digest_priv_ctx *priv, const void *data, si + return 1; + } + +- return digest_update_inner(priv, data, data_len); ++ return uadk_digest_update_inner(priv, data, data_len); + + soft_update: +- return digest_soft_update(priv->soft_ctx, data, data_len); ++ return uadk_digest_soft_update(priv->soft_ctx, data, data_len); + } + +-static void async_cb(struct wd_digest_req *req, void *data) ++static void uadk_async_cb(struct wd_digest_req *req, void *data) + { + struct uadk_e_cb_info *cb_param; + struct async_op *op; +@@ -413,7 +387,7 @@ static void async_cb(struct wd_digest_req *req, void *data) + } + } + +-static int do_digest_sync(struct digest_priv_ctx *priv) ++static int uadk_do_digest_sync(struct digest_priv_ctx *priv) + { + int ret; + +@@ -429,7 +403,7 @@ static int do_digest_sync(struct digest_priv_ctx *priv) + return 1; + } + +-static int do_digest_async(struct digest_priv_ctx *priv, struct async_op *op) ++static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *op) + { + struct uadk_e_cb_info cb_param; + int idx, ret; +@@ -441,7 +415,7 @@ static int do_digest_async(struct digest_priv_ctx *priv, struct async_op *op) + + cb_param.op = op; + cb_param.priv = priv; +- priv->req.cb = (void *)async_cb; ++ priv->req.cb = (void *)uadk_async_cb; + priv->req.cb_param = &cb_param; + + ret = async_get_free_task(&idx); +@@ -490,16 +464,16 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest + if (op.job == NULL) { + /* Synchronous, only the synchronous mode supports soft computing */ + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { +- ret = digest_soft_final(priv, digest); ++ ret = uadk_digest_soft_final(priv, digest); + digest_soft_cleanup(priv); + goto clear; + } + +- ret = do_digest_sync(priv); ++ ret = uadk_do_digest_sync(priv); + if (!ret) + goto sync_err; + } else { +- ret = do_digest_async(priv, &op); ++ ret = uadk_do_digest_async(priv, &op); + if (!ret) + goto clear; + } +@@ -509,7 +483,7 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest + + sync_err: + if (priv->state == SEC_DIGEST_INIT) { +- ret = uadk_e_digest_soft_work(priv, priv->req.in_bytes, digest); ++ ret = uadk_digest_soft_work(priv, priv->req.in_bytes, digest); + } else { + ret = 0; + fprintf(stderr, "do sec digest stream mode failed.\n"); +-- +2.25.1 + diff --git a/0012-uadk-add-uadk_prov_cipher.patch b/0012-uadk-add-uadk_prov_cipher.patch new file mode 100644 index 0000000..637d976 --- /dev/null +++ b/0012-uadk-add-uadk_prov_cipher.patch @@ -0,0 +1,944 @@ +From 67f7a6d5e934e64abab69fc0cbd7ef4b09bb045e Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Mon, 3 Jul 2023 07:05:17 +0000 +Subject: [PATCH 12/48] uadk: add uadk_prov_cipher + +Test: + +openssl list -provider uadk_provider -cipher-algorithms +openssl speed -provider uadk_provider -provider default -evp sm4-ecb +openssl speed -provider uadk_provider -provider default -evp sm4-cbc +openssl speed -provider uadk_provider -provider default -evp aes-128-cbc + +Signed-off-by: Zhangfei Gao +--- + src/Makefile.am | 3 +- + src/uadk_prov.h | 14 + + src/uadk_prov_cipher.c | 820 +++++++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 31 ++ + 4 files changed, 867 insertions(+), 1 deletion(-) + create mode 100644 src/uadk_prov_cipher.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index bfaeb78..af16d85 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -50,7 +50,8 @@ uadk_engine_la_SOURCES+=v1/alg/ciphers/sec_ciphers.c \ + v1/async/async_task_queue.c + endif #WD_KAE + +-uadk_provider_la_SOURCES=uadk_prov_init.c uadk_prov_digest.c uadk_async.c uadk_utils.c ++uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ ++ uadk_prov_digest.c uadk_prov_cipher.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index c63c3fe..35f1789 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -26,5 +26,19 @@ extern const OSSL_DISPATCH uadk_sha256_functions[]; + extern const OSSL_DISPATCH uadk_sha384_functions[]; + extern const OSSL_DISPATCH uadk_sha512_functions[]; + ++extern const OSSL_DISPATCH uadk_aes_128_cbc_functions[]; ++extern const OSSL_DISPATCH uadk_aes_192_cbc_functions[]; ++extern const OSSL_DISPATCH uadk_aes_256_cbc_functions[]; ++extern const OSSL_DISPATCH uadk_aes_128_ecb_functions[]; ++extern const OSSL_DISPATCH uadk_aes_192_ecb_functions[]; ++extern const OSSL_DISPATCH uadk_aes_256_ecb_functions[]; ++extern const OSSL_DISPATCH uadk_aes_128_xts_functions[]; ++extern const OSSL_DISPATCH uadk_aes_256_xts_functions[]; ++extern const OSSL_DISPATCH uadk_sm4_cbc_functions[]; ++extern const OSSL_DISPATCH uadk_sm4_ecb_functions[]; ++extern const OSSL_DISPATCH uadk_des_ede3_cbc_functions[]; ++extern const OSSL_DISPATCH uadk_des_ede3_ecb_functions[]; ++ + void uadk_prov_destroy_digest(void); ++void uadk_prov_destroy_cipher(void); + #endif +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +new file mode 100644 +index 0000000..af0fa02 +--- /dev/null ++++ b/src/uadk_prov_cipher.c +@@ -0,0 +1,820 @@ ++/* ++ * Copyright 2023-2024 Huawei Technologies Co.,Ltd. All rights reserved. ++ * Copyright 2023-2024 Linaro ltd. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "uadk.h" ++#include "uadk_async.h" ++ ++#define UADK_DO_SOFT (-0xE0) ++#define CTX_SYNC_ENC 0 ++#define CTX_SYNC_DEC 1 ++#define CTX_ASYNC_ENC 2 ++#define CTX_ASYNC_DEC 3 ++#define CTX_NUM 4 ++#define CTR_128BIT_COUNTER 16 ++#define CTR_MODE_LEN_SHIFT 4 ++#define BYTE_BITS 8 ++#define IV_LEN 16 ++#define ENV_ENABLED 1 ++#define MAX_KEY_LEN 64 ++#define ALG_NAME_SIZE 128 ++ ++/* Internal flags that can be queried */ ++#define PROV_CIPHER_FLAG_AEAD 0x0001 ++#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 ++#define PROV_CIPHER_FLAG_CTS 0x0004 ++#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 ++#define PROV_CIPHER_FLAG_RAND_KEY 0x0010 ++ ++/* Internal flags that are only used within the provider */ ++#define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 ++#define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 ++ ++#define SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT 192 ++ ++struct cipher_prov { ++ int pid; ++}; ++static struct cipher_prov prov; ++static pthread_mutex_t cipher_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++struct cipher_priv_ctx { ++ int nid; ++ handle_t sess; ++ struct wd_cipher_sess_setup setup; ++ struct wd_cipher_req req; ++ unsigned char iv[IV_LEN]; ++ unsigned char key[MAX_KEY_LEN]; ++ int switch_flag; ++ EVP_CIPHER_CTX *sw_ctx; ++ EVP_CIPHER *sw_cipher; ++ /* Crypto small packet offload threshold */ ++ size_t switch_threshold; ++ unsigned int enc : 1; ++ size_t blksize; ++ size_t keylen; ++ size_t ivlen; ++ char alg_name[ALG_NAME_SIZE]; ++}; ++ ++struct cipher_info { ++ int nid; ++ enum wd_cipher_alg alg; ++ enum wd_cipher_mode mode; ++ __u32 out_bytes; ++}; ++ ++static struct cipher_info cipher_info_table[] = { ++ { NID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, ++ { NID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, ++ { NID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, ++ { NID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 16}, ++ { NID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, ++ { NID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, ++ { NID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 32}, ++ { NID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 512}, ++ { NID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC, 16}, ++ { NID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC, 16}, ++ { NID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB, 16}, ++ { NID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, ++ { NID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, ++ { NID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, ++ { NID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, ++ { NID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, ++ { NID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, ++ { NID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, ++ { NID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, ++ { NID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, ++ { NID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB, 16}, ++ { NID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB, 16}, ++ { NID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB, 16}, ++ { NID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR, 16}, ++}; ++ ++static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) ++{ ++ if (priv->sw_cipher) ++ return 1; ++ ++ switch (priv->nid) { ++ case NID_aes_128_cbc: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", "provider=default"); ++ case NID_aes_192_cbc: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CBC", "provider=default"); ++ case NID_aes_256_cbc: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC", "provider=default"); ++ case NID_aes_128_ecb: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-ECB", "provider=default"); ++ case NID_aes_192_ecb: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-ECB", "provider=default"); ++ case NID_aes_256_ecb: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-ECB", "provider=default"); ++ case NID_aes_128_xts: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-XTS", "provider=default"); ++ case NID_aes_256_xts: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-XTS", "provider=default"); ++ case NID_sm4_cbc: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); ++ case NID_sm4_ecb: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-ECB", "provider=default"); ++ case NID_des_ede3_cbc: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-CBC", "provider=default"); ++ case NID_des_ede3_ecb: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-ECB", "provider=default"); ++ case NID_aes_128_ctr: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CTR", "provider=default"); ++ case NID_aes_192_ctr: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CTR", "provider=default"); ++ case NID_aes_256_ctr: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CTR", "provider=default"); ++ case NID_aes_128_ofb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-OFB", "provider=default"); ++ case NID_aes_192_ofb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-OFB", "provider=default"); ++ case NID_aes_256_ofb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-OFB", "provider=default"); ++ case NID_aes_128_cfb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CFB", "provider=default"); ++ case NID_aes_192_cfb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CFB", "provider=default"); ++ case NID_aes_256_cfb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CFB", "provider=default"); ++ case NID_sm4_ofb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-OFB", "provider=default"); ++ case NID_sm4_cfb128: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CFB", "provider=default"); ++ case NID_sm4_ctr: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CTR", "provider=default"); ++ default: ++ break; ++ } ++ ++ if (unlikely(priv->sw_cipher == NULL)) { ++ fprintf(stderr, "fail to fetch sw_cipher\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int uadk_prov_cipher_sw_init(struct cipher_priv_ctx *priv, ++ const unsigned char *key, ++ const unsigned char *iv) ++{ ++ if (!uadk_fetch_sw_cipher(priv)) ++ return 0; ++ ++ if (!EVP_CipherInit_ex2(priv->sw_ctx, priv->sw_cipher, key, iv, ++ priv->enc, NULL)) { ++ fprintf(stderr, "SW cipher init error!\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ int sw_final_len = 0; ++ int outlen = 0; ++ ++ if (priv->sw_cipher == NULL) ++ return 0; ++ ++ if (!EVP_CipherUpdate(priv->sw_ctx, out, &outlen, in, len)) { ++ fprintf(stderr, "EVP_CipherUpdate sw_ctx failed.\n"); ++ return 0; ++ } ++ ++ if (!EVP_CipherFinal_ex(priv->sw_ctx, out + outlen, &sw_final_len)) { ++ fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int uadk_cipher_env_poll(void *ctx) ++{ ++ __u64 rx_cnt = 0; ++ __u32 recv = 0; ++ /* Poll one packet currently */ ++ int expt = 1; ++ int ret; ++ ++ do { ++ ret = wd_cipher_poll(expt, &recv); ++ if (ret < 0 || recv == expt) ++ return ret; ++ rx_cnt++; ++ } while (rx_cnt < ENGINE_RECV_MAX_CNT); ++ ++ fprintf(stderr, "failed to poll msg: timeout!\n"); ++ ++ return -ETIMEDOUT; ++} ++ ++static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, ++ const unsigned char *key, size_t keylen, ++ const unsigned char *iv, size_t ivlen) ++{ ++ int cipher_counts = ARRAY_SIZE(cipher_info_table); ++ int ret, i; ++ ++ if (iv) ++ memcpy(priv->iv, iv, ivlen); ++ ++ for (i = 0; i < cipher_counts; i++) { ++ if (priv->nid == cipher_info_table[i].nid) { ++ priv->setup.alg = cipher_info_table[i].alg; ++ priv->setup.mode = cipher_info_table[i].mode; ++ priv->req.out_bytes = cipher_info_table[i].out_bytes; ++ break; ++ } ++ } ++ ++ if (i == cipher_counts) { ++ fprintf(stderr, "failed to setup the private ctx.\n"); ++ return 0; ++ } ++ ++ if (key) { ++ memcpy(priv->key, key, keylen); ++ ret = uadk_prov_cipher_sw_init(priv, key, iv); ++ if (unlikely(ret != 1)) ++ return 0; ++ } ++ ++ priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT; ++ ++ return 1; ++} ++ ++static void async_cb(struct wd_cipher_req *req, void *data) ++{ ++ struct uadk_e_cb_info *cb_param; ++ struct async_op *op; ++ ++ if (!req) ++ return; ++ ++ cb_param = req->cb_param; ++ if (!cb_param) ++ return; ++ ++ op = cb_param->op; ++ if (op && op->job && !op->done) { ++ op->done = 1; ++ async_free_poll_task(op->idx, 1); ++ async_wake_job(op->job); ++ } ++} ++ ++/* Increment counter (128-bit int) by c */ ++static void ctr_iv_inc(uint8_t *counter, __u32 c) ++{ ++ uint32_t n = CTR_128BIT_COUNTER; ++ uint8_t *counter1 = counter; ++ __u32 c_value = c; ++ ++ /* ++ * Since the counter has been increased 1 by the hardware, ++ * so the c need to decrease 1. ++ */ ++ c_value -= 1; ++ do { ++ --n; ++ c_value += counter1[n]; ++ counter1[n] = (uint8_t)c_value; ++ c_value >>= BYTE_BITS; ++ } while (n); ++} ++ ++static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) ++{ ++ __u16 iv_bytes = priv->req.iv_bytes; ++ int offset = priv->req.in_bytes - iv_bytes; ++ unsigned char K[IV_LEN] = {0}; ++ int i; ++ ++ switch (priv->setup.mode) { ++ case WD_CIPHER_CFB: ++ case WD_CIPHER_CBC: ++ if (priv->req.op_type == WD_CIPHER_ENCRYPTION) ++ memcpy(priv->iv, priv->req.dst + offset, iv_bytes); ++ else ++ memcpy(priv->iv, priv->req.src + offset, iv_bytes); ++ ++ break; ++ case WD_CIPHER_OFB: ++ for (i = 0; i < IV_LEN; i++) { ++ K[i] = *((unsigned char *)priv->req.src + offset + i) ^ ++ *((unsigned char *)priv->req.dst + offset + i); ++ } ++ memcpy(priv->iv, K, iv_bytes); ++ break; ++ case WD_CIPHER_CTR: ++ ctr_iv_inc(priv->iv, priv->req.in_bytes >> CTR_MODE_LEN_SHIFT); ++ break; ++ default: ++ break; ++ } ++} ++ ++static int uadk_do_cipher_sync(struct cipher_priv_ctx *priv) ++{ ++ int ret; ++ ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) ++ return 0; ++ ++ if (priv->switch_threshold >= priv->req.in_bytes) ++ return 0; ++ ++ ret = wd_do_cipher_sync(priv->sess, &priv->req); ++ if (ret) ++ return 0; ++ return 1; ++} ++ ++static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *op) ++{ ++ struct uadk_e_cb_info cb_param; ++ int idx, ret; ++ ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { ++ fprintf(stderr, "async cipher init failed.\n"); ++ return 0; ++ } ++ ++ cb_param.op = op; ++ cb_param.priv = priv; ++ priv->req.cb = (void *)async_cb; ++ priv->req.cb_param = &cb_param; ++ ret = async_get_free_task(&idx); ++ if (!ret) ++ return 0; ++ ++ op->idx = idx; ++ do { ++ ret = wd_do_cipher_async(priv->sess, &priv->req); ++ if (ret < 0 && ret != -EBUSY) { ++ fprintf(stderr, "do sec cipher failed, switch to soft cipher.\n"); ++ async_free_poll_task(op->idx, 0); ++ return 0; ++ } ++ } while (ret == -EBUSY); ++ ++ ret = async_pause_job(priv, op, ASYNC_TASK_CIPHER, idx); ++ if (!ret) ++ return 0; ++ return 1; ++} ++ ++static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) ++{ ++ struct sched_params params = {0}; ++ int ret; ++ ++ priv->req.iv_bytes = priv->ivlen; ++ priv->req.iv = priv->iv; ++ ++ if (priv->switch_flag == UADK_DO_SOFT) ++ return; ++ ++ pthread_mutex_lock(&cipher_mutex); ++ if (prov.pid != getpid()) { ++ ret = wd_cipher_init2(priv->alg_name, 0, 0); ++ if (unlikely(ret)) { ++ priv->switch_flag = UADK_DO_SOFT; ++ pthread_mutex_unlock(&cipher_mutex); ++ fprintf(stderr, "uadk failed to init cipher HW!\n"); ++ return; ++ } ++ prov.pid = getpid(); ++ async_register_poll_fn(ASYNC_TASK_CIPHER, uadk_cipher_env_poll); ++ } ++ pthread_mutex_unlock(&cipher_mutex); ++ ++ params.type = priv->req.op_type; ++ /* Use the default numa parameters */ ++ params.numa_id = -1; ++ priv->setup.sched_param = ¶ms; ++ ++ if (!priv->sess) { ++ priv->sess = wd_cipher_alloc_sess(&priv->setup); ++ if (!priv->sess) ++ fprintf(stderr, "uadk failed to alloc session!\n"); ++ } ++ ++ ret = wd_cipher_set_key(priv->sess, priv->key, priv->keylen); ++ if (ret) { ++ wd_cipher_free_sess(priv->sess); ++ priv->sess = 0; ++ fprintf(stderr, "uadk failed to set key!\n"); ++ } ++} ++ ++static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, ++ const unsigned char *in, size_t inlen) ++{ ++ struct async_op op; ++ int ret; ++ ++ priv->req.src = (unsigned char *)in; ++ priv->req.in_bytes = inlen; ++ priv->req.dst = out; ++ priv->req.out_buf_bytes = inlen; ++ ++ uadk_prov_cipher_ctx_init(priv); ++ ret = async_setup_async_event_notification(&op); ++ if (!ret) { ++ fprintf(stderr, "failed to setup async event notification.\n"); ++ return 0; ++ } ++ ++ if (op.job == NULL) { ++ /* Synchronous, only the synchronous mode supports soft computing */ ++ ret = uadk_do_cipher_sync(priv); ++ if (!ret) ++ goto sync_err; ++ } else { ++ /* ++ * If the length of the input data ++ * does not reach to hardware computing threshold, ++ * directly switch to soft cipher. ++ */ ++ if (priv->req.in_bytes <= priv->switch_threshold) ++ goto sync_err; ++ ++ ret = uadk_do_cipher_async(priv, &op); ++ if (!ret) ++ goto out_notify; ++ } ++ uadk_cipher_update_priv_ctx(priv); ++ ++ return 1; ++sync_err: ++ ret = uadk_prov_cipher_soft_work(priv, out, in, inlen); ++ if (ret != 1) ++ fprintf(stderr, "do soft ciphers failed.\n"); ++out_notify: ++ async_clear_async_event_notification(); ++ return ret; ++} ++ ++void uadk_prov_destroy_cipher(void) ++{ ++ pthread_mutex_lock(&cipher_mutex); ++ if (prov.pid == getpid()) { ++ wd_cipher_uninit2(); ++ prov.pid = 0; ++ } ++ pthread_mutex_unlock(&cipher_mutex); ++} ++ ++static OSSL_FUNC_cipher_encrypt_init_fn uadk_prov_cipher_einit; ++static OSSL_FUNC_cipher_decrypt_init_fn uadk_prov_cipher_dinit; ++static OSSL_FUNC_cipher_freectx_fn uadk_prov_cipher_freectx; ++static OSSL_FUNC_cipher_get_ctx_params_fn uadk_prov_cipher_get_ctx_params; ++static OSSL_FUNC_cipher_gettable_ctx_params_fn uadk_prov_cipher_gettable_ctx_params; ++static OSSL_FUNC_cipher_set_ctx_params_fn uadk_prov_cipher_set_ctx_params; ++static OSSL_FUNC_cipher_settable_ctx_params_fn uadk_prov_cipher_settable_ctx_params; ++ ++static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, ++ size_t outsize, const unsigned char *in, ++ size_t inl) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int ret; ++ ++ if (inl == 0) { ++ *outl = 0; ++ return 1; ++ } ++ ++ if (outsize < inl) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ ++ ret = uadk_prov_do_cipher(priv, out, in, inl); ++ if (ret != 1) ++ return ret; ++ ++ *outl = inl; ++ return 1; ++ ++} ++ ++static int uadk_prov_cipher_final(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize) ++{ ++ *outl = 0; ++ return 1; ++} ++ ++static int uadk_prov_cipher_update(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inl) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int ret; ++ ++ if (inl == 0) { ++ *outl = 0; ++ return 1; ++ } ++ ++ if (outsize < inl) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ ++ ret = uadk_prov_do_cipher(priv, out, in, inl); ++ if (ret != 1) ++ return ret; ++ ++ *outl = inl; ++ return 1; ++} ++ ++static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t keylen, ++ const unsigned char *iv, size_t ivlen, ++ const OSSL_PARAM params[]) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int ret; ++ ++ priv->req.op_type = WD_CIPHER_ENCRYPTION; ++ priv->enc = 1; ++ ++ ret = uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); ++ if (unlikely(ret != 1)) ++ return 0; ++ ++ return 1; ++} ++ ++static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t keylen, ++ const unsigned char *iv, size_t ivlen, ++ const OSSL_PARAM params[]) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int ret; ++ ++ priv->req.op_type = WD_CIPHER_DECRYPTION; ++ priv->enc = 0; ++ ++ ret = uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); ++ if (unlikely(ret != 1)) ++ return 0; ++ ++ return 1; ++} ++ ++static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_END ++}; ++ ++const OSSL_PARAM *uadk_prov_cipher_settable_ctx_params(ossl_unused void *cctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_settable_ctx_params; ++} ++ ++static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ const OSSL_PARAM *p; ++ int ret = 1; ++ ++ if (params == NULL) ++ return 1; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p != NULL) { ++ size_t keylen; ++ ++ if (!OSSL_PARAM_get_size_t(p, &keylen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); ++ return 0; ++ } ++ if (priv->keylen != keylen) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); ++ return 0; ++ } ++ } ++ ++ return ret; ++} ++ ++static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p != NULL && !OSSL_PARAM_set_size_t(p, priv->keylen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); ++ if (p != NULL && !OSSL_PARAM_set_size_t(p, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); ++ if (p != NULL && !OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) ++ && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); ++ if (p != NULL && !OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) ++ && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ return 1; ++} ++ ++static const OSSL_PARAM uadk_prov_default_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++const OSSL_PARAM *uadk_prov_cipher_gettable_ctx_params(ossl_unused void *cctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_default_ctx_params; ++} ++ ++static const OSSL_PARAM cipher_known_gettable_params[] = { ++ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_prov_cipher_gettable_params(ossl_unused void *provctx) ++{ ++ return cipher_known_gettable_params; ++} ++ ++static int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, ++ uint64_t flags, size_t kbits, ++ size_t blkbits, size_t ivbits) ++{ ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); ++ if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); ++ if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); ++ if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); ++ if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ return 1; ++} ++ ++static void uadk_prov_cipher_freectx(void *ctx) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)ctx; ++ ++ EVP_CIPHER_free(priv->sw_cipher); ++ EVP_CIPHER_CTX_free(priv->sw_ctx); ++ ++ if (priv->sess) { ++ wd_cipher_free_sess(priv->sess); ++ priv->sess = 0; ++ } ++ OPENSSL_clear_free(priv, sizeof(*priv)); ++} ++ ++#define UADK_CIPHER_DESCR(nm, blk_size, key_len, iv_len, \ ++ flags, e_nid, algnm, mode) \ ++static OSSL_FUNC_cipher_newctx_fn uadk_##nm##_newctx; \ ++static void *uadk_##nm##_newctx(void *provctx) \ ++{ \ ++ struct cipher_priv_ctx *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ ++ \ ++ if (ctx == NULL) \ ++ return NULL; \ ++ ctx->blksize = blk_size; \ ++ ctx->keylen = key_len; \ ++ ctx->ivlen = iv_len; \ ++ ctx->nid = e_nid; \ ++ ctx->sw_ctx = EVP_CIPHER_CTX_new(); \ ++ if (ctx->sw_ctx == NULL) \ ++ fprintf(stderr, "EVP_CIPHER_CTX_new failed.\n"); \ ++ strncpy(ctx->alg_name, #algnm, ALG_NAME_SIZE - 1); \ ++ return ctx; \ ++} \ ++static OSSL_FUNC_cipher_get_params_fn uadk_##nm##_get_params; \ ++static int uadk_##nm##_get_params(OSSL_PARAM params[]) \ ++{ \ ++ return ossl_cipher_generic_get_params(params, mode, flags, \ ++ key_len, blk_size, iv_len); \ ++} \ ++const OSSL_DISPATCH uadk_##nm##_functions[] = { \ ++ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))uadk_##nm##_newctx }, \ ++ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))uadk_prov_cipher_freectx }, \ ++ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, \ ++ (void (*)(void))uadk_prov_cipher_einit }, \ ++ { OSSL_FUNC_CIPHER_DECRYPT_INIT, \ ++ (void (*)(void))uadk_prov_cipher_dinit }, \ ++ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))uadk_prov_cipher_update }, \ ++ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))uadk_prov_cipher_final }, \ ++ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))uadk_prov_cipher_cipher }, \ ++ { OSSL_FUNC_CIPHER_GET_PARAMS, \ ++ (void (*)(void))uadk_##nm##_get_params }, \ ++ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ ++ (void (*)(void))uadk_prov_cipher_gettable_params }, \ ++ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_cipher_get_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_cipher_gettable_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_cipher_set_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_cipher_settable_ctx_params }, \ ++ { 0, NULL } \ ++} ++ ++UADK_CIPHER_DESCR(aes_128_cbc, 16, 16, 16, 0, NID_aes_128_cbc, cbc(aes), EVP_CIPH_CBC_MODE); ++UADK_CIPHER_DESCR(aes_192_cbc, 16, 24, 16, 0, NID_aes_192_cbc, cbc(aes), EVP_CIPH_CBC_MODE); ++UADK_CIPHER_DESCR(aes_256_cbc, 16, 32, 16, 0, NID_aes_256_cbc, cbc(aes), EVP_CIPH_CBC_MODE); ++UADK_CIPHER_DESCR(aes_128_ecb, 16, 16, 0, 0, NID_aes_128_ecb, ecb(aes), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(aes_192_ecb, 16, 24, 0, 0, NID_aes_192_ecb, ecb(aes), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, NID_aes_256_ecb, ecb(aes), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, 0, NID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); ++UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, 0, NID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); ++UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, NID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE); ++UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 16, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, NID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE); ++UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, NID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE); ++ ++/* v3 */ ++UADK_CIPHER_DESCR(aes_128_ctr, 1, 16, 16, 0, NID_aes_128_ctr, ctr(aes), EVP_CIPH_CTR_MODE); ++UADK_CIPHER_DESCR(aes_192_ctr, 1, 24, 16, 0, NID_aes_192_ctr, ctr(aes), EVP_CIPH_CTR_MODE); ++UADK_CIPHER_DESCR(aes_256_ctr, 1, 32, 16, 0, NID_aes_256_ctr, ctr(aes), EVP_CIPH_CTR_MODE); ++UADK_CIPHER_DESCR(aes_128_ofb128, 1, 16, 16, 0, NID_aes_128_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); ++UADK_CIPHER_DESCR(aes_192_ofb128, 1, 24, 16, 0, NID_aes_192_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); ++UADK_CIPHER_DESCR(aes_256_ofb128, 1, 32, 16, 0, NID_aes_256_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); ++UADK_CIPHER_DESCR(aes_128_cfb128, 1, 16, 16, 0, NID_aes_128_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); ++UADK_CIPHER_DESCR(aes_192_cfb128, 1, 24, 16, 0, NID_aes_192_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); ++UADK_CIPHER_DESCR(aes_256_cfb128, 1, 32, 16, 0, NID_aes_256_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); ++UADK_CIPHER_DESCR(sm4_ofb128, 1, 16, 16, 0, NID_sm4_ofb128, ofb(sm4), EVP_CIPH_OFB_MODE); ++UADK_CIPHER_DESCR(sm4_cfb128, 1, 16, 16, 0, NID_sm4_cfb128, cfb(sm4), EVP_CIPH_CFB_MODE); ++UADK_CIPHER_DESCR(sm4_ctr, 1, 16, 16, 0, NID_sm4_ctr, ctr(sm4), EVP_CIPH_CTR_MODE); +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index e363584..b59a4e8 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -52,6 +52,34 @@ const OSSL_ALGORITHM uadk_prov_digests[] = { + { NULL, NULL, NULL } + }; + ++const OSSL_ALGORITHM uadk_prov_ciphers[] = { ++ { "AES-128-CBC", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_128_cbc_functions, "uadk_provider aes-128-cbc" }, ++ { "AES-192-CBC", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_192_cbc_functions, "uadk_provider aes-192-cbc" }, ++ { "AES-256-CBC", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_256_cbc_functions, "uadk_provider aes-256-cbc" }, ++ { "AES-128-ECB", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_128_ecb_functions, "uadk_provider aes-128-ecb" }, ++ { "AES-192-ECB", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_192_ecb_functions, "uadk_provider aes-192-ecb" }, ++ { "AES-256-ECB", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_256_ecb_functions, "uadk_provider aes-256-ecb" }, ++ { "AES-128-XTS", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_128_xts_functions, "uadk_provider aes-128-xts" }, ++ { "AES-256-XTS", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_256_xts_functions, "uadk_provider aes-256-xts" }, ++ { "SM4-CBC:SM4", UADK_DEFAULT_PROPERTIES, ++ uadk_sm4_cbc_functions, "uadk_provider sm4-cbc" }, ++ { "SM4-ECB", UADK_DEFAULT_PROPERTIES, ++ uadk_sm4_ecb_functions, "uadk_provider sm4-ecb" }, ++ { "DES-EDE3-CBC", UADK_DEFAULT_PROPERTIES, ++ uadk_des_ede3_cbc_functions, "uadk_provider des-ede3-cbc" }, ++ { "DES-EDE3-ECB", UADK_DEFAULT_PROPERTIES, ++ uadk_des_ede3_ecb_functions, "uadk_provider des-ede3-ecb" }, ++ { NULL, NULL, NULL } ++}; ++ + static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + int *no_cache) + { +@@ -60,6 +88,8 @@ static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + switch (operation_id) { + case OSSL_OP_DIGEST: + return uadk_prov_digests; ++ case OSSL_OP_CIPHER: ++ return uadk_prov_ciphers; + } + return NULL; + } +@@ -69,6 +99,7 @@ static void p_teardown(void *provctx) + struct p_uadk_ctx *ctx = (struct p_uadk_ctx *)provctx; + + uadk_prov_destroy_digest(); ++ uadk_prov_destroy_cipher(); + OPENSSL_free(ctx); + } + +-- +2.25.1 + diff --git a/0013-sanity_test-add-prov_cipher-for-openssl-3.0.patch b/0013-sanity_test-add-prov_cipher-for-openssl-3.0.patch new file mode 100644 index 0000000..e142317 --- /dev/null +++ b/0013-sanity_test-add-prov_cipher-for-openssl-3.0.patch @@ -0,0 +1,63 @@ +From 398c8b00dac8bd71e00d1d48c726a7402552ea15 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 5 Jul 2023 03:19:35 +0000 +Subject: [PATCH 13/48] sanity_test: add prov_cipher for openssl 3.0 + +Add sanity test of cipher in openssl 3.0 + +Signed-off-by: Zhangfei Gao +--- + test/sanity_test.sh | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/test/sanity_test.sh b/test/sanity_test.sh +index 899d02c..d46c570 100755 +--- a/test/sanity_test.sh ++++ b/test/sanity_test.sh +@@ -14,6 +14,7 @@ if [[ $version =~ "3.0" ]]; then + fi + + digest_algs=$(openssl list -provider $engine_id -digest-algorithms) ++ cipher_algs=$(openssl list -provider $engine_id -digest-algorithms) + fi + + if [[ $digest_algs =~ "uadk_provider" ]]; then +@@ -35,6 +36,35 @@ if [[ $digest_algs =~ "uadk_provider" ]]; then + openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha2-512 + fi + ++if [[ $cipher_algs =~ "uadk_provider" ]]; then ++ echo "uadk_provider testing cipher" ++ openssl speed -provider $engine_id -provider default -evp aes-128-cbc ++ openssl speed -provider $engine_id -provider default -evp aes-192-cbc ++ openssl speed -provider $engine_id -provider default -evp aes-256-cbc ++ openssl speed -provider $engine_id -provider default -evp aes-128-ecb ++ openssl speed -provider $engine_id -provider default -evp aes-192-ecb ++ openssl speed -provider $engine_id -provider default -evp aes-256-ecb ++ openssl speed -provider $engine_id -provider default -evp aes-128-xts ++ openssl speed -provider $engine_id -provider default -evp aes-256-xts ++ openssl speed -provider $engine_id -provider default -evp sm4-cbc ++ openssl speed -provider $engine_id -provider default -evp sm4-ecb ++ openssl speed -provider $engine_id -provider default -evp des-ede3-cbc ++ openssl speed -provider $engine_id -provider default -evp des-ede3-ecb ++ ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-cbc ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-192-cbc ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-cbc ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-ecb ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-192-ecb ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-ecb ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-xts ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-xts ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sm4-cbc ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sm4-ecb ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp des-ede3-cbc ++ openssl speed -provider $engine_id -provider default -async_jobs 1 -evp des-ede3-ecb ++fi ++ + if [[ $version =~ "1.1.1" ]]; then + echo "openssl 1.1.1" + if [ ! -n "$1" ]; then +-- +2.25.1 + diff --git a/0014-uadk_engine-fixup-signed-unsigned-mix-with-relationa.patch b/0014-uadk_engine-fixup-signed-unsigned-mix-with-relationa.patch new file mode 100644 index 0000000..ceb1f75 --- /dev/null +++ b/0014-uadk_engine-fixup-signed-unsigned-mix-with-relationa.patch @@ -0,0 +1,431 @@ +From a0f9f17748a12f86385a39100177da5c6b7c1619 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Thu, 15 Jun 2023 19:31:57 +0800 +Subject: [PATCH 14/48] uadk_engine: fixup signed-unsigned mix with relational + +Fixup the following variable type issues: +1. Perform type conversion, using the same type in expressions. +2. Fixup subscript may be negative and signed-unsigned mix with + relational problems. + +Signed-off-by: Zhiqi Song +--- + src/uadk_cipher.c | 19 ++++++++++--------- + src/uadk_dh.c | 38 +++++++++++++++++++++++--------------- + src/uadk_digest.c | 11 +++++++---- + src/uadk_ec.c | 2 +- + src/uadk_ecx.c | 18 +++++++++--------- + src/uadk_pkey.c | 13 ++++++++----- + src/uadk_rsa.c | 3 ++- + src/uadk_utils.h | 1 - + 8 files changed, 60 insertions(+), 45 deletions(-) + +diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c +index 940c26c..05223ae 100644 +--- a/src/uadk_cipher.c ++++ b/src/uadk_cipher.c +@@ -203,8 +203,8 @@ static struct cipher_info cipher_info_table[] = { + + static const EVP_CIPHER *sec_ciphers_get_cipher_sw_impl(int n_id) + { +- int sec_cipher_sw_table_size = ARRAY_SIZE(sec_ciphers_sw_table); +- int i; ++ __u32 sec_cipher_sw_table_size = ARRAY_SIZE(sec_ciphers_sw_table); ++ __u32 i; + + for (i = 0; i < sec_cipher_sw_table_size; i++) { + if (n_id == sec_ciphers_sw_table[i].nid) +@@ -348,10 +348,9 @@ static int uadk_get_accel_platform(char *alg_name) + static int uadk_e_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) + { +- int ret = 1; + int *cipher_nids; +- int size; +- int i; ++ __u32 size, i; ++ int ret = 1; + + if (platform == HW_V2) { + size = (sizeof(cipher_hw_v2_nids) - 1) / sizeof(int); +@@ -665,8 +664,9 @@ static int uadk_e_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + { + struct cipher_priv_ctx *priv = + (struct cipher_priv_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); +- int cipher_counts = ARRAY_SIZE(cipher_info_table); +- int nid, ret, i; ++ __u32 cipher_counts = ARRAY_SIZE(cipher_info_table); ++ int nid, ret; ++ __u32 i; + + if (unlikely(!key)) { + fprintf(stderr, "ctx init parameter key is NULL.\n"); +@@ -762,7 +762,7 @@ static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) + __u16 iv_bytes = priv->req.iv_bytes; + int offset = priv->req.in_bytes - iv_bytes; + unsigned char K[IV_LEN] = {0}; +- int i; ++ __u32 i; + + switch (priv->setup.mode) { + case WD_CIPHER_CFB: +@@ -1150,7 +1150,8 @@ static void destroy_v3_cipher(void) + + void uadk_e_destroy_cipher(void) + { +- int i, ret; ++ __u32 i; ++ int ret; + + if (engine.pid == getpid()) { + ret = uadk_e_is_env_enabled("cipher"); +diff --git a/src/uadk_dh.c b/src/uadk_dh.c +index 89157d2..c5ef813 100644 +--- a/src/uadk_dh.c ++++ b/src/uadk_dh.c +@@ -67,7 +67,7 @@ struct uadk_dh_sess { + struct wd_dh_sess_setup setup; + struct wd_dh_req req; + DH *alg; +- uint32_t key_size; ++ __u16 key_size; + }; + + struct dh_res { +@@ -316,7 +316,7 @@ static int uadk_e_wd_dh_init(struct dh_res_config *config, struct uacce_dev *dev + struct wd_sched *sched = &config->sched.wd_sched; + struct wd_ctx_config *ctx_cfg; + int ret = 0; +- int i; ++ __u32 i; + + ret = uadk_e_is_env_enabled("dh"); + if (ret == ENV_ENABLED) +@@ -406,7 +406,8 @@ err_unlock: + static void uadk_e_wd_dh_uninit(void) + { + struct wd_ctx_config *ctx_cfg = g_dh_res.ctx_res; +- int i, ret; ++ __u32 i; ++ int ret; + + if (g_dh_res.pid == getpid()) { + ret = uadk_e_is_env_enabled("dh"); +@@ -440,9 +441,9 @@ static struct uadk_dh_sess *dh_new_eng_session(DH *dh_alg) + } + + static int dh_init_eng_session(struct uadk_dh_sess *dh_sess, +- int bits, bool is_g2) ++ __u16 bits, bool is_g2) + { +- uint32_t key_size = (uint32_t)bits >> CHAR_BIT_SIZE; ++ __u16 key_size = bits >> CHAR_BIT_SIZE; + struct sched_params params = {0}; + + if (dh_sess->sess && dh_sess->req.x_p) { +@@ -453,7 +454,7 @@ static int dh_init_eng_session(struct uadk_dh_sess *dh_sess, + + if (!dh_sess->sess) { + dh_sess->key_size = key_size; +- dh_sess->setup.key_bits = dh_sess->key_size << CHAR_BIT_SIZE; ++ dh_sess->setup.key_bits = bits; + dh_sess->setup.is_g2 = is_g2; + params.numa_id = g_dh_res.numa_id; + dh_sess->setup.sched_param = ¶ms; +@@ -482,7 +483,7 @@ static void dh_free_eng_session(struct uadk_dh_sess *dh_sess) + OPENSSL_free(dh_sess); + } + +-static struct uadk_dh_sess *dh_get_eng_session(DH *dh, int bits, ++static struct uadk_dh_sess *dh_get_eng_session(DH *dh, __u16 bits, + bool is_g2) + { + struct uadk_dh_sess *dh_sess = dh_new_eng_session(dh); +@@ -500,9 +501,10 @@ static struct uadk_dh_sess *dh_get_eng_session(DH *dh, int bits, + return dh_sess; + } + +-static int check_dh_bit_useful(const int bits) ++static int check_dh_bit_useful(const __u16 bits) + { +- /* Check whether bits exceeds the limit. ++ /* ++ * Check whether bits exceeds the limit. + * The max module bits of openssl soft alg is + * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. + * OpenSSL speed tool supports 2048/3072/4096/6144/8192 bits. +@@ -524,7 +526,7 @@ static int check_dh_bit_useful(const int bits) + return UADK_E_FAIL; + } + +-static int dh_prepare_data(const int bits, const BIGNUM *g, DH *dh, ++static int dh_prepare_data(const __u16 bits, const BIGNUM *g, DH *dh, + struct uadk_dh_sess **dh_sess, + BIGNUM **priv_key) + { +@@ -552,7 +554,7 @@ static int dh_prepare_data(const int bits, const BIGNUM *g, DH *dh, + return ret; + } + +-static int dh_set_g(const BIGNUM *g, const int key_size, ++static int dh_set_g(const BIGNUM *g, const __u16 key_size, + unsigned char *ag_bin, struct uadk_dh_sess *dh_sess) + { + struct wd_dtb g_dtb; +@@ -592,7 +594,7 @@ static int dh_fill_genkey_req(const BIGNUM *g, const BIGNUM *p, + const BIGNUM *priv_key, + struct uadk_dh_sess *dh_sess) + { +- int key_size = dh_sess->key_size; ++ __u16 key_size = dh_sess->key_size; + unsigned char *apriv_key_bin; + unsigned char *ag_bin; + unsigned char *ap_bin; +@@ -642,7 +644,7 @@ static int dh_fill_compkey_req(const BIGNUM *g, const BIGNUM *p, + const BIGNUM *priv_key, const BIGNUM *pub_key, + struct uadk_dh_sess *dh_sess) + { +- int key_size = dh_sess->key_size; ++ __u16 key_size = dh_sess->key_size; + unsigned char *apriv_key_bin; + unsigned char *ap_bin; + unsigned char *ag_bin; +@@ -759,10 +761,10 @@ static int uadk_e_dh_generate_key(DH *dh) + struct uadk_dh_sess *dh_sess = NULL; + BIGNUM *priv_key = NULL; + BIGNUM *pub_key = NULL; +- int bits = DH_bits(dh); + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; + const BIGNUM *q = NULL; ++ __u16 bits; + int ret; + + if (!dh) +@@ -776,6 +778,12 @@ static int uadk_e_dh_generate_key(DH *dh) + if (!p || !g || q) + goto exe_soft; + ++ /* ++ * The max module bits of DH is ++ * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. ++ */ ++ bits = (__u16)DH_bits(dh); ++ + /* Get session and prepare private key */ + ret = dh_prepare_data(bits, g, dh, &dh_sess, &priv_key); + if (!ret) { +@@ -819,8 +827,8 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh) + { + struct uadk_dh_sess *dh_sess = NULL; ++ __u16 bits = (__u16)DH_bits(dh); + BIGNUM *priv_key = NULL; +- int bits = DH_bits(dh); + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; + const BIGNUM *q = NULL; +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index b7718e6..94b2636 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -418,7 +418,8 @@ static int uadk_e_wd_digest_env_init(struct uacce_dev *dev) + + static int uadk_e_wd_digest_init(struct uacce_dev *dev) + { +- int ret, i, j; ++ __u32 i, j; ++ int ret; + + engine.numa_id = dev->numa_id; + +@@ -527,10 +528,11 @@ static int uadk_e_digest_init(EVP_MD_CTX *ctx) + { + struct digest_priv_ctx *priv = + (struct digest_priv_ctx *) EVP_MD_CTX_md_data(ctx); +- int digest_counts = ARRAY_SIZE(digest_info_table); ++ __u32 digest_counts = ARRAY_SIZE(digest_info_table); + int nid = EVP_MD_nid(EVP_MD_CTX_md(ctx)); + struct sched_params params = {0}; +- int ret, i; ++ __u32 i; ++ int ret; + + priv->e_nid = nid; + +@@ -911,7 +913,8 @@ int uadk_e_bind_digest(ENGINE *e) + + void uadk_e_destroy_digest(void) + { +- int i, ret; ++ __u32 i; ++ int ret; + + if (engine.pid == getpid()) { + ret = uadk_e_is_env_enabled("digest"); +diff --git a/src/uadk_ec.c b/src/uadk_ec.c +index 69ad4e8..d7ad815 100644 +--- a/src/uadk_ec.c ++++ b/src/uadk_ec.c +@@ -74,7 +74,7 @@ static void init_dtb_param(void *dtb, char *start, + { + struct wd_dtb *tmp = dtb; + char *buff = start; +- int i = 0; ++ __u32 i = 0; + + while (i++ < num) { + tmp->data = buff; +diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c +index 0537890..e45fa5e 100644 +--- a/src/uadk_ecx.c ++++ b/src/uadk_ecx.c +@@ -42,13 +42,13 @@ struct ecx_key { + + struct ecx_ctx { + handle_t sess; +- int key_size; ++ __u32 key_size; + int nid; + }; + +-static int reverse_bytes(unsigned char *to_buf, unsigned int size) ++static int reverse_bytes(unsigned char *to_buf, __u32 size) + { +- unsigned char *tmp_buf = to_buf + size - 1; ++ unsigned char *tmp_buf; + unsigned char tmp; + + if (!size) { +@@ -61,6 +61,7 @@ static int reverse_bytes(unsigned char *to_buf, unsigned int size) + return UADK_E_FAIL; + } + ++ tmp_buf = to_buf + size - 1; + while (to_buf < tmp_buf) { + tmp = *tmp_buf; + *tmp_buf-- = *to_buf; +@@ -234,7 +235,7 @@ static int ecx_get_nid(EVP_PKEY_CTX *ctx) + return nid; + } + +-static int ecx_create_privkey(struct ecx_key **ecx_key, int key_size) ++static int ecx_create_privkey(struct ecx_key **ecx_key, __u32 key_size) + { + unsigned char *privkey; + int ret; +@@ -293,12 +294,12 @@ static int ecx_keygen_set_private_key(struct ecx_ctx *ecx_ctx, + static int ecx_keygen_set_pkey(EVP_PKEY *pkey, struct ecx_ctx *ecx_ctx, + struct wd_ecc_req *req, struct ecx_key *ecx_key) + { ++ __u32 key_size = ecx_ctx->key_size; + struct wd_ecc_point *pubkey = NULL; +- int key_size = ecx_ctx->key_size; + int ret; + + if (key_size > ECX_MAX_KEYLEN) { +- fprintf(stderr, "invalid key size, key_size = %d\n", key_size); ++ fprintf(stderr, "invalid key size, key_size = %u\n", key_size); + return UADK_E_FAIL; + } + +@@ -308,8 +309,7 @@ static int ecx_keygen_set_pkey(EVP_PKEY *pkey, struct ecx_ctx *ecx_ctx, + return UADK_E_FAIL; + } + +- memcpy(ecx_key->pubkey, (const unsigned char *)pubkey->x.data, +- key_size); ++ memcpy(ecx_key->pubkey, (const unsigned char *)pubkey->x.data, key_size); + /* Trans public key from big-endian to little-endian */ + ret = reverse_bytes(ecx_key->pubkey, key_size); + if (!ret) { +@@ -507,7 +507,7 @@ static int ecx_compkey_init_iot(struct ecx_ctx *ecx_ctx, struct wd_ecc_req *req, + struct ecx_key *peer_ecx_key, + struct ecx_key *ecx_key) + { +- int key_size = ecx_ctx->key_size; ++ __u32 key_size = ecx_ctx->key_size; + char buf_y[ECX_MAX_KEYLEN] = {0}; + handle_t sess = ecx_ctx->sess; + struct wd_ecc_point in_pubkey; +diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c +index ba33b7d..b24c196 100644 +--- a/src/uadk_pkey.c ++++ b/src/uadk_pkey.c +@@ -197,7 +197,8 @@ static int uadk_e_wd_ecc_general_init(struct uacce_dev *dev, + struct wd_sched *sched) + { + struct wd_ctx_config *ctx_cfg; +- int ret, i; ++ __u32 i; ++ int ret; + + ctx_cfg = calloc(1, sizeof(struct wd_ctx_config)); + if (!ctx_cfg) +@@ -258,7 +259,8 @@ static int uadk_wd_ecc_init(struct ecc_res_config *config, struct uacce_dev *dev + static void uadk_wd_ecc_uninit(void) + { + struct wd_ctx_config *ctx_cfg = ecc_res.ctx_res; +- int i, ret; ++ __u32 i; ++ int ret; + + if (ecc_res.pid != getpid()) + return; +@@ -328,7 +330,7 @@ err: + + bool uadk_is_all_zero(const unsigned char *data, size_t dlen) + { +- int i; ++ size_t i; + + for (i = 0; i < dlen; i++) { + if (data[i]) +@@ -559,7 +561,7 @@ const EVP_PKEY_METHOD *get_openssl_pkey_meth(int nid) + size_t count = EVP_PKEY_meth_get_count(); + const EVP_PKEY_METHOD *pmeth; + int pkey_id = -1; +- int i; ++ size_t i; + + for (i = 0; i < count; i++) { + pmeth = EVP_PKEY_meth_get0(i); +@@ -636,7 +638,8 @@ void uadk_e_ecc_lock_init(void) + int uadk_e_bind_ecc(ENGINE *e) + { + static const char * const ecc_alg[] = {"sm2", "ecdsa", "ecdh", "x25519", "x448"}; +- int i, size, ret; ++ __u32 i, size; ++ int ret; + bool sp; + + /* Enumerate ecc algs to check whether it is supported and set tags */ +diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c +index 8af0844..23deb3c 100644 +--- a/src/uadk_rsa.c ++++ b/src/uadk_rsa.c +@@ -828,7 +828,8 @@ err_unlock: + static void uadk_e_rsa_uninit(void) + { + struct wd_ctx_config *ctx_cfg = g_rsa_res.ctx_res; +- int i, ret; ++ __u32 i; ++ int ret; + + if (g_rsa_res.pid == getpid()) { + ret = uadk_e_is_env_enabled("rsa"); +diff --git a/src/uadk_utils.h b/src/uadk_utils.h +index a16536b..028eb15 100644 +--- a/src/uadk_utils.h ++++ b/src/uadk_utils.h +@@ -17,7 +17,6 @@ + #ifndef UADK_UTILS + #define UADK_UTILS + #include +-#include + #include + + void *uadk_memcpy(void *dstpp, const void *srcpp, size_t len); +-- +2.25.1 + diff --git a/0015-uadk_engine-fixup-variable-naming-conflicts.patch b/0015-uadk_engine-fixup-variable-naming-conflicts.patch new file mode 100644 index 0000000..6099022 --- /dev/null +++ b/0015-uadk_engine-fixup-variable-naming-conflicts.patch @@ -0,0 +1,334 @@ +From 77a9e5523fad8473438c55ce5601bf0fabbb7279 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:27:32 +0800 +Subject: [PATCH 15/48] uadk_engine: fixup variable naming conflicts + +Use different global variable name in cipher and +digest algs. + +Signed-off-by: Zhiqi Song +--- + src/uadk_cipher.c | 80 +++++++++++++++++++++++------------------------ + src/uadk_digest.c | 64 ++++++++++++++++++------------------- + 2 files changed, 72 insertions(+), 72 deletions(-) + +diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c +index 05223ae..76680dd 100644 +--- a/src/uadk_cipher.c ++++ b/src/uadk_cipher.c +@@ -47,7 +47,7 @@ struct cipher_engine { + pthread_spinlock_t lock; + }; + +-static struct cipher_engine engine; ++static struct cipher_engine g_cipher_engine; + + struct sw_cipher_t { + int nid; +@@ -562,41 +562,41 @@ static int uadk_e_wd_cipher_init(struct uacce_dev *dev) + { + int ret, i, j; + +- engine.numa_id = dev->numa_id; ++ g_cipher_engine.numa_id = dev->numa_id; + + ret = uadk_e_is_env_enabled("cipher"); + if (ret == ENV_ENABLED) + return uadk_e_wd_cipher_env_init(dev); + +- memset(&engine.ctx_cfg, 0, sizeof(struct wd_ctx_config)); +- engine.ctx_cfg.ctx_num = CTX_NUM; +- engine.ctx_cfg.ctxs = calloc(CTX_NUM, sizeof(struct wd_ctx)); +- if (!engine.ctx_cfg.ctxs) ++ memset(&g_cipher_engine.ctx_cfg, 0, sizeof(struct wd_ctx_config)); ++ g_cipher_engine.ctx_cfg.ctx_num = CTX_NUM; ++ g_cipher_engine.ctx_cfg.ctxs = calloc(CTX_NUM, sizeof(struct wd_ctx)); ++ if (!g_cipher_engine.ctx_cfg.ctxs) + return -ENOMEM; + + for (i = 0; i < CTX_NUM; i++) { +- engine.ctx_cfg.ctxs[i].ctx = wd_request_ctx(dev); +- if (!engine.ctx_cfg.ctxs[i].ctx) { ++ g_cipher_engine.ctx_cfg.ctxs[i].ctx = wd_request_ctx(dev); ++ if (!g_cipher_engine.ctx_cfg.ctxs[i].ctx) { + ret = -ENOMEM; + goto err_freectx; + } + } + +- engine.ctx_cfg.ctxs[CTX_SYNC_ENC].op_type = CTX_TYPE_ENCRYPT; +- engine.ctx_cfg.ctxs[CTX_SYNC_DEC].op_type = CTX_TYPE_DECRYPT; +- engine.ctx_cfg.ctxs[CTX_ASYNC_ENC].op_type = CTX_TYPE_ENCRYPT; +- engine.ctx_cfg.ctxs[CTX_ASYNC_DEC].op_type = CTX_TYPE_DECRYPT; +- engine.ctx_cfg.ctxs[CTX_SYNC_ENC].ctx_mode = CTX_MODE_SYNC; +- engine.ctx_cfg.ctxs[CTX_SYNC_DEC].ctx_mode = CTX_MODE_SYNC; +- engine.ctx_cfg.ctxs[CTX_ASYNC_ENC].ctx_mode = CTX_MODE_ASYNC; +- engine.ctx_cfg.ctxs[CTX_ASYNC_DEC].ctx_mode = CTX_MODE_ASYNC; +- +- engine.sched.name = "sched_single"; +- engine.sched.pick_next_ctx = sched_single_pick_next_ctx; +- engine.sched.poll_policy = sched_single_poll_policy; +- engine.sched.sched_init = sched_single_init; +- +- ret = wd_cipher_init(&engine.ctx_cfg, &engine.sched); ++ g_cipher_engine.ctx_cfg.ctxs[CTX_SYNC_ENC].op_type = CTX_TYPE_ENCRYPT; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_SYNC_DEC].op_type = CTX_TYPE_DECRYPT; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_ASYNC_ENC].op_type = CTX_TYPE_ENCRYPT; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_ASYNC_DEC].op_type = CTX_TYPE_DECRYPT; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_SYNC_ENC].ctx_mode = CTX_MODE_SYNC; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_SYNC_DEC].ctx_mode = CTX_MODE_SYNC; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_ASYNC_ENC].ctx_mode = CTX_MODE_ASYNC; ++ g_cipher_engine.ctx_cfg.ctxs[CTX_ASYNC_DEC].ctx_mode = CTX_MODE_ASYNC; ++ ++ g_cipher_engine.sched.name = "sched_single"; ++ g_cipher_engine.sched.pick_next_ctx = sched_single_pick_next_ctx; ++ g_cipher_engine.sched.poll_policy = sched_single_poll_policy; ++ g_cipher_engine.sched.sched_init = sched_single_init; ++ ++ ret = wd_cipher_init(&g_cipher_engine.ctx_cfg, &g_cipher_engine.sched); + if (ret) + goto err_freectx; + +@@ -606,9 +606,9 @@ static int uadk_e_wd_cipher_init(struct uacce_dev *dev) + + err_freectx: + for (j = 0; j < i; j++) +- wd_release_ctx(engine.ctx_cfg.ctxs[j].ctx); ++ wd_release_ctx(g_cipher_engine.ctx_cfg.ctxs[j].ctx); + +- free(engine.ctx_cfg.ctxs); ++ free(g_cipher_engine.ctx_cfg.ctxs); + + return ret; + } +@@ -618,16 +618,16 @@ static int uadk_e_init_cipher(void) + struct uacce_dev *dev; + int ret; + +- if (engine.pid != getpid()) { +- pthread_spin_lock(&engine.lock); +- if (engine.pid == getpid()) { +- pthread_spin_unlock(&engine.lock); ++ if (g_cipher_engine.pid != getpid()) { ++ pthread_spin_lock(&g_cipher_engine.lock); ++ if (g_cipher_engine.pid == getpid()) { ++ pthread_spin_unlock(&g_cipher_engine.lock); + return 1; + } + + dev = wd_get_accel_dev("cipher"); + if (!dev) { +- pthread_spin_unlock(&engine.lock); ++ pthread_spin_unlock(&g_cipher_engine.lock); + fprintf(stderr, "failed to get device for cipher.\n"); + return 0; + } +@@ -636,15 +636,15 @@ static int uadk_e_init_cipher(void) + if (ret) + goto err_unlock; + +- engine.pid = getpid(); +- pthread_spin_unlock(&engine.lock); ++ g_cipher_engine.pid = getpid(); ++ pthread_spin_unlock(&g_cipher_engine.lock); + free(dev); + } + + return 1; + + err_unlock: +- pthread_spin_unlock(&engine.lock); ++ pthread_spin_unlock(&g_cipher_engine.lock); + free(dev); + fprintf(stderr, "failed to init cipher(%d).\n", ret); + +@@ -1153,20 +1153,20 @@ void uadk_e_destroy_cipher(void) + __u32 i; + int ret; + +- if (engine.pid == getpid()) { ++ if (g_cipher_engine.pid == getpid()) { + ret = uadk_e_is_env_enabled("cipher"); + if (ret == ENV_ENABLED) { + wd_cipher_env_uninit(); + } else { + wd_cipher_uninit(); +- for (i = 0; i < engine.ctx_cfg.ctx_num; i++) +- wd_release_ctx(engine.ctx_cfg.ctxs[i].ctx); +- free(engine.ctx_cfg.ctxs); ++ for (i = 0; i < g_cipher_engine.ctx_cfg.ctx_num; i++) ++ wd_release_ctx(g_cipher_engine.ctx_cfg.ctxs[i].ctx); ++ free(g_cipher_engine.ctx_cfg.ctxs); + } +- engine.pid = 0; ++ g_cipher_engine.pid = 0; + } + +- pthread_spin_destroy(&engine.lock); ++ pthread_spin_destroy(&g_cipher_engine.lock); + + destroy_v2_cipher(); + if (platform > HW_V2) +@@ -1175,5 +1175,5 @@ void uadk_e_destroy_cipher(void) + + void uadk_e_cipher_lock_init(void) + { +- pthread_spin_init(&engine.lock, PTHREAD_PROCESS_PRIVATE); ++ pthread_spin_init(&g_cipher_engine.lock, PTHREAD_PROCESS_PRIVATE); + } +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index 94b2636..984127e 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -73,7 +73,7 @@ struct digest_engine { + pthread_spinlock_t lock; + }; + +-static struct digest_engine engine; ++static struct digest_engine g_digest_engine; + + struct evp_md_ctx_st { + const EVP_MD *digest; +@@ -421,36 +421,36 @@ static int uadk_e_wd_digest_init(struct uacce_dev *dev) + __u32 i, j; + int ret; + +- engine.numa_id = dev->numa_id; ++ g_digest_engine.numa_id = dev->numa_id; + + ret = uadk_e_is_env_enabled("digest"); + if (ret == ENV_ENABLED) + return uadk_e_wd_digest_env_init(dev); + +- memset(&engine.ctx_cfg, 0, sizeof(struct wd_ctx_config)); +- engine.ctx_cfg.ctx_num = CTX_NUM; +- engine.ctx_cfg.ctxs = calloc(CTX_NUM, sizeof(struct wd_ctx)); +- if (!engine.ctx_cfg.ctxs) ++ memset(&g_digest_engine.ctx_cfg, 0, sizeof(struct wd_ctx_config)); ++ g_digest_engine.ctx_cfg.ctx_num = CTX_NUM; ++ g_digest_engine.ctx_cfg.ctxs = calloc(CTX_NUM, sizeof(struct wd_ctx)); ++ if (!g_digest_engine.ctx_cfg.ctxs) + return -ENOMEM; + + for (i = 0; i < CTX_NUM; i++) { +- engine.ctx_cfg.ctxs[i].ctx = wd_request_ctx(dev); +- if (!engine.ctx_cfg.ctxs[i].ctx) { ++ g_digest_engine.ctx_cfg.ctxs[i].ctx = wd_request_ctx(dev); ++ if (!g_digest_engine.ctx_cfg.ctxs[i].ctx) { + ret = -ENOMEM; + goto err_freectx; + } + +- engine.ctx_cfg.ctxs[i].op_type = CTX_TYPE_ENCRYPT; +- engine.ctx_cfg.ctxs[i].ctx_mode = ++ g_digest_engine.ctx_cfg.ctxs[i].op_type = CTX_TYPE_ENCRYPT; ++ g_digest_engine.ctx_cfg.ctxs[i].ctx_mode = + (i == 0) ? CTX_MODE_SYNC : CTX_MODE_ASYNC; + } + +- engine.sched.name = "sched_single"; +- engine.sched.pick_next_ctx = sched_single_pick_next_ctx; +- engine.sched.poll_policy = sched_single_poll_policy; +- engine.sched.sched_init = sched_single_init; ++ g_digest_engine.sched.name = "sched_single"; ++ g_digest_engine.sched.pick_next_ctx = sched_single_pick_next_ctx; ++ g_digest_engine.sched.poll_policy = sched_single_poll_policy; ++ g_digest_engine.sched.sched_init = sched_single_init; + +- ret = wd_digest_init(&engine.ctx_cfg, &engine.sched); ++ ret = wd_digest_init(&g_digest_engine.ctx_cfg, &g_digest_engine.sched); + if (ret) + goto err_freectx; + +@@ -460,9 +460,9 @@ static int uadk_e_wd_digest_init(struct uacce_dev *dev) + + err_freectx: + for (j = 0; j < i; j++) +- wd_release_ctx(engine.ctx_cfg.ctxs[j].ctx); ++ wd_release_ctx(g_digest_engine.ctx_cfg.ctxs[j].ctx); + +- free(engine.ctx_cfg.ctxs); ++ free(g_digest_engine.ctx_cfg.ctxs); + + return ret; + } +@@ -472,16 +472,16 @@ static int uadk_e_init_digest(void) + struct uacce_dev *dev; + int ret; + +- if (engine.pid != getpid()) { +- pthread_spin_lock(&engine.lock); +- if (engine.pid == getpid()) { +- pthread_spin_unlock(&engine.lock); ++ if (g_digest_engine.pid != getpid()) { ++ pthread_spin_lock(&g_digest_engine.lock); ++ if (g_digest_engine.pid == getpid()) { ++ pthread_spin_unlock(&g_digest_engine.lock); + return 1; + } + + dev = wd_get_accel_dev("digest"); + if (!dev) { +- pthread_spin_unlock(&engine.lock); ++ pthread_spin_unlock(&g_digest_engine.lock); + fprintf(stderr, "failed to get device for digest.\n"); + return 0; + } +@@ -490,15 +490,15 @@ static int uadk_e_init_digest(void) + if (ret) + goto err_unlock; + +- engine.pid = getpid(); +- pthread_spin_unlock(&engine.lock); ++ g_digest_engine.pid = getpid(); ++ pthread_spin_unlock(&g_digest_engine.lock); + free(dev); + } + + return 1; + + err_unlock: +- pthread_spin_unlock(&engine.lock); ++ pthread_spin_unlock(&g_digest_engine.lock); + free(dev); + fprintf(stderr, "failed to init digest(%d).\n", ret); + +@@ -860,7 +860,7 @@ do { \ + + void uadk_e_digest_lock_init(void) + { +- pthread_spin_init(&engine.lock, PTHREAD_PROCESS_PRIVATE); ++ pthread_spin_init(&g_digest_engine.lock, PTHREAD_PROCESS_PRIVATE); + } + + int uadk_e_bind_digest(ENGINE *e) +@@ -916,20 +916,20 @@ void uadk_e_destroy_digest(void) + __u32 i; + int ret; + +- if (engine.pid == getpid()) { ++ if (g_digest_engine.pid == getpid()) { + ret = uadk_e_is_env_enabled("digest"); + if (ret == ENV_ENABLED) { + wd_digest_env_uninit(); + } else { + wd_digest_uninit(); +- for (i = 0; i < engine.ctx_cfg.ctx_num; i++) +- wd_release_ctx(engine.ctx_cfg.ctxs[i].ctx); +- free(engine.ctx_cfg.ctxs); ++ for (i = 0; i < g_digest_engine.ctx_cfg.ctx_num; i++) ++ wd_release_ctx(g_digest_engine.ctx_cfg.ctxs[i].ctx); ++ free(g_digest_engine.ctx_cfg.ctxs); + } +- engine.pid = 0; ++ g_digest_engine.pid = 0; + } + +- pthread_spin_destroy(&engine.lock); ++ pthread_spin_destroy(&g_digest_engine.lock); + + EVP_MD_meth_free(uadk_md5); + uadk_md5 = 0; +-- +2.25.1 + diff --git a/0016-digest-fixup-free-source-method.patch b/0016-digest-fixup-free-source-method.patch new file mode 100644 index 0000000..7ec2c65 --- /dev/null +++ b/0016-digest-fixup-free-source-method.patch @@ -0,0 +1,30 @@ +From 1d402a0166a432073f065a8dc66252b13560b81b Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:29:38 +0800 +Subject: [PATCH 16/48] digest: fixup free source method + +Fix the issue of inconsistent interfaces used for +resource application and release in init and cleanp +process. + +Signed-off-by: Zhiqi Song +--- + src/uadk_digest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index 984127e..590a888 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -816,7 +816,7 @@ static int uadk_e_digest_cleanup(EVP_MD_CTX *ctx) + } + + if (priv && priv->data) +- OPENSSL_free(priv->data); ++ free(priv->data); + + return 1; + } +-- +2.25.1 + diff --git a/0017-ecc-fixup-free-source-method-inconsistent.patch b/0017-ecc-fixup-free-source-method-inconsistent.patch new file mode 100644 index 0000000..929cafa --- /dev/null +++ b/0017-ecc-fixup-free-source-method-inconsistent.patch @@ -0,0 +1,30 @@ +From 4f2cf55360921292716e68a44a4111126e1849b4 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:31:29 +0800 +Subject: [PATCH 17/48] ecc: fixup free source method inconsistent + +EC_POINT_point2buf() use OPENSSL_malloc() to allocate +memory for 'point_bin', we should use OPENSSL_free() +to release it, rather than free(). + +Signed-off-by: Zhiqi Song +--- + src/uadk_pkey.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c +index b24c196..35a2696 100644 +--- a/src/uadk_pkey.c ++++ b/src/uadk_pkey.c +@@ -375,7 +375,7 @@ int uadk_ecc_set_public_key(handle_t sess, const EC_KEY *eckey) + ret = UADK_DO_SOFT; + } + +- free(point_bin); ++ OPENSSL_free(point_bin); + + return ret; + } +-- +2.25.1 + diff --git a/0018-cipher-fixup-error-handling-in-ctx-init.patch b/0018-cipher-fixup-error-handling-in-ctx-init.patch new file mode 100644 index 0000000..0fb89a6 --- /dev/null +++ b/0018-cipher-fixup-error-handling-in-ctx-init.patch @@ -0,0 +1,79 @@ +From 89deb2fdea506068f0819cfd039b109e47ddc86b Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Thu, 13 Jul 2023 20:00:14 +0800 +Subject: [PATCH 18/48] cipher: fixup error handling in ctx init + +When wd_cipher_alloc_sess() failed, it should return in +error handling branch. Fixed this problem and make related +operation clearer. + +Signed-off-by: Zhiqi Song +--- + src/uadk_cipher.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c +index 76680dd..d4ad33c 100644 +--- a/src/uadk_cipher.c ++++ b/src/uadk_cipher.c +@@ -717,7 +717,7 @@ static int uadk_e_cipher_cleanup(EVP_CIPHER_CTX *ctx) + return 1; + } + +-static void async_cb(struct wd_cipher_req *req, void *data) ++static void uadk_e_cipher_cb(struct wd_cipher_req *req, void *data) + { + struct uadk_e_cb_info *cb_param; + struct async_op *op; +@@ -792,10 +792,16 @@ static int do_cipher_sync(struct cipher_priv_ctx *priv) + { + int ret; + +- if (unlikely(priv->switch_flag == UADK_DO_SOFT)) ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { ++ fprintf(stderr, "switch to soft cipher.\n"); + return 0; ++ } + +- if (priv->switch_threshold >= priv->req.in_bytes) ++ /* ++ * If the length of the input data does not reach to hardware computing threshold, ++ * directly switch to soft cipher. ++ */ ++ if (priv->req.in_bytes <= priv->switch_threshold) + return 0; + + ret = wd_do_cipher_sync(priv->sess, &priv->req); +@@ -810,14 +816,15 @@ static int do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *op) + int idx, ret; + + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { +- fprintf(stderr, "async cipher init failed.\n"); ++ fprintf(stderr, "switch to soft cipher.\n"); + return 0; + } + + cb_param.op = op; + cb_param.priv = priv; +- priv->req.cb = (void *)async_cb; ++ priv->req.cb = (void *)uadk_e_cipher_cb; + priv->req.cb_param = &cb_param; ++ + ret = async_get_free_task(&idx); + if (!ret) + return 0; +@@ -889,8 +896,10 @@ static void uadk_e_ctx_init(EVP_CIPHER_CTX *ctx, struct cipher_priv_ctx *priv) + } + + priv->sess = wd_cipher_alloc_sess(&priv->setup); +- if (!priv->sess) ++ if (!priv->sess) { + fprintf(stderr, "uadk failed to alloc session!\n"); ++ return; ++ } + } + + ret = wd_cipher_set_key(priv->sess, priv->key, EVP_CIPHER_CTX_key_length(ctx)); +-- +2.25.1 + diff --git a/0019-uadk_engine-modify-setting-async-poll-state-process.patch b/0019-uadk_engine-modify-setting-async-poll-state-process.patch new file mode 100644 index 0000000..ede6a9b --- /dev/null +++ b/0019-uadk_engine-modify-setting-async-poll-state-process.patch @@ -0,0 +1,40 @@ +From ccb3f9c8c0294bd466c1bf1b053f966cb12f9476 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:35:46 +0800 +Subject: [PATCH 19/48] uadk_engine: modify setting async poll state process + +To avoid accessing async task conflict in obtaining and +releasing async task process, disable async poll state +before free the async task. + +Signed-off-by: Zhiqi Song +--- + src/uadk_async.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/uadk_async.c b/src/uadk_async.c +index 86aa9e5..dfac1cb 100644 +--- a/src/uadk_async.c ++++ b/src/uadk_async.c +@@ -117,6 +117,9 @@ static void async_poll_task_free(void) + int error; + struct async_poll_task *task; + ++ /* Disable async poll state first */ ++ uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); ++ + error = pthread_mutex_lock(&poll_queue.async_task_mutex); + if (error != 0) + return; +@@ -127,8 +130,6 @@ static void async_poll_task_free(void) + + poll_queue.head = NULL; + +- uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); +- + pthread_mutex_unlock(&poll_queue.async_task_mutex); + sem_destroy(&poll_queue.empty_sem); + sem_destroy(&poll_queue.full_sem); +-- +2.25.1 + diff --git a/0020-dh-fixup-release-source-of-private-key.patch b/0020-dh-fixup-release-source-of-private-key.patch new file mode 100644 index 0000000..534d52c --- /dev/null +++ b/0020-dh-fixup-release-source-of-private-key.patch @@ -0,0 +1,223 @@ +From d07d9f91151efe4103143022721cc1e9de86b546 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:38:56 +0800 +Subject: [PATCH 20/48] dh: fixup release source of private key + +The private key that allocated in dh_prepare_data() should +be released in error handling branch. Fixed this problem +and cleanup the related functions. + +Signed-off-by: Zhiqi Song +--- + src/uadk_dh.c | 82 ++++++++++++++++++++++++--------------------------- + 1 file changed, 39 insertions(+), 43 deletions(-) + +diff --git a/src/uadk_dh.c b/src/uadk_dh.c +index c5ef813..fc91609 100644 +--- a/src/uadk_dh.c ++++ b/src/uadk_dh.c +@@ -51,6 +51,7 @@ + #define UADK_E_POLL_FAIL (-1) + #define UADK_E_INIT_SUCCESS 0 + #define ENV_ENABLED 1 ++#define KEY_GEN_BY_ENGINE 1 + + static DH_METHOD *uadk_dh_method; + +@@ -68,6 +69,8 @@ struct uadk_dh_sess { + struct wd_dh_req req; + DH *alg; + __u16 key_size; ++ /* key_flag: 0 - key is defined by user, 1 - key is generated by engine */ ++ int key_flag; + }; + + struct dh_res { +@@ -162,30 +165,24 @@ static int dh_generate_new_priv_key(const DH *dh, BIGNUM *new_priv_key) + return UADK_E_SUCCESS; + } + +-static int dh_try_get_priv_key(const DH *dh, BIGNUM **priv_key) ++static int dh_try_get_priv_key(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **priv_key) + { +- int generate_new_key = 0; +- BIGNUM *new_priv_key; +- + *priv_key = (BIGNUM *)DH_get0_priv_key(dh); + if (!(*priv_key)) { +- new_priv_key = BN_secure_new(); +- if (!new_priv_key) +- goto err; +- generate_new_key = 1; +- } ++ *priv_key = BN_secure_new(); ++ if (!(*priv_key)) ++ return UADK_E_FAIL; + +- if (generate_new_key) { +- if (!dh_generate_new_priv_key(dh, new_priv_key)) ++ if (!dh_generate_new_priv_key(dh, *priv_key)) + goto err; +- else +- *priv_key = new_priv_key; ++ ++ dh_sess->key_flag = KEY_GEN_BY_ENGINE; + } + + return UADK_E_SUCCESS; + + err: +- BN_free(new_priv_key); ++ BN_free(*priv_key); + return UADK_E_FAIL; + } + +@@ -526,13 +523,19 @@ static int check_dh_bit_useful(const __u16 bits) + return UADK_E_FAIL; + } + +-static int dh_prepare_data(const __u16 bits, const BIGNUM *g, DH *dh, ++static int dh_prepare_data(const BIGNUM *g, DH *dh, + struct uadk_dh_sess **dh_sess, + BIGNUM **priv_key) + { + bool is_g2 = BN_is_word(g, DH_GENERATOR_2); ++ __u16 bits; + int ret; + ++ /* ++ * The max module bits of DH is ++ * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. ++ */ ++ bits = (__u16)DH_bits(dh); + ret = check_dh_bit_useful(bits); + if (!ret) { + fprintf(stderr, "op size is not supported by uadk engine\n"); +@@ -545,8 +548,8 @@ static int dh_prepare_data(const __u16 bits, const BIGNUM *g, DH *dh, + return UADK_E_FAIL; + } + +- ret = dh_try_get_priv_key(dh, priv_key); +- if (!ret || !(*priv_key)) { ++ ret = dh_try_get_priv_key(*dh_sess, dh, priv_key); ++ if (!ret) { + dh_free_eng_session(*dh_sess); + return UADK_E_FAIL; + } +@@ -764,7 +767,6 @@ static int uadk_e_dh_generate_key(DH *dh) + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; + const BIGNUM *q = NULL; +- __u16 bits; + int ret; + + if (!dh) +@@ -778,14 +780,8 @@ static int uadk_e_dh_generate_key(DH *dh) + if (!p || !g || q) + goto exe_soft; + +- /* +- * The max module bits of DH is +- * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. +- */ +- bits = (__u16)DH_bits(dh); +- + /* Get session and prepare private key */ +- ret = dh_prepare_data(bits, g, dh, &dh_sess, &priv_key); ++ ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); + if (!ret) { + fprintf(stderr, "prepare dh data failed\n"); + goto exe_soft; +@@ -794,30 +790,30 @@ static int uadk_e_dh_generate_key(DH *dh) + ret = dh_fill_genkey_req(g, p, priv_key, dh_sess); + if (!ret) { + fprintf(stderr, "failed to fill req\n"); +- ret = UADK_DO_SOFT; +- goto free_sess; ++ goto free_data; + } + + ret = dh_do_crypto(dh_sess); + if (!ret) { + fprintf(stderr, "failed to generate DH key\n"); +- ret = UADK_DO_SOFT; +- goto free_sess; ++ goto free_data; + } + + ret = dh_get_pubkey(dh_sess, &pub_key); + if (!ret) { + fprintf(stderr, "failed to get public key\n"); +- ret = UADK_DO_SOFT; +- goto free_sess; ++ goto free_data; + } + + ret = dh_soft_set_pkey(dh, pub_key, priv_key); ++ dh_free_eng_session(dh_sess); + +-free_sess: ++ return ret; ++ ++free_data: ++ if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) ++ BN_free(priv_key); + dh_free_eng_session(dh_sess); +- if (ret != UADK_DO_SOFT) +- return ret; + exe_soft: + fprintf(stderr, "switch to execute openssl software calculation.\n"); + return uadk_e_dh_soft_generate_key(dh); +@@ -827,7 +823,6 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh) + { + struct uadk_dh_sess *dh_sess = NULL; +- __u16 bits = (__u16)DH_bits(dh); + BIGNUM *priv_key = NULL; + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; +@@ -845,7 +840,7 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + if (!p || !g) + goto exe_soft; + +- ret = dh_prepare_data(bits, g, dh, &dh_sess, &priv_key); ++ ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); + if (!ret) { + fprintf(stderr, "failed to prepare dh data\n"); + goto exe_soft; +@@ -854,24 +849,25 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + ret = dh_fill_compkey_req(g, p, priv_key, pub_key, dh_sess); + if (!ret) { + fprintf(stderr, "failed to fill req\n"); +- ret = UADK_DO_SOFT; +- goto free_sess; ++ goto free_data; + } + + ret = dh_do_crypto(dh_sess); + if (!ret) { + fprintf(stderr, "failed to generate DH shared key\n"); +- ret = UADK_DO_SOFT; +- goto free_sess; ++ goto free_data; + } + + memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); + ret = dh_sess->req.pri_bytes; ++ dh_free_eng_session(dh_sess); + +-free_sess: ++ return ret; ++ ++free_data: ++ if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) ++ BN_free(priv_key); + dh_free_eng_session(dh_sess); +- if (ret != UADK_DO_SOFT) +- return ret; + exe_soft: + fprintf(stderr, "switch to execute openssl software calculation.\n"); + return uadk_e_dh_soft_compute_key(key, pub_key, dh); +-- +2.25.1 + diff --git a/0021-ecc-Add-pkey-method-null-pointer-judgment.patch b/0021-ecc-Add-pkey-method-null-pointer-judgment.patch new file mode 100644 index 0000000..8e40b42 --- /dev/null +++ b/0021-ecc-Add-pkey-method-null-pointer-judgment.patch @@ -0,0 +1,125 @@ +From 5eaaad42f162a6cc998c9de232a83ed3f609ddae Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:42:06 +0800 +Subject: [PATCH 21/48] ecc: Add pkey method null pointer judgment + +Add pkey method null pointer judgement for function +get_openssl_pkey_meth(), avoid accessing null pointer +in abnormal cases. + +Signed-off-by: Zhiqi Song +--- + src/uadk_ec.c | 5 +++++ + src/uadk_ecx.c | 8 ++++++++ + src/uadk_sm2.c | 25 +++++++++++++++++++++++++ + 3 files changed, 38 insertions(+) + +diff --git a/src/uadk_ec.c b/src/uadk_ec.c +index d7ad815..781e7f1 100644 +--- a/src/uadk_ec.c ++++ b/src/uadk_ec.c +@@ -1418,6 +1418,11 @@ int uadk_ec_create_pmeth(struct uadk_pkey_meth *pkey_meth) + } + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_EC); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get ec pkey methods\n"); ++ return 0; ++ } ++ + EVP_PKEY_meth_copy(meth, openssl_meth); + + pkey_meth->ec = meth; +diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c +index e45fa5e..aebd808 100644 +--- a/src/uadk_ecx.c ++++ b/src/uadk_ecx.c +@@ -811,6 +811,10 @@ int uadk_x25519_create_pmeth(struct uadk_pkey_meth *pkey_meth) + } + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_X25519); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get x25519 pkey methods\n"); ++ return UADK_E_FAIL; ++ } + + EVP_PKEY_meth_copy(meth, openssl_meth); + +@@ -852,6 +856,10 @@ int uadk_x448_create_pmeth(struct uadk_pkey_meth *pkey_meth) + } + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_X448); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get x448 pkey methods\n"); ++ return UADK_E_FAIL; ++ } + + EVP_PKEY_meth_copy(meth, openssl_meth); + +diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c +index 63d4fdf..1f678ed 100644 +--- a/src/uadk_sm2.c ++++ b/src/uadk_sm2.c +@@ -279,6 +279,11 @@ static int openssl_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + PFUNC_SIGN sign_pfunc = NULL; + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ return -1; ++ } ++ + EVP_PKEY_meth_get_sign(openssl_meth, NULL, &sign_pfunc); + if (!sign_pfunc) { + fprintf(stderr, "sign_pfunc is NULL\n"); +@@ -296,6 +301,11 @@ static int openssl_verify(EVP_PKEY_CTX *ctx, + PFUNC_VERIFY verify_pfunc = NULL; + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ return -1; ++ } ++ + EVP_PKEY_meth_get_verify(openssl_meth, NULL, &verify_pfunc); + if (!verify_pfunc) { + fprintf(stderr, "verify_pfunc is NULL\n"); +@@ -313,6 +323,11 @@ static int openssl_encrypt(EVP_PKEY_CTX *ctx, + PFUNC_DEC enc_pfunc = NULL; + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ return -1; ++ } ++ + EVP_PKEY_meth_get_encrypt(openssl_meth, NULL, &enc_pfunc); + if (!enc_pfunc) { + fprintf(stderr, "enc_pfunc is NULL\n"); +@@ -330,6 +345,11 @@ static int openssl_decrypt(EVP_PKEY_CTX *ctx, + PFUNC_ENC dec_pfunc = NULL; + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ return -1; ++ } ++ + EVP_PKEY_meth_get_decrypt(openssl_meth, NULL, &dec_pfunc); + if (!dec_pfunc) { + fprintf(stderr, "dec_pfunc is NULL\n"); +@@ -1614,6 +1634,11 @@ int uadk_sm2_create_pmeth(struct uadk_pkey_meth *pkey_meth) + } + + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ return -1; ++ } ++ + EVP_PKEY_meth_copy(meth, openssl_meth); + + if (!uadk_e_ecc_get_support_state(SM2_SUPPORT)) { +-- +2.25.1 + diff --git a/0022-rsa-release-source-when-new-kg-out-failed.patch b/0022-rsa-release-source-when-new-kg-out-failed.patch new file mode 100644 index 0000000..6ef4166 --- /dev/null +++ b/0022-rsa-release-source-when-new-kg-out-failed.patch @@ -0,0 +1,31 @@ +From b9aac679244764bf876b5fcfbdae088bfd01234a Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:44:04 +0800 +Subject: [PATCH 22/48] rsa: release source when new kg out failed + +Release req.src when wd_rsa_new_kg_out() failed. + +Signed-off-by: Zhiqi Song +--- + src/uadk_rsa.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c +index 23deb3c..8669455 100644 +--- a/src/uadk_rsa.c ++++ b/src/uadk_rsa.c +@@ -1188,8 +1188,10 @@ static int rsa_fill_keygen_data(struct uadk_rsa_sess *rsa_sess, + return UADK_E_FAIL; + + rsa_sess->req.dst = wd_rsa_new_kg_out(rsa_sess->sess); +- if (!rsa_sess->req.dst) ++ if (!rsa_sess->req.dst) { ++ wd_rsa_del_kg_in(rsa_sess->sess, rsa_sess->req.src); + return UADK_E_FAIL; ++ } + + return UADK_E_SUCCESS; + } +-- +2.25.1 + diff --git a/0023-rsa-bugfix-repeated-source-release.patch b/0023-rsa-bugfix-repeated-source-release.patch new file mode 100644 index 0000000..ae3e551 --- /dev/null +++ b/0023-rsa-bugfix-repeated-source-release.patch @@ -0,0 +1,39 @@ +From 045807cc13f60a14f0a6ee8de69d54e600491740 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:46:46 +0800 +Subject: [PATCH 23/48] rsa: bugfix repeated source release + +Set 'g_rsa_res.ctx_res' to NULL when init failed. +This can avoid repeated source release in uninit +in abnormal cases. + +Signed-off-by: Zhiqi Song +--- + src/uadk_rsa.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c +index 8669455..bc51e7d 100644 +--- a/src/uadk_rsa.c ++++ b/src/uadk_rsa.c +@@ -818,6 +818,7 @@ static int uadk_e_rsa_init(void) + return UADK_E_INIT_SUCCESS; + + err_unlock: ++ g_rsa_res.ctx_res = NULL; + pthread_spin_unlock(&g_rsa_res.lock); + free(dev); + (void)fprintf(stderr, "failed to init rsa(%d)\n", ret); +@@ -831,6 +832,9 @@ static void uadk_e_rsa_uninit(void) + __u32 i; + int ret; + ++ if (!ctx_cfg) ++ return; ++ + if (g_rsa_res.pid == getpid()) { + ret = uadk_e_is_env_enabled("rsa"); + if (ret == ENV_ENABLED) { +-- +2.25.1 + diff --git a/0024-sm2-fixup-unreleased-source-in-data-conversion.patch b/0024-sm2-fixup-unreleased-source-in-data-conversion.patch new file mode 100644 index 0000000..1f633d0 --- /dev/null +++ b/0024-sm2-fixup-unreleased-source-in-data-conversion.patch @@ -0,0 +1,368 @@ +From 4c3a412586a5718b84fe582c84f13135cf080283 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:49:05 +0800 +Subject: [PATCH 24/48] sm2: fixup unreleased source in data conversion + +Release the memory that allocated for data conversion +between ber format and bin format in abnormal branch. +Otherwise, resource leakage will happen in abnormal +cases. And cleanup some code related to this issue, +make the related code logic clearer. + +Signed-off-by: Zhiqi Song +--- + src/uadk_sm2.c | 155 ++++++++++++++++++++++++++----------------------- + 1 file changed, 81 insertions(+), 74 deletions(-) + +diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c +index 1f678ed..ba90f68 100644 +--- a/src/uadk_sm2.c ++++ b/src/uadk_sm2.c +@@ -478,7 +478,7 @@ free_sig: + return ret; + } + +-static int cipher_bin_to_ber(const EVP_MD *md, struct wd_ecc_point *c1, ++static int cipher_bin_to_ber(struct wd_ecc_point *c1, + struct wd_dtb *c2, struct wd_dtb *c3, + unsigned char *ber, size_t *ber_len) + { +@@ -507,29 +507,33 @@ static int cipher_bin_to_ber(const EVP_MD *md, struct wd_ecc_point *c1, + goto free_y1; + } + ++ ret = ASN1_OCTET_STRING_set(ctext_struct.C3, (void *)c3->data, c3->dsize); ++ if (!ret) ++ goto free_c3; ++ + ctext_struct.C2 = ASN1_OCTET_STRING_new(); + if (!ctext_struct.C2) { + ret = -ENOMEM; +- goto free_y1; ++ goto free_c3; + } + +- if (!ASN1_OCTET_STRING_set(ctext_struct.C3, (void *)c3->data, c3->dsize) +- || !ASN1_OCTET_STRING_set(ctext_struct.C2, +- (void *)c2->data, c2->dsize)) { +- fprintf(stderr, "failed to ASN1_OCTET_STRING_set\n"); +- ret = -EINVAL; +- goto free_y1; +- } ++ ret = ASN1_OCTET_STRING_set(ctext_struct.C2, (void *)c2->data, c2->dsize); ++ if (!ret) ++ goto free_c2; + +- ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, +- (unsigned char **)&ber); ++ ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, &ber); + /* Ensure cast to size_t is safe */ + if (ciphertext_leni < 0) { + ret = -EINVAL; +- goto free_y1; ++ goto free_c2; + } + *ber_len = (size_t)ciphertext_leni; + ret = 0; ++ ++free_c2: ++ ASN1_OCTET_STRING_free(ctext_struct.C2); ++free_c3: ++ ASN1_OCTET_STRING_free(ctext_struct.C3); + free_y1: + BN_free(y1); + free_x1: +@@ -538,29 +542,18 @@ free_x1: + return ret; + } + +-static int cipher_ber_to_bin(unsigned char *ber, size_t ber_len, +- struct wd_ecc_point *c1, +- struct wd_dtb *c2, +- struct wd_dtb *c3) ++static int cipher_ber_to_bin(const EVP_MD *md, struct sm2_ciphertext *ctext_struct, ++ struct wd_ecc_point *c1, struct wd_dtb *c2, struct wd_dtb *c3) + { +- struct sm2_ciphertext *ctext_struct; +- int ret, len, len1; +- +- ctext_struct = d2i_SM2_Ciphertext(NULL, (const unsigned char **)&ber, +- ber_len); +- if (!ctext_struct) { +- fprintf(stderr, "failed to d2i_SM2_Ciphertext\n"); +- return -ENOMEM; +- } ++ int len, len1, md_size; + + len = BN_num_bytes(ctext_struct->C1x); + len1 = BN_num_bytes(ctext_struct->C1y); + c1->x.data = malloc(len + len1 + ctext_struct->C2->length + + ctext_struct->C3->length); +- if (!c1->x.data) { +- ret = -ENOMEM; +- goto free_ctext; +- } ++ if (!c1->x.data) ++ return -ENOMEM; ++ + c1->y.data = c1->x.data + len; + c3->data = c1->y.data + len1; + c2->data = c3->data + ctext_struct->C3->length; +@@ -568,13 +561,17 @@ static int cipher_ber_to_bin(unsigned char *ber, size_t ber_len, + memcpy(c3->data, ctext_struct->C3->data, ctext_struct->C3->length); + c2->dsize = ctext_struct->C2->length; + c3->dsize = ctext_struct->C3->length; ++ md_size = EVP_MD_size(md); ++ if (c3->dsize != md_size) { ++ fprintf(stderr, "invalid: c3 dsize(%u) != hash_size(%d)\n", c3->dsize, md_size); ++ free(c1->x.data); ++ return -EINVAL; ++ } ++ + c1->x.dsize = BN_bn2bin(ctext_struct->C1x, (void *)c1->x.data); + c1->y.dsize = BN_bn2bin(ctext_struct->C1y, (void *)c1->y.data); + + return 0; +-free_ctext: +- SM2_Ciphertext_free(ctext_struct); +- return ret; + } + + static size_t ec_field_size(const EC_GROUP *group) +@@ -681,21 +678,27 @@ static int sm2_sign_check(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + return UADK_DO_SOFT; + } + ++ if (smctx->init_status != CTX_INIT_SUCC) { ++ fprintf(stderr, "sm2 ctx init failed\n"); ++ return UADK_DO_SOFT; ++ } ++ + if (sig_sz <= 0) { + fprintf(stderr, "sig_sz error\n"); + return -EINVAL; + } + +- if (sig == NULL) { +- *siglen = (size_t)sig_sz; +- return 1; +- } +- + if (*siglen < (size_t)sig_sz) { + fprintf(stderr, "siglen(%lu) < sig_sz(%lu)\n", *siglen, (size_t)sig_sz); + return -EINVAL; + } + ++ if (!sig) { ++ fprintf(stderr, "invalid: sig is NULL\n"); ++ *siglen = (size_t)sig_sz; ++ return -EINVAL; ++ } ++ + if (tbslen > SM2_KEY_BYTES) + return UADK_DO_SOFT; + +@@ -709,21 +712,15 @@ static int sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + struct sm2_ctx *smctx = EVP_PKEY_CTX_get_data(ctx); ++ struct wd_ecc_req req = {0}; + struct wd_dtb *r = NULL; + struct wd_dtb *s = NULL; +- struct wd_ecc_req req; + int ret; + + ret = sm2_sign_check(ctx, sig, siglen, tbs, tbslen); + if (ret) + goto do_soft; + +- if (smctx->init_status != CTX_INIT_SUCC) { +- ret = UADK_DO_SOFT; +- goto do_soft; +- } +- +- memset(&req, 0, sizeof(req)); + ret = sm2_sign_init_iot(smctx->sess, &req, (void *)tbs, tbslen); + if (ret) + goto do_soft; +@@ -798,6 +795,11 @@ static int sm2_verify_check(EVP_PKEY_CTX *ctx, + return UADK_DO_SOFT; + } + ++ if (smctx->init_status != CTX_INIT_SUCC) { ++ fprintf(stderr, "sm2 ctx init failed\n"); ++ return UADK_DO_SOFT; ++ } ++ + if (tbslen > SM2_KEY_BYTES) + return UADK_DO_SOFT; + +@@ -816,21 +818,16 @@ static int sm2_verify(EVP_PKEY_CTX *ctx, + unsigned char buf_s[UADK_ECC_MAX_KEY_BYTES] = {0}; + EVP_PKEY *p_key = EVP_PKEY_CTX_get0_pkey(ctx); + EC_KEY *ec = EVP_PKEY_get0(p_key); ++ struct wd_ecc_req req = {0}; + struct wd_dtb e = {0}; + struct wd_dtb r = {0}; + struct wd_dtb s = {0}; +- struct wd_ecc_req req; + int ret; + + ret = sm2_verify_check(ctx, sig, siglen, tbs, tbslen); + if (ret) + goto do_soft; + +- if (smctx->init_status != CTX_INIT_SUCC) { +- ret = UADK_DO_SOFT; +- goto do_soft; +- } +- + r.data = (void *)buf_r; + s.data = (void *)buf_s; + r.bsize = UADK_ECC_MAX_KEY_BYTES; +@@ -841,7 +838,6 @@ static int sm2_verify(EVP_PKEY_CTX *ctx, + + e.data = (void *)tbs; + e.dsize = tbslen; +- memset(&req, 0, sizeof(req)); + ret = sm2_verify_init_iot(smctx->sess, &req, &e, &r, &s); + if (ret) + goto do_soft; +@@ -910,6 +906,11 @@ static int sm2_encrypt_check(EVP_PKEY_CTX *ctx, + return UADK_DO_SOFT; + } + ++ if (smctx->init_status != CTX_INIT_SUCC) { ++ fprintf(stderr, "sm2 ctx init failed\n"); ++ return UADK_DO_SOFT; ++ } ++ + md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; + c3_size = EVP_MD_size(md); + if (c3_size <= 0) { +@@ -941,22 +942,16 @@ static int sm2_encrypt(EVP_PKEY_CTX *ctx, + { + struct sm2_ctx *smctx = EVP_PKEY_CTX_get_data(ctx); + struct wd_ecc_point *c1 = NULL; ++ struct wd_ecc_req req = {0}; + struct wd_dtb *c2 = NULL; + struct wd_dtb *c3 = NULL; +- struct wd_ecc_req req; + const EVP_MD *md; +- int ret; ++ int md_size, ret; + + ret = sm2_encrypt_check(ctx, out, outlen, in, inlen); + if (ret) + goto do_soft; + +- if (smctx->init_status != CTX_INIT_SUCC) { +- ret = UADK_DO_SOFT; +- goto do_soft; +- } +- +- memset(&req, 0, sizeof(req)); + ret = sm2_encrypt_init_iot(smctx->sess, &req, (void *)in, inlen); + if (ret) + goto do_soft; +@@ -974,18 +969,25 @@ static int sm2_encrypt(EVP_PKEY_CTX *ctx, + goto uninit_iot; + } + +- md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; + wd_sm2_get_enc_out_params(req.dst, &c1, &c2, &c3); + if (!c1 || !c2 || !c3) { + ret = UADK_DO_SOFT; + goto uninit_iot; + } + +- ret = cipher_bin_to_ber(md, c1, c2, c3, out, outlen); ++ ret = cipher_bin_to_ber(c1, c2, c3, out, outlen); + if (ret) + goto uninit_iot; + ++ md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; ++ md_size = EVP_MD_size(md); ++ if (c3->dsize != md_size) { ++ fprintf(stderr, "invalid: c3 dsize(%u) != hash_size(%d)\n", c3->dsize, md_size); ++ goto uninit_iot; ++ } ++ + ret = 1; ++ + uninit_iot: + wd_ecc_del_in(smctx->sess, req.src); + wd_ecc_del_out(smctx->sess, req.dst); +@@ -1015,6 +1017,11 @@ static int sm2_decrypt_check(EVP_PKEY_CTX *ctx, + return UADK_DO_SOFT; + } + ++ if (smctx->init_status != CTX_INIT_SUCC) { ++ fprintf(stderr, "sm2 ctx init failed\n"); ++ return UADK_DO_SOFT; ++ } ++ + md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; + hash_size = EVP_MD_size(md); + if (hash_size <= 0) { +@@ -1092,8 +1099,9 @@ static int sm2_decrypt(EVP_PKEY_CTX *ctx, + const unsigned char *in, size_t inlen) + { + struct sm2_ctx *smctx = EVP_PKEY_CTX_get_data(ctx); ++ struct sm2_ciphertext *ctext_struct; ++ struct wd_ecc_req req = {0}; + struct wd_ecc_point c1; +- struct wd_ecc_req req; + struct wd_dtb c2, c3; + const EVP_MD *md; + int ret; +@@ -1102,24 +1110,20 @@ static int sm2_decrypt(EVP_PKEY_CTX *ctx, + if (ret) + goto do_soft; + +- if (smctx->init_status != CTX_INIT_SUCC) { +- ret = UADK_DO_SOFT; +- goto do_soft; +- } +- + md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; + +- ret = cipher_ber_to_bin((void *)in, inlen, &c1, &c2, &c3); +- if (ret) ++ ctext_struct = d2i_SM2_Ciphertext(NULL, &in, inlen); ++ if (!ctext_struct) { ++ ret = UADK_DO_SOFT; + goto do_soft; ++ } + +- if (c3.dsize != EVP_MD_size(md)) { +- fprintf(stderr, "c3 dsize != hash_size\n"); +- ret = -EINVAL; +- goto free_c1; ++ ret = cipher_ber_to_bin(md, ctext_struct, &c1, &c2, &c3); ++ if (ret) { ++ ret = UADK_DO_SOFT; ++ goto free_ctext; + } + +- memset(&req, 0, sizeof(req)); + ret = sm2_decrypt_init_iot(smctx->sess, &req, &c1, &c2, &c3); + if (ret) + goto free_c1; +@@ -1142,10 +1146,13 @@ static int sm2_decrypt(EVP_PKEY_CTX *ctx, + goto uninit_iot; + + ret = 1; ++ + uninit_iot: + sm2_decrypt_uninit_iot(smctx->sess, &req); + free_c1: + free(c1.x.data); ++free_ctext: ++ SM2_Ciphertext_free(ctext_struct); + do_soft: + if (ret != UADK_DO_SOFT) + return ret; +-- +2.25.1 + diff --git a/0025-ecc-add-openssl-method-null-pointer-judgement.patch b/0025-ecc-add-openssl-method-null-pointer-judgement.patch new file mode 100644 index 0000000..3796fcb --- /dev/null +++ b/0025-ecc-add-openssl-method-null-pointer-judgement.patch @@ -0,0 +1,111 @@ +From 6ba22cd5ac33d740580dcbe8dae84d41cff26e47 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:51:24 +0800 +Subject: [PATCH 25/48] ecc: add openssl method null pointer judgement + +Add openssl method null pointer judgement of ecc +algs to avoid null pointer access in abnornal cases. +And release the pkey method in error handling branch. + +Signed-off-by: Zhiqi Song +--- + src/uadk_ec.c | 21 +++++++++++++++++++++ + src/uadk_ecx.c | 2 ++ + src/uadk_sm2.c | 1 + + 3 files changed, 24 insertions(+) + +diff --git a/src/uadk_ec.c b/src/uadk_ec.c +index 781e7f1..5852d04 100644 +--- a/src/uadk_ec.c ++++ b/src/uadk_ec.c +@@ -405,6 +405,11 @@ static ECDSA_SIG *openssl_do_sign(const unsigned char *dgst, int dlen, + EC_KEY_METHOD *openssl_meth; + + openssl_meth = (EC_KEY_METHOD *)EC_KEY_OpenSSL(); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get OpenSSL method\n"); ++ return NULL; ++ } ++ + EC_KEY_METHOD_get_sign(openssl_meth, NULL, NULL, + &sign_sig_pfunc); + if (!sign_sig_pfunc) { +@@ -647,6 +652,11 @@ static int openssl_do_verify(const unsigned char *dgst, int dlen, + EC_KEY_METHOD *openssl_meth; + + openssl_meth = (EC_KEY_METHOD *)EC_KEY_OpenSSL(); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get OpenSSL method\n"); ++ return -1; ++ } ++ + EC_KEY_METHOD_get_verify(openssl_meth, NULL, + &verify_sig_pfunc); + if (!verify_sig_pfunc) { +@@ -814,6 +824,11 @@ static int openssl_do_generate(EC_KEY *eckey) + EC_KEY_METHOD *openssl_meth; + + openssl_meth = (EC_KEY_METHOD *)EC_KEY_OpenSSL(); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get OpenSSL method\n"); ++ return -1; ++ } ++ + EC_KEY_METHOD_get_keygen(openssl_meth, &gen_key_pfunc); + if (!gen_key_pfunc) { + fprintf(stderr, "gen_key_pfunc is NULL\n"); +@@ -1255,6 +1270,11 @@ static int openssl_do_compute(unsigned char **pout, + EC_KEY_METHOD *openssl_meth; + + openssl_meth = (EC_KEY_METHOD *)EC_KEY_OpenSSL(); ++ if (!openssl_meth) { ++ fprintf(stderr, "failed to get OpenSSL method\n"); ++ return -1; ++ } ++ + EC_KEY_METHOD_get_compute_key(openssl_meth, &comp_key_pfunc); + if (!comp_key_pfunc) { + fprintf(stderr, "comp_key_pfunc is NULL\n"); +@@ -1420,6 +1440,7 @@ int uadk_ec_create_pmeth(struct uadk_pkey_meth *pkey_meth) + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_EC); + if (!openssl_meth) { + fprintf(stderr, "failed to get ec pkey methods\n"); ++ EVP_PKEY_meth_free(meth); + return 0; + } + +diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c +index aebd808..3eafdfb 100644 +--- a/src/uadk_ecx.c ++++ b/src/uadk_ecx.c +@@ -813,6 +813,7 @@ int uadk_x25519_create_pmeth(struct uadk_pkey_meth *pkey_meth) + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_X25519); + if (!openssl_meth) { + fprintf(stderr, "failed to get x25519 pkey methods\n"); ++ EVP_PKEY_meth_free(meth); + return UADK_E_FAIL; + } + +@@ -858,6 +859,7 @@ int uadk_x448_create_pmeth(struct uadk_pkey_meth *pkey_meth) + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_X448); + if (!openssl_meth) { + fprintf(stderr, "failed to get x448 pkey methods\n"); ++ EVP_PKEY_meth_free(meth); + return UADK_E_FAIL; + } + +diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c +index ba90f68..f393641 100644 +--- a/src/uadk_sm2.c ++++ b/src/uadk_sm2.c +@@ -1643,6 +1643,7 @@ int uadk_sm2_create_pmeth(struct uadk_pkey_meth *pkey_meth) + openssl_meth = get_openssl_pkey_meth(EVP_PKEY_SM2); + if (!openssl_meth) { + fprintf(stderr, "failed to get sm2 pkey methods\n"); ++ EVP_PKEY_meth_free(meth); + return -1; + } + +-- +2.25.1 + diff --git a/0026-uadk_engine-cleanup-call-form-of-callback-func.patch b/0026-uadk_engine-cleanup-call-form-of-callback-func.patch new file mode 100644 index 0000000..e308343 --- /dev/null +++ b/0026-uadk_engine-cleanup-call-form-of-callback-func.patch @@ -0,0 +1,169 @@ +From 27049955574b083e870d8308d38ccca7ac6b37ea Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Sat, 17 Jun 2023 20:57:01 +0800 +Subject: [PATCH 26/48] uadk_engine: cleanup call form of callback func + +Modify the call form of callback function in async +mode, matching the definition in uadk. + +Signed-off-by: Zhiqi Song +--- + src/uadk_cipher.c | 10 ++++++---- + src/uadk_dh.c | 2 +- + src/uadk_digest.c | 12 ++++++++---- + src/uadk_pkey.c | 4 ++-- + src/uadk_pkey.h | 2 +- + src/uadk_rsa.c | 2 +- + 6 files changed, 19 insertions(+), 13 deletions(-) + +diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c +index d4ad33c..c87c7ee 100644 +--- a/src/uadk_cipher.c ++++ b/src/uadk_cipher.c +@@ -717,17 +717,17 @@ static int uadk_e_cipher_cleanup(EVP_CIPHER_CTX *ctx) + return 1; + } + +-static void uadk_e_cipher_cb(struct wd_cipher_req *req, void *data) ++static void *uadk_e_cipher_cb(struct wd_cipher_req *req, void *data) + { + struct uadk_e_cb_info *cb_param; + struct async_op *op; + + if (!req) +- return; ++ return NULL; + + cb_param = req->cb_param; + if (!cb_param) +- return; ++ return NULL; + + op = cb_param->op; + if (op && op->job && !op->done) { +@@ -735,6 +735,8 @@ static void uadk_e_cipher_cb(struct wd_cipher_req *req, void *data) + async_free_poll_task(op->idx, 1); + async_wake_job(op->job); + } ++ ++ return NULL; + } + + /* Increment counter (128-bit int) by c */ +@@ -822,7 +824,7 @@ static int do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *op) + + cb_param.op = op; + cb_param.priv = priv; +- priv->req.cb = (void *)uadk_e_cipher_cb; ++ priv->req.cb = uadk_e_cipher_cb; + priv->req.cb_param = &cb_param; + + ret = async_get_free_task(&idx); +diff --git a/src/uadk_dh.c b/src/uadk_dh.c +index fc91609..acb5b8a 100644 +--- a/src/uadk_dh.c ++++ b/src/uadk_dh.c +@@ -711,7 +711,7 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess) + } else { + cb_param.op = &op; + cb_param.priv = &dh_sess->req; +- dh_sess->req.cb = (void *)uadk_e_dh_cb; ++ dh_sess->req.cb = uadk_e_dh_cb; + dh_sess->req.cb_param = &cb_param; + dh_sess->req.status = -1; + ret = async_get_free_task(&idx); +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index 590a888..b75c408 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -674,23 +674,27 @@ soft_update: + return digest_soft_update(priv, data, data_len); + } + +-static void async_cb(struct wd_digest_req *req, void *data) ++static void *uadk_e_digest_cb(void *data) + { ++ struct wd_digest_req *req = (struct wd_digest_req *)data; + struct uadk_e_cb_info *cb_param; + struct async_op *op; + + if (!req) +- return; ++ return NULL; + + cb_param = req->cb_param; + if (!cb_param) +- return; ++ return NULL; ++ + op = cb_param->op; + if (op && op->job && !op->done) { + op->done = 1; + async_free_poll_task(op->idx, 1); + async_wake_job(op->job); + } ++ ++ return NULL; + } + + static int do_digest_sync(struct digest_priv_ctx *priv) +@@ -721,7 +725,7 @@ static int do_digest_async(struct digest_priv_ctx *priv, struct async_op *op) + + cb_param.op = op; + cb_param.priv = priv; +- priv->req.cb = (void *)async_cb; ++ priv->req.cb = uadk_e_digest_cb; + priv->req.cb_param = &cb_param; + + ret = async_get_free_task(&idx); +diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c +index 35a2696..60e3238 100644 +--- a/src/uadk_pkey.c ++++ b/src/uadk_pkey.c +@@ -76,7 +76,7 @@ static int ecc_poll_policy(handle_t h_sched_ctx, __u32 expect, __u32 *count) + return 0; + } + +-void uadk_ecc_cb(void *req_t) ++void uadk_e_ecc_cb(void *req_t) + { + struct wd_ecc_req *req_new = (struct wd_ecc_req *)req_t; + struct uadk_e_cb_info *cb_param; +@@ -296,7 +296,7 @@ int uadk_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) + cb_param.op = &op; + cb_param.priv = req; + req->cb_param = &cb_param; +- req->cb = (void *)uadk_ecc_cb; ++ req->cb = uadk_e_ecc_cb; + req->status = -1; + ret = async_get_free_task(&idx); + if (!ret) +diff --git a/src/uadk_pkey.h b/src/uadk_pkey.h +index b80e425..3168474 100644 +--- a/src/uadk_pkey.h ++++ b/src/uadk_pkey.h +@@ -58,7 +58,7 @@ struct uadk_pkey_meth { + bool uadk_is_all_zero(const unsigned char *data, size_t dlen); + bool uadk_support_algorithm(const char *alg); + int uadk_ecc_get_rand(char *out, size_t out_len, void *usr); +-void uadk_ecc_cb(void *req_t); ++void uadk_e_ecc_cb(void *req_t); + void uadk_ecc_fill_req(struct wd_ecc_req *req, + unsigned int op, void *in, void *out); + int uadk_ecc_set_private_key(handle_t sess, const EC_KEY *eckey); +diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c +index bc51e7d..d0780a7 100644 +--- a/src/uadk_rsa.c ++++ b/src/uadk_rsa.c +@@ -1101,7 +1101,7 @@ static int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) + } + cb_param.op = &op; + cb_param.priv = &(rsa_sess->req); +- rsa_sess->req.cb = (void *)uadk_e_rsa_cb; ++ rsa_sess->req.cb = uadk_e_rsa_cb; + rsa_sess->req.cb_param = &cb_param; + rsa_sess->req.status = -1; + +-- +2.25.1 + diff --git a/0027-uadk_engine-cleanup-empty-body-warning-in-v1.patch b/0027-uadk_engine-cleanup-empty-body-warning-in-v1.patch new file mode 100644 index 0000000..74d6de4 --- /dev/null +++ b/0027-uadk_engine-cleanup-empty-body-warning-in-v1.patch @@ -0,0 +1,36 @@ +From 98352587af77f492bf54bdbc1282b324c2c1e984 Mon Sep 17 00:00:00 2001 +From: Hao Fang +Date: Sat, 17 Jun 2023 20:59:00 +0800 +Subject: [PATCH 27/48] uadk_engine: cleanup empty-body warning in v1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix the warning: +[-Wempty-body] suggest braces around empty body +in an ‘if’ statement. + +Just simplify the code. + +Signed-off-by: Hao Fang +--- + src/v1/utils/engine_log.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/v1/utils/engine_log.c b/src/v1/utils/engine_log.c +index ef009e5..330defb 100644 +--- a/src/v1/utils/engine_log.c ++++ b/src/v1/utils/engine_log.c +@@ -158,8 +158,7 @@ void ENGINE_LOG_LIMIT(int level, int times, int limit, const char *fmt, ...) + fprintf(g_kae_debug_log_file, "\n"); + if (ftell(g_kae_debug_log_file) > KAE_LOG_MAX_SIZE) { + kae_save_log(g_kae_debug_log_file); +- if (ftruncate(g_kae_debug_log_file->_fileno, 0)) +- ; ++ ftruncate(g_kae_debug_log_file->_fileno, 0); + fseek(g_kae_debug_log_file, 0, SEEK_SET); + } + pthread_mutex_unlock(&g_debug_file_mutex); +-- +2.25.1 + diff --git a/0028-sanity_test.sh-check-version-for-openssl-version-3.0.patch b/0028-sanity_test.sh-check-version-for-openssl-version-3.0.patch new file mode 100644 index 0000000..b3a25f6 --- /dev/null +++ b/0028-sanity_test.sh-check-version-for-openssl-version-3.0.patch @@ -0,0 +1,43 @@ +From 98d2ed1649935a3b6f5325b3c07e2819b88c498a Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Thu, 27 Jul 2023 09:56:29 +0800 +Subject: [PATCH 28/48] sanity_test.sh: check version for openssl version 3.0 + and later + +Such as openssl 3.0 and 3.2 +Previously openssl 3.2 doesn't work. + +Signed-off-by: Guodong Xu +--- + test/sanity_test.sh | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/test/sanity_test.sh b/test/sanity_test.sh +index d46c570..0fe4472 100755 +--- a/test/sanity_test.sh ++++ b/test/sanity_test.sh +@@ -5,14 +5,18 @@ sudo chmod 666 /dev/hisi_* + + version=$(openssl version) + echo $version +-if [[ $version =~ "3.0" ]]; then +- echo "openssl 3.0" ++ ++# Extract the major version number (e.g., "3") from the version string ++major_version=$(echo $version | awk -F'[ .]' '{print $2}') ++echo "OpenSSL major version is "$major_version ++ ++# Check if the major version is equal to or greater than 3 ++if ((major_version >= 3)); then + if [ ! -n "$1" ]; then + engine_id=uadk_provider + else + engine_id=$1 + fi +- + digest_algs=$(openssl list -provider $engine_id -digest-algorithms) + cipher_algs=$(openssl list -provider $engine_id -digest-algorithms) + fi +-- +2.25.1 + diff --git a/0029-README-fix-openEuler-build-libdir.patch b/0029-README-fix-openEuler-build-libdir.patch new file mode 100644 index 0000000..c6fcf47 --- /dev/null +++ b/0029-README-fix-openEuler-build-libdir.patch @@ -0,0 +1,29 @@ +From f1c812781059e3d11378f1663057d854f6cce5ca Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Thu, 27 Jul 2023 06:48:37 +0000 +Subject: [PATCH 29/48] README: fix openEuler build libdir + +openEuler also use --libdir=/usr/local/lib/ossl-modules/ + +Signed-off-by: Zhangfei Gao +--- + README.md | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/README.md b/README.md +index 86676db..ae586e2 100644 +--- a/README.md ++++ b/README.md +@@ -82,9 +82,6 @@ For openssl 3.0 + git clone https://github.com/Linaro/uadk_engine.git + cd uadk_engine + autoreconf -i +- // openEuler +- ./configure --libdir=/usr/local/lib/engines-3/ +- // ubuntu + ./configure --libdir=/usr/local/lib/ossl-modules/ + make + sudo make install +-- +2.25.1 + diff --git a/0030-uadk_prov_digest-provider-default-may-not-exist.patch b/0030-uadk_prov_digest-provider-default-may-not-exist.patch new file mode 100644 index 0000000..217cbdb --- /dev/null +++ b/0030-uadk_prov_digest-provider-default-may-not-exist.patch @@ -0,0 +1,95 @@ +From c56df72b255482f6bdc928f08fbfc2304deb526d Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Mon, 28 Aug 2023 17:38:44 +0800 +Subject: [PATCH 30/48] uadk_prov_digest: provider default may not exist + +When provider default is not provided, priv->soft_md is NULL + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_digest.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index 5456d2d..ecb8d23 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -158,19 +158,30 @@ static int uadk_digests_soft_md(struct digest_priv_ctx *priv) + + static int uadk_digest_soft_init(struct digest_priv_ctx *priv) + { +- return EVP_DigestInit(priv->soft_ctx, priv->soft_md); ++ if (priv->soft_md) ++ return EVP_DigestInit_ex(priv->soft_ctx, priv->soft_md, NULL); ++ ++ return 0; + } + +-static int uadk_digest_soft_update(EVP_MD_CTX *ctx, const void *data, size_t len) ++static int uadk_digest_soft_update(struct digest_priv_ctx *priv, ++ const void *data, size_t len) + { +- return EVP_DigestUpdate(ctx, data, len); ++ if (priv->soft_md) ++ return EVP_DigestUpdate(priv->soft_ctx, data, len); ++ ++ return 0; + } + + static int uadk_digest_soft_final(struct digest_priv_ctx *priv, unsigned char *digest) + { +- unsigned int digest_length = EVP_MD_get_size(priv->soft_md); ++ if (priv->soft_md) { ++ unsigned int digest_length; ++ ++ return EVP_DigestFinal_ex(priv->soft_ctx, digest, &digest_length); ++ } + +- return EVP_DigestFinal(priv->soft_ctx, digest, &digest_length); ++ return 0; + } + + static void digest_soft_cleanup(struct digest_priv_ctx *priv) +@@ -195,10 +206,13 @@ static void digest_soft_cleanup(struct digest_priv_ctx *priv) + static int uadk_digest_soft_work(struct digest_priv_ctx *priv, int len, + unsigned char *digest) + { ++ if (!priv->soft_md) ++ return 0; ++ + uadk_digest_soft_init(priv); + + if (len != 0) +- uadk_digest_soft_update(priv->soft_ctx, priv->data, len); ++ uadk_digest_soft_update(priv, priv->data, len); + + uadk_digest_soft_final(priv, digest); + digest_soft_cleanup(priv); +@@ -338,13 +352,11 @@ do_soft_digest: + && priv->last_update_bufflen != 0) { + priv->switch_flag = UADK_DO_SOFT; + uadk_digest_soft_init(priv); +- ret = uadk_digest_soft_update(priv->soft_ctx, +- priv->data, priv->last_update_bufflen); ++ ret = uadk_digest_soft_update(priv, priv->data, priv->last_update_bufflen); + if (ret != 1) + return ret; + +- return uadk_digest_soft_update(priv->soft_ctx, +- tmpdata, left_len); ++ return uadk_digest_soft_update(priv, tmpdata, left_len); + } + + fprintf(stderr, "do soft digest failed during updating!\n"); +@@ -365,7 +377,7 @@ static int uadk_digest_update(struct digest_priv_ctx *priv, const void *data, si + return uadk_digest_update_inner(priv, data, data_len); + + soft_update: +- return uadk_digest_soft_update(priv->soft_ctx, data, data_len); ++ return uadk_digest_soft_update(priv, data, data_len); + } + + static void uadk_async_cb(struct wd_digest_req *req, void *data) +-- +2.25.1 + diff --git a/0031-uadk_provider-iv_len-in-SM4_ECB-mode-must-be-0.patch b/0031-uadk_provider-iv_len-in-SM4_ECB-mode-must-be-0.patch new file mode 100644 index 0000000..ffa1443 --- /dev/null +++ b/0031-uadk_provider-iv_len-in-SM4_ECB-mode-must-be-0.patch @@ -0,0 +1,32 @@ +From 162c06fb92f301b3d7396aa703825e64eb3512b0 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Sun, 3 Sep 2023 06:36:37 +0800 +Subject: [PATCH 31/48] uadk_provider: iv_len in SM4_ECB mode must be 0 + +iv_len of ECB mode must be 0. Without this, openssl's evp_test +will fail at: + +[openssl.git]/test/evp_test.c, cipher_test_run(): + if (!cdat->iv && EVP_CIPHER_get_iv_length(cdat->cipher)) { + +Signed-off-by: Guodong Xu +--- + src/uadk_prov_cipher.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index af0fa02..c0c52a3 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -801,7 +801,7 @@ UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, NID_aes_256_ecb, ecb(aes), EVP_CIPH + UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, 0, NID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); + UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, 0, NID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); + UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, NID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 16, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE); + UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, NID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE); + UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, NID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE); + +-- +2.25.1 + diff --git a/0032-uadk_provider-load-default-provider-into-Global-libr.patch b/0032-uadk_provider-load-default-provider-into-Global-libr.patch new file mode 100644 index 0000000..4ce0e18 --- /dev/null +++ b/0032-uadk_provider-load-default-provider-into-Global-libr.patch @@ -0,0 +1,71 @@ +From 3c01ab789093fcc27a68029642b64eaf9d114e74 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Mon, 4 Sep 2023 09:45:05 +0800 +Subject: [PATCH 32/48] uadk_provider: load default provider into Global + library context + +Implementations in default provider are required in some cases. +For example when the package size is small. + +In current design, we load default provider into Global library context, +aka. NULL. + +Signed-off-by: Guodong Xu +--- + src/uadk_prov_init.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index b59a4e8..57910ac 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -22,6 +22,8 @@ + #include + #include + #include ++#include ++#include + + #include "uadk_async.h" + #include "uadk_prov.h" +@@ -32,7 +34,8 @@ struct p_uadk_ctx { + }; + + const char *engine_uadk_id = "uadk_provider"; +-static const char UADK_DEFAULT_PROPERTIES[] = "provider=uadk"; ++static const char UADK_DEFAULT_PROPERTIES[] = "provider=uadk_provider"; ++static OSSL_PROVIDER *prov; + + const OSSL_ALGORITHM uadk_prov_digests[] = { + { OSSL_DIGEST_NAME_MD5, UADK_DEFAULT_PROPERTIES, +@@ -83,8 +86,18 @@ const OSSL_ALGORITHM uadk_prov_ciphers[] = { + static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + int *no_cache) + { +- *no_cache = 0; ++ static int prov_init; ++ ++ prov = OSSL_PROVIDER_load(NULL, "default"); ++ if (!prov_init) { ++ prov_init = 1; ++ /* uadk_provider takes the highest priority ++ * and overwrite the openssl.cnf property. ++ */ ++ EVP_set_default_properties(NULL, "?provider=uadk_provider"); ++ } + ++ *no_cache = 0; + switch (operation_id) { + case OSSL_OP_DIGEST: + return uadk_prov_digests; +@@ -101,6 +114,7 @@ static void p_teardown(void *provctx) + uadk_prov_destroy_digest(); + uadk_prov_destroy_cipher(); + OPENSSL_free(ctx); ++ OSSL_PROVIDER_unload(prov); + } + + static const OSSL_DISPATCH p_test_table[] = { +-- +2.25.1 + diff --git a/0033-uadk_provider-handle-the-async_poll_task_free-in-pro.patch b/0033-uadk_provider-handle-the-async_poll_task_free-in-pro.patch new file mode 100644 index 0000000..da6b663 --- /dev/null +++ b/0033-uadk_provider-handle-the-async_poll_task_free-in-pro.patch @@ -0,0 +1,84 @@ +From fb3715e15d70b089e6be7735ebae9aa764dc40d3 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Wed, 6 Sep 2023 17:53:39 +0800 +Subject: [PATCH 33/48] uadk_provider: handle the async_poll_task_free in + provider teardown + +Previously, async_poll_task_free() is registered as part of OPENSSL_atexit. +However, in the dynamic loading scenario, after uadk_provider is unloaded, +the function entry of async_poll_task_free() is not valid any more. Calling +it as part of OPENSSL_cleanup() (who calls all _atexit handlers) generates +a Segmentation Fault. + +Since this async_poll_task_free() is about uadk_provider's resources free, +so move the call of this functiion into provider teardown. This ensures +this function is called before uadk_provider module's destruction. + +Signed-off-by: Guodong Xu +--- + src/uadk_async.c | 4 +--- + src/uadk_async.h | 1 + + src/uadk_engine_init.c | 2 ++ + src/uadk_prov_init.c | 1 + + 4 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/uadk_async.c b/src/uadk_async.c +index dfac1cb..c46976c 100644 +--- a/src/uadk_async.c ++++ b/src/uadk_async.c +@@ -112,7 +112,7 @@ int async_clear_async_event_notification(void) + return 1; + } + +-static void async_poll_task_free(void) ++void async_poll_task_free(void) + { + int error; + struct async_poll_task *task; +@@ -381,8 +381,6 @@ int async_module_init(void) + goto err; + + poll_queue.thread_id = thread_id; +- OPENSSL_atexit(async_poll_task_free); +- + return 1; + + err: +diff --git a/src/uadk_async.h b/src/uadk_async.h +index d7a8bb5..9160c98 100644 +--- a/src/uadk_async.h ++++ b/src/uadk_async.h +@@ -78,4 +78,5 @@ int async_module_init(void); + int async_wake_job(ASYNC_JOB *job); + void async_free_poll_task(int id, bool is_cb); + int async_get_free_task(int *id); ++void async_poll_task_free(void); + #endif +diff --git a/src/uadk_engine_init.c b/src/uadk_engine_init.c +index 0a9e3e6..e2aa392 100644 +--- a/src/uadk_engine_init.c ++++ b/src/uadk_engine_init.c +@@ -220,6 +220,8 @@ static int uadk_destroy(ENGINE *e) + if (uadk_dh) + uadk_e_destroy_dh(); + ++ async_poll_task_free(); ++ + pthread_mutex_lock(&uadk_engine_mutex); + uadk_inited = 0; + pthread_mutex_unlock(&uadk_engine_mutex); +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 57910ac..af22dfa 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -115,6 +115,7 @@ static void p_teardown(void *provctx) + uadk_prov_destroy_cipher(); + OPENSSL_free(ctx); + OSSL_PROVIDER_unload(prov); ++ async_poll_task_free(); + } + + static const OSSL_DISPATCH p_test_table[] = { +-- +2.25.1 + diff --git a/0034-uadk_cipher-iv_len-in-SM4_ECB-mode-must-be-0.patch b/0034-uadk_cipher-iv_len-in-SM4_ECB-mode-must-be-0.patch new file mode 100644 index 0000000..9dff2e0 --- /dev/null +++ b/0034-uadk_cipher-iv_len-in-SM4_ECB-mode-must-be-0.patch @@ -0,0 +1,28 @@ +From 1b13c2c933eb544020ab17aaec1f28b21f228dec Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 6 Sep 2023 22:00:03 +0800 +Subject: [PATCH 34/48] uadk_cipher: iv_len in SM4_ECB mode must be 0 + +The iv_len of ECB mode must be 0. + +Signed-off-by: Zhangfei Gao +--- + src/uadk_cipher.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c +index c87c7ee..901c29e 100644 +--- a/src/uadk_cipher.c ++++ b/src/uadk_cipher.c +@@ -1024,7 +1024,7 @@ static int bind_v2_cipher(void) + sizeof(struct cipher_priv_ctx), uadk_e_cipher_init, + uadk_e_do_cipher, uadk_e_cipher_cleanup, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv); +- UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 16, EVP_CIPH_ECB_MODE, ++ UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, EVP_CIPH_ECB_MODE, + sizeof(struct cipher_priv_ctx), uadk_e_cipher_init, + uadk_e_do_cipher, uadk_e_cipher_cleanup, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv); +-- +2.25.1 + diff --git a/0035-uadk_prov_cipher-add-handling-of-param-padding.patch b/0035-uadk_prov_cipher-add-handling-of-param-padding.patch new file mode 100644 index 0000000..7060ef6 --- /dev/null +++ b/0035-uadk_prov_cipher-add-handling-of-param-padding.patch @@ -0,0 +1,38 @@ +From 3e70bfc8641d7d292341958a21df6365a70b2efc Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Tue, 5 Sep 2023 15:47:43 +0800 +Subject: [PATCH 35/48] uadk_prov_cipher: add handling of param padding + +Add handling of OSSL_CIPHER_PARAM_PADDING. Without this, +openssl ./test/evp_test fails. + +Signed-off-by: Guodong Xu +--- + src/uadk_prov_cipher.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index c0c52a3..1e4c40d 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -616,6 +616,17 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] + if (params == NULL) + return 1; + ++ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); ++ if (p != NULL) { ++ unsigned int pad; ++ ++ if (!OSSL_PARAM_get_uint(p, &pad)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); ++ return 0; ++ } ++ EVP_CIPHER_CTX_set_padding(priv->sw_ctx, pad); ++ } ++ + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL) { + size_t keylen; +-- +2.25.1 + diff --git a/0036-uadk_prov_cipher-fix-padding.patch b/0036-uadk_prov_cipher-fix-padding.patch new file mode 100644 index 0000000..3ac8b26 --- /dev/null +++ b/0036-uadk_prov_cipher-fix-padding.patch @@ -0,0 +1,605 @@ +From 40769962ee162ba9b27d88d54d53b5c406a41886 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Thu, 31 Aug 2023 11:26:04 +0800 +Subject: [PATCH 36/48] uadk_prov_cipher: fix padding + +Unlike openssl 1.1, openssl 3.0 requires "It is the responsibility +of the cipher implementation to handle input lengths that are no +multiples of the block length" [1] + +Add padding handling via referring +providers/implementations/ciphers/ciphercommon.c + +Additionally, the patch finds that using software and hardware +ciphers does not work properly if alternating between the two. +If using hardware, it is necessary to keep using hardware, and vice versa. + +[1] https://www.openssl.org/docs/manmaster/man7/provider-cipher.html + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_cipher.c | 382 ++++++++++++++++++++++++++++++++++------- + 1 file changed, 324 insertions(+), 58 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 1e4c40d..87beb76 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,7 +28,8 @@ + #include "uadk.h" + #include "uadk_async.h" + +-#define UADK_DO_SOFT (-0xE0) ++#define UADK_DO_SOFT (-0xE0) ++#define UADK_DO_HW (-0xF0) + #define CTX_SYNC_ENC 0 + #define CTX_SYNC_DEC 1 + #define CTX_ASYNC_ENC 2 +@@ -40,6 +42,7 @@ + #define ENV_ENABLED 1 + #define MAX_KEY_LEN 64 + #define ALG_NAME_SIZE 128 ++#define GENERIC_BLOCK_SIZE 16 + + /* Internal flags that can be queried */ + #define PROV_CIPHER_FLAG_AEAD 0x0001 +@@ -66,6 +69,8 @@ struct cipher_priv_ctx { + struct wd_cipher_sess_setup setup; + struct wd_cipher_req req; + unsigned char iv[IV_LEN]; ++ /* Buffer of partial blocks processed via update calls */ ++ unsigned char buf[GENERIC_BLOCK_SIZE]; + unsigned char key[MAX_KEY_LEN]; + int switch_flag; + EVP_CIPHER_CTX *sw_ctx; +@@ -76,6 +81,7 @@ struct cipher_priv_ctx { + size_t blksize; + size_t keylen; + size_t ivlen; ++ size_t bufsz; /* Number of bytes in buf */ + char alg_name[ALG_NAME_SIZE]; + }; + +@@ -121,60 +127,82 @@ static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) + switch (priv->nid) { + case NID_aes_128_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", "provider=default"); ++ break; + case NID_aes_192_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CBC", "provider=default"); ++ break; + case NID_aes_256_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC", "provider=default"); ++ break; + case NID_aes_128_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-ECB", "provider=default"); ++ break; + case NID_aes_192_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-ECB", "provider=default"); ++ break; + case NID_aes_256_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-ECB", "provider=default"); ++ break; + case NID_aes_128_xts: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-XTS", "provider=default"); ++ break; + case NID_aes_256_xts: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-XTS", "provider=default"); ++ break; + case NID_sm4_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); ++ break; + case NID_sm4_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-ECB", "provider=default"); ++ break; + case NID_des_ede3_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-CBC", "provider=default"); ++ break; + case NID_des_ede3_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-ECB", "provider=default"); ++ break; + case NID_aes_128_ctr: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CTR", "provider=default"); ++ break; + case NID_aes_192_ctr: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CTR", "provider=default"); ++ break; + case NID_aes_256_ctr: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CTR", "provider=default"); ++ break; + case NID_aes_128_ofb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-OFB", "provider=default"); ++ break; + case NID_aes_192_ofb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-OFB", "provider=default"); ++ break; + case NID_aes_256_ofb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-OFB", "provider=default"); ++ break; + case NID_aes_128_cfb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CFB", "provider=default"); ++ break; + case NID_aes_192_cfb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CFB", "provider=default"); ++ break; + case NID_aes_256_cfb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CFB", "provider=default"); ++ break; + case NID_sm4_ofb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-OFB", "provider=default"); ++ break; + case NID_sm4_cfb128: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CFB", "provider=default"); ++ break; + case NID_sm4_ctr: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CTR", "provider=default"); ++ break; + default: + break; + } + +- if (unlikely(priv->sw_cipher == NULL)) { +- fprintf(stderr, "fail to fetch sw_cipher\n"); ++ if (unlikely(priv->sw_cipher == NULL)) + return 0; +- } + + return 1; + } +@@ -192,27 +220,25 @@ static int uadk_prov_cipher_sw_init(struct cipher_priv_ctx *priv, + return 0; + } + ++ priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT; ++ + return 1; + } + + static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t len) ++ int *outl, const unsigned char *in, size_t len) + { + int sw_final_len = 0; +- int outlen = 0; + + if (priv->sw_cipher == NULL) + return 0; + +- if (!EVP_CipherUpdate(priv->sw_ctx, out, &outlen, in, len)) { ++ if (!EVP_CipherUpdate(priv->sw_ctx, out, outl, in, len)) { + fprintf(stderr, "EVP_CipherUpdate sw_ctx failed.\n"); + return 0; + } + +- if (!EVP_CipherFinal_ex(priv->sw_ctx, out + outlen, &sw_final_len)) { +- fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); +- return 0; +- } ++ priv->switch_flag = UADK_DO_SOFT; + + return 1; + } +@@ -261,15 +287,10 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, + return 0; + } + +- if (key) { ++ if (key) + memcpy(priv->key, key, keylen); +- ret = uadk_prov_cipher_sw_init(priv, key, iv); +- if (unlikely(ret != 1)) +- return 0; +- } +- +- priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT; + ++ uadk_prov_cipher_sw_init(priv, key, iv); + return 1; + } + +@@ -348,12 +369,6 @@ static int uadk_do_cipher_sync(struct cipher_priv_ctx *priv) + { + int ret; + +- if (unlikely(priv->switch_flag == UADK_DO_SOFT)) +- return 0; +- +- if (priv->switch_threshold >= priv->req.in_bytes) +- return 0; +- + ret = wd_do_cipher_sync(priv->sess, &priv->req); + if (ret) + return 0; +@@ -407,11 +422,39 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) + + pthread_mutex_lock(&cipher_mutex); + if (prov.pid != getpid()) { +- ret = wd_cipher_init2(priv->alg_name, 0, 0); ++ struct wd_ctx_nums *ctx_set_num; ++ struct wd_ctx_params cparams = {0}; ++ ++ /* 0: enc, 1: dec */ ++ ctx_set_num = calloc(2, sizeof(*ctx_set_num)); ++ if (!ctx_set_num) { ++ fprintf(stderr, "failed to alloc ctx_set_size!\n"); ++ return; ++ } ++ ++ cparams.op_type_num = 2; ++ cparams.ctx_set_num = ctx_set_num; ++ cparams.bmp = numa_allocate_nodemask(); ++ if (!cparams.bmp) { ++ fprintf(stderr, "failed to create nodemask!\n"); ++ free(ctx_set_num); ++ return; ++ } ++ ++ numa_bitmask_setall(cparams.bmp); ++ ++ ctx_set_num[0].sync_ctx_num = 2; ++ ctx_set_num[0].async_ctx_num = 2; ++ ctx_set_num[1].sync_ctx_num = 2; ++ ctx_set_num[1].async_ctx_num = 2; ++ ++ ret = wd_cipher_init2_(priv->alg_name, 0, 0, &cparams); ++ numa_free_nodemask(cparams.bmp); ++ free(ctx_set_num); ++ + if (unlikely(ret)) { + priv->switch_flag = UADK_DO_SOFT; + pthread_mutex_unlock(&cipher_mutex); +- fprintf(stderr, "uadk failed to init cipher HW!\n"); + return; + } + prov.pid = getpid(); +@@ -438,52 +481,225 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) + } + } + +-static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, ++/* ++ * Fills a single block of buffered data from the input, and returns the amount ++ * of data remaining in the input that is a multiple of the blocksize. The buffer ++ * is only filled if it already has some data in it, isn't full already or we ++ * don't have at least one block in the input. ++ * ++ * buf: a buffer of blocksize bytes ++ * buflen: contains the amount of data already in buf on entry. Updated with the ++ * amount of data in buf at the end. On entry *buflen must always be ++ * less than the blocksize ++ * blocksize: size of a block. Must be greater than 0 and a power of 2 ++ * in: pointer to a pointer containing the input data ++ * inlen: amount of input data available ++ * ++ * On return buf is filled with as much data as possible up to a full block, ++ * *buflen is updated containing the amount of data in buf. *in is updated to ++ * the new location where input data should be read from, *inlen is updated with ++ * the remaining amount of data in *in. Returns the largest value <= *inlen ++ * which is a multiple of the blocksize. ++ */ ++static size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, ++ size_t blocksize, ++ const unsigned char **in, size_t *inlen) ++{ ++ size_t blockmask = ~(blocksize - 1); ++ size_t bufremain = blocksize - *buflen; ++ ++ if (*inlen < bufremain) ++ bufremain = *inlen; ++ memcpy(buf + *buflen, *in, bufremain); ++ *in += bufremain; ++ *inlen -= bufremain; ++ *buflen += bufremain; ++ ++ return *inlen & blockmask; ++} ++ ++/* ++ * Fills the buffer with trailing data from an encryption/decryption that didn't ++ * fit into a full block. ++ */ ++int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, ++ const unsigned char **in, size_t *inlen) ++{ ++ if (*inlen == 0) ++ return 1; ++ ++ if (*buflen + *inlen > blocksize) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ memcpy(buf + *buflen, *in, *inlen); ++ *buflen += *inlen; ++ *inlen = 0; ++ ++ return 1; ++} ++ ++/* Pad the final block for encryption */ ++static void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t blocksize) ++{ ++ size_t i; ++ unsigned char pad = (unsigned char)(blocksize - *buflen); ++ ++ for (i = *buflen; i < blocksize; i++) ++ buf[i] = pad; ++} ++ ++static int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) ++{ ++ size_t pad, i; ++ size_t len = *buflen; ++ ++ if (len != blocksize) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ ++ /* ++ * The following assumes that the ciphertext has been authenticated. ++ * Otherwise it provides a padding oracle. ++ */ ++ pad = buf[blocksize - 1]; ++ if (pad == 0 || pad > blocksize) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); ++ return 0; ++ } ++ for (i = 0; i < pad; i++) { ++ if (buf[--len] != pad) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); ++ return 0; ++ } ++ } ++ *buflen = len; ++ return 1; ++} ++ ++static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, ++ size_t *outl, size_t outsize, + const unsigned char *in, size_t inlen) + { ++ size_t blksz = priv->blksize; + struct async_op op; + int ret; + ++ if (outsize < blksz) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ ++ priv->switch_flag = UADK_DO_HW; + priv->req.src = (unsigned char *)in; + priv->req.in_bytes = inlen; + priv->req.dst = out; + priv->req.out_buf_bytes = inlen; + + uadk_prov_cipher_ctx_init(priv); +- ret = async_setup_async_event_notification(&op); +- if (!ret) { +- fprintf(stderr, "failed to setup async event notification.\n"); +- return 0; +- } + +- if (op.job == NULL) { +- /* Synchronous, only the synchronous mode supports soft computing */ ++ if (inlen <= blksz) { ++ /* small packet directly using sync? */ + ret = uadk_do_cipher_sync(priv); + if (!ret) +- goto sync_err; ++ return 0; + } else { +- /* +- * If the length of the input data +- * does not reach to hardware computing threshold, +- * directly switch to soft cipher. +- */ +- if (priv->req.in_bytes <= priv->switch_threshold) +- goto sync_err; +- +- ret = uadk_do_cipher_async(priv, &op); +- if (!ret) +- goto out_notify; ++ ret = async_setup_async_event_notification(&op); ++ if (!ret) { ++ fprintf(stderr, "failed to setup async event notification.\n"); ++ return 0; ++ } ++ ++ if (op.job == NULL) { ++ /* Synchronous, only the synchronous mode supports soft computing */ ++ ret = uadk_do_cipher_sync(priv); ++ if (!ret) { ++ async_clear_async_event_notification(); ++ return 0; ++ } ++ } else { ++ ret = uadk_do_cipher_async(priv, &op); ++ if (!ret) { ++ async_clear_async_event_notification(); ++ return 0; ++ } ++ } + } +- uadk_cipher_update_priv_ctx(priv); + ++ uadk_cipher_update_priv_ctx(priv); + return 1; +-sync_err: +- ret = uadk_prov_cipher_soft_work(priv, out, in, inlen); +- if (ret != 1) ++} ++ ++static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inlen) ++{ ++ size_t blksz = priv->blksize; ++ size_t nextblocks; ++ int outlint = 0; ++ int ret; ++ ++ if (priv->switch_flag == UADK_DO_SOFT || ++ (priv->sw_cipher && priv->switch_flag != UADK_DO_HW && ++ inlen <= priv->switch_threshold)) { ++ /* have issue if both using hw and soft partly */ ++ ret = uadk_prov_cipher_soft_work(priv, out, &outlint, in, inlen); ++ if (ret) { ++ *outl = outlint; ++ return 1; ++ } ++ + fprintf(stderr, "do soft ciphers failed.\n"); +-out_notify: +- async_clear_async_event_notification(); +- return ret; ++ } ++ ++ if (priv->bufsz != 0) ++ nextblocks = ossl_cipher_fillblock(priv->buf, &priv->bufsz, ++ blksz, &in, &inlen); ++ else ++ nextblocks = inlen & ~(blksz-1); ++ ++ /* ++ * If we're decrypting and we end an update on a block boundary we hold ++ * the last block back in case this is the last update call and the last ++ * block is padded. ++ */ ++ if (priv->bufsz == blksz && inlen > 0) { ++ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); ++ if (ret != 1) { ++ fprintf(stderr, "do hw ciphers failed.\n"); ++ return ret; ++ } ++ ++ priv->bufsz = 0; ++ outlint = blksz; ++ out += blksz; ++ } ++ ++ if (nextblocks == 0) ++ goto out; ++ ++ if (!priv->enc && nextblocks == inlen) ++ nextblocks -= blksz; ++ ++ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); ++ if (ret != 1) { ++ fprintf(stderr, "do hw ciphers failed.\n"); ++ return ret; ++ } ++ ++ outlint += nextblocks; ++ in += nextblocks; ++ inlen -= nextblocks; ++ ++ if (inlen != 0 ++ && !ossl_cipher_trailingdata(priv->buf, &priv->bufsz, ++ blksz, &in, &inlen)) ++ return 0; ++out: ++ *outl = outlint; ++ return inlen == 0; + } + + void uadk_prov_destroy_cipher(void) +@@ -521,19 +737,70 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, + return 0; + } + +- ret = uadk_prov_do_cipher(priv, out, in, inl); ++ ret = uadk_prov_do_cipher(priv, out, outl, outsize, in, inl); + if (ret != 1) + return ret; + + *outl = inl; + return 1; +- + } + + static int uadk_prov_cipher_final(void *vctx, unsigned char *out, + size_t *outl, size_t outsize) + { +- *outl = 0; ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ size_t blksz = priv->blksize; ++ int sw_final_len = 0; ++ int ret; ++ ++ if (priv->switch_flag == UADK_DO_SOFT) { ++ if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { ++ fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); ++ return 0; ++ } ++ *outl = sw_final_len; ++ return 1; ++ } ++ ++ if (priv->enc) { ++ if (priv->bufsz <= blksz) { ++ ossl_cipher_padblock(priv->buf, &priv->bufsz, blksz); ++ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); ++ if (ret != 1) { ++ fprintf(stderr, "do hw ciphers failed.\n"); ++ return ret; ++ } ++ *outl = blksz; ++ return 1; ++ } ++ *outl = sw_final_len; ++ return 1; ++ } ++ ++ /* dec should handle last blk since pad */ ++ if (priv->bufsz != blksz) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); ++ return 0; ++ } ++ ++ ret = uadk_prov_hw_cipher(priv, priv->buf, outl, outsize, priv->buf, blksz); ++ if (ret != 1) { ++ fprintf(stderr, "do hw ciphers failed.\n"); ++ return ret; ++ } ++ if (!ossl_cipher_unpadblock(priv->buf, &priv->bufsz, blksz)) { ++ /* ERR_raise already called */ ++ return 0; ++ } ++ ++ if (outsize < priv->bufsz) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ memcpy(out, priv->buf, priv->bufsz); ++ *outl = priv->bufsz; ++ priv->bufsz = 0; ++ + return 1; + } + +@@ -554,11 +821,10 @@ static int uadk_prov_cipher_update(void *vctx, unsigned char *out, + return 0; + } + +- ret = uadk_prov_do_cipher(priv, out, in, inl); ++ ret = uadk_prov_do_cipher(priv, out, outl, outsize, in, inl); + if (ret != 1) + return ret; + +- *outl = inl; + return 1; + } + +-- +2.25.1 + diff --git a/0037-uadk_prov_cipher-add-stream-mode.patch b/0037-uadk_prov_cipher-add-stream-mode.patch new file mode 100644 index 0000000..dfa6723 --- /dev/null +++ b/0037-uadk_prov_cipher-add-stream-mode.patch @@ -0,0 +1,189 @@ +From ee4e7949e3a94fc37d8cf9499991c3159c7cbba7 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Mon, 4 Sep 2023 17:36:08 +0800 +Subject: [PATCH 37/48] uadk_prov_cipher: add stream mode + +In stream mode, the incoming data can be of any length and may not +be aligned with the specified block size. + +The stream mode allows for direct processing of the data without the +need to handle padding or alignment. + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_cipher.c | 125 ++++++++++++++++++++++++++++++----------- + 1 file changed, 93 insertions(+), 32 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 87beb76..7a359f6 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -745,8 +745,8 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, + return 1; + } + +-static int uadk_prov_cipher_final(void *vctx, unsigned char *out, +- size_t *outl, size_t outsize) ++static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize) + { + struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; + size_t blksz = priv->blksize; +@@ -804,9 +804,9 @@ static int uadk_prov_cipher_final(void *vctx, unsigned char *out, + return 1; + } + +-static int uadk_prov_cipher_update(void *vctx, unsigned char *out, +- size_t *outl, size_t outsize, +- const unsigned char *in, size_t inl) ++static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inl) + { + struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; + int ret; +@@ -828,6 +828,65 @@ static int uadk_prov_cipher_update(void *vctx, unsigned char *out, + return 1; + } + ++static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inl) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int ret; ++ ++ if (inl == 0) { ++ *outl = 0; ++ return 1; ++ } ++ ++ if (outsize < inl) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ ++ if (priv->switch_flag == UADK_DO_SOFT || ++ (priv->sw_cipher && priv->switch_flag != UADK_DO_HW && ++ inl <= priv->switch_threshold)) { ++ int len = 0; ++ ++ /* have isseu if both using hw and soft partly */ ++ ret = uadk_prov_cipher_soft_work(priv, out, &len, in, inl); ++ if (ret) { ++ *outl = len; ++ return 1; ++ } ++ ++ fprintf(stderr, "do soft ciphers failed.\n"); ++ } ++ ++ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, inl); ++ if (ret != 1) ++ return ret; ++ ++ *outl = inl; ++ return 1; ++} ++ ++static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize) ++{ ++ struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; ++ int sw_final_len = 0; ++ ++ if (priv->switch_flag == UADK_DO_SOFT) { ++ if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { ++ fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); ++ return 0; ++ } ++ *outl = sw_final_len; ++ return 1; ++ } ++ ++ *outl = 0; ++ return 1; ++} ++ + static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +@@ -1020,7 +1079,7 @@ static void uadk_prov_cipher_freectx(void *ctx) + } + + #define UADK_CIPHER_DESCR(nm, blk_size, key_len, iv_len, \ +- flags, e_nid, algnm, mode) \ ++ flags, e_nid, algnm, mode, typ) \ + static OSSL_FUNC_cipher_newctx_fn uadk_##nm##_newctx; \ + static void *uadk_##nm##_newctx(void *provctx) \ + { \ +@@ -1051,8 +1110,10 @@ const OSSL_DISPATCH uadk_##nm##_functions[] = { \ + (void (*)(void))uadk_prov_cipher_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, \ + (void (*)(void))uadk_prov_cipher_dinit }, \ +- { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))uadk_prov_cipher_update }, \ +- { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))uadk_prov_cipher_final }, \ ++ { OSSL_FUNC_CIPHER_UPDATE, \ ++ (void (*)(void))uadk_prov_cipher_##typ##_update }, \ ++ { OSSL_FUNC_CIPHER_FINAL, \ ++ (void (*)(void))uadk_prov_cipher_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))uadk_prov_cipher_cipher }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void))uadk_##nm##_get_params }, \ +@@ -1069,29 +1130,29 @@ const OSSL_DISPATCH uadk_##nm##_functions[] = { \ + { 0, NULL } \ + } + +-UADK_CIPHER_DESCR(aes_128_cbc, 16, 16, 16, 0, NID_aes_128_cbc, cbc(aes), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(aes_192_cbc, 16, 24, 16, 0, NID_aes_192_cbc, cbc(aes), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(aes_256_cbc, 16, 32, 16, 0, NID_aes_256_cbc, cbc(aes), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(aes_128_ecb, 16, 16, 0, 0, NID_aes_128_ecb, ecb(aes), EVP_CIPH_ECB_MODE); +-UADK_CIPHER_DESCR(aes_192_ecb, 16, 24, 0, 0, NID_aes_192_ecb, ecb(aes), EVP_CIPH_ECB_MODE); +-UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, NID_aes_256_ecb, ecb(aes), EVP_CIPH_ECB_MODE); +-UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, 0, NID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); +-UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, 0, NID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV); +-UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, NID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE); +-UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, NID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE); +-UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, NID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE); ++UADK_CIPHER_DESCR(aes_128_cbc, 16, 16, 16, 0, NID_aes_128_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); ++UADK_CIPHER_DESCR(aes_192_cbc, 16, 24, 16, 0, NID_aes_192_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); ++UADK_CIPHER_DESCR(aes_256_cbc, 16, 32, 16, 0, NID_aes_256_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); ++UADK_CIPHER_DESCR(aes_128_ecb, 16, 16, 0, 0, NID_aes_128_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); ++UADK_CIPHER_DESCR(aes_192_ecb, 16, 24, 0, 0, NID_aes_192_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); ++UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, NID_aes_256_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); ++UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, PROV_CIPHER_FLAG_CUSTOM_IV, NID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); ++UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, PROV_CIPHER_FLAG_CUSTOM_IV, NID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); ++UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, NID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE, block); ++UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE, block); ++UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, NID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE, block); ++UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, NID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE, block); + + /* v3 */ +-UADK_CIPHER_DESCR(aes_128_ctr, 1, 16, 16, 0, NID_aes_128_ctr, ctr(aes), EVP_CIPH_CTR_MODE); +-UADK_CIPHER_DESCR(aes_192_ctr, 1, 24, 16, 0, NID_aes_192_ctr, ctr(aes), EVP_CIPH_CTR_MODE); +-UADK_CIPHER_DESCR(aes_256_ctr, 1, 32, 16, 0, NID_aes_256_ctr, ctr(aes), EVP_CIPH_CTR_MODE); +-UADK_CIPHER_DESCR(aes_128_ofb128, 1, 16, 16, 0, NID_aes_128_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); +-UADK_CIPHER_DESCR(aes_192_ofb128, 1, 24, 16, 0, NID_aes_192_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); +-UADK_CIPHER_DESCR(aes_256_ofb128, 1, 32, 16, 0, NID_aes_256_ofb128, ofb(aes), EVP_CIPH_OFB_MODE); +-UADK_CIPHER_DESCR(aes_128_cfb128, 1, 16, 16, 0, NID_aes_128_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); +-UADK_CIPHER_DESCR(aes_192_cfb128, 1, 24, 16, 0, NID_aes_192_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); +-UADK_CIPHER_DESCR(aes_256_cfb128, 1, 32, 16, 0, NID_aes_256_cfb128, cfb(aes), EVP_CIPH_CFB_MODE); +-UADK_CIPHER_DESCR(sm4_ofb128, 1, 16, 16, 0, NID_sm4_ofb128, ofb(sm4), EVP_CIPH_OFB_MODE); +-UADK_CIPHER_DESCR(sm4_cfb128, 1, 16, 16, 0, NID_sm4_cfb128, cfb(sm4), EVP_CIPH_CFB_MODE); +-UADK_CIPHER_DESCR(sm4_ctr, 1, 16, 16, 0, NID_sm4_ctr, ctr(sm4), EVP_CIPH_CTR_MODE); ++UADK_CIPHER_DESCR(aes_128_ctr, 1, 16, 16, 0, NID_aes_128_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); ++UADK_CIPHER_DESCR(aes_192_ctr, 1, 24, 16, 0, NID_aes_192_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); ++UADK_CIPHER_DESCR(aes_256_ctr, 1, 32, 16, 0, NID_aes_256_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); ++UADK_CIPHER_DESCR(aes_128_ofb128, 1, 16, 16, 0, NID_aes_128_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); ++UADK_CIPHER_DESCR(aes_192_ofb128, 1, 24, 16, 0, NID_aes_192_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); ++UADK_CIPHER_DESCR(aes_256_ofb128, 1, 32, 16, 0, NID_aes_256_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); ++UADK_CIPHER_DESCR(aes_128_cfb128, 1, 16, 16, 0, NID_aes_128_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); ++UADK_CIPHER_DESCR(aes_192_cfb128, 1, 24, 16, 0, NID_aes_192_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); ++UADK_CIPHER_DESCR(aes_256_cfb128, 1, 32, 16, 0, NID_aes_256_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); ++UADK_CIPHER_DESCR(sm4_ofb128, 1, 16, 16, 0, NID_sm4_ofb128, ofb(sm4), EVP_CIPH_OFB_MODE, stream); ++UADK_CIPHER_DESCR(sm4_cfb128, 1, 16, 16, 0, NID_sm4_cfb128, cfb(sm4), EVP_CIPH_CFB_MODE, stream); ++UADK_CIPHER_DESCR(sm4_ctr, 1, 16, 16, 0, NID_sm4_ctr, ctr(sm4), EVP_CIPH_CTR_MODE, stream); +-- +2.25.1 + diff --git a/0038-uadk_prov_cipher-xts-mode-does-not-use-default-provi.patch b/0038-uadk_prov_cipher-xts-mode-does-not-use-default-provi.patch new file mode 100644 index 0000000..88a4e9a --- /dev/null +++ b/0038-uadk_prov_cipher-xts-mode-does-not-use-default-provi.patch @@ -0,0 +1,44 @@ +From 2036c60489df2d6b8c6ee4925f9c9826d44de69a Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Thu, 7 Sep 2023 17:19:27 +0800 +Subject: [PATCH 38/48] uadk_prov_cipher: xts mode does not use default + provider + +Now uadk_provider chooses the default provider for small packets, +when inlen < threshold (192), but xts mode fails in speed test. +Temporarily solving the problem by disabling default for xfs mode. + +Fail: openssl speed -provider uadk_provider -evp aes-128-xts -bytes 16 +Success: openssl speed -provider default -evp aes-128-xts -bytes 16 + +The speed will call EVP_CipherInit_ex2 twice, without iv the second +time, and EVP_CIPHER_CTX_reset clears iv_set = 0 causing error. The default +provider does not call EVP_CIPHER_CTX_reset, so iv_set = 1 without problem. + +A bit tricky, simply not using the default pvovider for xts mode. + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_cipher.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 7a359f6..64058ee 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -143,12 +143,6 @@ static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) + case NID_aes_256_ecb: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-ECB", "provider=default"); + break; +- case NID_aes_128_xts: +- priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-XTS", "provider=default"); +- break; +- case NID_aes_256_xts: +- priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-XTS", "provider=default"); +- break; + case NID_sm4_cbc: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); + break; +-- +2.25.1 + diff --git a/0039-uadk_prov_cipher-handle-no-padding-case.patch b/0039-uadk_prov_cipher-handle-no-padding-case.patch new file mode 100644 index 0000000..f9f47b5 --- /dev/null +++ b/0039-uadk_prov_cipher-handle-no-padding-case.patch @@ -0,0 +1,129 @@ +From 351967a019a91d53916cacb84b2cf4fd2a70443d Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Fri, 8 Sep 2023 20:42:40 +0800 +Subject: [PATCH 39/48] uadk_prov_cipher: handle no padding case + +The padding can be disabled via set_ctx_params +Add handling of no padding case + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_cipher.c | 45 +++++++++++++++++++++++++++++++----------- + 1 file changed, 34 insertions(+), 11 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 64058ee..5f9ed45 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -78,6 +78,7 @@ struct cipher_priv_ctx { + /* Crypto small packet offload threshold */ + size_t switch_threshold; + unsigned int enc : 1; ++ unsigned int pad : 1; /* Whether padding should be used or not */ + size_t blksize; + size_t keylen; + size_t ivlen; +@@ -659,7 +660,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, + * the last block back in case this is the last update call and the last + * block is padded. + */ +- if (priv->bufsz == blksz && inlen > 0) { ++ if (priv->bufsz == blksz && (priv->enc || inlen > 0 || !priv->pad)) { + ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); + if (ret != 1) { + fprintf(stderr, "do hw ciphers failed.\n"); +@@ -674,7 +675,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, + if (nextblocks == 0) + goto out; + +- if (!priv->enc && nextblocks == inlen) ++ if (!priv->enc && priv->pad && nextblocks == inlen) + nextblocks -= blksz; + + ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); +@@ -757,22 +758,36 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, + } + + if (priv->enc) { +- if (priv->bufsz <= blksz) { ++ if (priv->pad) { + ossl_cipher_padblock(priv->buf, &priv->bufsz, blksz); +- ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); +- if (ret != 1) { +- fprintf(stderr, "do hw ciphers failed.\n"); +- return ret; +- } +- *outl = blksz; ++ } else if (priv->bufsz == 0) { ++ *outl = 0; + return 1; ++ } else if (priv->bufsz != blksz) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); ++ return 0; + } +- *outl = sw_final_len; ++ ++ if (outsize < blksz) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return 0; ++ } ++ ++ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); ++ if (ret != 1) { ++ fprintf(stderr, "do hw ciphers failed.\n"); ++ return ret; ++ } ++ *outl = blksz; + return 1; + } + + /* dec should handle last blk since pad */ + if (priv->bufsz != blksz) { ++ if (priv->bufsz == 0 && !priv->pad) { ++ *outl = 0; ++ return 1; ++ } + ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); + return 0; + } +@@ -782,7 +797,8 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, + fprintf(stderr, "do hw ciphers failed.\n"); + return ret; + } +- if (!ossl_cipher_unpadblock(priv->buf, &priv->bufsz, blksz)) { ++ ++ if (priv->pad && !ossl_cipher_unpadblock(priv->buf, &priv->bufsz, blksz)) { + /* ERR_raise already called */ + return 0; + } +@@ -791,6 +807,7 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } ++ + memcpy(out, priv->buf, priv->bufsz); + *outl = priv->bufsz; + priv->bufsz = 0; +@@ -943,6 +960,7 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } ++ priv->pad = pad ? 1 : 0; + EVP_CIPHER_CTX_set_padding(priv->sw_ctx, pad); + } + +@@ -978,6 +996,11 @@ static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); ++ if (p != NULL && !OSSL_PARAM_set_uint(p, priv->pad)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); + if (p != NULL && !OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { +-- +2.25.1 + diff --git a/0040-sanity_test.sh-change-provider-name-to-its-full-path.patch b/0040-sanity_test.sh-change-provider-name-to-its-full-path.patch new file mode 100644 index 0000000..b1ab6b1 --- /dev/null +++ b/0040-sanity_test.sh-change-provider-name-to-its-full-path.patch @@ -0,0 +1,63 @@ +From 651c2a2b95252c89833bb57e959ad2f24fbcfbe7 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Sun, 3 Sep 2023 06:45:03 +0800 +Subject: [PATCH 40/48] sanity_test.sh: change provider name to its full + pathname + +By using the full pathname, avoid the configuration +burden. Test script can always run against the expected (just-built) +udak_provider.so + +Signed-off-by: Guodong Xu +Signed-off-by: Zhangfei Gao +--- + test/sanity_test.sh | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/test/sanity_test.sh b/test/sanity_test.sh +index 0fe4472..10aa149 100755 +--- a/test/sanity_test.sh ++++ b/test/sanity_test.sh +@@ -1,7 +1,9 @@ + #!/bin/bash + ++set -x + sudo chmod 666 /dev/hisi_* + ++TEST_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + version=$(openssl version) + echo $version +@@ -12,13 +14,9 @@ echo "OpenSSL major version is "$major_version + + # Check if the major version is equal to or greater than 3 + if ((major_version >= 3)); then +- if [ ! -n "$1" ]; then +- engine_id=uadk_provider +- else +- engine_id=$1 +- fi ++ engine_id="$TEST_SCRIPT_DIR/../src/.libs/uadk_provider.so" + digest_algs=$(openssl list -provider $engine_id -digest-algorithms) +- cipher_algs=$(openssl list -provider $engine_id -digest-algorithms) ++ cipher_algs=$(openssl list -provider $engine_id -cipher-algorithms) + fi + + if [[ $digest_algs =~ "uadk_provider" ]]; then +@@ -71,12 +69,7 @@ fi + + if [[ $version =~ "1.1.1" ]]; then + echo "openssl 1.1.1" +- if [ ! -n "$1" ]; then +- engine_id=uadk_engine +- else +- engine_id=$1 +- fi +- ++ engine_id="$TEST_SCRIPT_DIR/../src/.libs/uadk_engine.so" + algs=$(openssl engine -c $engine_id) + echo $algs + fi +-- +2.25.1 + diff --git a/0041-sanity_test-remove-default-provider.patch b/0041-sanity_test-remove-default-provider.patch new file mode 100644 index 0000000..f373f01 --- /dev/null +++ b/0041-sanity_test-remove-default-provider.patch @@ -0,0 +1,110 @@ +From f1e1fdba87a02d56911b40076e1d0bbb9416a2a8 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 13 Sep 2023 11:11:27 +0800 +Subject: [PATCH 41/48] sanity_test: remove default provider + +Remove the default provider, which is not required now + +Signed-off-by: Zhangfei Gao +--- + test/sanity_test.sh | 80 ++++++++++++++++++++++----------------------- + 1 file changed, 40 insertions(+), 40 deletions(-) + +diff --git a/test/sanity_test.sh b/test/sanity_test.sh +index 10aa149..1e9983b 100755 +--- a/test/sanity_test.sh ++++ b/test/sanity_test.sh +@@ -21,50 +21,50 @@ fi + + if [[ $digest_algs =~ "uadk_provider" ]]; then + echo "uadk_provider testing digest" +- openssl speed -provider $engine_id -provider default -evp md5 +- openssl speed -provider $engine_id -provider default -evp sm3 +- openssl speed -provider $engine_id -provider default -evp sha1 +- openssl speed -provider $engine_id -provider default -evp sha2-224 +- openssl speed -provider $engine_id -provider default -evp sha2-256 +- openssl speed -provider $engine_id -provider default -evp sha2-384 +- openssl speed -provider $engine_id -provider default -evp sha2-512 +- +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp md5 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sm3 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha1 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha2-224 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha2-256 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha2-384 +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sha2-512 ++ openssl speed -provider $engine_id -evp md5 ++ openssl speed -provider $engine_id -evp sm3 ++ openssl speed -provider $engine_id -evp sha1 ++ openssl speed -provider $engine_id -evp sha2-224 ++ openssl speed -provider $engine_id -evp sha2-256 ++ openssl speed -provider $engine_id -evp sha2-384 ++ openssl speed -provider $engine_id -evp sha2-512 ++ ++ openssl speed -provider $engine_id -async_jobs 1 -evp md5 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sm3 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sha1 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sha2-224 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sha2-256 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sha2-384 ++ openssl speed -provider $engine_id -async_jobs 1 -evp sha2-512 + fi + + if [[ $cipher_algs =~ "uadk_provider" ]]; then + echo "uadk_provider testing cipher" +- openssl speed -provider $engine_id -provider default -evp aes-128-cbc +- openssl speed -provider $engine_id -provider default -evp aes-192-cbc +- openssl speed -provider $engine_id -provider default -evp aes-256-cbc +- openssl speed -provider $engine_id -provider default -evp aes-128-ecb +- openssl speed -provider $engine_id -provider default -evp aes-192-ecb +- openssl speed -provider $engine_id -provider default -evp aes-256-ecb +- openssl speed -provider $engine_id -provider default -evp aes-128-xts +- openssl speed -provider $engine_id -provider default -evp aes-256-xts +- openssl speed -provider $engine_id -provider default -evp sm4-cbc +- openssl speed -provider $engine_id -provider default -evp sm4-ecb +- openssl speed -provider $engine_id -provider default -evp des-ede3-cbc +- openssl speed -provider $engine_id -provider default -evp des-ede3-ecb +- +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-cbc +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-192-cbc +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-cbc +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-ecb +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-192-ecb +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-ecb +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-128-xts +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp aes-256-xts +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sm4-cbc +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp sm4-ecb +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp des-ede3-cbc +- openssl speed -provider $engine_id -provider default -async_jobs 1 -evp des-ede3-ecb ++ openssl speed -provider $engine_id -evp aes-128-cbc ++ openssl speed -provider $engine_id -evp aes-192-cbc ++ openssl speed -provider $engine_id -evp aes-256-cbc ++ openssl speed -provider $engine_id -evp aes-128-ecb ++ openssl speed -provider $engine_id -evp aes-192-ecb ++ openssl speed -provider $engine_id -evp aes-256-ecb ++ openssl speed -provider $engine_id -evp aes-128-xts ++ openssl speed -provider $engine_id -evp aes-256-xts ++ openssl speed -provider $engine_id -evp sm4-cbc ++ openssl speed -provider $engine_id -evp sm4-ecb ++ openssl speed -provider $engine_id -evp des-ede3-cbc ++ openssl speed -provider $engine_id -evp des-ede3-ecb ++ ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-128-cbc ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-192-cbc ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-256-cbc ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-128-ecb ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-192-ecb ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-256-ecb ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-128-xts ++ openssl speed -provider $engine_id -async_jobs 1 -evp aes-256-xts ++ openssl speed -provider $engine_id -async_jobs 1 -evp sm4-cbc ++ openssl speed -provider $engine_id -async_jobs 1 -evp sm4-ecb ++ openssl speed -provider $engine_id -async_jobs 1 -evp des-ede3-cbc ++ openssl speed -provider $engine_id -async_jobs 1 -evp des-ede3-ecb + fi + + if [[ $version =~ "1.1.1" ]]; then +-- +2.25.1 + diff --git a/0042-uadk_prov_cipher-add-static-descriptor-to-uadk_prov_.patch b/0042-uadk_prov_cipher-add-static-descriptor-to-uadk_prov_.patch new file mode 100644 index 0000000..5119c53 --- /dev/null +++ b/0042-uadk_prov_cipher-add-static-descriptor-to-uadk_prov_.patch @@ -0,0 +1,29 @@ +From de8448dd775231f5fcd3f050fafceb2ed013f34a Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Tue, 12 Sep 2023 08:55:28 +0800 +Subject: [PATCH 42/48] uadk_prov_cipher: add static descriptor to + uadk_prov_cipher_gettable_ctx_params() + +Signed-off-by: Guodong Xu +--- + src/uadk_prov_cipher.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 5f9ed45..9a2c27b 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -1024,8 +1024,8 @@ static const OSSL_PARAM uadk_prov_default_ctx_params[] = { + OSSL_PARAM_END + }; + +-const OSSL_PARAM *uadk_prov_cipher_gettable_ctx_params(ossl_unused void *cctx, +- ossl_unused void *provctx) ++static const OSSL_PARAM *uadk_prov_cipher_gettable_ctx_params(ossl_unused void *cctx, ++ ossl_unused void *provctx) + { + return uadk_prov_default_ctx_params; + } +-- +2.25.1 + diff --git a/0043-tentative-ctx-handle-handle.patch b/0043-tentative-ctx-handle-handle.patch new file mode 100644 index 0000000..3fa5a60 --- /dev/null +++ b/0043-tentative-ctx-handle-handle.patch @@ -0,0 +1,25 @@ +From 657cda03fd4adde660b617ccc61a9e534da08950 Mon Sep 17 00:00:00 2001 +From: Guodong Xu +Date: Tue, 12 Sep 2023 08:51:42 +0800 +Subject: [PATCH 43/48] tentative: ctx->handle=handle + +Signed-off-by: Guodong Xu +--- + src/uadk_prov_init.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index af22dfa..965092d 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -145,6 +145,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + if (ctx == NULL) + return 0; + ++ ctx->handle = handle; + ret = async_module_init(); + if (!ret) + fprintf(stderr, "async_module_init fail!\n"); +-- +2.25.1 + diff --git a/0044-uadk-add-uadk_prov_rsa-for-openssl-3.0.patch b/0044-uadk-add-uadk_prov_rsa-for-openssl-3.0.patch new file mode 100644 index 0000000..2d3c255 --- /dev/null +++ b/0044-uadk-add-uadk_prov_rsa-for-openssl-3.0.patch @@ -0,0 +1,3157 @@ +From 49894a710e811b03fe311bbb27eddb99bede1733 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 13 Sep 2023 17:46:29 +0800 +Subject: [PATCH 44/48] uadk: add uadk_prov_rsa for openssl 3.0 + +Test: +openssl speed -provider uadk_provider rsa1024 +openssl speed -provider uadk_provider rsa2048 +openssl speed -provider uadk_provider rsa4096 +openssl speed -provider uadk_provider -async_jobs 1 rsa1024 +openssl speed -provider uadk_provider -async_jobs 1 rsa2048 +openssl speed -provider uadk_provider -async_jobs 1 rsa4096 +openssl genrsa -out prikey.pem -provider uadk_provider 1024 +openssl rsa -in prikey.pem -pubout -out pubkey.pem \ + -provider uadk_provider -provider default +echo "Content to be encrypted" > plain.txt +openssl pkeyutl -encrypt -in plain.txt -inkey pubkey.pem -pubin -out enc.txt \ +-pkeyopt rsa_padding_mode:pkcs1 -provider uadk_provider -provider default + +openssl pkeyutl -decrypt -in enc.txt -inkey prikey.pem -out dec.txt \ +-pkeyopt rsa_padding_mode:pkcs1 -provider uadk_provider -provider default + +Notes: +"-provider default" is required when -store-loaders is required +$ openssl list -provider default -store-loaders +Provided STORE LOADERs: + file @ default + +$ openssl rsa -in prikey.pem -pubout -out pubkey.pem -provider uadk_provider -provider default +writing RSA key + +$ openssl rsa -in prikey.pem -pubout -out pubkey.pem -provider uadk_provider +Could not open file or uri for loading private key from prikey.pem +206096A7FFFF0000:error:16000069:STORE routines:ossl_store_get0_loader_int:unregistered scheme:crypto/store/store_register.c:237:scheme=file +206096A7FFFF0000:error:1608010C:STORE routines:inner_loader_fetch:unsupported:crypto/store/store_meth.c:383:No store loader found. For standard store loaders you need at least one of the default or base providers available. Did you forget to load them? Info: Global default library context, Scheme (file : 0), Properties () + +Signed-off-by: Zhangfei Gao +--- + src/Makefile.am | 3 +- + src/uadk_prov.h | 17 + + src/uadk_prov_init.c | 29 +- + src/uadk_prov_rsa.c | 2953 ++++++++++++++++++++++++++++++++++++++++++ + test/sanity_test.sh | 21 + + 5 files changed, 3017 insertions(+), 6 deletions(-) + create mode 100644 src/uadk_prov_rsa.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index af16d85..6fdee47 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -51,7 +51,8 @@ uadk_engine_la_SOURCES+=v1/alg/ciphers/sec_ciphers.c \ + endif #WD_KAE + + uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ +- uadk_prov_digest.c uadk_prov_cipher.c ++ uadk_prov_digest.c uadk_prov_cipher.c \ ++ uadk_prov_rsa.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 35f1789..f8a3cd7 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -18,6 +18,18 @@ + #ifndef UADK_PROV_H + #define UADK_PROV_H + ++struct p_uadk_ctx { ++ const OSSL_CORE_HANDLE *handle; ++ OSSL_LIB_CTX *libctx; ++}; ++ ++static inline OSSL_LIB_CTX *prov_libctx_of(struct p_uadk_ctx *ctx) ++{ ++ if (ctx == NULL) ++ return NULL; ++ return ctx->libctx; ++} ++ + extern const OSSL_DISPATCH uadk_md5_functions[]; + extern const OSSL_DISPATCH uadk_sm3_functions[]; + extern const OSSL_DISPATCH uadk_sha1_functions[]; +@@ -39,6 +51,11 @@ extern const OSSL_DISPATCH uadk_sm4_ecb_functions[]; + extern const OSSL_DISPATCH uadk_des_ede3_cbc_functions[]; + extern const OSSL_DISPATCH uadk_des_ede3_ecb_functions[]; + ++extern const OSSL_DISPATCH uadk_rsa_signature_functions[]; ++extern const OSSL_DISPATCH uadk_rsa_keymgmt_functions[]; ++extern const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[]; ++ + void uadk_prov_destroy_digest(void); + void uadk_prov_destroy_cipher(void); ++void uadk_prov_destroy_rsa(void); + #endif +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 965092d..b28ce69 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -28,11 +28,6 @@ + #include "uadk_async.h" + #include "uadk_prov.h" + +-struct p_uadk_ctx { +- const OSSL_CORE_HANDLE *handle; +- OSSL_LIB_CTX *libctx; +-}; +- + const char *engine_uadk_id = "uadk_provider"; + static const char UADK_DEFAULT_PROPERTIES[] = "provider=uadk_provider"; + static OSSL_PROVIDER *prov; +@@ -83,6 +78,23 @@ const OSSL_ALGORITHM uadk_prov_ciphers[] = { + { NULL, NULL, NULL } + }; + ++static const OSSL_ALGORITHM uadk_prov_signature[] = { ++ {"RSA", UADK_DEFAULT_PROPERTIES, ++ uadk_rsa_signature_functions, "uadk_provider rsa_signature" }, ++ {NULL, NULL, NULL} ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { ++ {"RSA", UADK_DEFAULT_PROPERTIES, ++ uadk_rsa_keymgmt_functions, "uadk RSA Keymgmt implementation."}, ++ {NULL, NULL, NULL} ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { ++ { "RSA", UADK_DEFAULT_PROPERTIES, uadk_rsa_asym_cipher_functions }, ++ { NULL, NULL, NULL } ++}; ++ + static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + int *no_cache) + { +@@ -103,6 +115,12 @@ static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + return uadk_prov_digests; + case OSSL_OP_CIPHER: + return uadk_prov_ciphers; ++ case OSSL_OP_SIGNATURE: ++ return uadk_prov_signature; ++ case OSSL_OP_KEYMGMT: ++ return uadk_prov_keymgmt; ++ case OSSL_OP_ASYM_CIPHER: ++ return uadk_prov_asym_cipher; + } + return NULL; + } +@@ -113,6 +131,7 @@ static void p_teardown(void *provctx) + + uadk_prov_destroy_digest(); + uadk_prov_destroy_cipher(); ++ uadk_prov_destroy_rsa(); + OPENSSL_free(ctx); + OSSL_PROVIDER_unload(prov); + async_poll_task_free(); +diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c +new file mode 100644 +index 0000000..a342e92 +--- /dev/null ++++ b/src/uadk_prov_rsa.c +@@ -0,0 +1,2953 @@ ++/* ++ * Copyright 2023-2024 Huawei Technologies Co.,Ltd. All rights reserved. ++ * Copyright 2023-2024 Linaro ltd. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "uadk_async.h" ++#include "uadk.h" ++#include "uadk_prov.h" ++ ++#define UN_SET 0 ++#define IS_SET 1 ++#define BIT_BYTES_SHIFT 3 ++#define RSA_MIN_MODULUS_BITS 512 ++#define RSA_MAX_PRIME_NUM 2 ++#define RSA1024BITS 1024 ++#define RSA2048BITS 2048 ++#define RSA3072BITS 3072 ++#define RSA4096BITS 4096 ++#define OPENSSLRSA7680BITS 7680 ++#define OPENSSLRSA15360BITS 15360 ++#define CTX_ASYNC 1 ++#define CTX_SYNC 0 ++#define CTX_NUM 2 ++#define BN_CONTINUE 1 ++#define BN_VALID 0 ++#define BN_ERR (-1) ++#define BN_REDO (-2) ++#define GET_ERR_FINISH 0 ++#define SOFT 2 ++#define UNUSED(x) ((void)(x)) ++#define UADK_E_SUCCESS 1 ++#define UADK_E_FAIL 0 ++#define UADK_DO_SOFT (-0xE0) ++#define UADK_E_POLL_SUCCESS 0 ++#define UADK_E_POLL_FAIL (-1) ++#define UADK_E_INIT_SUCCESS 0 ++#define CHECK_PADDING_FAIL (-1) ++#define ENV_ENABLED 1 ++#define PRIME_RETRY_COUNT 4 ++#define GENCB_NEXT 2 ++#define GENCB_RETRY 3 ++#define PRIME_CHECK_BIT_NUM 4 ++ ++struct bignum_st { ++ BN_ULONG *d; ++ int top; ++ int dmax; ++ int neg; ++ int flags; ++}; ++ ++struct rsa_keypair { ++ struct wd_rsa_pubkey *pubkey; ++ struct wd_rsa_prikey *prikey; ++}; ++ ++struct rsa_keygen_param { ++ struct wd_dtb *wd_e; ++ struct wd_dtb *wd_p; ++ struct wd_dtb *wd_q; ++}; ++ ++struct rsa_keygen_param_bn { ++ BIGNUM *e; ++ BIGNUM *p; ++ BIGNUM *q; ++}; ++ ++struct rsa_pubkey_param { ++ const BIGNUM *e; ++ const BIGNUM *n; ++}; ++ ++struct rsa_prikey_param { ++ const BIGNUM *n; ++ const BIGNUM *e; ++ const BIGNUM *d; ++ const BIGNUM *p; ++ const BIGNUM *q; ++ const BIGNUM *dmp1; ++ const BIGNUM *dmq1; ++ const BIGNUM *iqmp; ++ int is_crt; ++}; ++ ++struct rsa_prime_param { ++ BIGNUM *r1; ++ BIGNUM *r2; ++ BIGNUM *rsa_p; ++ BIGNUM *rsa_q; ++ BIGNUM *prime; ++}; ++ ++struct uadk_rsa_sess { ++ handle_t sess; ++ struct wd_rsa_sess_setup setup; ++ struct wd_rsa_req req; ++ RSA *alg; ++ int is_pubkey_ready; ++ int is_prikey_ready; ++ int key_size; ++}; ++ ++struct rsa_sched { ++ int sched_type; ++ struct wd_sched wd_sched; ++}; ++ ++struct rsa_prov { ++ int pid; ++}; ++static struct rsa_prov g_rsa_prov; ++ ++static pthread_mutex_t rsa_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++typedef struct { ++ OSSL_LIB_CTX *libctx; ++ char *propq; ++ RSA *rsa; ++ int operation; ++ ++ /* ++ * Flag to determine if the hash function can be changed (1) or not (0) ++ * Because it's dangerous to change during a DigestSign or DigestVerify ++ * operation, this flag is cleared by their Init function, and set again ++ * by their Final function. ++ */ ++ unsigned int flag_allow_md : 1; ++ unsigned int mgf1_md_set : 1; ++ ++ /* main digest */ ++ EVP_MD *md; ++ EVP_MD_CTX *mdctx; ++ int mdnid; ++ char mdname[50]; /* Purely informational */ ++ ++ /* RSA padding mode */ ++ int pad_mode; ++ /* message digest for MGF1 */ ++ EVP_MD *mgf1_md; ++ int mgf1_mdnid; ++ char mgf1_mdname[50]; /* Purely informational */ ++ /* PSS salt length */ ++ int saltlen; ++ /* Minimum salt length or -1 if no PSS parameter restriction */ ++ int min_saltlen; ++ ++ /* Temp buffer */ ++ unsigned char *tbuf; ++ ++ unsigned int soft : 1; ++} PROV_RSA_SIG_CTX; ++ ++typedef struct rsa_pss_params_30_st { ++ int hash_algorithm_nid; ++ struct { ++ int algorithm_nid; /* Currently always NID_mgf1 */ ++ int hash_algorithm_nid; ++ } mask_gen; ++ int salt_len; ++ int trailer_field; ++} RSA_PSS_PARAMS_30; ++ ++struct rsa_st { ++ /* ++ * #legacy ++ * The first field is used to pickup errors where this is passed ++ * instead of an EVP_PKEY. It is always zero. ++ * THIS MUST REMAIN THE FIRST FIELD. ++ */ ++ int dummy_zero; ++ ++ OSSL_LIB_CTX *libctx; ++ int32_t version; ++ const RSA_METHOD *meth; ++ /* functional reference if 'meth' is ENGINE-provided */ ++ ENGINE *engine; ++ BIGNUM *n; ++ BIGNUM *e; ++ BIGNUM *d; ++ BIGNUM *p; ++ BIGNUM *q; ++ BIGNUM *dmp1; ++ BIGNUM *dmq1; ++ BIGNUM *iqmp; ++ ++ /* ++ * If a PSS only key this contains the parameter restrictions. ++ * There are two structures for the same thing, used in different cases. ++ */ ++ /* This is used uniquely by OpenSSL provider implementations. */ ++ RSA_PSS_PARAMS_30 pss_params; ++ ++ /* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */ ++ RSA_PSS_PARAMS *pss; ++ /* for multi-prime RSA, defined in RFC 8017 */ ++ STACK_OF(RSA_PRIME_INFO) * prime_infos; ++ /* Be careful using this if the RSA structure is shared */ ++ CRYPTO_EX_DATA ex_data; ++ ++ int references; //CRYPTO_REF_COUNT references; ++ int flags; ++ /* Used to cache montgomery values */ ++ BN_MONT_CTX *_method_mod_n; ++ BN_MONT_CTX *_method_mod_p; ++ BN_MONT_CTX *_method_mod_q; ++ BN_BLINDING *blinding; ++ BN_BLINDING *mt_blinding; ++ CRYPTO_RWLOCK *lock; ++ ++ int dirty_cnt; ++}; ++ ++typedef struct rsa_st RSA; ++ ++typedef int CRYPTO_REF_COUNT; ++ ++struct evp_signature_st { ++ int name_id; ++ char *type_name; ++ const char *description; ++ OSSL_PROVIDER *prov; ++ CRYPTO_REF_COUNT refcnt; ++ CRYPTO_RWLOCK *lock; ++ ++ OSSL_FUNC_signature_newctx_fn *newctx; ++ OSSL_FUNC_signature_sign_init_fn *sign_init; ++ OSSL_FUNC_signature_sign_fn *sign; ++ OSSL_FUNC_signature_verify_init_fn *verify_init; ++ OSSL_FUNC_signature_verify_fn *verify; ++ OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; ++ OSSL_FUNC_signature_verify_recover_fn *verify_recover; ++ OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; ++ OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; ++ OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; ++ OSSL_FUNC_signature_digest_sign_fn *digest_sign; ++ OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; ++ OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; ++ OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; ++ OSSL_FUNC_signature_digest_verify_fn *digest_verify; ++ OSSL_FUNC_signature_freectx_fn *freectx; ++ OSSL_FUNC_signature_dupctx_fn *dupctx; ++ OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; ++ OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; ++ OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; ++ OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; ++ OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; ++ OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; ++ OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; ++ OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; ++} /* EVP_SIGNATURE */; ++ ++struct evp_asym_cipher_st { ++ int name_id; ++ char *type_name; ++ const char *description; ++ OSSL_PROVIDER *prov; ++ CRYPTO_REF_COUNT refcnt; ++ CRYPTO_RWLOCK *lock; ++ ++ OSSL_FUNC_asym_cipher_newctx_fn *newctx; ++ OSSL_FUNC_asym_cipher_encrypt_init_fn *encrypt_init; ++ OSSL_FUNC_asym_cipher_encrypt_fn *encrypt; ++ OSSL_FUNC_asym_cipher_decrypt_init_fn *decrypt_init; ++ OSSL_FUNC_asym_cipher_decrypt_fn *decrypt; ++ OSSL_FUNC_asym_cipher_freectx_fn *freectx; ++ OSSL_FUNC_asym_cipher_dupctx_fn *dupctx; ++ OSSL_FUNC_asym_cipher_get_ctx_params_fn *get_ctx_params; ++ OSSL_FUNC_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; ++ OSSL_FUNC_asym_cipher_set_ctx_params_fn *set_ctx_params; ++ OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; ++} /* EVP_ASYM_CIPHER */; ++ ++typedef struct{ ++ int id; /* libcrypto internal */ ++ int name_id; ++ char *type_name; ++ const char *description; ++ OSSL_PROVIDER *prov; ++ ++ int refcnt; ++ void *lock; ++ ++ /* Constructor(s), destructor, information */ ++ OSSL_FUNC_keymgmt_new_fn *new; ++ OSSL_FUNC_keymgmt_free_fn *free; ++ OSSL_FUNC_keymgmt_get_params_fn *get_params; ++ OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; ++ OSSL_FUNC_keymgmt_set_params_fn *set_params; ++ OSSL_FUNC_keymgmt_settable_params_fn *settable_params; ++ ++ /* Generation, a complex constructor */ ++ OSSL_FUNC_keymgmt_gen_init_fn *gen_init; ++ OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; ++ OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; ++ OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; ++ OSSL_FUNC_keymgmt_gen_fn *gen; ++ OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; ++ OSSL_FUNC_keymgmt_load_fn *load; ++ ++ /* Key object checking */ ++ OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; ++ OSSL_FUNC_keymgmt_has_fn *has; ++ OSSL_FUNC_keymgmt_validate_fn *validate; ++ OSSL_FUNC_keymgmt_match_fn *match; ++ ++ /* Import and export routines */ ++ OSSL_FUNC_keymgmt_import_fn *import; ++ OSSL_FUNC_keymgmt_import_types_fn *import_types; ++ OSSL_FUNC_keymgmt_export_fn *export; ++ OSSL_FUNC_keymgmt_export_types_fn *export_types; ++ OSSL_FUNC_keymgmt_dup_fn *dup; ++} UADK_RSA_KEYMGMT; ++ ++typedef struct { ++ OSSL_LIB_CTX *libctx; ++ RSA *rsa; ++ int pad_mode; ++ int operation; ++ /* OAEP message digest */ ++ EVP_MD *oaep_md; ++ /* message digest for MGF1 */ ++ EVP_MD *mgf1_md; ++ /* OAEP label */ ++ unsigned char *oaep_label; ++ size_t oaep_labellen; ++ /* TLS padding */ ++ unsigned int client_version; ++ unsigned int alt_version; ++ ++ unsigned int soft : 1; ++} PROV_RSA_ASYM_CTX; ++ ++struct rsa_gen_ctx { ++ OSSL_LIB_CTX *libctx; ++ const char *propq; ++ ++ int rsa_type; ++ ++ size_t nbits; ++ BIGNUM *pub_exp; ++ size_t primes; ++ ++ /* For PSS */ ++ RSA_PSS_PARAMS_30 pss_params; ++ int pss_defaults_set; ++ ++ /* For generation callback */ ++ OSSL_CALLBACK *cb; ++ void *cbarg; ++}; ++ ++enum { ++ INVALID = 0, ++ PUB_ENC, ++ PUB_DEC, ++ PRI_ENC, ++ PRI_DEC, ++ MAX_CODE, ++}; ++ ++static void uadk_rsa_clear_flags(RSA *r, int flags) ++{ ++ r->flags &= ~flags; ++} ++ ++static int uadk_rsa_test_flags(const RSA *r, int flags) ++{ ++ return r->flags & flags; ++} ++ ++static void uadk_rsa_set_flags(RSA *r, int flags) ++{ ++ r->flags |= flags; ++} ++ ++static int uadk_rsa_get_version(RSA *r) ++{ ++ /* { two-prime(0), multi(1) } */ ++ return r->version; ++} ++ ++static void uadk_rsa_get0_factors(const RSA *r, const BIGNUM **p, ++ const BIGNUM **q) ++{ ++ if (p != NULL) ++ *p = r->p; ++ if (q != NULL) ++ *q = r->q; ++} ++ ++static void uadk_rsa_get0_key(const RSA *r, const BIGNUM **n, ++ const BIGNUM **e, const BIGNUM **d) ++{ ++ if (n != NULL) ++ *n = r->n; ++ if (e != NULL) ++ *e = r->e; ++ if (d != NULL) ++ *d = r->d; ++} ++ ++static int uadk_rsa_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ /* If the fields n and e in r are NULL, the corresponding input ++ * parameters MUST be non-NULL for n and e. d may be ++ * left NULL (in case only the public key is used). ++ */ ++ if ((r->n == NULL && n == NULL) ++ || (r->e == NULL && e == NULL)) ++ return 0; ++ ++ if (n != NULL) { ++ BN_free(r->n); ++ r->n = n; ++ } ++ if (e != NULL) { ++ BN_free(r->e); ++ r->e = e; ++ } ++ if (d != NULL) { ++ BN_clear_free(r->d); ++ r->d = d; ++ BN_set_flags(r->d, BN_FLG_CONSTTIME); ++ } ++ r->dirty_cnt++; ++ ++ return 1; ++} ++ ++static void uadk_rsa_get0_crt_params(const RSA *r, const BIGNUM **dmp1, ++ const BIGNUM **dmq1, const BIGNUM **iqmp) ++{ ++ if (dmp1 != NULL) ++ *dmp1 = r->dmp1; ++ if (dmq1 != NULL) ++ *dmq1 = r->dmq1; ++ if (iqmp != NULL) ++ *iqmp = r->iqmp; ++} ++ ++static int uadk_rsa_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) ++{ ++ /* If the fields p and q in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) ++ return 0; ++ ++ if (p != NULL) { ++ BN_clear_free(r->p); ++ r->p = p; ++ BN_set_flags(r->p, BN_FLG_CONSTTIME); ++ } ++ ++ if (q != NULL) { ++ BN_clear_free(r->q); ++ r->q = q; ++ BN_set_flags(r->q, BN_FLG_CONSTTIME); ++ } ++ ++ r->dirty_cnt++; ++ ++ return 1; ++} ++ ++static int uadk_rsa_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) ++{ ++ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->dmp1 == NULL && dmp1 == NULL) ++ || (r->dmq1 == NULL && dmq1 == NULL) ++ || (r->iqmp == NULL && iqmp == NULL)) ++ return 0; ++ ++ if (dmp1 != NULL) { ++ BN_clear_free(r->dmp1); ++ r->dmp1 = dmp1; ++ BN_set_flags(r->dmp1, BN_FLG_CONSTTIME); ++ } ++ ++ if (dmq1 != NULL) { ++ BN_clear_free(r->dmq1); ++ r->dmq1 = dmq1; ++ BN_set_flags(r->dmq1, BN_FLG_CONSTTIME); ++ } ++ ++ if (iqmp != NULL) { ++ BN_clear_free(r->iqmp); ++ r->iqmp = iqmp; ++ BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); ++ } ++ ++ r->dirty_cnt++; ++ ++ return 1; ++} ++ ++static int uadk_rsa_bits(const RSA *r) ++{ ++ return BN_num_bits(r->n); ++} ++ ++static int uadk_rsa_size(const RSA *r) ++{ ++ return BN_num_bytes(r->n); ++} ++ ++static int setup_tbuf(PROV_RSA_SIG_CTX *ctx) ++{ ++ if (ctx->tbuf != NULL) ++ return 1; ++ ++ ctx->tbuf = OPENSSL_malloc(uadk_rsa_size(ctx->rsa)); ++ if (ctx->tbuf == NULL) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static void clean_tbuf(PROV_RSA_SIG_CTX *ctx) ++{ ++ if (ctx->tbuf != NULL) ++ OPENSSL_cleanse(ctx->tbuf, uadk_rsa_size(ctx->rsa)); ++} ++ ++static void free_tbuf(PROV_RSA_SIG_CTX *ctx) ++{ ++ clean_tbuf(ctx); ++ OPENSSL_free(ctx->tbuf); ++ ctx->tbuf = NULL; ++} ++ ++static int rsa_check_bit_useful(const int bits, int flen) ++{ ++ if (flen > bits) ++ return SOFT; ++ ++ if (bits < RSA_MIN_MODULUS_BITS) ++ return UADK_E_FAIL; ++ ++ switch (bits) { ++ case RSA1024BITS: ++ case RSA2048BITS: ++ case RSA3072BITS: ++ case RSA4096BITS: ++ return UADK_E_SUCCESS; ++ case OPENSSLRSA7680BITS: ++ case OPENSSLRSA15360BITS: ++ case RSA_MIN_MODULUS_BITS: ++ return SOFT; ++ default: ++ return SOFT; ++ } ++} ++ ++static int rsa_prime_mul_res(int num, struct rsa_prime_param *param, ++ BN_CTX *ctx, BN_GENCB *cb) ++{ ++ if (num == 1) { ++ if (!BN_mul(param->r1, param->rsa_p, param->rsa_q, ctx)) ++ return BN_ERR; ++ } else { ++ if (!BN_GENCB_call(cb, GENCB_RETRY, num)) ++ return BN_ERR; ++ return BN_CONTINUE; ++ } ++ ++ return BN_VALID; ++} ++ ++static int check_rsa_prime_sufficient(int *num, const int *bitsr, ++ int *bitse, int * const n, ++ struct rsa_prime_param *param, ++ BN_CTX *ctx, BN_GENCB *cb) ++{ ++ static int retries; ++ BN_ULONG bitst; ++ int ret; ++ ++ ret = rsa_prime_mul_res(*num, param, ctx, cb); ++ if (ret) ++ return ret; ++ /* ++ * If |r1|, product of factors so far, is not as long as expected ++ * (by checking the first 4 bits are less than 0x9 or greater than ++ * 0xF). If so, re-generate the last prime. ++ * ++ * NOTE: This actually can't happen in two-prime case, because of ++ * the way factors are generated. ++ * ++ * Besides, another consideration is, for multi-prime case, even the ++ * length modulus is as long as expected, the modulus could start at ++ * 0x8, which could be utilized to distinguish a multi-prime private ++ * key by using the modulus in a certificate. This is also covered ++ * by checking the length should not be less than 0x9. ++ */ ++ if (!BN_rshift(param->r2, param->r1, *bitse - PRIME_CHECK_BIT_NUM)) ++ return BN_ERR; ++ ++ bitst = BN_get_word(param->r2); ++ if (bitst < 0x9 || bitst > 0xF) { ++ /* ++ * For keys with more than 4 primes, we attempt longer factor to ++ * meet length requirement. ++ * Otherwise, we just re-generate the prime with the same length. ++ * This strategy has the following goals: ++ * 1. 1024-bit factors are efficient when using 3072 and 4096-bit key ++ * 2. stay the same logic with normal 2-prime key ++ */ ++ if (*num < RSA_MAX_PRIME_NUM) ++ *bitse -= bitsr[*num]; ++ else ++ return -1; ++ ++ ret = BN_GENCB_call(cb, GENCB_NEXT, *n); ++ (*n)++; ++ if (!ret) ++ return -1; ++ ++ if (retries == PRIME_RETRY_COUNT) { ++ *num = -1; ++ *bitse = 0; ++ retries = 0; ++ return BN_CONTINUE; ++ } ++ retries++; ++ return BN_REDO; ++ } ++ ++ ret = BN_GENCB_call(cb, GENCB_RETRY, *num); ++ if (!ret) ++ return BN_ERR; ++ retries = 0; ++ ++ return BN_VALID; ++} ++ ++static void rsa_set_primes(int num, BIGNUM *rsa_p, BIGNUM *rsa_q, ++ BIGNUM **prime) ++{ ++ if (num == 0) ++ *prime = rsa_p; ++ else ++ *prime = rsa_q; ++ /* Set BN_FLG_CONSTTIME to prime exponent */ ++ BN_set_flags(*prime, BN_FLG_CONSTTIME); ++} ++ ++static int check_rsa_prime_equal(int num, BIGNUM *rsa_p, BIGNUM *rsa_q, ++ BIGNUM *prime) ++{ ++ BIGNUM *prev_prime; ++ int j; ++ ++ for (j = 0; j < num; j++) { ++ prev_prime = NULL; ++ if (j == 0) ++ prev_prime = rsa_p; ++ else ++ prev_prime = rsa_q; ++ /* ++ * BN_cmp(a,b) returns -1 if a < b; ++ * returns 0 if a == b; ++ * returns 1 if a > b. ++ */ ++ if (!BN_cmp(prime, prev_prime)) ++ return UADK_E_FAIL; ++ } ++ ++ return UADK_E_SUCCESS; ++} ++ ++static int check_rsa_prime_useful(int * const n, struct rsa_prime_param *param, ++ BIGNUM *e_pub, BN_CTX *ctx, BN_GENCB *cb) ++{ ++ unsigned long err; ++ int ret; ++ ++ /* ++ * BN_sub(r, a, b) substracts b from a and place the result in r, ++ * r = a - b. ++ * BN_value_one() returns a BIGNUM constant of value 1. ++ * r2 = prime - 1. ++ */ ++ if (!BN_sub(param->r2, param->prime, BN_value_one())) ++ return -1; ++ ERR_set_mark(); ++ BN_set_flags(param->r2, BN_FLG_CONSTTIME); ++ /* ++ * BN_mod_inverse(r, a, n, ctx) used to compute inverse modulo n. ++ * Precisely, it computes the inverse of "a" modulo "n", and places ++ * the result in "r", which means (a * r) % n == 1. ++ * If r == NULL, error. If r != NULL, success. ++ * The expected result: (r2 * r1) % e_pub == 1, ++ * the inverse of r2 exist, that is r1. ++ */ ++ if (BN_mod_inverse(param->r1, param->r2, e_pub, ctx)) ++ return UADK_E_SUCCESS; ++ ++ err = ERR_peek_last_error(); ++ if (ERR_GET_LIB(err) == ERR_LIB_BN && ++ ERR_GET_REASON(err) == BN_R_NO_INVERSE) ++ ERR_pop_to_mark(); ++ else ++ return BN_ERR; ++ ++ ret = BN_GENCB_call(cb, GENCB_NEXT, *n); ++ (*n)++; ++ if (!ret) ++ return BN_ERR; ++ ++ return GET_ERR_FINISH; ++} ++ ++static int get_rsa_prime_once(int num, const int *bitsr, int * const n, ++ BIGNUM *e_pub, struct rsa_prime_param *param, ++ BN_CTX *ctx, BN_GENCB *cb) ++{ ++ int ret = -1; ++ ++ if (num >= RSA_MAX_PRIME_NUM) ++ return ret; ++ while (1) { ++ /* Generate prime with bitsr[num] len. */ ++ if (!BN_generate_prime_ex(param->prime, bitsr[num], ++ 0, NULL, NULL, cb)) ++ return BN_ERR; ++ if (!check_rsa_prime_equal(num, param->rsa_p, param->rsa_q, ++ param->prime)) ++ continue; ++ ret = check_rsa_prime_useful(n, param, e_pub, ctx, cb); ++ if (ret == BN_ERR) ++ return BN_ERR; ++ else if (ret == UADK_E_SUCCESS) ++ break; ++ } ++ ++ return ret; ++} ++ ++static void rsa_switch_p_q(BIGNUM *rsa_p, BIGNUM *rsa_q, BIGNUM *p, BIGNUM *q) ++{ ++ BIGNUM *tmp; ++ ++ if (BN_cmp(rsa_p, rsa_q) < 0) { ++ tmp = rsa_p; ++ rsa_p = rsa_q; ++ rsa_q = tmp; ++ } ++ ++ BN_copy(q, rsa_q); ++ BN_copy(p, rsa_p); ++} ++ ++static int check_rsa_is_crt(RSA *rsa) ++{ ++ const BIGNUM *p = NULL; ++ const BIGNUM *q = NULL; ++ const BIGNUM *dmp1 = NULL; ++ const BIGNUM *dmq1 = NULL; ++ const BIGNUM *iqmp = NULL; ++ int version; ++ ++ if (uadk_rsa_test_flags(rsa, RSA_FLAG_EXT_PKEY)) ++ return IS_SET; ++ ++ version = uadk_rsa_get_version(rsa); ++ if (version == RSA_ASN1_VERSION_MULTI) ++ return IS_SET; ++ ++ uadk_rsa_get0_factors(rsa, &p, &q); ++ uadk_rsa_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); ++ if ((p != NULL) && (q != NULL) && (dmp1 != NULL) && ++ (dmq1 != NULL) && (iqmp != NULL)) ++ return IS_SET; ++ ++ return UN_SET; ++} ++ ++static int get_rsa_prime_param(struct rsa_prime_param *param, BN_CTX *ctx) ++{ ++ param->r1 = BN_CTX_get(ctx); ++ if (!param->r1) ++ goto end; ++ ++ param->r2 = BN_CTX_get(ctx); ++ if (!param->r2) ++ goto end; ++ ++ param->rsa_p = BN_CTX_get(ctx); ++ if (!param->rsa_p) ++ goto end; ++ ++ param->rsa_q = BN_CTX_get(ctx); ++ if (!param->rsa_q) ++ goto end; ++ ++ return UADK_E_SUCCESS; ++ ++end: ++ fprintf(stderr, "failed to allocate rsa prime params\n"); ++ return -ENOMEM; ++} ++ ++static int rsa_primes_gen(int bits, BIGNUM *e_pub, BIGNUM *p, ++ BIGNUM *q, BN_GENCB *cb) ++{ ++ struct rsa_prime_param *param = NULL; ++ int bitsr[RSA_MAX_PRIME_NUM] = {0}; ++ int flag, quo, rmd, i; ++ BN_CTX *ctx; ++ int bitse = 0; ++ int ret = 0; ++ /* n: modulo n, a part of public key */ ++ int n = 0; ++ ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return ret; ++ ++ BN_CTX_start(ctx); ++ param = OPENSSL_zalloc(sizeof(struct rsa_prime_param)); ++ if (!param) ++ goto free_ctx; ++ ++ ret = get_rsa_prime_param(param, ctx); ++ if (ret != UADK_E_SUCCESS) ++ goto free_param; ++ ++ /* Divide bits into 'primes' pieces evenly */ ++ quo = bits / RSA_MAX_PRIME_NUM; ++ rmd = bits % RSA_MAX_PRIME_NUM; ++ for (i = 0; i < RSA_MAX_PRIME_NUM; i++) ++ bitsr[i] = (i < rmd) ? quo + 1 : quo; ++ ++ /* Generate p, q and other primes (if any) */ ++ for (i = 0; i < RSA_MAX_PRIME_NUM; i++) { ++ /* flag: whether primes are generated correctely. */ ++ flag = 1; ++ /* Set flag for primes rsa_p and rsa_q separately. */ ++ rsa_set_primes(i, param->rsa_p, param->rsa_q, ¶m->prime); ++ while (flag == 1) { ++ ret = get_rsa_prime_once(i, bitsr, &n, e_pub, param, ++ ctx, cb); ++ if (ret == -1) ++ goto free_param; ++ bitse += bitsr[i]; ++ ret = check_rsa_prime_sufficient(&i, bitsr, &bitse, &n, ++ param, ctx, cb); ++ if (ret == BN_ERR) ++ goto free_param; ++ else if (ret == BN_REDO) ++ continue; ++ else ++ flag = 0; ++ } ++ } ++ rsa_switch_p_q(param->rsa_p, param->rsa_q, p, q); ++ ++ ret = UADK_E_SUCCESS; ++ ++free_param: ++ OPENSSL_free(param); ++free_ctx: ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ return ret; ++} ++ ++static int add_rsa_pubenc_padding(int flen, const unsigned char *from, ++ unsigned char *buf, int num, int padding) ++{ ++ int ret; ++ ++ if (!buf || !num) { ++ fprintf(stderr, "buf or num is invalid\n"); ++ return UADK_E_FAIL; ++ } ++ ++ switch (padding) { ++ case RSA_PKCS1_PADDING: ++ ret = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ break; ++ case RSA_PKCS1_OAEP_PADDING: ++ ret = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err\n"); ++ break; ++ default: ++ ret = UADK_E_FAIL; ++ } ++ ++ return ret; ++} ++ ++static int check_rsa_pridec_padding(unsigned char *to, int num, ++ const unsigned char *buf, int len, ++ int padding) ++{ ++ int ret; ++ ++ switch (padding) { ++ case RSA_PKCS1_PADDING: ++ ret = RSA_padding_check_PKCS1_type_2(to, num, buf, len, num); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ break; ++ case RSA_PKCS1_OAEP_PADDING: ++ ret = RSA_padding_check_PKCS1_OAEP(to, num, buf, len, num, ++ NULL, 0); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err\n"); ++ break; ++ default: ++ ret = UADK_E_FAIL; ++ } ++ ++ if (ret == CHECK_PADDING_FAIL) ++ ret = UADK_E_FAIL; ++ ++ return ret; ++} ++ ++static int add_rsa_prienc_padding(int flen, const unsigned char *from, ++ unsigned char *to_buf, int tlen, ++ int padding) ++{ ++ int ret; ++ ++ switch (padding) { ++ case RSA_PKCS1_PADDING: ++ ret = RSA_padding_add_PKCS1_type_1(to_buf, tlen, from, flen); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ break; ++ case RSA_X931_PADDING: ++ ret = RSA_padding_add_X931(to_buf, tlen, from, flen); ++ if (!ret) ++ fprintf(stderr, "RSA_X931_PADDING err\n"); ++ break; ++ default: ++ ret = UADK_E_FAIL; ++ } ++ if (ret <= 0) ++ ret = UADK_E_FAIL; ++ ++ return ret; ++} ++ ++static int check_rsa_pubdec_padding(unsigned char *to, int num, ++ const unsigned char *buf, int len, ++ int padding) ++{ ++ int ret; ++ ++ switch (padding) { ++ case RSA_PKCS1_PADDING: ++ ret = RSA_padding_check_PKCS1_type_1(to, num, buf, len, num); ++ if (!ret) ++ fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ break; ++ case RSA_X931_PADDING: ++ ret = RSA_padding_check_X931(to, num, buf, len, num); ++ if (!ret) ++ fprintf(stderr, "RSA_X931_PADDING err\n"); ++ break; ++ default: ++ ret = UADK_E_FAIL; ++ } ++ ++ if (ret == CHECK_PADDING_FAIL) ++ ret = UADK_E_FAIL; ++ ++ return ret; ++} ++ ++static int check_rsa_input_para(const int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa) ++{ ++ if (!rsa || !from || !to || flen <= 0) { ++ fprintf(stderr, "input param invalid\n"); ++ return UADK_E_FAIL; ++ } ++ ++ return rsa_check_bit_useful(uadk_rsa_bits(rsa), flen); ++} ++ ++static BN_ULONG *bn_get_words(const BIGNUM *a) ++{ ++ return a->d; ++} ++ ++static int rsa_get_sign_res(int padding, BIGNUM *to_bn, const BIGNUM *n, ++ BIGNUM *ret_bn, BIGNUM **res) ++{ ++ if (padding == RSA_X931_PADDING) { ++ if (!BN_sub(to_bn, n, ret_bn)) ++ return UADK_E_FAIL; ++ if (BN_cmp(ret_bn, to_bn) > 0) ++ *res = to_bn; ++ else ++ *res = ret_bn; ++ } else { ++ *res = ret_bn; ++ } ++ ++ return UADK_E_SUCCESS; ++} ++ ++static int rsa_get_verify_res(int padding, const BIGNUM *n, BIGNUM *ret_bn) ++{ ++ BIGNUM *to_bn = NULL; ++ ++ if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret_bn)[0] & 0xf) ++ != 0x0c)) { ++ if (!BN_sub(to_bn, n, ret_bn)) ++ return UADK_E_FAIL; ++ } ++ ++ return UADK_E_SUCCESS; ++} ++ ++static int uadk_rsa_env_poll(void *ctx) ++{ ++ __u64 rx_cnt = 0; ++ __u32 recv = 0; ++ /* Poll one packet currently */ ++ int expt = 1; ++ int ret; ++ ++ do { ++ ret = wd_rsa_poll(expt, &recv); ++ if (ret < 0 || recv == expt) ++ return ret; ++ rx_cnt++; ++ } while (rx_cnt < ENGINE_RECV_MAX_CNT); ++ ++ fprintf(stderr, "failed to poll msg: timeout!\n"); ++ ++ return -ETIMEDOUT; ++} ++ ++static int uadk_prov_rsa_init(void) ++{ ++ int ret; ++ ++ pthread_mutex_lock(&rsa_mutex); ++ if (g_rsa_prov.pid != getpid()) { ++ ret = wd_rsa_init2("rsa", 0, 0); ++ if (unlikely(ret)) ++ return ret; ++ g_rsa_prov.pid = getpid(); ++ async_register_poll_fn(ASYNC_TASK_RSA, uadk_rsa_env_poll); ++ } ++ pthread_mutex_unlock(&rsa_mutex); ++ ++ return UADK_E_INIT_SUCCESS; ++} ++ ++static struct uadk_rsa_sess *rsa_new_eng_session(RSA *rsa) ++{ ++ struct uadk_rsa_sess *rsa_sess; ++ ++ rsa_sess = OPENSSL_malloc(sizeof(struct uadk_rsa_sess)); ++ if (!rsa_sess) ++ return NULL; ++ ++ memset(rsa_sess, 0, sizeof(struct uadk_rsa_sess)); ++ rsa_sess->alg = rsa; ++ rsa_sess->is_prikey_ready = UN_SET; ++ rsa_sess->is_pubkey_ready = UN_SET; ++ ++ return rsa_sess; ++} ++ ++static void rsa_free_eng_session(struct uadk_rsa_sess *rsa_sess) ++{ ++ if (!rsa_sess) ++ return; ++ ++ rsa_sess->alg = NULL; ++ rsa_sess->is_prikey_ready = UN_SET; ++ rsa_sess->is_pubkey_ready = UN_SET; ++ ++ wd_rsa_free_sess(rsa_sess->sess); ++ OPENSSL_free(rsa_sess); ++} ++ ++static struct uadk_rsa_sess *rsa_get_eng_session(RSA *rsa, unsigned int bits, ++ int is_crt) ++{ ++ unsigned int key_size = bits >> BIT_BYTES_SHIFT; ++ struct sched_params params = {0}; ++ struct uadk_rsa_sess *rsa_sess; ++ ++ rsa_sess = rsa_new_eng_session(rsa); ++ if (!rsa_sess) ++ return NULL; ++ ++ rsa_sess->key_size = key_size; ++ rsa_sess->setup.key_bits = key_size << BIT_BYTES_SHIFT; ++ ++ /* Use the default numa parameters */ ++ params.numa_id = -1; ++ rsa_sess->setup.sched_param = ¶ms; ++ rsa_sess->setup.is_crt = is_crt; ++ ++ rsa_sess->sess = wd_rsa_alloc_sess(&rsa_sess->setup); ++ if (!rsa_sess->sess) { ++ rsa_free_eng_session(rsa_sess); ++ return NULL; ++ } ++ ++ return rsa_sess; ++} ++ ++static int rsa_fill_pubkey(struct rsa_pubkey_param *pubkey_param, ++ struct uadk_rsa_sess *rsa_sess, ++ unsigned char *in_buf, unsigned char *to) ++{ ++ struct wd_rsa_pubkey *pubkey = NULL; ++ struct wd_dtb *wd_e = NULL; ++ struct wd_dtb *wd_n = NULL; ++ ++ if (!rsa_sess->is_pubkey_ready) { ++ wd_rsa_get_pubkey(rsa_sess->sess, &pubkey); ++ if (!pubkey) ++ return UADK_E_FAIL; ++ ++ wd_rsa_get_pubkey_params(pubkey, &wd_e, &wd_n); ++ if (!wd_e || !wd_n) ++ return UADK_E_FAIL; ++ ++ wd_e->dsize = BN_bn2bin(pubkey_param->e, ++ (unsigned char *)wd_e->data); ++ wd_n->dsize = BN_bn2bin(pubkey_param->n, ++ (unsigned char *)wd_n->data); ++ rsa_sess->is_pubkey_ready = IS_SET; ++ rsa_sess->req.src_bytes = rsa_sess->key_size; ++ rsa_sess->req.dst_bytes = rsa_sess->key_size; ++ rsa_sess->req.op_type = WD_RSA_VERIFY; ++ rsa_sess->req.src = in_buf; ++ rsa_sess->req.dst = to; ++ ++ return UADK_E_SUCCESS; ++ } ++ ++ return UADK_E_FAIL; ++} ++ ++static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess, ++ struct rsa_prikey_param *pri, ++ unsigned char *in_buf, unsigned char *to) ++{ ++ struct wd_rsa_prikey *prikey = NULL; ++ struct wd_dtb *wd_qinv = NULL; ++ struct wd_dtb *wd_dq = NULL; ++ struct wd_dtb *wd_dp = NULL; ++ struct wd_dtb *wd_q = NULL; ++ struct wd_dtb *wd_p = NULL; ++ struct wd_dtb *wd_d = NULL; ++ struct wd_dtb *wd_n = NULL; ++ ++ if (!(rsa_sess->is_prikey_ready) && (pri->is_crt)) { ++ wd_rsa_get_prikey(rsa_sess->sess, &prikey); ++ if (!prikey) ++ return UADK_E_FAIL; ++ ++ wd_rsa_get_crt_prikey_params(prikey, &wd_dq, &wd_dp, ++ &wd_qinv, &wd_q, &wd_p); ++ if (!wd_dq || !wd_dp || !wd_qinv || !wd_q || !wd_p) ++ return UADK_E_FAIL; ++ ++ wd_dq->dsize = BN_bn2bin(pri->dmq1, ++ (unsigned char *)wd_dq->data); ++ wd_dp->dsize = BN_bn2bin(pri->dmp1, ++ (unsigned char *)wd_dp->data); ++ wd_q->dsize = BN_bn2bin(pri->q, ++ (unsigned char *)wd_q->data); ++ wd_p->dsize = BN_bn2bin(pri->p, ++ (unsigned char *)wd_p->data); ++ wd_qinv->dsize = BN_bn2bin(pri->iqmp, ++ (unsigned char *)wd_qinv->data); ++ } else if (!(rsa_sess->is_prikey_ready) && !(pri->is_crt)) { ++ wd_rsa_get_prikey(rsa_sess->sess, &prikey); ++ if (!prikey) ++ return UADK_E_FAIL; ++ ++ wd_rsa_get_prikey_params(prikey, &wd_d, &wd_n); ++ if (!wd_d || !wd_n) ++ return UADK_E_FAIL; ++ ++ wd_d->dsize = BN_bn2bin(pri->d, ++ (unsigned char *)wd_d->data); ++ wd_n->dsize = BN_bn2bin(pri->n, ++ (unsigned char *)wd_n->data); ++ } else { ++ return UADK_E_FAIL; ++ } ++ rsa_sess->is_prikey_ready = IS_SET; ++ rsa_sess->req.src_bytes = rsa_sess->key_size; ++ rsa_sess->req.op_type = WD_RSA_SIGN; ++ rsa_sess->req.dst_bytes = rsa_sess->key_size; ++ rsa_sess->req.src = in_buf; ++ rsa_sess->req.dst = to; ++ ++ return UADK_E_SUCCESS; ++} ++ ++static int rsa_get_keygen_param(struct wd_rsa_req *req, handle_t ctx, RSA *rsa, ++ struct rsa_keygen_param_bn *bn_param, BN_CTX **bn_ctx_in) ++{ ++ struct wd_rsa_kg_out *out = (struct wd_rsa_kg_out *)req->dst; ++ struct wd_dtb wd_d, wd_n, wd_qinv, wd_dq, wd_dp; ++ BIGNUM *dmp1, *dmq1, *iqmp, *n, *d; ++ unsigned int key_bits, key_size; ++ BN_CTX *bn_ctx = *bn_ctx_in; ++ ++ key_bits = wd_rsa_get_key_bits(ctx); ++ if (!key_bits) ++ return UADK_E_FAIL; ++ ++ key_size = key_bits >> BIT_BYTES_SHIFT; ++ wd_rsa_get_kg_out_params(out, &wd_d, &wd_n); ++ wd_rsa_get_kg_out_crt_params(out, &wd_qinv, &wd_dq, &wd_dp); ++ ++ dmp1 = BN_CTX_get(bn_ctx); ++ if (!dmp1) ++ return UADK_E_FAIL; ++ ++ dmq1 = BN_CTX_get(bn_ctx); ++ if (!dmq1) ++ return UADK_E_FAIL; ++ ++ iqmp = BN_CTX_get(bn_ctx); ++ if (!iqmp) ++ return UADK_E_FAIL; ++ ++ n = BN_CTX_get(bn_ctx); ++ if (!n) ++ return UADK_E_FAIL; ++ ++ d = BN_CTX_get(bn_ctx); ++ if (!d) ++ return UADK_E_FAIL; ++ ++ BN_bin2bn((unsigned char *)wd_d.data, key_size, d); ++ BN_bin2bn((unsigned char *)wd_n.data, key_size, n); ++ BN_bin2bn((unsigned char *)wd_qinv.data, wd_qinv.dsize, iqmp); ++ BN_bin2bn((unsigned char *)wd_dq.data, wd_dq.dsize, dmq1); ++ BN_bin2bn((unsigned char *)wd_dp.data, wd_dp.dsize, dmp1); ++ ++ if (!(uadk_rsa_set0_key(rsa, n, bn_param->e, d) && ++ uadk_rsa_set0_factors(rsa, bn_param->p, bn_param->q) && ++ uadk_rsa_set0_crt_params(rsa, dmp1, dmq1, iqmp))) ++ return UADK_E_FAIL; ++ ++ return UADK_E_SUCCESS; ++} ++ ++static void uadk_e_rsa_cb(void *req_t) ++{ ++ struct wd_rsa_req *req_new = (struct wd_rsa_req *)req_t; ++ struct uadk_e_cb_info *cb_param; ++ struct wd_rsa_req *req_origin; ++ struct async_op *op; ++ ++ if (!req_new) ++ return; ++ ++ cb_param = req_new->cb_param; ++ if (!cb_param) ++ return; ++ ++ req_origin = cb_param->priv; ++ if (!req_origin) ++ return; ++ ++ req_origin->status = req_new->status; ++ ++ op = cb_param->op; ++ if (op && op->job && !op->done) { ++ op->done = 1; ++ async_free_poll_task(op->idx, 1); ++ async_wake_job(op->job); ++ } ++} ++ ++static int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) ++{ ++ struct uadk_e_cb_info cb_param; ++ struct async_op op; ++ int idx, ret; ++ ++ ret = async_setup_async_event_notification(&op); ++ if (!ret) { ++ fprintf(stderr, "failed to setup async event notification.\n"); ++ return UADK_E_FAIL; ++ } ++ ++ if (!op.job) { ++ ret = wd_do_rsa_sync(rsa_sess->sess, &(rsa_sess->req)); ++ if (ret) ++ goto err; ++ return UADK_E_SUCCESS; ++ } ++ cb_param.op = &op; ++ cb_param.priv = &(rsa_sess->req); ++ rsa_sess->req.cb = uadk_e_rsa_cb; ++ rsa_sess->req.cb_param = &cb_param; ++ rsa_sess->req.status = -1; ++ ++ ret = async_get_free_task(&idx); ++ if (ret == 0) ++ goto err; ++ ++ op.idx = idx; ++ do { ++ ret = wd_do_rsa_async(rsa_sess->sess, &(rsa_sess->req)); ++ if (ret < 0 && ret != -EBUSY) { ++ async_free_poll_task(op.idx, 0); ++ goto err; ++ } ++ } while (ret == -EBUSY); ++ ++ ret = async_pause_job(rsa_sess, &op, ASYNC_TASK_RSA, idx); ++ if (!ret) ++ goto err; ++ ++ if (rsa_sess->req.status) ++ return UADK_E_FAIL; ++ ++ return UADK_E_SUCCESS; ++ ++err: ++ (void)async_clear_async_event_notification(); ++ return UADK_E_FAIL; ++} ++ ++static int rsa_fill_keygen_data(struct uadk_rsa_sess *rsa_sess, ++ struct rsa_keypair *key_pair, ++ struct rsa_keygen_param *keygen_param, ++ struct rsa_keygen_param_bn *bn_param) ++{ ++ wd_rsa_get_pubkey(rsa_sess->sess, &key_pair->pubkey); ++ if (!key_pair->pubkey) ++ return UADK_E_FAIL; ++ ++ wd_rsa_get_pubkey_params(key_pair->pubkey, &keygen_param->wd_e, NULL); ++ if (!keygen_param->wd_e) ++ return UADK_E_FAIL; ++ ++ keygen_param->wd_e->dsize = BN_bn2bin(bn_param->e, ++ (unsigned char *)keygen_param->wd_e->data); ++ ++ wd_rsa_get_prikey(rsa_sess->sess, &key_pair->prikey); ++ if (!key_pair->prikey) ++ return UADK_E_FAIL; ++ ++ wd_rsa_get_crt_prikey_params(key_pair->prikey, NULL, NULL, NULL, ++ &keygen_param->wd_q, &keygen_param->wd_p); ++ if (!keygen_param->wd_q || !keygen_param->wd_p) ++ return UADK_E_FAIL; ++ ++ keygen_param->wd_q->dsize = BN_bn2bin(bn_param->q, ++ (unsigned char *)keygen_param->wd_q->data); ++ keygen_param->wd_p->dsize = BN_bn2bin(bn_param->p, ++ (unsigned char *)keygen_param->wd_p->data); ++ ++ rsa_sess->req.src_bytes = rsa_sess->key_size; ++ rsa_sess->req.dst_bytes = rsa_sess->key_size; ++ rsa_sess->req.op_type = WD_RSA_GENKEY; ++ rsa_sess->req.src = wd_rsa_new_kg_in(rsa_sess->sess, ++ keygen_param->wd_e, ++ keygen_param->wd_p, ++ keygen_param->wd_q); ++ if (!rsa_sess->req.src) ++ return UADK_E_FAIL; ++ ++ rsa_sess->req.dst = wd_rsa_new_kg_out(rsa_sess->sess); ++ if (!rsa_sess->req.dst) { ++ wd_rsa_del_kg_in(rsa_sess->sess, rsa_sess->req.src); ++ return UADK_E_FAIL; ++ } ++ ++ return UADK_E_SUCCESS; ++} ++ ++static void rsa_free_keygen_data(struct uadk_rsa_sess *rsa_sess) ++{ ++ if (!rsa_sess) ++ return; ++ ++ wd_rsa_del_kg_in(rsa_sess->sess, rsa_sess->req.src); ++ wd_rsa_del_kg_out(rsa_sess->sess, rsa_sess->req.dst); ++} ++ ++static int rsa_keygen_param_alloc(struct rsa_keygen_param **keygen_param, ++ struct rsa_keygen_param_bn **keygen_bn_param, ++ struct rsa_keypair **key_pair, BN_CTX **bn_ctx_in) ++{ ++ BN_CTX *bn_ctx; ++ ++ *keygen_param = OPENSSL_malloc(sizeof(struct rsa_keygen_param)); ++ if (!(*keygen_param)) ++ goto err; ++ ++ *keygen_bn_param = (struct rsa_keygen_param_bn *) ++ OPENSSL_malloc(sizeof(struct rsa_keygen_param_bn)); ++ if (!(*keygen_bn_param)) ++ goto free_keygen_param; ++ ++ *key_pair = OPENSSL_malloc(sizeof(struct rsa_keypair)); ++ if (!(*key_pair)) ++ goto free_keygen_bn_param; ++ ++ bn_ctx = BN_CTX_new(); ++ if (!bn_ctx) ++ goto free_key_pair; ++ ++ BN_CTX_start(bn_ctx); ++ *bn_ctx_in = bn_ctx; ++ ++ (*keygen_bn_param)->e = BN_CTX_get(bn_ctx); ++ if (!(*keygen_bn_param)->e) ++ goto free_bn_ctx; ++ ++ (*keygen_bn_param)->p = BN_CTX_get(bn_ctx); ++ if (!(*keygen_bn_param)->p) ++ goto free_bn_ctx; ++ ++ (*keygen_bn_param)->q = BN_CTX_get(bn_ctx); ++ if (!(*keygen_bn_param)->q) ++ goto free_bn_ctx; ++ ++ return UADK_E_SUCCESS; ++ ++free_bn_ctx: ++ BN_CTX_end(bn_ctx); ++ BN_CTX_free(bn_ctx); ++free_key_pair: ++ OPENSSL_free(*key_pair); ++free_keygen_bn_param: ++ OPENSSL_free(*keygen_bn_param); ++free_keygen_param: ++ OPENSSL_free(*keygen_param); ++err: ++ return -ENOMEM; ++} ++ ++static void rsa_keygen_param_free(struct rsa_keygen_param **keygen_param, ++ struct rsa_keygen_param_bn **keygen_bn_param, ++ struct rsa_keypair **key_pair, BN_CTX **bn_ctx, ++ int free_bn_ctx_tag) ++{ ++ /* ++ * When an abnormal situation occurs, uadk engine needs ++ * to switch to software keygen function, so we need to ++ * free BN ctx we alloced before. But in normal situation, ++ * the BN ctx should be freed by OpenSSL tools or users. ++ * Therefore, we use a tag to distinguish these cases. ++ */ ++ if (free_bn_ctx_tag == UADK_DO_SOFT) { ++ BN_CTX_end(*bn_ctx); ++ BN_CTX_free(*bn_ctx); ++ } ++ ++ OPENSSL_free(*keygen_bn_param); ++ OPENSSL_free(*keygen_param); ++ OPENSSL_free(*key_pair); ++} ++ ++static int rsa_pkey_param_alloc(struct rsa_pubkey_param **pub, ++ struct rsa_prikey_param **pri) ++{ ++ if (pub) { ++ *pub = OPENSSL_malloc(sizeof(struct rsa_pubkey_param)); ++ if (!(*pub)) ++ return -ENOMEM; ++ } ++ ++ if (pri) { ++ *pri = OPENSSL_malloc(sizeof(struct rsa_prikey_param)); ++ if (!(*pri)) { ++ if (pub) ++ OPENSSL_free(*pub); ++ return -ENOMEM; ++ } ++ } ++ ++ return UADK_E_SUCCESS; ++} ++ ++static void rsa_pkey_param_free(struct rsa_pubkey_param **pub, ++ struct rsa_prikey_param **pri) ++{ ++ if (pub) ++ OPENSSL_free(*pub); ++ if (pri) ++ OPENSSL_free(*pri); ++} ++ ++static int rsa_create_pub_bn_ctx(RSA *rsa, struct rsa_pubkey_param *pub, ++ unsigned char **from_buf, int *num_bytes) ++{ ++ uadk_rsa_get0_key(rsa, &pub->n, &pub->e, NULL); ++ if (!(pub->n) || !(pub->e)) ++ return UADK_E_FAIL; ++ ++ *num_bytes = BN_num_bytes(pub->n); ++ if (!(*num_bytes)) ++ return UADK_E_FAIL; ++ ++ *from_buf = OPENSSL_malloc(*num_bytes); ++ if (!(*from_buf)) ++ return -ENOMEM; ++ ++ return UADK_E_SUCCESS; ++} ++ ++static void rsa_free_pub_bn_ctx(unsigned char **from_buf) ++{ ++ OPENSSL_free(*from_buf); ++} ++ ++static int rsa_create_pri_bn_ctx(RSA *rsa, struct rsa_prikey_param *pri, ++ unsigned char **from_buf, int *num_bytes) ++{ ++ uadk_rsa_get0_key(rsa, &pri->n, &pri->e, &pri->d); ++ if (!(pri->n) || !(pri->e) || !(pri->d)) ++ return UADK_E_FAIL; ++ ++ uadk_rsa_get0_factors(rsa, &pri->p, &pri->q); ++ if (!(pri->p) || !(pri->q)) ++ return UADK_E_FAIL; ++ ++ uadk_rsa_get0_crt_params(rsa, &pri->dmp1, &pri->dmq1, &pri->iqmp); ++ if (!(pri->dmp1) || !(pri->dmq1) || !(pri->iqmp)) ++ return UADK_E_FAIL; ++ ++ *num_bytes = BN_num_bytes(pri->n); ++ if (!(*num_bytes)) ++ return UADK_E_FAIL; ++ ++ *from_buf = OPENSSL_malloc(*num_bytes); ++ if (!(*from_buf)) ++ return -ENOMEM; ++ ++ return UADK_E_SUCCESS; ++} ++ ++static void rsa_free_pri_bn_ctx(unsigned char **from_buf) ++{ ++ OPENSSL_free(*from_buf); ++} ++ ++static int uadk_prov_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) ++{ ++ struct rsa_keygen_param *keygen_param = NULL; ++ struct rsa_keygen_param_bn *bn_param = NULL; ++ struct uadk_rsa_sess *rsa_sess = NULL; ++ struct rsa_keypair *key_pair = NULL; ++ BN_CTX *bn_ctx = NULL; ++ int is_crt = 1; ++ int ret; ++ ++ ret = rsa_check_bit_useful(bits, 0); ++ if (!ret || ret == SOFT) ++ return UADK_DO_SOFT; ++ ++ ret = rsa_keygen_param_alloc(&keygen_param, &bn_param, &key_pair, &bn_ctx); ++ if (ret == -ENOMEM) ++ return UADK_DO_SOFT; ++ ++ rsa_sess = rsa_get_eng_session(rsa, bits, is_crt); ++ if (!rsa_sess) { ++ ret = UADK_DO_SOFT; ++ goto free_keygen; ++ } ++ ++ ret = rsa_primes_gen(bits, e, bn_param->p, bn_param->q, cb); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ if (!BN_copy(bn_param->e, e)) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = rsa_fill_keygen_data(rsa_sess, key_pair, keygen_param, bn_param); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = rsa_do_crypto(rsa_sess); ++ if (!ret || rsa_sess->req.status) { ++ ret = UADK_DO_SOFT; ++ goto free_kg_in_out; ++ } ++ ++ ret = rsa_get_keygen_param(&rsa_sess->req, rsa_sess->sess, rsa, bn_param, &bn_ctx); ++ if (!ret) ++ ret = UADK_DO_SOFT; ++ ++free_kg_in_out: ++ rsa_free_keygen_data(rsa_sess); ++free_sess: ++ rsa_free_eng_session(rsa_sess); ++free_keygen: ++ rsa_keygen_param_free(&keygen_param, &bn_param, &key_pair, &bn_ctx, ret); ++ return ret; ++} ++ ++static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) ++{ ++ struct rsa_pubkey_param *pub_enc = NULL; ++ struct uadk_rsa_sess *rsa_sess = NULL; ++ unsigned char *from_buf = NULL; ++ int num_bytes, is_crt, ret; ++ BIGNUM *enc_bn = NULL; ++ ++ ret = check_rsa_input_para(flen, from, to, rsa); ++ if (!ret || ret == SOFT) ++ return UADK_DO_SOFT; ++ ++ ret = rsa_pkey_param_alloc(&pub_enc, NULL); ++ if (ret == -ENOMEM) ++ return UADK_DO_SOFT; ++ ++ is_crt = check_rsa_is_crt(rsa); ++ ++ rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), is_crt); ++ if (!rsa_sess) { ++ ret = UADK_DO_SOFT; ++ goto free_pkey; ++ } ++ ++ ret = rsa_create_pub_bn_ctx(rsa, pub_enc, &from_buf, &num_bytes); ++ if (ret <= 0 || flen > num_bytes) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = add_rsa_pubenc_padding(flen, from, from_buf, num_bytes, padding); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = rsa_fill_pubkey(pub_enc, rsa_sess, from_buf, to); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = rsa_do_crypto(rsa_sess); ++ if (!ret || rsa_sess->req.status) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ enc_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, ++ rsa_sess->req.dst_bytes, NULL); ++ if (!enc_bn) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = BN_bn2binpad(enc_bn, to, num_bytes); ++ if (ret == -1) ++ ret = UADK_DO_SOFT; ++ ++ BN_free(enc_bn); ++ ++free_buf: ++ rsa_free_pub_bn_ctx(&from_buf); ++free_sess: ++ rsa_free_eng_session(rsa_sess); ++free_pkey: ++ rsa_pkey_param_free(&pub_enc, NULL); ++ return ret; ++} ++ ++static int uadk_prov_rsa_private_decrypt(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) ++{ ++ struct rsa_prikey_param *pri = NULL; ++ unsigned char *from_buf = NULL; ++ struct uadk_rsa_sess *rsa_sess; ++ int num_bytes, len, ret; ++ BIGNUM *dec_bn = NULL; ++ ++ ret = check_rsa_input_para(flen, from, to, rsa); ++ if (!ret || ret == SOFT) ++ return UADK_DO_SOFT; ++ ++ ret = rsa_pkey_param_alloc(NULL, &pri); ++ if (ret == -ENOMEM) ++ return UADK_DO_SOFT; ++ ++ pri->is_crt = check_rsa_is_crt(rsa); ++ ++ rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), pri->is_crt); ++ if (!rsa_sess) { ++ ret = UADK_DO_SOFT; ++ goto free_pkey; ++ } ++ ++ ret = rsa_create_pri_bn_ctx(rsa, pri, &from_buf, &num_bytes); ++ if (ret <= 0 || flen > num_bytes) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ memcpy(rsa_sess->req.src, from, rsa_sess->req.src_bytes); ++ ++ ret = rsa_do_crypto(rsa_sess); ++ if (!ret || rsa_sess->req.status) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ dec_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, ++ rsa_sess->req.dst_bytes, NULL); ++ if (!dec_bn) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ len = BN_bn2binpad(dec_bn, from_buf, num_bytes); ++ if (!len) { ++ ret = UADK_DO_SOFT; ++ goto free_dec_bn; ++ } ++ ++ ret = check_rsa_pridec_padding(to, num_bytes, from_buf, len, padding); ++ if (!ret) ++ ret = UADK_DO_SOFT; ++ ++free_dec_bn: ++ BN_free(dec_bn); ++free_buf: ++ rsa_free_pri_bn_ctx(&from_buf); ++free_sess: ++ rsa_free_eng_session(rsa_sess); ++free_pkey: ++ rsa_pkey_param_free(NULL, &pri); ++ return ret; ++} ++ ++static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) ++{ ++ struct uadk_rsa_sess *rsa_sess = NULL; ++ struct rsa_prikey_param *pri = NULL; ++ unsigned char *from_buf = NULL; ++ BIGNUM *sign_bn = NULL; ++ BIGNUM *to_bn = NULL; ++ BIGNUM *res = NULL; ++ int num_bytes, ret; ++ ++ ret = check_rsa_input_para(flen, from, to, rsa); ++ if (!ret || ret == SOFT) ++ return UADK_DO_SOFT; ++ ++ ret = rsa_pkey_param_alloc(NULL, &pri); ++ if (ret == -ENOMEM) ++ return UADK_DO_SOFT; ++ ++ pri->is_crt = check_rsa_is_crt(rsa); ++ ++ rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), pri->is_crt); ++ if (!rsa_sess) { ++ ret = UADK_DO_SOFT; ++ goto free_pkey; ++ } ++ ++ ret = rsa_create_pri_bn_ctx(rsa, pri, &from_buf, &num_bytes); ++ if (ret <= 0 || flen > num_bytes) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = add_rsa_prienc_padding(flen, from, from_buf, num_bytes, padding); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = rsa_do_crypto(rsa_sess); ++ if (!ret || rsa_sess->req.status) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ sign_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, ++ rsa_sess->req.dst_bytes, NULL); ++ if (!sign_bn) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ to_bn = BN_bin2bn(from_buf, num_bytes, NULL); ++ if (!to_bn) { ++ ret = UADK_DO_SOFT; ++ goto free_sign_bn; ++ } ++ ++ ret = rsa_get_sign_res(padding, to_bn, pri->n, sign_bn, &res); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_to_bn; ++ } ++ ++ ret = BN_bn2binpad(res, to, num_bytes); ++ ++free_to_bn: ++ BN_free(to_bn); ++free_sign_bn: ++ BN_free(sign_bn); ++free_buf: ++ rsa_free_pri_bn_ctx(&from_buf); ++free_sess: ++ rsa_free_eng_session(rsa_sess); ++free_pkey: ++ rsa_pkey_param_free(NULL, &pri); ++ return ret; ++} ++ ++static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) ++{ ++ struct uadk_rsa_sess *rsa_sess = NULL; ++ struct rsa_pubkey_param *pub = NULL; ++ int num_bytes, is_crt, len, ret; ++ unsigned char *from_buf = NULL; ++ BIGNUM *verify_bn = NULL; ++ ++ ret = check_rsa_input_para(flen, from, to, rsa); ++ if (!ret) ++ return UADK_E_FAIL; ++ else if (ret == SOFT) ++ return UADK_DO_SOFT; ++ ++ ret = rsa_pkey_param_alloc(&pub, NULL); ++ if (ret == -ENOMEM) ++ return UADK_DO_SOFT; ++ ++ is_crt = check_rsa_is_crt(rsa); ++ ++ rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), is_crt); ++ if (!rsa_sess) { ++ ret = UADK_DO_SOFT; ++ goto free_pkey; ++ } ++ ++ ret = rsa_create_pub_bn_ctx(rsa, pub, &from_buf, &num_bytes); ++ if (ret <= 0 || flen > num_bytes) { ++ ret = UADK_DO_SOFT; ++ goto free_sess; ++ } ++ ++ ret = rsa_fill_pubkey(pub, rsa_sess, from_buf, to); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ memcpy(rsa_sess->req.src, from, rsa_sess->req.src_bytes); ++ ret = rsa_do_crypto(rsa_sess); ++ if (!ret || rsa_sess->req.status) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ verify_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, ++ rsa_sess->req.dst_bytes, NULL); ++ if (!verify_bn) { ++ ret = UADK_DO_SOFT; ++ goto free_buf; ++ } ++ ++ ret = rsa_get_verify_res(padding, pub->n, verify_bn); ++ if (!ret) { ++ ret = UADK_DO_SOFT; ++ goto free_verify_bn; ++ } ++ ++ len = BN_bn2binpad(verify_bn, from_buf, num_bytes); ++ if (!len) { ++ ret = UADK_DO_SOFT; ++ goto free_verify_bn; ++ } ++ ++ ret = check_rsa_pubdec_padding(to, num_bytes, from_buf, len, padding); ++ if (!ret) ++ ret = UADK_DO_SOFT; ++ ++free_verify_bn: ++ BN_free(verify_bn); ++free_buf: ++ rsa_free_pub_bn_ctx(&from_buf); ++free_sess: ++ rsa_free_eng_session(rsa_sess); ++free_pkey: ++ rsa_pkey_param_free(&pub, NULL); ++ return ret; ++} ++ ++static EVP_SIGNATURE get_default_rsa_signature(void) ++{ ++ static EVP_SIGNATURE s_signature; ++ static int initilazed; ++ ++ if (!initilazed) { ++ EVP_SIGNATURE *signature = ++ (EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "RSA", "provider=default"); ++ if (signature) { ++ s_signature = *signature; ++ EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "EVP_SIGNATURE_fetch from default provider failed"); ++ } ++ } ++ return s_signature; ++} ++ ++static EVP_ASYM_CIPHER get_default_asym_cipher(void) ++{ ++ static EVP_ASYM_CIPHER s_asym_cipher; ++ static int initilazed; ++ ++ if (!initilazed) { ++ EVP_ASYM_CIPHER *asym_cipher = ++ (EVP_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, "RSA", "provider=default"); ++ if (asym_cipher) { ++ s_asym_cipher = *asym_cipher; ++ EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "EVP_ASYM_CIPHER_fetch from default provider failed"); ++ } ++ } ++ return s_asym_cipher; ++} ++ ++static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[], int operation) ++{ ++ PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; ++ ++ priv->rsa = vrsa; ++ priv->operation = operation; ++ ++ switch (uadk_rsa_test_flags(priv->rsa, RSA_FLAG_TYPE_MASK)) { ++ case RSA_FLAG_TYPE_RSA: ++ priv->pad_mode = RSA_PKCS1_PADDING; ++ break; ++ case RSA_FLAG_TYPE_RSASSAPSS: ++ priv->pad_mode = RSA_PKCS1_PSS_PADDING; ++ break; ++ default: ++ ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ++ return 0; ++ } ++ ++ if (uadk_prov_rsa_init()) ++ priv->soft = 1; ++ ++ return 1; ++} ++ ++static int uadk_rsa_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[], int operation) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ ++ if (priv == NULL || vrsa == NULL) ++ return 0; ++ ++ priv->rsa = vrsa; ++ priv->operation = operation; ++ ++ /* Maximum for sign, auto for verify */ ++ priv->saltlen = RSA_PSS_SALTLEN_AUTO; ++ priv->min_saltlen = -1; ++ ++ switch (uadk_rsa_test_flags(priv->rsa, RSA_FLAG_TYPE_MASK)) { ++ case RSA_FLAG_TYPE_RSA: ++ priv->pad_mode = RSA_PKCS1_PADDING; ++ break; ++ case RSA_FLAG_TYPE_RSASSAPSS: ++ priv->pad_mode = RSA_PKCS1_PSS_PADDING; ++ break; ++ default: ++ ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ++ return 0; ++ } ++ ++ if (uadk_prov_rsa_init()) ++ priv->soft = 1; ++ ++ return 1; ++} ++ ++static int uadk_rsa_verify_recover_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[]) ++{ ++ return 1; ++} ++ ++static int uadk_rsa_verify_recover(void *vprsactx, unsigned char *rout, ++ size_t *routlen, size_t routsize, ++ const unsigned char *sig, size_t siglen) ++{ ++ return 1; ++} ++ ++static int uadk_rsa_verify_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[]) ++{ ++ return uadk_rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); ++} ++ ++static int uadk_rsa_verify(void *vprsactx, const unsigned char *sig, ++ size_t siglen, const unsigned char *tbs, ++ size_t tbslen) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, const unsigned char *sig, ++ size_t siglen, const unsigned char *tbs, ++ size_t tbslen); ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ size_t rslen = 0; ++ ++ if (priv->soft) ++ goto soft; ++ ++ /* todo call public_verify */ ++ if (priv->md != NULL) { ++ /* todo */ ++ } else { ++ if (!setup_tbuf(priv)) ++ return 0; ++ rslen = uadk_prov_rsa_public_verify(siglen, sig, priv->tbuf, ++ priv->rsa, priv->pad_mode); ++ if (rslen == UADK_DO_SOFT) ++ goto soft; ++ } ++ ++ if ((rslen != tbslen) || memcmp(tbs, priv->tbuf, rslen)) ++ return 0; ++ ++ return 1; ++ ++soft: ++ fprintf(stderr, "switch to execute openssl software calculation.\n"); ++ fun_ptr fun = get_default_rsa_signature().verify; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, sig, siglen, tbs, tbslen); ++} ++ ++static int uadk_rsa_sign(void *vprsactx, unsigned char *sig, ++ size_t *siglen, size_t sigsize, ++ const unsigned char *tbs, size_t tbslen) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, unsigned char *sig, ++ size_t *siglen, size_t sigsize, ++ const unsigned char *tbs, size_t tbslen); ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ size_t rsasize = uadk_rsa_size(priv->rsa); ++ int ret; ++ ++ if (priv->soft) ++ goto soft; ++ ++ if (sig == NULL) { ++ *siglen = rsasize; ++ return 1; ++ } ++ ++ if (sigsize < rsasize) { ++ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE, ++ "is %zu, should be at least %zu", sigsize, rsasize); ++ return 0; ++ } ++ ++ ret = uadk_prov_rsa_private_sign(tbslen, tbs, sig, priv->rsa, priv->pad_mode); ++ if (ret == UADK_DO_SOFT) ++ goto soft; ++ ++ if (ret < 0) ++ return ret; ++ ++ *siglen = ret; ++ ++ return 1; ++soft: ++ fprintf(stderr, "switch to execute openssl software calculation.\n"); ++ fun_ptr fun = get_default_rsa_signature().sign; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, sig, siglen, sigsize, tbs, tbslen); ++} ++ ++static int uadk_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) ++{ ++ return uadk_rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_SIGN); ++} ++ ++static void *uadk_rsa_signature_newctx(void *provctx, const char *propq) ++{ ++ PROV_RSA_SIG_CTX *priv = OPENSSL_zalloc(sizeof(PROV_RSA_SIG_CTX)); ++ char *propq_copy = NULL; ++ ++ if (priv == NULL) ++ goto err; ++ ++ if (propq != NULL) { ++ propq_copy = OPENSSL_strdup(propq); ++ if (propq_copy == NULL) ++ goto err; ++ } ++ ++ priv->libctx = prov_libctx_of(provctx); ++ priv->flag_allow_md = 1; ++ priv->propq = propq_copy; ++ return priv; ++ ++err: ++ OPENSSL_free(priv); ++ fprintf(stderr, "%s failed.\n", __func__); ++ return NULL; ++} ++ ++static void uadk_rsa_signature_freectx(void *vprsactx) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ ++ if (priv == NULL) ++ return; ++ ++ free_tbuf(priv); ++ OPENSSL_clear_free(priv, sizeof(*priv)); ++} ++ ++static void *uadk_rsa_asym_newctx(void *provctx) ++{ ++ PROV_RSA_ASYM_CTX *priv = NULL; ++ ++ priv = OPENSSL_zalloc(sizeof(*priv)); ++ if (priv == NULL) ++ return NULL; ++ priv->libctx = prov_libctx_of(provctx); ++ ++ return priv; ++} ++ ++static void uadk_rsa_asym_freectx(void *vprsactx) ++{ ++ PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; ++ ++ if (priv == NULL) ++ return; ++ ++ OPENSSL_free(priv); ++} ++ ++static int uadk_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ ++ if (priv == NULL) ++ return 0; ++ if (params == NULL) ++ return 1; ++ ++ /* todo */ ++ ++ return 1; ++} ++ ++static const OSSL_PARAM settable_ctx_params[] = { ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM settable_ctx_params_no_digest[] = { ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_rsa_settable_ctx_params(void *vprsactx, ++ void *provctx) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ ++ if (priv != NULL && !priv->flag_allow_md) ++ return settable_ctx_params_no_digest; ++ ++ return settable_ctx_params; ++} ++ ++static int ++uadk_rsa_digest_sign_init(void *vprsactx, const char *mdname, ++ void *vrsa, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, const char *mdname, ++ void *vrsa, const OSSL_PARAM params[]); ++ ++ fun_ptr fun = get_default_rsa_signature().digest_sign_init; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, mdname, vrsa, params); ++} ++ ++static int uadk_rsa_digest_signverify_update(void *vprsactx, ++ const unsigned char *data, ++ size_t datalen) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ ++ if (priv == NULL || priv->mdctx == NULL) ++ return 0; ++ ++ return EVP_DigestUpdate(priv->mdctx, data, datalen); ++} ++ ++static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, ++ size_t *siglen, size_t sigsize) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ unsigned char digest[EVP_MAX_MD_SIZE]; ++ unsigned int dlen = 0; ++ ++ if (priv == NULL) ++ return 0; ++ priv->flag_allow_md = 1; ++ ++ if (priv->mdctx == NULL) ++ return 0; ++ /* ++ * If sig is NULL then we're just finding out the sig size. Other fields ++ * are ignored. Defer to rsa_sign. ++ */ ++ if (sig != NULL) { ++ /* ++ * The digests used here are all known (see rsa_get_md_nid()), so they ++ * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. ++ */ ++ if (!EVP_DigestFinal_ex(priv->mdctx, digest, &dlen)) ++ return 0; ++ } ++ ++ return uadk_rsa_sign(vprsactx, sig, siglen, sigsize, ++ digest, (size_t)dlen); ++} ++ ++static int uadk_rsa_digest_verify_init(void *vprsactx, const char *mdname, ++ void *vrsa, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, const char *mdname, ++ void *vrsa, const OSSL_PARAM params[]); ++ fun_ptr fun = get_default_rsa_signature().digest_verify_init; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, mdname, vrsa, params); ++} ++ ++ ++static int uadk_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, ++ size_t siglen) ++{ ++ PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ unsigned char digest[EVP_MAX_MD_SIZE]; ++ unsigned int dlen = 0; ++ ++ if (priv == NULL) ++ return 0; ++ priv->flag_allow_md = 1; ++ if (priv->mdctx == NULL) ++ return 0; ++ ++ /* ++ * The digests used here are all known (see rsa_get_md_nid()), so they ++ * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. ++ */ ++ if (!EVP_DigestFinal_ex(priv->mdctx, digest, &dlen)) ++ return 0; ++ ++ return uadk_rsa_verify(vprsactx, sig, siglen, ++ digest, (size_t)dlen); ++} ++ ++ ++static void *uadk_rsa_dupctx(void *vprsactx) ++{ ++ typedef void* (*fun_ptr)(void *vprsactx); ++ fun_ptr fun = get_default_rsa_signature().dupctx; ++ ++ if (!fun) ++ return NULL; ++ ++ return fun(vprsactx); ++} ++ ++static int uadk_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); ++ fun_ptr fun = get_default_rsa_signature().get_ctx_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, params); ++} ++ ++static const OSSL_PARAM *uadk_rsa_gettable_ctx_md_params(void *vprsactx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); ++ fun_ptr fun = get_default_rsa_signature().gettable_ctx_md_params; ++ ++ if (!fun) ++ return NULL; ++ return fun(vprsactx); ++} ++ ++ ++static int uadk_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, const OSSL_PARAM params[]); ++ fun_ptr fun = get_default_rsa_signature().set_ctx_md_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, params); ++} ++ ++static const OSSL_PARAM *uadk_rsa_settable_ctx_md_params(void *vprsactx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); ++ fun_ptr fun = get_default_rsa_signature().settable_ctx_md_params; ++ ++ if (!fun) ++ return NULL; ++ return fun(vprsactx); ++} ++ ++static const OSSL_PARAM *uadk_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ++ ossl_unused void *provctx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(ossl_unused void *vprsactx, ++ ossl_unused void *provctx); ++ fun_ptr fun = get_default_rsa_signature().gettable_ctx_params; ++ ++ if (!fun) ++ return NULL; ++ ++ return fun(vprsactx, provctx); ++} ++ ++static int uadk_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); ++ fun_ptr fun = get_default_rsa_signature().get_ctx_md_params; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, params); ++} ++ ++static int uadk_rsa_asym_encrypt_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[]) ++{ ++ return uadk_rsa_asym_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT); ++} ++ ++static int uadk_rsa_asym_decrypt_init(void *vprsactx, void *vrsa, ++ const OSSL_PARAM params[]) ++{ ++ return uadk_rsa_asym_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT); ++} ++ ++static int uadk_rsa_asym_encrypt(void *vprsactx, unsigned char *out, ++ size_t *outlen, size_t outsize, ++ const unsigned char *in, size_t inlen) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, ++ size_t outsize, const unsigned char *in, size_t inlen); ++ PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; ++ int ret; ++ ++ if (priv->soft) ++ goto soft; ++ ++ if (out == NULL) { ++ size_t len = uadk_rsa_size(priv->rsa); ++ ++ if (len == 0) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); ++ return 0; ++ } ++ *outlen = len; ++ return 1; ++ } ++ ++ ret = uadk_prov_rsa_public_encrypt(inlen, in, out, priv->rsa, priv->pad_mode); ++ if (ret == UADK_DO_SOFT) ++ goto soft; ++ if (ret < 0) ++ return ret; ++ ++ *outlen = ret; ++ ++ return 1; ++soft: ++ fprintf(stderr, "switch to execute openssl software calculation.\n"); ++ fun_ptr fun = get_default_asym_cipher().encrypt; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, out, outlen, outsize, in, inlen); ++} ++ ++static int uadk_rsa_asym_decrypt(void *vprsactx, unsigned char *out, ++ size_t *outlen, size_t outsize, ++ const unsigned char *in, size_t inlen) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, ++ size_t outsize, const unsigned char *in, size_t inlen); ++ PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; ++ size_t len = uadk_rsa_size(priv->rsa); ++ int ret; ++ ++ if (priv->soft) ++ goto soft; ++ ++ if (out == NULL) { ++ if (len == 0) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); ++ return 0; ++ } ++ *outlen = len; ++ return 1; ++ } ++ ++ if (outsize < len) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); ++ return 0; ++ } ++ ++ ret = uadk_prov_rsa_private_decrypt(inlen, in, out, priv->rsa, priv->pad_mode); ++ if (ret == UADK_DO_SOFT) ++ goto soft; ++ if (ret < 0) ++ return ret; ++ ++ *outlen = ret; ++ ++ return 1; ++soft: ++ fprintf(stderr, "switch to execute openssl software calculation.\n"); ++ fun_ptr fun = get_default_asym_cipher().decrypt; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(vprsactx, out, outlen, outsize, in, inlen); ++} ++ ++static int uadk_rsa_asym_get_ctx_params(void *vprsactx, OSSL_PARAM *params) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); ++ fun_ptr fun = get_default_asym_cipher().get_ctx_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, params); ++} ++ ++static const OSSL_PARAM *uadk_rsa_asym_gettable_ctx_params(void *vprsactx, ++ void *provctx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx, void *provctx); ++ fun_ptr fun = get_default_asym_cipher().gettable_ctx_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, provctx); ++} ++ ++static int uadk_rsa_asym_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *vprsactx, const OSSL_PARAM *params); ++ fun_ptr fun = get_default_asym_cipher().set_ctx_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, params); ++} ++ ++static const OSSL_PARAM *uadk_rsa_asym_settable_ctx_params(void *vprsactx, ++ void *provctx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx, void *provctx); ++ fun_ptr fun = get_default_asym_cipher().settable_ctx_params; ++ ++ if (!fun) ++ return 0; ++ return fun(vprsactx, provctx); ++} ++ ++static UADK_RSA_KEYMGMT get_default_keymgmt(void) ++{ ++ static UADK_RSA_KEYMGMT s_keymgmt; ++ static int initialized; ++ ++ if (!initialized) { ++ UADK_RSA_KEYMGMT *keymgmt = ++ (UADK_RSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "RSA", "provider=default"); ++ if (keymgmt) { ++ s_keymgmt = *keymgmt; ++ EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); ++ initialized = 1; ++ } else { ++ fprintf(stderr, "EVP_KEYMGMT_fetch from default provider failed"); ++ } ++ } ++ return s_keymgmt; ++} ++ ++static void *uadk_keymgmt_rsa_newdata(void *provctx) ++{ ++ typedef void* (*fun_ptr)(void *); ++ fun_ptr fun = get_default_keymgmt().new; ++ ++ if (!fun) ++ return NULL; ++ return fun(provctx); ++} ++ ++static void uadk_keymgmt_rsa_freedata(void *keydata) ++{ ++ typedef void (*fun_ptr)(void *); ++ fun_ptr fun = get_default_keymgmt().free; ++ ++ if (!fun) ++ return; ++ fun(keydata); ++} ++ ++static int uadk_keymgmt_rsa_has(const void *keydata, int selection) ++{ ++ typedef int (*fun_ptr)(const void *, int); ++ fun_ptr fun = get_default_keymgmt().has; ++ ++ if (!fun) ++ return 0; ++ ++ return fun(keydata, selection); ++} ++ ++static int uadk_keymgmt_rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *, int, const OSSL_PARAM*); ++ fun_ptr fun = get_default_keymgmt().import; ++ ++ if (!fun) ++ return 0; ++ return fun(keydata, selection, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_rsa_import_types(int selection) ++{ ++ typedef const OSSL_PARAM* (*fun_ptr)(int); ++ fun_ptr fun = get_default_keymgmt().import_types; ++ ++ if (!fun) ++ return NULL; ++ return fun(selection); ++} ++ ++static void *uadk_keymgmt_rsa_gen_init(void *provctx, int selection, ++ const OSSL_PARAM params[]) ++{ ++ typedef void * (*fun_ptr)(void *, int, const OSSL_PARAM *); ++ fun_ptr fun = get_default_keymgmt().gen_init; ++ ++ if (!fun) ++ return NULL; ++ return fun(provctx, selection, params); ++} ++ ++static int uadk_keymgmt_rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *, const OSSL_PARAM *); ++ fun_ptr fun = get_default_keymgmt().gen_set_params; ++ ++ if (!fun) ++ return 0; ++ return fun(genctx, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_rsa_gen_settable_params(ossl_unused void *genctx, ++ ossl_unused void *provctx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *, void *); ++ fun_ptr fun = get_default_keymgmt().gen_settable_params; ++ ++ if (!fun) ++ return NULL; ++ return fun(genctx, provctx); ++} ++ ++static int rsa_gencb(int p, int n, BN_GENCB *cb) ++{ ++ struct rsa_gen_ctx *gctx = BN_GENCB_get_arg(cb); ++ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; ++ ++ params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); ++ params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n); ++ return gctx->cb(params, gctx->cbarg); ++} ++ ++static RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx) ++{ ++ RSA *ret = OPENSSL_zalloc(sizeof(*ret)); ++ ++ if (ret == NULL) { ++ ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ ret->references = 1; ++ ret->lock = CRYPTO_THREAD_lock_new(); ++ if (ret->lock == NULL) { ++ ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); ++ OPENSSL_free(ret); ++ return NULL; ++ } ++ ++ ret->libctx = libctx; ++ ++ return ret; ++} ++ ++static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ++{ ++ typedef void * (*fun_ptr)(void *, OSSL_CALLBACK *, void *); ++ struct rsa_gen_ctx *gctx = genctx; ++ RSA *rsa = NULL; ++ BN_GENCB *gencb = NULL; ++ int ret; ++ ++ if (gctx == NULL) ++ return NULL; ++ ++ ret = uadk_prov_rsa_init(); ++ if (ret) ++ goto exe_soft; ++ ++ rsa = ossl_rsa_new_with_ctx(gctx->libctx); ++ if (rsa == NULL) ++ return NULL; ++ ++ gctx->cb = osslcb; ++ gctx->cbarg = cbarg; ++ gencb = BN_GENCB_new(); ++ if (gencb != NULL) ++ BN_GENCB_set(gencb, rsa_gencb, genctx); ++ ++ ret = uadk_prov_rsa_keygen(rsa, (int)gctx->nbits, gctx->pub_exp, gencb); ++ if (ret == UADK_DO_SOFT) { ++ BN_GENCB_free(gencb); ++ uadk_keymgmt_rsa_freedata(rsa); ++ goto exe_soft; ++ } ++ uadk_rsa_clear_flags(rsa, RSA_FLAG_TYPE_MASK); ++ uadk_rsa_set_flags(rsa, gctx->rsa_type); ++ BN_GENCB_free(gencb); ++ ++ return rsa; ++ ++exe_soft: ++ fprintf(stderr, "switch to execute openssl software calculation.\n"); ++ fun_ptr fun = get_default_keymgmt().gen; ++ ++ if (!fun) ++ return NULL; ++ return fun(genctx, osslcb, cbarg); ++} ++ ++static void uadk_keymgmt_rsa_gen_cleanup(void *genctx) ++{ ++ typedef void (*fun_ptr)(void *); ++ fun_ptr fun = get_default_keymgmt().gen_cleanup; ++ ++ if (!fun) ++ return; ++ fun(genctx); ++} ++ ++static void *uadk_keymgmt_rsa_load(const void *reference, size_t reference_sz) ++{ ++ typedef void * (*fun_ptr)(const void *, size_t); ++ fun_ptr fun = get_default_keymgmt().load; ++ ++ if (!fun) ++ return NULL; ++ return fun(reference, reference_sz); ++} ++ ++static int uadk_keymgmt_rsa_get_params(void *key, OSSL_PARAM params[]) ++{ ++ typedef int (*fun_ptr)(void *, OSSL_PARAM *); ++ fun_ptr fun = get_default_keymgmt().get_params; ++ ++ if (!fun) ++ return 0; ++ return fun(key, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_rsa_gettable_params(void *provctx) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(void *); ++ fun_ptr fun = get_default_keymgmt().gettable_params; ++ ++ if (!fun) ++ return NULL; ++ return fun(provctx); ++} ++ ++static int uadk_keymgmt_rsa_match(const void *keydata1, const void *keydata2, int selection) ++{ ++ typedef int (*fun_ptr)(const void *, const void *, int); ++ fun_ptr fun = get_default_keymgmt().match; ++ ++ if (!fun) ++ return 0; ++ return fun(keydata1, keydata2, selection); ++} ++ ++static int uadk_keymgmt_rsa_validate(const void *keydata, int selection, int checktype) ++{ ++ typedef int (*fun_ptr)(const void *, int, int); ++ fun_ptr fun = get_default_keymgmt().validate; ++ ++ if (!fun) ++ return 0; ++ return fun(keydata, selection, checktype); ++} ++ ++static int uadk_keymgmt_rsa_export(void *keydata, int selection, ++ OSSL_CALLBACK *param_callback, void *cbarg) ++{ ++ typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); ++ fun_ptr fun = get_default_keymgmt().export; ++ ++ if (!fun) ++ return 0; ++ return fun(keydata, selection, param_callback, cbarg); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_rsa_export_types(int selection) ++{ ++ typedef const OSSL_PARAM * (*fun_ptr)(int); ++ fun_ptr fun = get_default_keymgmt().export_types; ++ ++ if (!fun) ++ return NULL; ++ return fun(selection); ++} ++ ++static void *uadk_keymgmt_rsa_dup(const void *keydata_from, int selection) ++{ ++ typedef void * (*fun_ptr)(const void *, int); ++ fun_ptr fun = get_default_keymgmt().dup; ++ ++ if (!fun) ++ return NULL; ++ return fun(keydata_from, selection); ++} ++ ++const OSSL_DISPATCH uadk_rsa_keymgmt_functions[] = { ++ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))uadk_keymgmt_rsa_newdata }, ++ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))uadk_keymgmt_rsa_freedata }, ++ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))uadk_keymgmt_rsa_has }, ++ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))uadk_keymgmt_rsa_import }, ++ { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, ++ (void (*)(void))uadk_keymgmt_rsa_import_types }, ++ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))uadk_keymgmt_rsa_gen_init }, ++ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, ++ (void (*)(void))uadk_keymgmt_rsa_gen_set_params }, ++ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, ++ (void (*)(void))uadk_keymgmt_rsa_gen_settable_params }, ++ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))uadk_keymgmt_rsa_gen }, ++ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))uadk_keymgmt_rsa_gen_cleanup }, ++ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))uadk_keymgmt_rsa_load }, ++ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))uadk_keymgmt_rsa_get_params }, ++ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, ++ (void (*) (void))uadk_keymgmt_rsa_gettable_params }, ++ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))uadk_keymgmt_rsa_match }, ++ { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))uadk_keymgmt_rsa_validate }, ++ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))uadk_keymgmt_rsa_export }, ++ { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))uadk_keymgmt_rsa_export_types }, ++ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))uadk_keymgmt_rsa_dup }, ++ {0, NULL} ++}; ++ ++const OSSL_DISPATCH uadk_rsa_signature_functions[] = { ++ {OSSL_FUNC_SIGNATURE_NEWCTX, ++ (void (*)(void))uadk_rsa_signature_newctx}, ++ {OSSL_FUNC_SIGNATURE_SIGN_INIT, ++ (void (*)(void))uadk_rsa_sign_init}, ++ {OSSL_FUNC_SIGNATURE_SIGN, ++ (void (*)(void))uadk_rsa_sign}, ++ {OSSL_FUNC_SIGNATURE_VERIFY_INIT, ++ (void (*)(void))uadk_rsa_verify_init }, ++ {OSSL_FUNC_SIGNATURE_VERIFY, ++ (void (*)(void))uadk_rsa_verify }, ++ {OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, ++ (void (*)(void))uadk_rsa_verify_recover_init }, ++ {OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, ++ (void (*)(void))uadk_rsa_verify_recover }, ++ {OSSL_FUNC_SIGNATURE_FREECTX, ++ (void (*)(void))uadk_rsa_signature_freectx}, ++ {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_set_ctx_params}, ++ {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_settable_ctx_params}, ++ {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, ++ (void (*)(void))uadk_rsa_digest_sign_init }, ++ {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, ++ (void (*)(void))uadk_rsa_digest_signverify_update }, ++ {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, ++ (void (*)(void))uadk_rsa_digest_sign_final }, ++ {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, ++ (void (*)(void))uadk_rsa_digest_verify_init }, ++ {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, ++ (void (*)(void))uadk_rsa_digest_signverify_update }, ++ {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, ++ (void (*)(void))uadk_rsa_digest_verify_final }, ++ {OSSL_FUNC_SIGNATURE_DUPCTX, ++ (void (*)(void))uadk_rsa_dupctx }, ++ {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_get_ctx_params }, ++ {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_gettable_ctx_params }, ++ {OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, ++ (void (*)(void))uadk_rsa_get_ctx_md_params }, ++ {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, ++ (void (*)(void))uadk_rsa_gettable_ctx_md_params }, ++ {OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, ++ (void (*)(void))uadk_rsa_set_ctx_md_params }, ++ {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, ++ (void (*)(void))uadk_rsa_settable_ctx_md_params }, ++ {0, NULL} ++}; ++ ++const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[] = { ++ { OSSL_FUNC_ASYM_CIPHER_NEWCTX, ++ (void (*)(void))uadk_rsa_asym_newctx }, ++ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, ++ (void (*)(void))uadk_rsa_asym_encrypt_init }, ++ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, ++ (void (*)(void))uadk_rsa_asym_encrypt }, ++ { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, ++ (void (*)(void))uadk_rsa_asym_decrypt_init }, ++ { OSSL_FUNC_ASYM_CIPHER_DECRYPT, ++ (void (*)(void))uadk_rsa_asym_decrypt }, ++ { OSSL_FUNC_ASYM_CIPHER_FREECTX, ++ (void (*)(void))uadk_rsa_asym_freectx }, ++ { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_asym_get_ctx_params }, ++ { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_asym_gettable_ctx_params }, ++ { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_asym_set_ctx_params }, ++ { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_rsa_asym_settable_ctx_params }, ++ { 0, NULL } ++}; ++ ++void uadk_prov_destroy_rsa(void) ++{ ++ pthread_mutex_lock(&rsa_mutex); ++ if (g_rsa_prov.pid == getpid()) { ++ wd_rsa_uninit2(); ++ g_rsa_prov.pid = 0; ++ } ++ pthread_mutex_unlock(&rsa_mutex); ++} +diff --git a/test/sanity_test.sh b/test/sanity_test.sh +index 1e9983b..6a37014 100755 +--- a/test/sanity_test.sh ++++ b/test/sanity_test.sh +@@ -17,6 +17,7 @@ if ((major_version >= 3)); then + engine_id="$TEST_SCRIPT_DIR/../src/.libs/uadk_provider.so" + digest_algs=$(openssl list -provider $engine_id -digest-algorithms) + cipher_algs=$(openssl list -provider $engine_id -cipher-algorithms) ++ signature_algs=$(openssl list -provider $engine_id -signature-algorithms) + fi + + if [[ $digest_algs =~ "uadk_provider" ]]; then +@@ -67,6 +68,26 @@ if [[ $cipher_algs =~ "uadk_provider" ]]; then + openssl speed -provider $engine_id -async_jobs 1 -evp des-ede3-ecb + fi + ++if [[ $signature_algs =~ "uadk_provider" ]]; then ++ echo "uadk_provider testing rsa" ++ openssl speed -provider $engine_id rsa1024 ++ openssl speed -provider $engine_id rsa2048 ++ openssl speed -provider $engine_id rsa4096 ++ openssl speed -provider $engine_id -async_jobs 1 rsa1024 ++ openssl speed -provider $engine_id -async_jobs 1 rsa2048 ++ openssl speed -provider $engine_id -async_jobs 1 rsa4096 ++ ++ openssl genrsa -out prikey.pem -provider $engine_id 1024 ++ openssl rsa -in prikey.pem -pubout -out pubkey.pem -provider $engine_id -provider default ++ echo "Content to be encrypted" > plain.txt ++ ++ openssl pkeyutl -encrypt -in plain.txt -inkey pubkey.pem -pubin -out enc.txt \ ++ -pkeyopt rsa_padding_mode:pkcs1 -provider uadk_provider -provider default ++ ++ openssl pkeyutl -decrypt -in enc.txt -inkey prikey.pem -out dec.txt \ ++ -pkeyopt rsa_padding_mode:pkcs1 -provider $engine_id -provider default ++fi ++ + if [[ $version =~ "1.1.1" ]]; then + echo "openssl 1.1.1" + engine_id="$TEST_SCRIPT_DIR/../src/.libs/uadk_engine.so" +-- +2.25.1 + diff --git a/0045-uadk_provider-add-DOPENSSL_SUPPRESS_DEPRECATED.patch b/0045-uadk_provider-add-DOPENSSL_SUPPRESS_DEPRECATED.patch new file mode 100644 index 0000000..456e7e5 --- /dev/null +++ b/0045-uadk_provider-add-DOPENSSL_SUPPRESS_DEPRECATED.patch @@ -0,0 +1,36 @@ +From 2ae4dceb9cd43a0a05b793efb155e4bca145f16c Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Mon, 11 Sep 2023 15:42:11 +0800 +Subject: [PATCH 45/48] uadk_provider: add -DOPENSSL_SUPPRESS_DEPRECATED + +uadk_prov_rsa reported a warning of deprecation, +Unfortunately, can not solve the warning at the moment. +Suppress the deprecated warning temporarily + +warning: 'RSA_padding_add_PKCS1_type_2' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_add_PKCS1_OAEP' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_check_PKCS1_type_2' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_check_PKCS1_OAEP' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_add_PKCS1_type_1' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_add_X931' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_check_PKCS1_type_1' is deprecated: Since OpenSSL 3.0 +warning: 'RSA_padding_check_X931' is deprecated: Since OpenSSL 3.0 + +Signed-off-by: Zhangfei Gao +--- + src/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index 6fdee47..9d5102a 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -57,4 +57,4 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread + uadk_provider_la_CFLAGS=$(WD_CFLAGS) $(libcrypto_CFLAGS) +-uadk_provider_la_CFLAGS+=-DCRYPTO3 ++uadk_provider_la_CFLAGS+=-DOPENSSL_SUPPRESS_DEPRECATED +-- +2.25.1 + diff --git a/0046-uadk_prov_cipher-fix-build-warning.patch b/0046-uadk_prov_cipher-fix-build-warning.patch new file mode 100644 index 0000000..58e13ab --- /dev/null +++ b/0046-uadk_prov_cipher-fix-build-warning.patch @@ -0,0 +1,46 @@ +From ad0aa5e29072d9258ff223dfef629c43869f7d4d Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Tue, 10 Oct 2023 04:59:26 +0000 +Subject: [PATCH 46/48] uadk_prov_cipher: fix build warning + +With CFLAGS=-Wall, build reports warning + +uadk_prov_cipher.c: In function 'uadk_prov_cipher_soft_work': +uadk_prov_cipher.c:226:6: warning: unused variable 'sw_final_len' [-Wunused-variable] + 226 | int sw_final_len = 0; + | ^~~~~~~~~~~~ +uadk_prov_cipher.c: In function 'uadk_prov_cipher_init': +uadk_prov_cipher.c:266:6: warning: unused variable 'ret' [-Wunused-variable] + 266 | int ret, i; + | ^~~ + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov_cipher.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 9a2c27b..21bf0a2 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -223,8 +223,6 @@ static int uadk_prov_cipher_sw_init(struct cipher_priv_ctx *priv, + static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned char *out, + int *outl, const unsigned char *in, size_t len) + { +- int sw_final_len = 0; +- + if (priv->sw_cipher == NULL) + return 0; + +@@ -263,7 +261,7 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, + const unsigned char *iv, size_t ivlen) + { + int cipher_counts = ARRAY_SIZE(cipher_info_table); +- int ret, i; ++ int i; + + if (iv) + memcpy(priv->iv, iv, ivlen); +-- +2.25.1 + diff --git a/0047-uadk_prov_init-change-name-more-informative.patch b/0047-uadk_prov_init-change-name-more-informative.patch new file mode 100644 index 0000000..91d7d1e --- /dev/null +++ b/0047-uadk_prov_init-change-name-more-informative.patch @@ -0,0 +1,92 @@ +From 04b50bae1c84427ea25c64ed82bdfd875dbb8e39 Mon Sep 17 00:00:00 2001 +From: Zhangfei Gao +Date: Wed, 11 Oct 2023 06:38:59 +0000 +Subject: [PATCH 47/48] uadk_prov_init: change name more informative + +Use a more informative name uadk_xxx instead of p_xxx + +Signed-off-by: Zhangfei Gao +--- + src/uadk_prov.h | 4 ++-- + src/uadk_prov_init.c | 18 +++++++++--------- + 2 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index f8a3cd7..efb29ee 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -18,12 +18,12 @@ + #ifndef UADK_PROV_H + #define UADK_PROV_H + +-struct p_uadk_ctx { ++struct uadk_prov_ctx { + const OSSL_CORE_HANDLE *handle; + OSSL_LIB_CTX *libctx; + }; + +-static inline OSSL_LIB_CTX *prov_libctx_of(struct p_uadk_ctx *ctx) ++static inline OSSL_LIB_CTX *prov_libctx_of(struct uadk_prov_ctx *ctx) + { + if (ctx == NULL) + return NULL; +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index b28ce69..2bde080 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -95,8 +95,8 @@ static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { + { NULL, NULL, NULL } + }; + +-static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, +- int *no_cache) ++static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, ++ int *no_cache) + { + static int prov_init; + +@@ -125,9 +125,9 @@ static const OSSL_ALGORITHM *p_prov_query(void *provctx, int operation_id, + return NULL; + } + +-static void p_teardown(void *provctx) ++static void uadk_teardown(void *provctx) + { +- struct p_uadk_ctx *ctx = (struct p_uadk_ctx *)provctx; ++ struct uadk_prov_ctx *ctx = (struct uadk_prov_ctx *)provctx; + + uadk_prov_destroy_digest(); + uadk_prov_destroy_cipher(); +@@ -137,9 +137,9 @@ static void p_teardown(void *provctx) + async_poll_task_free(); + } + +-static const OSSL_DISPATCH p_test_table[] = { +- { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_prov_query }, +- { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown }, ++static const OSSL_DISPATCH uadk_dispatch_table[] = { ++ { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))uadk_query }, ++ { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))uadk_teardown }, + { 0, NULL } + }; + +@@ -157,7 +157,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH **out, + void **provctx) + { +- struct p_uadk_ctx *ctx; ++ struct uadk_prov_ctx *ctx; + int ret; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); +@@ -171,6 +171,6 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + pthread_atfork(NULL, NULL, provider_init_child_at_fork_handler); + + *provctx = (void *)ctx; +- *out = p_test_table; ++ *out = uadk_dispatch_table; + return 1; + } +-- +2.25.1 + diff --git a/0048-digest-alloc-session-and-data-when-copy-evp-context.patch b/0048-digest-alloc-session-and-data-when-copy-evp-context.patch new file mode 100644 index 0000000..3509cce --- /dev/null +++ b/0048-digest-alloc-session-and-data-when-copy-evp-context.patch @@ -0,0 +1,316 @@ +From ce4625a39433d7d9b263263a6fbdb0c1c4ef1572 Mon Sep 17 00:00:00 2001 +From: Wenkai Lin +Date: Tue, 17 Oct 2023 16:10:51 +0800 +Subject: [PATCH 48/48] digest: alloc session and data when copy evp context + +There is a problem caused by shared session that session status +will be modified and another data flow will use the wrong status, +so we need let each context get different session when we copy context, +and the table is no longer needed. + +Since the new session does not have any stream information, the engine +need to send a message with total length and message status to uadk, +so that uadk can correctly configure the session. + +Signed-off-by: Wenkai Lin +--- + src/uadk_digest.c | 144 ++++++++++++++++++++++++++++++++-------------- + 1 file changed, 102 insertions(+), 42 deletions(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index b75c408..beb9f51 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -35,8 +35,6 @@ + #define CTX_SYNC 0 + #define CTX_ASYNC 1 + #define CTX_NUM 2 +-#define DIGEST_DOING 1 +-#define DIGEST_END 0 + #define ENV_ENABLED 1 + + /* The max BD data length is 16M-512B */ +@@ -99,7 +97,9 @@ struct digest_priv_ctx { + uint32_t state; + uint32_t switch_threshold; + int switch_flag; +- bool copy; ++ uint32_t app_datasize; ++ bool is_stream_copy; ++ size_t total_data_len; + }; + + struct digest_info { +@@ -199,7 +199,7 @@ static int digest_soft_init(struct digest_priv_ctx *md_ctx) + uint32_t e_nid = md_ctx->e_nid; + const EVP_MD *digest_md = NULL; + EVP_MD_CTX *ctx = NULL; +- int ctx_len; ++ int app_datasize; + + /* Allocate a soft ctx for hardware engine */ + if (md_ctx->soft_ctx == NULL) +@@ -213,13 +213,15 @@ static int digest_soft_init(struct digest_priv_ctx *md_ctx) + return 0; + } + +- ctx_len = EVP_MD_meth_get_app_datasize(digest_md); ++ app_datasize = EVP_MD_meth_get_app_datasize(digest_md); + if (ctx->md_data == NULL) { +- ctx->md_data = OPENSSL_malloc(ctx_len); ++ ctx->md_data = OPENSSL_malloc(app_datasize); + if (ctx->md_data == NULL) + return 0; + } + ++ md_ctx->app_datasize = app_datasize; ++ + return EVP_MD_meth_get_init(digest_md)(ctx); + } + +@@ -267,17 +269,14 @@ static void digest_soft_cleanup(struct digest_priv_ctx *md_ctx) + { + EVP_MD_CTX *ctx = md_ctx->soft_ctx; + +- /* Prevent double-free after the copy is used */ +- if (md_ctx->copy) +- return; +- + if (ctx != NULL) { + if (ctx->md_data) { + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + } + EVP_MD_CTX_free(ctx); +- ctx = NULL; ++ md_ctx->soft_ctx = NULL; ++ md_ctx->app_datasize = 0; + } + } + +@@ -515,13 +514,16 @@ static void digest_priv_ctx_setup(struct digest_priv_ctx *priv, + priv->req.out_bytes = out_len; + } + +-static void digest_priv_ctx_cleanup(struct digest_priv_ctx *priv) ++static void digest_priv_ctx_reset(struct digest_priv_ctx *priv) + { + /* Ensure that private variable values are initialized */ + priv->state = SEC_DIGEST_INIT; + priv->last_update_bufflen = 0; + priv->switch_threshold = 0; + priv->switch_flag = 0; ++ priv->total_data_len = 0; ++ priv->app_datasize = 0; ++ priv->is_stream_copy = false; + } + + static int uadk_e_digest_init(EVP_MD_CTX *ctx) +@@ -529,24 +531,23 @@ static int uadk_e_digest_init(EVP_MD_CTX *ctx) + struct digest_priv_ctx *priv = + (struct digest_priv_ctx *) EVP_MD_CTX_md_data(ctx); + __u32 digest_counts = ARRAY_SIZE(digest_info_table); +- int nid = EVP_MD_nid(EVP_MD_CTX_md(ctx)); + struct sched_params params = {0}; + __u32 i; + int ret; + +- priv->e_nid = nid; ++ priv->e_nid = EVP_MD_nid(EVP_MD_CTX_md(ctx)); + +- digest_priv_ctx_cleanup(priv); ++ digest_priv_ctx_reset(priv); + + ret = uadk_e_init_digest(); + if (unlikely(!ret)) { + priv->switch_flag = UADK_DO_SOFT; + fprintf(stderr, "uadk failed to initialize digest.\n"); +- goto soft_init; ++ return digest_soft_init(priv); + } + + for (i = 0; i < digest_counts; i++) { +- if (nid == digest_info_table[i].nid) { ++ if (priv->e_nid == digest_info_table[i].nid) { + digest_priv_ctx_setup(priv, digest_info_table[i].alg, + digest_info_table[i].mode, digest_info_table[i].out_len); + break; +@@ -561,22 +562,24 @@ static int uadk_e_digest_init(EVP_MD_CTX *ctx) + /* Use the default numa parameters */ + params.numa_id = -1; + priv->setup.sched_param = ¶ms; +- priv->sess = wd_digest_alloc_sess(&priv->setup); +- if (unlikely(!priv->sess)) +- return 0; ++ if (!priv->sess) { ++ priv->sess = wd_digest_alloc_sess(&priv->setup); ++ if (unlikely(!priv->sess)) ++ return 0; + +- priv->data = malloc(DIGEST_BLOCK_SIZE); +- if (unlikely(!priv->data)) { +- wd_digest_free_sess(priv->sess); +- return 0; ++ priv->data = malloc(DIGEST_BLOCK_SIZE); ++ if (unlikely(!priv->data)) ++ goto out; + } + +- priv->switch_threshold = sec_digest_get_sw_threshold(nid); ++ priv->switch_threshold = sec_digest_get_sw_threshold(priv->e_nid); + + return 1; + +-soft_init: +- return digest_soft_init(priv); ++out: ++ wd_digest_free_sess(priv->sess); ++ priv->sess = 0; ++ return 0; + } + + static void digest_update_out_length(EVP_MD_CTX *ctx) +@@ -592,6 +595,16 @@ static void digest_update_out_length(EVP_MD_CTX *ctx) + priv->req.out_bytes = WD_DIGEST_SHA384_FULL_LEN; + } + ++static void digest_set_msg_state(struct digest_priv_ctx *priv, bool is_end) ++{ ++ if (unlikely(priv->is_stream_copy)) { ++ priv->req.has_next = is_end ? WD_DIGEST_STREAM_END : WD_DIGEST_STREAM_DOING; ++ priv->is_stream_copy = false; ++ } else { ++ priv->req.has_next = is_end ? WD_DIGEST_END : WD_DIGEST_DOING; ++ } ++} ++ + static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_len) + { + struct digest_priv_ctx *priv = +@@ -602,8 +615,7 @@ static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_le + int ret; + + digest_update_out_length(ctx); +- +- priv->req.has_next = DIGEST_DOING; ++ digest_set_msg_state(priv, false); + + while (priv->last_update_bufflen + left_len > DIGEST_BLOCK_SIZE) { + copy_to_bufflen = DIGEST_BLOCK_SIZE - priv->last_update_bufflen; +@@ -662,6 +674,8 @@ static int uadk_e_digest_update(EVP_MD_CTX *ctx, const void *data, size_t data_l + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) + goto soft_update; + ++ priv->total_data_len += data_len; ++ + if (priv->last_update_bufflen + data_len <= DIGEST_BLOCK_SIZE) { + uadk_memcpy(priv->data + priv->last_update_bufflen, data, data_len); + priv->last_update_bufflen += data_len; +@@ -753,9 +767,10 @@ static int uadk_e_digest_final(EVP_MD_CTX *ctx, unsigned char *digest) + { + struct digest_priv_ctx *priv = + (struct digest_priv_ctx *)EVP_MD_CTX_md_data(ctx); +- int ret = 1; + struct async_op op; +- priv->req.has_next = DIGEST_END; ++ int ret = 1; ++ ++ digest_set_msg_state(priv, true); + priv->req.in = priv->data; + priv->req.out = priv->out; + priv->req.in_bytes = priv->last_update_bufflen; +@@ -810,17 +825,21 @@ static int uadk_e_digest_cleanup(EVP_MD_CTX *ctx) + struct digest_priv_ctx *priv = + (struct digest_priv_ctx *)EVP_MD_CTX_md_data(ctx); + +- /* Prevent double-free after the copy is used */ +- if (!priv || priv->copy) ++ if (!priv) + return 1; + ++ if (priv->data) { ++ free(priv->data); ++ priv->data = NULL; ++ } ++ + if (priv->sess) { + wd_digest_free_sess(priv->sess); + priv->sess = 0; + } + +- if (priv && priv->data) +- free(priv->data); ++ if (priv->soft_ctx) ++ digest_soft_cleanup(priv); + + return 1; + } +@@ -831,17 +850,58 @@ static int uadk_e_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) + (struct digest_priv_ctx *)EVP_MD_CTX_md_data(from); + struct digest_priv_ctx *t = + (struct digest_priv_ctx *)EVP_MD_CTX_md_data(to); ++ struct sched_params params = {0}; ++ int ret; ++ ++ if (!t) ++ return 1; ++ ++ if (t->sess) { ++ params.numa_id = -1; ++ t->setup.sched_param = ¶ms; ++ t->sess = wd_digest_alloc_sess(&t->setup); ++ if (!t->sess) { ++ fprintf(stderr, "failed to alloc session for digest ctx copy.\n"); ++ return 0; ++ } ++ ++ t->data = malloc(DIGEST_BLOCK_SIZE); ++ if (!t->data) ++ goto free_sess; + +- /* +- * EVP_MD_CTX_copy will copy from->priv to to->priv, +- * including data pointer. Instead of coping data contents, +- * add a flag to prevent double-free. +- */ ++ if (t->state != SEC_DIGEST_INIT) { ++ t->is_stream_copy = true; ++ /* Length that the hardware has processed should be equal to ++ * total input data length minus software cache data length. ++ */ ++ t->req.long_data_len = t->total_data_len - t->last_update_bufflen; ++ } ++ ++ memcpy(t->data, f->data, f->last_update_bufflen); ++ } ++ ++ if (t->soft_ctx) { ++ t->soft_ctx = NULL; ++ ret = digest_soft_init(t); ++ if (!ret) ++ goto free_data; + +- if (f && f->data) +- t->copy = true; ++ memcpy(t->soft_ctx->md_data, f->soft_ctx->md_data, t->app_datasize); ++ } + + return 1; ++ ++free_data: ++ if (t->data) { ++ free(t->data); ++ t->data = NULL; ++ } ++free_sess: ++ if (t->sess) { ++ wd_digest_free_sess(t->sess); ++ t->sess = 0; ++ } ++ return 0; + } + + +-- +2.25.1 + diff --git a/uadk_engine.spec b/uadk_engine.spec index 2348f5a..e9428c9 100644 --- a/uadk_engine.spec +++ b/uadk_engine.spec @@ -1,7 +1,7 @@ Name: uadk_engine Summary: UADK Accelerator Engine Version: 1.2.0 -Release: 1 +Release: 2 License: Apache-2.0 Source: %{name}-%{version}.tar.gz ExclusiveOS: linux @@ -23,6 +23,44 @@ Patch0007: 0007-README-update-openssl-3.0.patch Patch0008: 0008-cipher-fix-double-free-error.patch Patch0009: 0009-cipher-fix-set-key-error.patch Patch0010: 0010-cipher-fix-async-hardware-computing-error.patch +Patch0011: 0011-uadk_prov_digest-merge-threshold-table.patch +Patch0012: 0012-uadk-add-uadk_prov_cipher.patch +Patch0013: 0013-sanity_test-add-prov_cipher-for-openssl-3.0.patch +Patch0014: 0014-uadk_engine-fixup-signed-unsigned-mix-with-relationa.patch +Patch0015: 0015-uadk_engine-fixup-variable-naming-conflicts.patch +Patch0016: 0016-digest-fixup-free-source-method.patch +Patch0017: 0017-ecc-fixup-free-source-method-inconsistent.patch +Patch0018: 0018-cipher-fixup-error-handling-in-ctx-init.patch +Patch0019: 0019-uadk_engine-modify-setting-async-poll-state-process.patch +Patch0020: 0020-dh-fixup-release-source-of-private-key.patch +Patch0021: 0021-ecc-Add-pkey-method-null-pointer-judgment.patch +Patch0022: 0022-rsa-release-source-when-new-kg-out-failed.patch +Patch0023: 0023-rsa-bugfix-repeated-source-release.patch +Patch0024: 0024-sm2-fixup-unreleased-source-in-data-conversion.patch +Patch0025: 0025-ecc-add-openssl-method-null-pointer-judgement.patch +Patch0026: 0026-uadk_engine-cleanup-call-form-of-callback-func.patch +Patch0027: 0027-uadk_engine-cleanup-empty-body-warning-in-v1.patch +Patch0028: 0028-sanity_test.sh-check-version-for-openssl-version-3.0.patch +Patch0029: 0029-README-fix-openEuler-build-libdir.patch +Patch0030: 0030-uadk_prov_digest-provider-default-may-not-exist.patch +Patch0031: 0031-uadk_provider-iv_len-in-SM4_ECB-mode-must-be-0.patch +Patch0032: 0032-uadk_provider-load-default-provider-into-Global-libr.patch +Patch0033: 0033-uadk_provider-handle-the-async_poll_task_free-in-pro.patch +Patch0034: 0034-uadk_cipher-iv_len-in-SM4_ECB-mode-must-be-0.patch +Patch0035: 0035-uadk_prov_cipher-add-handling-of-param-padding.patch +Patch0036: 0036-uadk_prov_cipher-fix-padding.patch +Patch0037: 0037-uadk_prov_cipher-add-stream-mode.patch +Patch0038: 0038-uadk_prov_cipher-xts-mode-does-not-use-default-provi.patch +Patch0039: 0039-uadk_prov_cipher-handle-no-padding-case.patch +Patch0040: 0040-sanity_test.sh-change-provider-name-to-its-full-path.patch +Patch0041: 0041-sanity_test-remove-default-provider.patch +Patch0042: 0042-uadk_prov_cipher-add-static-descriptor-to-uadk_prov_.patch +Patch0043: 0043-tentative-ctx-handle-handle.patch +Patch0044: 0044-uadk-add-uadk_prov_rsa-for-openssl-3.0.patch +Patch0045: 0045-uadk_provider-add-DOPENSSL_SUPPRESS_DEPRECATED.patch +Patch0046: 0046-uadk_prov_cipher-fix-build-warning.patch +Patch0047: 0047-uadk_prov_init-change-name-more-informative.patch +Patch0048: 0048-digest-alloc-session-and-data-when-copy-evp-context.patch %description This package contains the UADK Accelerator Engine @@ -72,6 +110,9 @@ fi /sbin/ldconfig %changelog +* Tue Oct 31 2023 JiangShui Yang 1.2.0-2 +- Backport uadk engine build patch + * Tue Aug 22 2023 JiangShui Yang 1.2.0-1 - Backport uadk engine patch form v1.0.1 to 1.2.0