From 851a6dd59d9fa0a5b4a29e90853b3ea62932b843 Mon Sep 17 00:00:00 2001 From: Eingesch <884071658@qq.com> Date: Fri, 25 Apr 2025 17:31:55 +0800 Subject: [PATCH] uadk_provider: add soft switching function for uadk_provider --- ...-fix-a-memory-leak-issue-in-BIO_meth.patch | 40 + ...rovider-fix-atomic-compare-parameter.patch | 56 + ...upport-switching-to-software-in-init.patch | 461 +++++++ ...x-async-packet-reception-timeout-err.patch | 219 ++++ ...d-hmac-alg-for-uadk_provider-in-open.patch | 987 ++++++++++++++ ...d-soft-mac-switching-function-for-ua.patch | 540 ++++++++ ...-add-dh-switching-software-computati.patch | 241 ++++ ...a-add-rsa-switching-software-computa.patch | 370 ++++++ ...2-add-sm2-switching-software-computa.patch | 551 ++++++++ ...x-add-x448-and-x25519-switching-soft.patch | 426 ++++++ ...dsa-add-ecdsa-switching-software-com.patch | 171 +++ ...dh-add-ecdh-switching-software-compu.patch | 243 ++++ 0032-digest-fix-for-digest-soft-work.patch | 161 +++ 0033-digest-fix-for-digest-soft-init.patch | 135 ++ 0034-uadk_engine-fix-print-format.patch | 58 + ...upport-switching-to-soft-calculation.patch | 1156 +++++++++++++++++ ...a-digest-software-switching-issue-in.patch | 50 + ...v-default-to-turn-on-the-soft-switch.patch | 29 + uadk_engine.spec | 24 +- 19 files changed, 5917 insertions(+), 1 deletion(-) create mode 100644 0020-uadk_provider-fix-a-memory-leak-issue-in-BIO_meth.patch create mode 100644 0021-uadk_provider-fix-atomic-compare-parameter.patch create mode 100644 0022-uadk_provider-support-switching-to-software-in-init.patch create mode 100644 0023-uadk_provider-fix-async-packet-reception-timeout-err.patch create mode 100644 0024-uadk_provider-add-hmac-alg-for-uadk_provider-in-open.patch create mode 100644 0025-uadk_provider-add-soft-mac-switching-function-for-ua.patch create mode 100644 0026-uadk_provider-dh-add-dh-switching-software-computati.patch create mode 100644 0027-uadk_provider-rsa-add-rsa-switching-software-computa.patch create mode 100644 0028-uadk_provider-sm2-add-sm2-switching-software-computa.patch create mode 100644 0029-uadk_provider-ecx-add-x448-and-x25519-switching-soft.patch create mode 100644 0030-uadk_provider-ecdsa-add-ecdsa-switching-software-com.patch create mode 100644 0031-uadk_provider-ecdh-add-ecdh-switching-software-compu.patch create mode 100644 0032-digest-fix-for-digest-soft-work.patch create mode 100644 0033-digest-fix-for-digest-soft-init.patch create mode 100644 0034-uadk_engine-fix-print-format.patch create mode 100644 0035-uadk_prov-sec-support-switching-to-soft-calculation.patch create mode 100644 0036-uadk_engine-fix-a-digest-software-switching-issue-in.patch create mode 100644 0037-uadk_prov-default-to-turn-on-the-soft-switch.patch diff --git a/0020-uadk_provider-fix-a-memory-leak-issue-in-BIO_meth.patch b/0020-uadk_provider-fix-a-memory-leak-issue-in-BIO_meth.patch new file mode 100644 index 0000000..bbbf2e8 --- /dev/null +++ b/0020-uadk_provider-fix-a-memory-leak-issue-in-BIO_meth.patch @@ -0,0 +1,40 @@ +From c7856c73bb422f324f0bc0e8553233714b6f142c Mon Sep 17 00:00:00 2001 +From: Chenghai Huang +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 20/36] uadk_provider: fix a memory leak issue in BIO_meth + +After BIO_meth_new, it need to call BIO_meth_free to free the +memery. + +Signed-off-by: Chenghai Huang +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_init.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index a6012ab..f3f360f 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -260,13 +260,17 @@ static void uadk_teardown(void *provctx) + { + struct uadk_prov_ctx *ctx = (struct uadk_prov_ctx *)provctx; + ++ if (ctx) { ++ BIO_meth_free(ctx->corebiometh); ++ OPENSSL_free(ctx); ++ } ++ + uadk_prov_destroy_digest(); + uadk_prov_destroy_cipher(); + uadk_prov_destroy_aead(); + uadk_prov_destroy_rsa(); + uadk_prov_ecc_uninit(); + uadk_prov_dh_uninit(); +- OPENSSL_free(ctx); + OSSL_PROVIDER_unload(prov); + async_module_uninit(); + } +-- +2.25.1 + diff --git a/0021-uadk_provider-fix-atomic-compare-parameter.patch b/0021-uadk_provider-fix-atomic-compare-parameter.patch new file mode 100644 index 0000000..744309a --- /dev/null +++ b/0021-uadk_provider-fix-atomic-compare-parameter.patch @@ -0,0 +1,56 @@ +From 3a40be0e6e739d15dba20badd6d750e1717777bd Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 21/36] uadk_provider: fix atomic compare parameter + +Use explicit initialization values in __atomic_compare_exchange_n(). + +Signed-off-by: Zhiqi Song +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_init.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index f3f360f..54e3fcb 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -209,24 +209,29 @@ static const OSSL_ALGORITHM uadk_prov_keyexch[] = { + static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, + int *no_cache) + { ++ OSSL_LIB_CTX *libctx; + static int prov_init; + int ver; + +- prov = OSSL_PROVIDER_load(NULL, "default"); +- if (!prov_init) { +- prov_init = 1; ++ if (__atomic_compare_exchange_n(&prov_init, &(int){0}, 1, false, __ATOMIC_SEQ_CST, ++ __ATOMIC_SEQ_CST)) { ++ libctx = prov_libctx_of(provctx); ++ prov = OSSL_PROVIDER_load(libctx, "default"); ++ if (!prov) { ++ fprintf(stderr, "failed to load default provider\n"); ++ return NULL; ++ } + /* + * uadk_provider takes the highest priority + * and overwrite the openssl.cnf property. + */ +- EVP_set_default_properties(NULL, "?provider=uadk_provider"); ++ EVP_set_default_properties(libctx, "?provider=uadk_provider"); + /* + * In asynchronous scenarios, if random numbers are obtained using + * uadk provider cipher, deadlocks may occur. Therefore, random numbers are + * obtained using default provider cipher. + */ +- (void)RAND_set_DRBG_type(prov_libctx_of(provctx), NULL, +- "provider=default", NULL, NULL); ++ (void)RAND_set_DRBG_type(libctx, NULL, "provider=default", NULL, NULL); + } + + *no_cache = 0; +-- +2.25.1 + diff --git a/0022-uadk_provider-support-switching-to-software-in-init.patch b/0022-uadk_provider-support-switching-to-software-in-init.patch new file mode 100644 index 0000000..2a2b22f --- /dev/null +++ b/0022-uadk_provider-support-switching-to-software-in-init.patch @@ -0,0 +1,461 @@ +From ad50418b46c727c848238de3036c5662f7a6300a Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 22/36] uadk_provider: support switching to software in init + +Switch to software computing when hardware device detection +fails during initialization. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov.h | 3 + + src/uadk_prov_cipher.c | 2 +- + src/uadk_prov_digest.c | 15 +++++ + src/uadk_prov_init.c | 143 +++++++++++++++++++++++++++++++---------- + src/uadk_prov_pkey.c | 28 +++++++- + src/uadk_prov_pkey.h | 6 ++ + 6 files changed, 160 insertions(+), 37 deletions(-) + +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 7cb1eee..47bfb43 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -198,6 +198,9 @@ void uadk_prov_destroy_dh(void); + void uadk_prov_ecc_uninit(void); + void uadk_prov_dh_uninit(void); + int uadk_prov_cipher_version(void); ++int uadk_prov_digest_version(void); ++int uadk_get_sw_offload_state(void); ++void uadk_set_sw_offload_state(int enable); + + /* offload small packets to sw */ + extern int enable_sw_offload; +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index 04a6489..ff1b2ee 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -1288,7 +1288,7 @@ int uadk_prov_cipher_version(void) + + dev = wd_get_accel_dev("cipher"); + if (!dev) { +- fprintf(stderr, "no device available!\n"); ++ fprintf(stderr, "no cipher device available!\n"); + return 0; + } + +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index caac877..921c3db 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -956,3 +956,18 @@ UADK_PROVIDER_IMPLEMENTATION(sha384, NID_sha384, 48, 128); + UADK_PROVIDER_IMPLEMENTATION(sha512, NID_sha512, 64, 128); + UADK_PROVIDER_IMPLEMENTATION(sha512_224, NID_sha512_224, 28, 128); + UADK_PROVIDER_IMPLEMENTATION(sha512_256, NID_sha512_256, 32, 128); ++ ++int uadk_prov_digest_version(void) ++{ ++ struct uacce_dev *dev; ++ ++ dev = wd_get_accel_dev("digest"); ++ if (!dev) { ++ fprintf(stderr, "no digest device available!\n"); ++ return UADK_DIGEST_FAIL; ++ } ++ ++ free(dev); ++ ++ return UADK_DIGEST_SUCCESS; ++} +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 54e3fcb..b5588f2 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -33,7 +33,7 @@ + #include "uadk_prov_pkey.h" + + static const char UADK_DEFAULT_PROPERTIES[] = "provider=uadk_provider"; +-static OSSL_PROVIDER *prov; ++static OSSL_PROVIDER *default_prov; + + /* Functions provided by the core */ + static OSSL_FUNC_core_gettable_params_fn *c_gettable_params; +@@ -48,11 +48,11 @@ struct uadk_provider_params { + int enable_sw_offload; + + const OSSL_ALGORITHM uadk_prov_digests[] = { +- { OSSL_DIGEST_NAME_MD5, UADK_DEFAULT_PROPERTIES, ++ { PROV_NAMES_MD5, UADK_DEFAULT_PROPERTIES, + uadk_md5_functions, "uadk_provider md5" }, +- { OSSL_DIGEST_NAME_SM3, UADK_DEFAULT_PROPERTIES, ++ { PROV_NAMES_SM3, UADK_DEFAULT_PROPERTIES, + uadk_sm3_functions, "uadk_provider sm3" }, +- { OSSL_DIGEST_NAME_SHA1, UADK_DEFAULT_PROPERTIES, ++ { PROV_NAMES_SHA1, UADK_DEFAULT_PROPERTIES, + uadk_sha1_functions, "uadk_provider sha1" }, + { PROV_NAMES_SHA2_224, UADK_DEFAULT_PROPERTIES, + uadk_sha224_functions, "uadk_provider sha2-224" }, +@@ -62,9 +62,9 @@ const OSSL_ALGORITHM uadk_prov_digests[] = { + uadk_sha384_functions, "uadk_provider sha2-384" }, + { PROV_NAMES_SHA2_512, UADK_DEFAULT_PROPERTIES, + uadk_sha512_functions, "uadk_provider sha2-512" }, +- { "SHA2-512/224:SHA-512/224:SHA512-224", UADK_DEFAULT_PROPERTIES, ++ { PROV_NAMES_SHA2_512_224, UADK_DEFAULT_PROPERTIES, + uadk_sha512_224_functions, "uadk_provider sha2-512-224" }, +- { "SHA2-512/256:SHA-512/256:SHA512-256", UADK_DEFAULT_PROPERTIES, ++ { PROV_NAMES_SHA2_512_256, UADK_DEFAULT_PROPERTIES, + uadk_sha512_256_functions, "uadk_provider sha2-512-256" }, + { NULL, NULL, NULL } + }; +@@ -161,7 +161,13 @@ const OSSL_ALGORITHM uadk_prov_ciphers_v3[] = { + { NULL, NULL, NULL } + }; + +-static const OSSL_ALGORITHM uadk_prov_signature[] = { ++static const OSSL_ALGORITHM uadk_prov_signature_v2[] = { ++ { "RSA", UADK_DEFAULT_PROPERTIES, ++ uadk_rsa_signature_functions, "uadk_provider rsa_signature" }, ++ { NULL, NULL, NULL } ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_signature_v3[] = { + { "RSA", UADK_DEFAULT_PROPERTIES, + uadk_rsa_signature_functions, "uadk_provider rsa_signature" }, + { "SM2", UADK_DEFAULT_PROPERTIES, +@@ -171,7 +177,14 @@ static const OSSL_ALGORITHM uadk_prov_signature[] = { + { NULL, NULL, NULL } + }; + +-static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { ++static const OSSL_ALGORITHM uadk_prov_keymgmt_v2[] = { ++ { "RSA", UADK_DEFAULT_PROPERTIES, ++ uadk_rsa_keymgmt_functions, "uadk RSA Keymgmt implementation." }, ++ { "DH", UADK_DEFAULT_PROPERTIES, uadk_dh_keymgmt_functions }, ++ { NULL, NULL, NULL } ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_keymgmt_v3[] = { + { "RSA", UADK_DEFAULT_PROPERTIES, + uadk_rsa_keymgmt_functions, "uadk RSA Keymgmt implementation." }, + { "DH", UADK_DEFAULT_PROPERTIES, uadk_dh_keymgmt_functions }, +@@ -186,7 +199,13 @@ static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { + { NULL, NULL, NULL } + }; + +-static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { ++static const OSSL_ALGORITHM uadk_prov_asym_cipher_v2[] = { ++ { "RSA", UADK_DEFAULT_PROPERTIES, ++ uadk_rsa_asym_cipher_functions, "uadk RSA asym cipher implementation." }, ++ { NULL, NULL, NULL } ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_asym_cipher_v3[] = { + { "RSA", UADK_DEFAULT_PROPERTIES, + uadk_rsa_asym_cipher_functions, "uadk RSA asym cipher implementation." }, + { "SM2", UADK_DEFAULT_PROPERTIES, +@@ -194,7 +213,13 @@ static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { + { NULL, NULL, NULL } + }; + +-static const OSSL_ALGORITHM uadk_prov_keyexch[] = { ++static const OSSL_ALGORITHM uadk_prov_keyexch_v2[] = { ++ { "DH", UADK_DEFAULT_PROPERTIES, ++ uadk_dh_keyexch_functions, "UADK DH keyexch implementation"}, ++ { NULL, NULL, NULL } ++}; ++ ++static const OSSL_ALGORITHM uadk_prov_keyexch_v3[] = { + { "DH", UADK_DEFAULT_PROPERTIES, + uadk_dh_keyexch_functions, "UADK DH keyexch implementation"}, + { "ECDH", UADK_DEFAULT_PROPERTIES, +@@ -216,8 +241,8 @@ static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, + if (__atomic_compare_exchange_n(&prov_init, &(int){0}, 1, false, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST)) { + libctx = prov_libctx_of(provctx); +- prov = OSSL_PROVIDER_load(libctx, "default"); +- if (!prov) { ++ default_prov = OSSL_PROVIDER_load(libctx, "default"); ++ if (!default_prov) { + fprintf(stderr, "failed to load default provider\n"); + return NULL; + } +@@ -234,31 +259,59 @@ static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, + (void)RAND_set_DRBG_type(libctx, NULL, "provider=default", NULL, NULL); + } + +- *no_cache = 0; ++ if (no_cache) ++ *no_cache = 0; ++ + switch (operation_id) { + case OSSL_OP_DIGEST: ++ ver = uadk_prov_digest_version(); ++ if (!ver && uadk_get_sw_offload_state()) ++ break; + return uadk_prov_digests; + case OSSL_OP_CIPHER: + ver = uadk_prov_cipher_version(); +- if (ver == HW_SEC_V3) ++ if (!ver && uadk_get_sw_offload_state()) ++ break; ++ else if (ver == HW_SEC_V3) + return uadk_prov_ciphers_v3; + return uadk_prov_ciphers_v2; + case OSSL_OP_SIGNATURE: + uadk_prov_signature_alg(); +- return uadk_prov_signature; ++ ver = uadk_prov_pkey_version(); ++ if (!ver && uadk_get_sw_offload_state()) ++ break; ++ else if (ver == HW_PKEY_V3) ++ return uadk_prov_signature_v3; ++ return uadk_prov_signature_v2; + case OSSL_OP_KEYMGMT: + uadk_prov_keymgmt_alg(); +- return uadk_prov_keymgmt; ++ ver = uadk_prov_pkey_version(); ++ if (!ver && uadk_get_sw_offload_state()) ++ break; ++ else if (ver == HW_PKEY_V3) ++ return uadk_prov_keymgmt_v3; ++ return uadk_prov_keymgmt_v2; + case OSSL_OP_ASYM_CIPHER: + uadk_prov_asym_cipher_alg(); +- return uadk_prov_asym_cipher; ++ ver = uadk_prov_pkey_version(); ++ if (!ver && uadk_get_sw_offload_state()) ++ break; ++ else if (ver == HW_PKEY_V3) ++ return uadk_prov_asym_cipher_v3; ++ return uadk_prov_asym_cipher_v2; + case OSSL_OP_KEYEXCH: + uadk_prov_keyexch_alg(); +- return uadk_prov_keyexch; +- case OSSL_OP_STORE: +- return prov->query_operation(provctx, operation_id, no_cache); ++ ver = uadk_prov_pkey_version(); ++ if (!ver && uadk_get_sw_offload_state()) ++ break; ++ else if (ver == HW_PKEY_V3) ++ return uadk_prov_keyexch_v3; ++ return uadk_prov_keyexch_v2; ++ default: ++ break; + } +- return NULL; ++ ++ return OSSL_PROVIDER_query_operation(default_prov, operation_id, no_cache); + } + + static void uadk_teardown(void *provctx) +@@ -276,36 +329,60 @@ static void uadk_teardown(void *provctx) + uadk_prov_destroy_rsa(); + uadk_prov_ecc_uninit(); + uadk_prov_dh_uninit(); +- OSSL_PROVIDER_unload(prov); + async_module_uninit(); ++ if (default_prov) { ++ OSSL_PROVIDER_unload(default_prov); ++ default_prov = NULL; ++ } ++} ++ ++static int uadk_get_params(OSSL_PARAM params[]) ++{ ++ return UADK_P_SUCCESS; + } + + static const OSSL_DISPATCH uadk_dispatch_table[] = { + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))uadk_query }, + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))uadk_teardown }, ++ { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))uadk_get_params }, + { 0, NULL } + }; + ++int uadk_get_sw_offload_state(void) ++{ ++ return enable_sw_offload; ++} ++ ++/* enable = 0 means disable sw offload, enable = 1 means enable sw offload */ ++void uadk_set_sw_offload_state(int enable) ++{ ++ enable_sw_offload = enable; ++} ++ + int uadk_get_params_from_core(const OSSL_CORE_HANDLE *handle) + { + OSSL_PARAM core_params[2], *p = core_params; + ++ if (handle == NULL) { ++ fprintf(stderr, "invalid: OSSL_CORE_HANDLE is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ + *p++ = OSSL_PARAM_construct_utf8_ptr( + "enable_sw_offload", + (char **)&uadk_params.enable_sw_offload, + 0); +- + *p = OSSL_PARAM_construct_end(); + + if (!c_get_params(handle, core_params)) { + fprintf(stderr, "WARN: UADK get parameters from core is failed.\n"); +- return 0; ++ return UADK_P_FAIL; + } + + if (uadk_params.enable_sw_offload) +- enable_sw_offload = atoi(uadk_params.enable_sw_offload); ++ uadk_set_sw_offload_state(atoi(uadk_params.enable_sw_offload)); + +- return 1; ++ return UADK_P_SUCCESS; + } + + static void provider_init_child_at_fork_handler(void) +@@ -324,12 +401,12 @@ static int uadk_prov_ctx_set_core_bio_method(struct uadk_prov_ctx *ctx) + core_bio = ossl_bio_prov_init_bio_method(); + if (core_bio == NULL) { + fprintf(stderr, "failed to set bio from dispatch\n"); +- return 0; ++ return UADK_P_FAIL; + } + + ctx->corebiometh = core_bio; + +- return 1; ++ return UADK_P_SUCCESS; + } + + static void ossl_prov_core_from_dispatch(const OSSL_DISPATCH *fns) +@@ -363,7 +440,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + + if (oin == NULL) { + fprintf(stderr, "failed to get dispatch in\n"); +- return 0; ++ return UADK_P_FAIL; + } + + ossl_prov_bio_from_dispatch(oin); +@@ -371,12 +448,12 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + + /* get parameters from uadk_provider.cnf */ + if (!uadk_get_params_from_core(handle)) +- return 0; ++ return UADK_P_FAIL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + fprintf(stderr, "failed to alloc ctx\n"); +- return 0; ++ return UADK_P_FAIL; + } + + /* Set handle from core to get core functions */ +@@ -385,7 +462,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + + ret = uadk_prov_ctx_set_core_bio_method(ctx); + if (!ret) +- return 0; ++ return UADK_P_FAIL; + + ret = async_module_init(); + if (!ret) +@@ -395,5 +472,5 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + *provctx = (void *)ctx; + *out = uadk_dispatch_table; + +- return 1; ++ return UADK_P_SUCCESS; + } +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index ee702e1..1323cfd 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -869,7 +869,7 @@ int uadk_prov_ecc_bit_check(const EC_GROUP *group) + + fprintf(stderr, "invalid: unsupport key bits %d!\n", bits); + +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + /* Currently, disable the security checks in the default provider and uadk provider */ +@@ -906,8 +906,8 @@ int uadk_prov_ecc_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) + + curve_name = EC_curve_nid2nist(nid); + if (!curve_name) { +- fprintf(stderr, "invalid: Curve %s is not approved in FIPS mode!\n", +- curve_name); ++ fprintf(stderr, "invalid: Curve NID %d is not approved in FIPS mode!\n", ++ nid); + return UADK_P_FAIL; + } + +@@ -936,3 +936,25 @@ int uadk_prov_ecc_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) + return UADK_P_SUCCESS; + } + #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ ++ ++int uadk_prov_pkey_version(void) ++{ ++ struct uacce_dev *dev1, *dev2; ++ ++ dev1 = wd_get_accel_dev("rsa"); ++ if (!dev1) { ++ fprintf(stderr, "no pkey device available!\n"); ++ return HW_PKEY_INVALID; ++ } ++ ++ dev2 = wd_get_accel_dev("sm2"); ++ if (!dev2) { ++ free(dev1); ++ return HW_PKEY_V2; ++ } ++ ++ free(dev1); ++ free(dev2); ++ ++ return HW_PKEY_V3; ++} +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index 0f01baf..1886117 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -41,6 +41,7 @@ + #define UADK_ECC_MAX_KEY_BITS 521 + #define UADK_ECC_MAX_KEY_BYTES 66 + #define UADK_ECC_CV_PARAM_NUM 6 ++#define UADK_DO_SOFT (-0xE0) + #define UADK_P_SUCCESS 1 + #define UADK_P_FAIL 0 + #define UADK_P_INVALID (-1) +@@ -65,6 +66,9 @@ + #define TRANS_BITS_BYTES_SHIFT 3 + #define GET_MS_BYTE(n) ((n) >> 8) + #define GET_LS_BYTE(n) ((n) & 0xFF) ++#define HW_PKEY_V2 2 ++#define HW_PKEY_V3 3 ++#define HW_PKEY_INVALID 0 + + enum { + KEYMGMT_SM2 = 0x0, +@@ -400,6 +404,7 @@ typedef struct { + const char *description; + OSSL_PROVIDER *prov; + int refcnt; ++ void *lock; + + OSSL_FUNC_keyexch_newctx_fn *newctx; + OSSL_FUNC_keyexch_init_fn *init; +@@ -467,5 +472,6 @@ int uadk_prov_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + int uadk_prov_securitycheck_enabled(OSSL_LIB_CTX *ctx); + int uadk_prov_ecc_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect); ++int uadk_prov_pkey_version(void); + + #endif +-- +2.25.1 + diff --git a/0023-uadk_provider-fix-async-packet-reception-timeout-err.patch b/0023-uadk_provider-fix-async-packet-reception-timeout-err.patch new file mode 100644 index 0000000..3c3e040 --- /dev/null +++ b/0023-uadk_provider-fix-async-packet-reception-timeout-err.patch @@ -0,0 +1,219 @@ +From ee79fcaf81a3f9109481a678c3711c9568eb85bb Mon Sep 17 00:00:00 2001 +From: Qi Tao +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 23/36] uadk_provider: fix async packet reception timeout error + +Async packet reception timeout without timely failure return +can lead to issues such as software calculation failure. +First initialize the value of req.state to -1. If the value of +req.state is not 0 after async_pause_job(), it indicates +an exception in packet reception, and the function can directly +return an error. + +Signed-off-by: Qi Tao +Signed-off-by: JiangShui Yang +--- + src/uadk_prov.h | 1 + + src/uadk_prov_aead.c | 26 ++++++++------------------ + src/uadk_prov_cipher.c | 8 ++++++-- + src/uadk_prov_dh.c | 2 +- + src/uadk_prov_digest.c | 6 +++++- + src/uadk_prov_pkey.c | 2 +- + src/uadk_prov_rsa.c | 2 +- + 7 files changed, 23 insertions(+), 24 deletions(-) + +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 47bfb43..b6c236a 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -28,6 +28,7 @@ + #define UADK_DEVICE_ERROR 3 + #define HW_SEC_V2 2 + #define HW_SEC_V3 3 ++#define POLL_ERROR (-1) + + /* Copy openssl/providers/implementations/include/prov/names.h */ + #define PROV_NAMES_SHA2_224 "SHA2-224:SHA-224:SHA224:2.16.840.1.101.3.4.2.4" +diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c +index 1163328..6f33f43 100644 +--- a/src/uadk_prov_aead.c ++++ b/src/uadk_prov_aead.c +@@ -360,7 +360,7 @@ static int uadk_do_aead_sync(struct aead_priv_ctx *priv, unsigned char *out, + static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, + unsigned char *out, const unsigned char *in, size_t inlen) + { +- struct uadk_e_cb_info *cb_param; ++ struct uadk_e_cb_info cb_param; + int cnt = 0; + int ret; + +@@ -376,22 +376,16 @@ static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, + + uadk_do_aead_async_prepare(priv, out, in, inlen); + +- cb_param = malloc(sizeof(struct uadk_e_cb_info)); +- if (unlikely(!cb_param)) { +- fprintf(stderr, "failed to alloc cb_param.\n"); +- return UADK_AEAD_FAIL; +- } +- +- cb_param->op = op; +- cb_param->priv = &priv->req; ++ cb_param.op = op; ++ cb_param.priv = &priv->req; + priv->req.cb = uadk_prov_aead_cb; +- priv->req.cb_param = cb_param; ++ priv->req.cb_param = &cb_param; + priv->req.msg_state = AEAD_MSG_BLOCK; +- priv->req.state = UADK_AEAD_FAIL; ++ priv->req.state = POLL_ERROR; + + ret = async_get_free_task(&op->idx); + if (unlikely(!ret)) +- goto free_cb_param; ++ return UADK_AEAD_FAIL; + + do { + ret = wd_do_aead_async(priv->sess, &priv->req); +@@ -404,8 +398,7 @@ static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, + continue; + + async_free_poll_task(op->idx, 0); +- ret = UADK_AEAD_FAIL; +- goto free_cb_param; ++ return UADK_AEAD_FAIL; + } + } while (ret == -EBUSY); + +@@ -413,15 +406,12 @@ static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, + if (unlikely(!ret || priv->req.state)) { + fprintf(stderr, "do aead async job failed, ret: %d, state: %u!\n", + ret, priv->req.state); +- ret = UADK_AEAD_FAIL; +- goto free_cb_param; ++ return UADK_AEAD_FAIL; + } + + if (priv->req.assoc_bytes) + memcpy(out, priv->req.dst + priv->req.assoc_bytes, inlen); + +-free_cb_param: +- free(cb_param); + return ret; + } + +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index ff1b2ee..f4c73e5 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -418,12 +418,15 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, + static void async_cb(struct wd_cipher_req *req, void *data) + { + struct uadk_e_cb_info *cipher_cb_param; ++ struct wd_cipher_req *req_origin; + struct async_op *op; + + if (!req || !req->cb_param) + return; + + cipher_cb_param = req->cb_param; ++ req_origin = cipher_cb_param->priv; ++ req_origin->state = req->state; + op = cipher_cb_param->op; + if (op && op->job && !op->done) { + op->done = 1; +@@ -454,9 +457,10 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o + } + + cb_param.op = op; +- cb_param.priv = priv; ++ cb_param.priv = &priv->req; + priv->req.cb = (void *)async_cb; + priv->req.cb_param = &cb_param; ++ priv->req.state = POLL_ERROR; + ret = async_get_free_task(&idx); + if (!ret) + return UADK_P_FAIL; +@@ -472,7 +476,7 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o + } while (ret == -EBUSY); + + ret = async_pause_job(priv, op, ASYNC_TASK_CIPHER); +- if (!ret) ++ if (!ret || priv->req.state) + return UADK_P_FAIL; + + return UADK_P_SUCCESS; +diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c +index f3724ac..f6262d4 100644 +--- a/src/uadk_prov_dh.c ++++ b/src/uadk_prov_dh.c +@@ -845,7 +845,7 @@ static int uadk_prov_dh_do_crypto(struct uadk_dh_sess *dh_sess) + cb_param.priv = &dh_sess->req; + dh_sess->req.cb = uadk_prov_dh_cb; + dh_sess->req.cb_param = &cb_param; +- dh_sess->req.status = -1; ++ dh_sess->req.status = POLL_ERROR; + ret = async_get_free_task(&idx); + if (!ret) + goto err; +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index 921c3db..d6af557 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -497,12 +497,15 @@ soft_update: + static void uadk_async_cb(struct wd_digest_req *req, void *data) + { + struct uadk_e_cb_info *digest_cb_param; ++ struct wd_digest_req *req_origin; + struct async_op *op; + + if (!req || !req->cb_param) + return; + + digest_cb_param = req->cb_param; ++ req_origin = digest_cb_param->priv; ++ req_origin->state = req->state; + op = digest_cb_param->op; + if (op && op->job && !op->done) { + op->done = 1; +@@ -540,9 +543,10 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o + } + + cb_param.op = op; +- cb_param.priv = priv; ++ cb_param.priv = &priv->req; + priv->req.cb = (void *)uadk_async_cb; + priv->req.cb_param = &cb_param; ++ priv->req.state = POLL_ERROR; + + ret = async_get_free_task(&idx); + if (!ret) +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index 1323cfd..ca853ae 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -390,7 +390,7 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) + cb_param.priv = req; + req->cb = uadk_prov_ecc_cb; + req->cb_param = &cb_param; +- req->status = -1; ++ req->status = POLL_ERROR; + + ret = async_get_free_task(&idx); + if (ret == 0) +diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c +index eac4e46..8f7d734 100644 +--- a/src/uadk_prov_rsa.c ++++ b/src/uadk_prov_rsa.c +@@ -1297,7 +1297,7 @@ static int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) + 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; ++ rsa_sess->req.status = POLL_ERROR; + + ret = async_get_free_task(&idx); + if (ret == 0) +-- +2.25.1 + diff --git a/0024-uadk_provider-add-hmac-alg-for-uadk_provider-in-open.patch b/0024-uadk_provider-add-hmac-alg-for-uadk_provider-in-open.patch new file mode 100644 index 0000000..31979ab --- /dev/null +++ b/0024-uadk_provider-add-hmac-alg-for-uadk_provider-in-open.patch @@ -0,0 +1,987 @@ +From eaeaca8451fdee71acfca35dd2ace7a06772e755 Mon Sep 17 00:00:00 2001 +From: Chenghai Huang +Date: Wed, 23 Apr 2025 10:19:47 +0800 +Subject: [PATCH 24/36] uadk_provider: add hmac alg for uadk_provider in + openssl3.0 + +Add the HMAC mode for the following digest algorithm: +md5 sm3 sha1 sha224 sha256 sha384 sha512 sha512_224 sha512_256 + +Signed-off-by: Chenghai Huang +Signed-off-by: JiangShui Yang +--- + src/Makefile.am | 3 +- + src/uadk_async.h | 1 + + src/uadk_prov.h | 7 + + src/uadk_prov_digest.c | 6 +- + src/uadk_prov_hmac.c | 837 +++++++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 9 + + 6 files changed, 859 insertions(+), 4 deletions(-) + create mode 100644 src/uadk_prov_hmac.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index c1863e1..b262319 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -67,7 +67,8 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_prov_pkey.c uadk_prov_sm2.c \ + uadk_prov_ffc.c uadk_prov_aead.c \ + uadk_prov_ec_kmgmt.c uadk_prov_ecdh_exch.c \ +- uadk_prov_ecx.c uadk_prov_ecdsa.c ++ uadk_prov_ecx.c uadk_prov_ecdsa.c \ ++ uadk_prov_hmac.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_async.h b/src/uadk_async.h +index dcb94d3..8de3c3c 100644 +--- a/src/uadk_async.h ++++ b/src/uadk_async.h +@@ -44,6 +44,7 @@ typedef int (*async_recv_t)(void *ctx); + enum task_type { + ASYNC_TASK_CIPHER = 0x1, + ASYNC_TASK_DIGEST, ++ ASYNC_TASK_HMAC, + ASYNC_TASK_AEAD, + ASYNC_TASK_RSA, + ASYNC_TASK_DH, +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index b6c236a..ac83ee5 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -31,10 +31,15 @@ + #define POLL_ERROR (-1) + + /* Copy openssl/providers/implementations/include/prov/names.h */ ++#define PROV_NAMES_MD5 "MD5:SSL3-MD5:1.2.840.113549.2.5" ++#define PROV_NAMES_SM3 "SM3:1.2.156.10197.1.401" ++#define PROV_NAMES_SHA1 "SHA1:SHA-1:SSL3-SHA1:1.3.14.3.2.26" + #define PROV_NAMES_SHA2_224 "SHA2-224:SHA-224:SHA224:2.16.840.1.101.3.4.2.4" + #define PROV_NAMES_SHA2_256 "SHA2-256:SHA-256:SHA256:2.16.840.1.101.3.4.2.1" + #define PROV_NAMES_SHA2_384 "SHA2-384:SHA-384:SHA384:2.16.840.1.101.3.4.2.2" + #define PROV_NAMES_SHA2_512 "SHA2-512:SHA-512:SHA512:2.16.840.1.101.3.4.2.3" ++#define PROV_NAMES_SHA2_512_224 "SHA2-512/224:SHA-512/224:SHA512-224:2.16.840.1.101.3.4.2.5" ++#define PROV_NAMES_SHA2_512_256 "SHA2-512/256:SHA-512/256:SHA512-256:2.16.840.1.101.3.4.2.6" + + typedef int CRYPTO_REF_COUNT; + +@@ -137,6 +142,7 @@ extern const OSSL_DISPATCH uadk_sha384_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sha512_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sha512_224_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sha512_256_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_hmac_functions[FUNC_MAX_NUM]; + + extern const OSSL_DISPATCH uadk_aes_128_cbc_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_aes_192_cbc_functions[FUNC_MAX_NUM]; +@@ -192,6 +198,7 @@ extern const OSSL_DISPATCH uadk_x25519_keyexch_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_ecdsa_signature_functions[FUNC_MAX_NUM]; + + void uadk_prov_destroy_digest(void); ++void uadk_prov_destroy_hmac(void); + void uadk_prov_destroy_cipher(void); + void uadk_prov_destroy_aead(void); + void uadk_prov_destroy_rsa(void); +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index d6af557..562e786 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -309,8 +309,8 @@ static int uadk_prov_digest_dev_init(struct digest_priv_ctx *priv) + ctx_set_num.async_ctx_num = UADK_DIGEST_DEF_CTXS; + + ret = wd_digest_init2_(priv->alg_name, TASK_MIX, SCHED_POLICY_RR, &cparams); +- if (unlikely(ret)) { +- fprintf(stderr, "uadk failed to initialize digest.\n"); ++ if (unlikely(ret && ret != -WD_EEXIST)) { ++ fprintf(stderr, "uadk failed to initialize digest dev, ret = %d\n", ret); + goto free_nodemask; + } + ret = UADK_DIGEST_SUCCESS; +@@ -568,7 +568,7 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o + } while (ret == -EBUSY); + + ret = async_pause_job(priv, op, ASYNC_TASK_DIGEST); +- if (!ret) ++ if (!ret || priv->req.state) + return UADK_DIGEST_FAIL; + + return UADK_DIGEST_SUCCESS; +diff --git a/src/uadk_prov_hmac.c b/src/uadk_prov_hmac.c +new file mode 100644 +index 0000000..752a326 +--- /dev/null ++++ b/src/uadk_prov_hmac.c +@@ -0,0 +1,837 @@ ++// SPDX-License-Identifier: Apache-2.0 ++/* ++ * 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.h" ++#include "uadk_async.h" ++#include "uadk_prov.h" ++#include "uadk_utils.h" ++ ++#define UADK_HMAC_SUCCESS 1 ++#define UADK_HMAC_FAIL 0 ++ ++/* The max BD data length is 16M-512B */ ++#define BUF_LEN 0xFFFE00 ++ ++#define MAX_DIGEST_LENGTH 64 ++#define MAX_KEY_LEN 144 ++#define HMAC_BLOCK_SIZE (512 * 1024) ++#define ALG_NAME_SIZE 128 ++ ++#define KEY_4BYTE_ALIGN(keylen) ((keylen + 3) & ~3) ++ ++#define UADK_DIGEST_DEF_CTXS 1 ++#define UADK_DIGEST_OP_NUM 1 ++ ++enum sec_digest_state { ++ SEC_DIGEST_INIT, ++ SEC_DIGEST_FIRST_UPDATING, ++ SEC_DIGEST_DOING, ++ SEC_DIGEST_FINAL ++}; ++ ++struct hmac_prov { ++ int pid; ++}; ++ ++static struct hmac_prov hprov; ++static pthread_mutex_t hmac_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++struct hmac_priv_ctx { ++ __u32 alg_id; ++ __u32 state; ++ size_t out_len; ++ size_t blk_size; ++ size_t keylen; ++ size_t last_update_bufflen; ++ size_t total_data_len; ++ OSSL_LIB_CTX *libctx; ++ handle_t sess; ++ struct wd_digest_sess_setup setup; ++ struct wd_digest_req req; ++ unsigned char *data; ++ unsigned char key[MAX_KEY_LEN]; ++ unsigned char out[MAX_DIGEST_LENGTH]; ++ char alg_name[ALG_NAME_SIZE]; ++ bool is_stream_copy; ++}; ++ ++struct hmac_info { ++ enum wd_digest_type alg; ++ __u32 alg_id; ++ size_t out_len; ++ size_t blk_size; ++ const char ossl_alg_name[ALG_NAME_SIZE]; ++}; ++ ++static struct hmac_info hmac_info_table[] = { ++ {WD_DIGEST_MD5, NID_md5, 16, 64, PROV_NAMES_MD5}, ++ {WD_DIGEST_SM3, NID_sm3, 32, 64, PROV_NAMES_SM3}, ++ {WD_DIGEST_SHA1, NID_sha1, 20, 64, PROV_NAMES_SHA1}, ++ {WD_DIGEST_SHA224, NID_sha224, 28, 64, PROV_NAMES_SHA2_224}, ++ {WD_DIGEST_SHA256, NID_sha256, 32, 64, PROV_NAMES_SHA2_256}, ++ {WD_DIGEST_SHA384, NID_sha384, 48, 64, PROV_NAMES_SHA2_384}, ++ {WD_DIGEST_SHA512, NID_sha512, 64, 128, PROV_NAMES_SHA2_512}, ++ {WD_DIGEST_SHA512_224, NID_sha512_224, 28, 128, PROV_NAMES_SHA2_512_224}, ++ {WD_DIGEST_SHA512_256, NID_sha512_256, 32, 128, PROV_NAMES_SHA2_512_256} ++}; ++ ++static OSSL_FUNC_mac_newctx_fn uadk_prov_hmac_newctx; ++static OSSL_FUNC_mac_dupctx_fn uadk_prov_hmac_dupctx; ++static OSSL_FUNC_mac_freectx_fn uadk_prov_hmac_freectx; ++static OSSL_FUNC_mac_init_fn uadk_prov_hmac_init; ++static OSSL_FUNC_mac_update_fn uadk_prov_hmac_update; ++static OSSL_FUNC_mac_final_fn uadk_prov_hmac_final; ++static OSSL_FUNC_mac_gettable_ctx_params_fn ++ uadk_prov_hmac_gettable_ctx_params; ++static OSSL_FUNC_mac_get_ctx_params_fn uadk_prov_hmac_get_ctx_params; ++static OSSL_FUNC_mac_settable_ctx_params_fn ++ uadk_prov_hmac_settable_ctx_params; ++static OSSL_FUNC_mac_set_ctx_params_fn uadk_prov_hmac_set_ctx_params; ++ ++static int uadk_hmac_poll(void *ctx) ++{ ++ __u64 rx_cnt = 0; ++ __u32 recv = 0; ++ /* Poll one packet currently */ ++ __u32 expt = 1; ++ int ret; ++ ++ do { ++ ret = wd_digest_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 void uadk_fill_mac_buffer_len(struct hmac_priv_ctx *priv, bool is_end) ++{ ++ /* Sha224 and Sha384 and Sha512-XXX need full length mac buffer as doing long hash */ ++ switch (priv->alg_id) { ++ case NID_sha224: ++ priv->req.out_bytes = is_end ? WD_DIGEST_SHA224_LEN : WD_DIGEST_SHA224_FULL_LEN; ++ break; ++ case NID_sha384: ++ priv->req.out_bytes = is_end ? WD_DIGEST_SHA384_LEN : WD_DIGEST_SHA384_FULL_LEN; ++ break; ++ case NID_sha512_224: ++ priv->req.out_bytes = is_end ? ++ WD_DIGEST_SHA512_224_LEN : WD_DIGEST_SHA512_224_FULL_LEN; ++ break; ++ case NID_sha512_256: ++ priv->req.out_bytes = is_end ? ++ WD_DIGEST_SHA512_256_LEN : WD_DIGEST_SHA512_256_FULL_LEN; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void uadk_digest_set_msg_state(struct hmac_priv_ctx *priv, bool is_end) ++{ ++ if (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 uadk_get_hmac_info(struct hmac_priv_ctx *priv) ++{ ++ int digest_counts = ARRAY_SIZE(hmac_info_table); ++ int i; ++ ++ for (i = 0; i < digest_counts; i++) { ++ if (strstr(hmac_info_table[i].ossl_alg_name, priv->alg_name)) { ++ priv->alg_id = hmac_info_table[i].alg_id; ++ priv->out_len = hmac_info_table[i].out_len; ++ priv->blk_size = hmac_info_table[i].blk_size; ++ priv->setup.alg = hmac_info_table[i].alg; ++ priv->setup.mode = WD_DIGEST_HMAC; ++ priv->req.out_buf_bytes = MAX_DIGEST_LENGTH; ++ priv->req.out_bytes = hmac_info_table[i].out_len; ++ ++ return UADK_HMAC_SUCCESS; ++ } ++ } ++ ++ fprintf(stderr, "failed to setup the private ctx, algname = %s.\n", priv->alg_name); ++ return UADK_HMAC_FAIL; ++} ++ ++static const char *get_uadk_alg_name(__u32 alg_id) ++{ ++ switch (alg_id) { ++ case NID_md5: ++ return "md5"; ++ case NID_sm3: ++ return "sm3"; ++ case NID_sha1: ++ return "sha1"; ++ case NID_sha224: ++ return "sha224"; ++ case NID_sha256: ++ return "sha256"; ++ case NID_sha384: ++ return "sha384"; ++ case NID_sha512: ++ return "sha512"; ++ case NID_sha512_224: ++ return "sha512-224"; ++ case NID_sha512_256: ++ return "sha512-256"; ++ default: ++ break; ++ } ++ ++ fprintf(stderr, "failed to find alg, nid = %u.\n", alg_id); ++ return NULL; ++} ++ ++static void uadk_hmac_mutex_infork(void) ++{ ++ /* Release the replication lock of the child process */ ++ pthread_mutex_unlock(&hmac_mutex); ++} ++ ++static int uadk_prov_hmac_dev_init(struct hmac_priv_ctx *priv) ++{ ++ struct wd_ctx_params cparams = {0}; ++ struct wd_ctx_nums ctx_set_num; ++ int ret = UADK_HMAC_SUCCESS; ++ const char *alg_name; ++ ++ pthread_atfork(NULL, NULL, uadk_hmac_mutex_infork); ++ pthread_mutex_lock(&hmac_mutex); ++ if (hprov.pid == getpid()) ++ goto mutex_unlock; ++ ++ alg_name = get_uadk_alg_name(priv->alg_id); ++ if (!alg_name) { ++ ret = UADK_HMAC_FAIL; ++ goto mutex_unlock; ++ } ++ ++ cparams.op_type_num = UADK_DIGEST_OP_NUM; ++ cparams.ctx_set_num = &ctx_set_num; ++ cparams.bmp = numa_allocate_nodemask(); ++ if (!cparams.bmp) { ++ ret = UADK_HMAC_FAIL; ++ fprintf(stderr, "failed to create nodemask!\n"); ++ goto mutex_unlock; ++ } ++ ++ numa_bitmask_setall(cparams.bmp); ++ ++ ctx_set_num.sync_ctx_num = UADK_DIGEST_DEF_CTXS; ++ ctx_set_num.async_ctx_num = UADK_DIGEST_DEF_CTXS; ++ ++ ret = wd_digest_init2_((char *)alg_name, TASK_MIX, SCHED_POLICY_RR, &cparams); ++ if (unlikely(ret && ret != -WD_EEXIST)) { ++ fprintf(stderr, "uadk failed to initialize hmac, ret = %d\n", ret); ++ goto free_nodemask; ++ } ++ ret = UADK_HMAC_SUCCESS; ++ ++ hprov.pid = getpid(); ++ async_register_poll_fn(ASYNC_TASK_HMAC, uadk_hmac_poll); ++ ++free_nodemask: ++ numa_free_nodemask(cparams.bmp); ++mutex_unlock: ++ pthread_mutex_unlock(&hmac_mutex); ++ return ret; ++} ++ ++static int uadk_prov_compute_key_hash(struct hmac_priv_ctx *priv, ++ const unsigned char *key, size_t keylen) ++{ ++ int ret = UADK_HMAC_FAIL; ++ EVP_MD_CTX *ctx = NULL; ++ EVP_MD *key_md = NULL; ++ __u32 outlen = 0; ++ ++ key_md = EVP_MD_fetch(priv->libctx, priv->alg_name, NULL); ++ if (!key_md) ++ return UADK_HMAC_FAIL; ++ ++ ctx = EVP_MD_CTX_new(); ++ if (!ctx) ++ goto free_md; ++ ++ if (!EVP_DigestInit_ex2(ctx, key_md, NULL) ++ || !EVP_DigestUpdate(ctx, key, keylen) ++ || !EVP_DigestFinal_ex(ctx, priv->key, &outlen)) ++ goto free_ctx; ++ ++ priv->keylen = outlen; ++ ret = UADK_HMAC_SUCCESS; ++ ++free_ctx: ++ EVP_MD_CTX_free(ctx); ++free_md: ++ EVP_MD_free(key_md); ++ ++ return ret; ++} ++ ++static int uadk_hmac_ctx_init(struct hmac_priv_ctx *priv) ++{ ++ struct wd_digest_sess_setup setup = {0}; ++ struct sched_params params = {0}; ++ int ret; ++ ++ ret = uadk_prov_hmac_dev_init(priv); ++ if (unlikely(ret <= 0)) ++ return UADK_HMAC_FAIL; ++ ++ /* Use the default numa parameters */ ++ params.numa_id = -1; ++ setup.sched_param = ¶ms; ++ setup.alg = priv->setup.alg; ++ setup.mode = priv->setup.mode; ++ ++ if (!priv->sess) { ++ priv->sess = wd_digest_alloc_sess(&setup); ++ if (unlikely(!priv->sess)) { ++ fprintf(stderr, "uadk failed to alloc hmac sess.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ ret = wd_digest_set_key(priv->sess, priv->key, priv->keylen); ++ if (ret) { ++ fprintf(stderr, "uadk failed to set hmac key!\n"); ++ goto free_sess; ++ } ++ } ++ ++ return UADK_HMAC_SUCCESS; ++ ++free_sess: ++ wd_digest_free_sess(priv->sess); ++ priv->sess = 0; ++ return UADK_HMAC_FAIL; ++} ++ ++static void uadk_hmac_async_cb(struct wd_digest_req *req, void *data) ++{ ++ struct uadk_e_cb_info *hmac_cb_param; ++ struct wd_digest_req *req_origin; ++ struct async_op *op; ++ ++ if (!req || !req->cb_param) ++ return; ++ ++ hmac_cb_param = req->cb_param; ++ req_origin = hmac_cb_param->priv; ++ req_origin->state = req->state; ++ op = hmac_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 uadk_do_hmac_sync(struct hmac_priv_ctx *priv) ++{ ++ int ret; ++ ++ ret = wd_do_digest_sync(priv->sess, &priv->req); ++ if (ret) { ++ fprintf(stderr, "do sec hmac sync failed.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static int uadk_do_hmac_async(struct hmac_priv_ctx *priv, struct async_op *op) ++{ ++ struct uadk_e_cb_info cb_param; ++ int idx, ret; ++ int cnt = 0; ++ ++ cb_param.op = op; ++ cb_param.priv = &priv->req; ++ priv->req.cb = (void *)uadk_hmac_async_cb; ++ priv->req.cb_param = &cb_param; ++ priv->req.state = POLL_ERROR; ++ ++ ret = async_get_free_task(&idx); ++ if (!ret) ++ return UADK_HMAC_FAIL; ++ ++ op->idx = idx; ++ do { ++ ret = wd_do_digest_async(priv->sess, &priv->req); ++ if (ret < 0 && ret != -EBUSY) { ++ fprintf(stderr, "do sec digest async failed.\n"); ++ goto free_poll_task; ++ } ++ ++ if (unlikely(++cnt > ENGINE_SEND_MAX_CNT)) { ++ fprintf(stderr, "do digest async operation timeout.\n"); ++ goto free_poll_task; ++ } ++ } while (ret == -EBUSY); ++ ++ ret = async_pause_job(priv, op, ASYNC_TASK_HMAC); ++ if (!ret || priv->req.state) ++ return UADK_HMAC_FAIL; ++ ++ return UADK_HMAC_SUCCESS; ++ ++free_poll_task: ++ async_free_poll_task(op->idx, 0); ++ return UADK_HMAC_FAIL; ++} ++ ++static int uadk_hmac_update_inner(struct hmac_priv_ctx *priv, const void *data, size_t data_len) ++{ ++ unsigned char *input_data = (unsigned char *)data; ++ size_t remain_len = data_len; ++ size_t processing_len; ++ int ret; ++ ++ ret = uadk_hmac_ctx_init(priv); ++ if (ret != UADK_HMAC_SUCCESS) ++ return UADK_HMAC_FAIL; ++ ++ uadk_digest_set_msg_state(priv, false); ++ uadk_fill_mac_buffer_len(priv, false); ++ ++ do { ++ /* ++ * If there is data in the buffer, it will be filled and processed. Otherwise, it ++ * will be processed according to the UADK package len(16M-512Byte). Finally the ++ * remaining data less than the size of the buffer will be stored in the buffer. ++ */ ++ if (priv->last_update_bufflen != 0) { ++ processing_len = HMAC_BLOCK_SIZE - priv->last_update_bufflen; ++ uadk_memcpy(priv->data + priv->last_update_bufflen, input_data, ++ processing_len); ++ ++ priv->req.in_bytes = HMAC_BLOCK_SIZE; ++ priv->req.in = priv->data; ++ priv->last_update_bufflen = 0; ++ } else { ++ if (remain_len > BUF_LEN) ++ processing_len = BUF_LEN; ++ else ++ processing_len = remain_len - (remain_len % HMAC_BLOCK_SIZE); ++ ++ priv->req.in_bytes = processing_len; ++ priv->req.in = input_data; ++ } ++ ++ if (priv->state == SEC_DIGEST_INIT) ++ priv->state = SEC_DIGEST_FIRST_UPDATING; ++ else if (priv->state == SEC_DIGEST_FIRST_UPDATING) ++ priv->state = SEC_DIGEST_DOING; ++ ++ priv->req.out = priv->out; ++ ++ ret = uadk_do_hmac_sync(priv); ++ if (!ret) { ++ fprintf(stderr, "do sec digest update failed.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ remain_len -= processing_len; ++ input_data += processing_len; ++ } while (remain_len > HMAC_BLOCK_SIZE); ++ ++ priv->last_update_bufflen = remain_len; ++ uadk_memcpy(priv->data, input_data, priv->last_update_bufflen); ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static int uadk_hmac_update(struct hmac_priv_ctx *priv, const void *data, size_t data_len) ++{ ++ if (!priv->data) { ++ fprintf(stderr, "failed to do digest update, data in CTX is NULL.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ priv->total_data_len += data_len; ++ ++ if (priv->last_update_bufflen + data_len <= HMAC_BLOCK_SIZE) { ++ uadk_memcpy(priv->data + priv->last_update_bufflen, data, data_len); ++ priv->last_update_bufflen += data_len; ++ return UADK_HMAC_SUCCESS; ++ } ++ ++ return uadk_hmac_update_inner(priv, data, data_len); ++} ++ ++static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) ++{ ++ struct async_op op; ++ int ret; ++ ++ if (!priv->data) { ++ fprintf(stderr, "failed to do digest final, data in CTX is NULL.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ ret = uadk_hmac_ctx_init(priv); ++ if (!ret) ++ return UADK_HMAC_FAIL; ++ ++ priv->req.in = priv->data; ++ priv->req.out = priv->state == SEC_DIGEST_INIT ? digest : priv->out; ++ priv->req.in_bytes = priv->last_update_bufflen; ++ ++ uadk_digest_set_msg_state(priv, true); ++ uadk_fill_mac_buffer_len(priv, true); ++ ++ ret = async_setup_async_event_notification(&op); ++ if (unlikely(!ret)) { ++ fprintf(stderr, "failed to setup async event notification.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ if (!op.job) ++ ret = uadk_do_hmac_sync(priv); ++ else ++ ret = uadk_do_hmac_async(priv, &op); ++ ++ if (!ret) ++ goto clear; ++ ++ if (priv->state != SEC_DIGEST_INIT) ++ memcpy(digest, priv->req.out, priv->req.out_bytes); ++ ++ return UADK_HMAC_SUCCESS; ++ ++clear: ++ async_clear_async_event_notification(); ++ return ret; ++} ++ ++static void *uadk_prov_hmac_dupctx(void *hctx) ++{ ++ struct hmac_priv_ctx *dst_ctx, *src_ctx; ++ ++ if (!hctx) ++ return NULL; ++ ++ src_ctx = (struct hmac_priv_ctx *)hctx; ++ dst_ctx = OPENSSL_memdup(src_ctx, sizeof(struct hmac_priv_ctx)); ++ if (!dst_ctx) ++ return NULL; ++ ++ /* ++ * When a copy is performed during digest execution, ++ * the status in the sess needs to be synchronized. ++ */ ++ if (dst_ctx->sess && dst_ctx->state != SEC_DIGEST_INIT) { ++ dst_ctx->is_stream_copy = true; ++ /* ++ * Length that the hardware has processed should be equal to ++ * total input data length minus software cache data length. ++ */ ++ dst_ctx->req.long_data_len = dst_ctx->total_data_len - ++ dst_ctx->last_update_bufflen; ++ } ++ ++ dst_ctx->sess = 0; ++ dst_ctx->data = OPENSSL_memdup(src_ctx->data, HMAC_BLOCK_SIZE); ++ if (!dst_ctx->data) ++ goto free_ctx; ++ ++ return dst_ctx; ++ ++free_data: ++ OPENSSL_clear_free(dst_ctx->data, HMAC_BLOCK_SIZE); ++free_ctx: ++ OPENSSL_clear_free(dst_ctx, sizeof(*dst_ctx)); ++ return NULL; ++} ++ ++static void uadk_hmac_cleanup(struct hmac_priv_ctx *priv) ++{ ++ if (priv->sess) ++ wd_digest_free_sess(priv->sess); ++ ++ if (priv->data) ++ OPENSSL_clear_free(priv->data, HMAC_BLOCK_SIZE); ++} ++ ++static void uadk_prov_hmac_freectx(void *hctx) ++{ ++ struct hmac_priv_ctx *priv = (struct hmac_priv_ctx *)hctx; ++ ++ if (!hctx) { ++ fprintf(stderr, "the CTX to be free is NULL.\n"); ++ return; ++ } ++ ++ uadk_hmac_cleanup(priv); ++ OPENSSL_clear_free(priv, sizeof(*priv)); ++} ++ ++static int uadk_prov_hmac_setkey(struct hmac_priv_ctx *priv, ++ const unsigned char *key, size_t keylen) ++{ ++ size_t padding; ++ ++ memset(priv->key, 0, MAX_KEY_LEN); ++ ++ if (keylen > priv->blk_size) ++ return uadk_prov_compute_key_hash(priv, key, keylen); ++ ++ padding = KEY_4BYTE_ALIGN(keylen); ++ memcpy(priv->key, key, keylen); ++ priv->keylen = padding; ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static int uadk_prov_hmac_init(void *hctx, const unsigned char *key, ++ size_t keylen, const OSSL_PARAM params[]) ++{ ++ struct hmac_priv_ctx *priv = (struct hmac_priv_ctx *)hctx; ++ int ret; ++ ++ if (!hctx) { ++ fprintf(stderr, "CTX is NULL.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ ret = uadk_prov_hmac_set_ctx_params(hctx, params); ++ if (unlikely(!ret)) ++ return UADK_HMAC_FAIL; ++ ++ ret = uadk_get_hmac_info(priv); ++ if (unlikely(!ret)) ++ return UADK_HMAC_FAIL; ++ ++ if (key) { ++ ret = uadk_prov_hmac_setkey(priv, key, keylen); ++ if (!ret) ++ return UADK_HMAC_FAIL; ++ } ++ ++ ret = uadk_prov_hmac_dev_init(priv); ++ if (unlikely(ret <= 0)) ++ return UADK_HMAC_FAIL; ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static int uadk_prov_hmac_update(void *hctx, const unsigned char *data, size_t datalen) ++{ ++ if (!hctx || !data) { ++ fprintf(stderr, "CTX or input data is NULL.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ return uadk_hmac_update((struct hmac_priv_ctx *)hctx, data, datalen); ++} ++ ++/* ++ * Note: ++ * The I parameter contains a pointer to the provider side context. ++ * The digest should be written to I<*out> and the length of the digest to I<*outl>. ++ * The digest should not exceed I bytes. ++ */ ++static int uadk_prov_hmac_final(void *hctx, unsigned char *out, size_t *outl, ++ size_t outsize) ++{ ++ struct hmac_priv_ctx *priv = (struct hmac_priv_ctx *)hctx; ++ int ret; ++ ++ if (!hctx) { ++ fprintf(stderr, "hmac CTX or output data is NULL.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ if (out && outsize > 0) { ++ ret = uadk_hmac_final(priv, out); ++ if (!ret) ++ return ret; ++ } ++ ++ if (outl) ++ *outl = priv->out_len; ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++void uadk_prov_destroy_hmac(void) ++{ ++ pthread_mutex_lock(&hmac_mutex); ++ if (hprov.pid == getpid()) { ++ wd_digest_uninit2(); ++ hprov.pid = 0; ++ } ++ pthread_mutex_unlock(&hmac_mutex); ++} ++ ++static const OSSL_PARAM uadk_prov_hmac_known_gettable_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), ++ OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_prov_hmac_gettable_ctx_params(ossl_unused void *ctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_hmac_known_gettable_ctx_params; ++} ++ ++static int uadk_prov_hmac_get_ctx_params(void *hctx, OSSL_PARAM params[]) ++{ ++ struct hmac_priv_ctx *priv = (struct hmac_priv_ctx *)hctx; ++ OSSL_PARAM *p = NULL; ++ ++ if (!hctx) ++ return UADK_HMAC_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE); ++ if (p && !OSSL_PARAM_set_size_t(p, priv->out_len)) ++ return UADK_HMAC_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE); ++ if (p && !OSSL_PARAM_set_size_t(p, priv->blk_size)) ++ return UADK_HMAC_FAIL; ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { ++ OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_prov_hmac_settable_ctx_params(ossl_unused void *ctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_settable_ctx_params; ++} ++ ++static void uadk_hmac_name_uppercase(char *str) ++{ ++ size_t length = strlen(str); ++ ++ for (size_t i = 0; i < length; i++) ++ str[i] = toupper(str[i]); ++} ++ ++/* ++ * ALL parameters should be set before init(). ++ */ ++static int uadk_prov_hmac_set_ctx_params(void *hctx, const OSSL_PARAM params[]) ++{ ++ struct hmac_priv_ctx *priv = (struct hmac_priv_ctx *)hctx; ++ const OSSL_PARAM *p; ++ int ret; ++ ++ if (!params || !params->key) ++ return UADK_HMAC_SUCCESS; ++ ++ if (!hctx) ++ return UADK_HMAC_FAIL; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST); ++ if (p) { ++ if (p->data_type != OSSL_PARAM_UTF8_STRING || ++ strlen((char *)p->data) > ALG_NAME_SIZE - 1) ++ return UADK_HMAC_FAIL; ++ ++ /* ++ * For subsequent character string matching, no end flag is added, ++ * and the length will be within the value of ALG_NAME_SIZE. ++ */ ++ ret = snprintf(priv->alg_name, ALG_NAME_SIZE, "%s", (char *)p->data); ++ if (ret < 0) { ++ fprintf(stderr, "Invalid alg name %s.\n", (char *)p->data); ++ return UADK_HMAC_FAIL; ++ } ++ ++ uadk_hmac_name_uppercase(priv->alg_name); ++ } ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY); ++ if (p) { ++ if (p->data_type != OSSL_PARAM_OCTET_STRING) ++ return UADK_HMAC_FAIL; ++ ++ if (!uadk_prov_hmac_setkey(priv, p->data, p->data_size)) ++ return UADK_HMAC_FAIL; ++ } ++ ++ return UADK_HMAC_SUCCESS; ++} ++ ++static void *uadk_prov_hmac_newctx(void *hctx) ++{ ++ struct hmac_priv_ctx *ctx; ++ ++ ctx = OPENSSL_zalloc(sizeof(*ctx)); ++ if (!ctx) ++ return NULL; ++ ++ ctx->libctx = prov_libctx_of(hctx); ++ ++ ctx->data = OPENSSL_zalloc(HMAC_BLOCK_SIZE); ++ if (!ctx->data) { ++ OPENSSL_free(ctx); ++ return NULL; ++ } ++ ++ return ctx; ++} ++ ++const OSSL_DISPATCH uadk_hmac_functions[] = { ++ { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))uadk_prov_hmac_newctx }, ++ { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))uadk_prov_hmac_dupctx }, ++ { OSSL_FUNC_MAC_FREECTX, (void (*)(void))uadk_prov_hmac_freectx }, ++ { OSSL_FUNC_MAC_INIT, (void (*)(void))uadk_prov_hmac_init }, ++ { OSSL_FUNC_MAC_UPDATE, (void (*)(void))uadk_prov_hmac_update }, ++ { OSSL_FUNC_MAC_FINAL, (void (*)(void))uadk_prov_hmac_final }, ++ { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_prov_hmac_gettable_ctx_params }, ++ { OSSL_FUNC_MAC_GET_CTX_PARAMS, ++ (void (*)(void))uadk_prov_hmac_get_ctx_params }, ++ { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, ++ (void (*)(void))uadk_prov_hmac_settable_ctx_params }, ++ { OSSL_FUNC_MAC_SET_CTX_PARAMS, ++ (void (*)(void))uadk_prov_hmac_set_ctx_params }, ++ { 0, NULL } ++}; +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index b5588f2..c29500b 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -69,6 +69,12 @@ const OSSL_ALGORITHM uadk_prov_digests[] = { + { NULL, NULL, NULL } + }; + ++const OSSL_ALGORITHM uadk_prov_hmac[] = { ++ { "HMAC", UADK_DEFAULT_PROPERTIES, ++ uadk_hmac_functions, "uadk_provider hmac" }, ++ { NULL, NULL, NULL } ++}; ++ + const OSSL_ALGORITHM uadk_prov_ciphers_v2[] = { + { "AES-128-CBC", UADK_DEFAULT_PROPERTIES, + uadk_aes_128_cbc_functions, "uadk_provider aes-128-cbc" }, +@@ -268,6 +274,8 @@ static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, + if (!ver && uadk_get_sw_offload_state()) + break; + return uadk_prov_digests; ++ case OSSL_OP_MAC: ++ return uadk_prov_hmac; + case OSSL_OP_CIPHER: + ver = uadk_prov_cipher_version(); + if (!ver && uadk_get_sw_offload_state()) +@@ -324,6 +332,7 @@ static void uadk_teardown(void *provctx) + } + + uadk_prov_destroy_digest(); ++ uadk_prov_destroy_hmac(); + uadk_prov_destroy_cipher(); + uadk_prov_destroy_aead(); + uadk_prov_destroy_rsa(); +-- +2.25.1 + diff --git a/0025-uadk_provider-add-soft-mac-switching-function-for-ua.patch b/0025-uadk_provider-add-soft-mac-switching-function-for-ua.patch new file mode 100644 index 0000000..fd8e298 --- /dev/null +++ b/0025-uadk_provider-add-soft-mac-switching-function-for-ua.patch @@ -0,0 +1,540 @@ +From 1a13243035616a1b4e54d0f720acff31dcb2c38f Mon Sep 17 00:00:00 2001 +From: Chenghai Huang +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 25/36] uadk_provider: add soft mac switching function for + uadk_provider + +When HW hmac processing failed, uadk_provider could switch to +soft mac to keep the work success. + +When HMAC switches to software, if the new libctx is not used, +the digest of hardware is used for software computing. For the +uadk, hmac and digest are the same module. When any fault +occurs, do not try to use hardware again. + +Signed-off-by: Chenghai Huang +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_hmac.c | 333 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 307 insertions(+), 26 deletions(-) + +diff --git a/src/uadk_prov_hmac.c b/src/uadk_prov_hmac.c +index 752a326..db49612 100644 +--- a/src/uadk_prov_hmac.c ++++ b/src/uadk_prov_hmac.c +@@ -32,6 +32,7 @@ + #include "uadk_prov.h" + #include "uadk_utils.h" + ++#define UADK_DO_SOFT (-0xE0) + #define UADK_HMAC_SUCCESS 1 + #define UADK_HMAC_FAIL 0 + +@@ -42,8 +43,14 @@ + #define MAX_KEY_LEN 144 + #define HMAC_BLOCK_SIZE (512 * 1024) + #define ALG_NAME_SIZE 128 ++#define PARAMS_SIZE 2 + + #define KEY_4BYTE_ALIGN(keylen) ((keylen + 3) & ~3) ++#define SW_SWITCH_PRINT_ENABLE(SW) (SW ? ", switch to soft hmac" : "") ++ ++#define SM3_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT (512) ++#define MD5_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT (8 * 1024) ++#define SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT (512) + + #define UADK_DIGEST_DEF_CTXS 1 + #define UADK_DIGEST_OP_NUM 1 +@@ -65,12 +72,17 @@ static pthread_mutex_t hmac_mutex = PTHREAD_MUTEX_INITIALIZER; + struct hmac_priv_ctx { + __u32 alg_id; + __u32 state; ++ int switch_flag; + size_t out_len; + size_t blk_size; + size_t keylen; + size_t last_update_bufflen; + size_t total_data_len; ++ size_t switch_threshold; + OSSL_LIB_CTX *libctx; ++ OSSL_LIB_CTX *soft_libctx; ++ EVP_MAC_CTX *soft_ctx; ++ EVP_MAC *soft_md; + handle_t sess; + struct wd_digest_sess_setup setup; + struct wd_digest_req req; +@@ -84,23 +96,185 @@ struct hmac_priv_ctx { + struct hmac_info { + enum wd_digest_type alg; + __u32 alg_id; ++ __u32 threshold; + size_t out_len; + size_t blk_size; + const char ossl_alg_name[ALG_NAME_SIZE]; + }; + + static struct hmac_info hmac_info_table[] = { +- {WD_DIGEST_MD5, NID_md5, 16, 64, PROV_NAMES_MD5}, +- {WD_DIGEST_SM3, NID_sm3, 32, 64, PROV_NAMES_SM3}, +- {WD_DIGEST_SHA1, NID_sha1, 20, 64, PROV_NAMES_SHA1}, +- {WD_DIGEST_SHA224, NID_sha224, 28, 64, PROV_NAMES_SHA2_224}, +- {WD_DIGEST_SHA256, NID_sha256, 32, 64, PROV_NAMES_SHA2_256}, +- {WD_DIGEST_SHA384, NID_sha384, 48, 64, PROV_NAMES_SHA2_384}, +- {WD_DIGEST_SHA512, NID_sha512, 64, 128, PROV_NAMES_SHA2_512}, +- {WD_DIGEST_SHA512_224, NID_sha512_224, 28, 128, PROV_NAMES_SHA2_512_224}, +- {WD_DIGEST_SHA512_256, NID_sha512_256, 32, 128, PROV_NAMES_SHA2_512_256} ++ {WD_DIGEST_MD5, NID_md5, MD5_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 16, 64, PROV_NAMES_MD5}, ++ {WD_DIGEST_SM3, NID_sm3, SM3_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 32, 64, PROV_NAMES_SM3}, ++ {WD_DIGEST_SHA1, NID_sha1, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 20, 64, PROV_NAMES_SHA1}, ++ {WD_DIGEST_SHA224, NID_sha224, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 28, 64, PROV_NAMES_SHA2_224}, ++ {WD_DIGEST_SHA256, NID_sha256, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 32, 64, PROV_NAMES_SHA2_256}, ++ {WD_DIGEST_SHA384, NID_sha384, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 48, 64, PROV_NAMES_SHA2_384}, ++ {WD_DIGEST_SHA512, NID_sha512, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 64, 128, PROV_NAMES_SHA2_512}, ++ {WD_DIGEST_SHA512_224, NID_sha512_224, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 28, 128, PROV_NAMES_SHA2_512_224}, ++ {WD_DIGEST_SHA512_256, NID_sha512_256, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT, ++ 32, 128, PROV_NAMES_SHA2_512_256} + }; + ++static int uadk_create_hmac_soft_ctx(struct hmac_priv_ctx *priv) ++{ ++ if (priv->soft_md) ++ return UADK_HMAC_SUCCESS; ++ ++ priv->soft_libctx = OSSL_LIB_CTX_new(); ++ if (!priv->soft_libctx) { ++ fprintf(stderr, "new soft libctx failed.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ switch (priv->alg_id) { ++ case NID_md5: ++ case NID_sm3: ++ case NID_sha1: ++ case NID_sha224: ++ case NID_sha256: ++ case NID_sha384: ++ case NID_sha512: ++ case NID_sha512_224: ++ case NID_sha512_256: ++ priv->soft_md = EVP_MAC_fetch(priv->soft_libctx, "HMAC", NULL); ++ break; ++ default: ++ break; ++ } ++ ++ if (unlikely(!priv->soft_md)) { ++ fprintf(stderr, "hmac soft fetch failed.\n"); ++ goto free_libctx; ++ } ++ ++ priv->soft_ctx = EVP_MAC_CTX_new(priv->soft_md); ++ if (!priv->soft_ctx) { ++ fprintf(stderr, "hmac soft new ctx failed.\n"); ++ goto free_mac_md; ++ } ++ ++ return UADK_HMAC_SUCCESS; ++ ++free_mac_md: ++ EVP_MAC_free(priv->soft_md); ++ priv->soft_md = NULL; ++free_libctx: ++ OSSL_LIB_CTX_free(priv->soft_libctx); ++ priv->soft_libctx = NULL; ++ ++ return UADK_HMAC_FAIL; ++} ++ ++static int uadk_hmac_soft_init(struct hmac_priv_ctx *priv) ++{ ++ OSSL_PARAM params[PARAMS_SIZE]; ++ OSSL_PARAM *p = params; ++ int ret; ++ ++ if (!priv->soft_md) ++ return UADK_HMAC_FAIL; ++ ++ /* The underlying digest to be used */ ++ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, priv->alg_name, ++ sizeof(priv->alg_name)); ++ *p = OSSL_PARAM_construct_end(); ++ ++ ret = EVP_MAC_init(priv->soft_ctx, priv->key, priv->keylen, params); ++ if (!ret) { ++ fprintf(stderr, "do soft hmac init failed!\n"); ++ return UADK_HMAC_FAIL; ++ } ++ ++ priv->switch_flag = UADK_DO_SOFT; ++ ++ return ret; ++} ++ ++static int uadk_hmac_soft_update(struct hmac_priv_ctx *priv, ++ const void *data, size_t len) ++{ ++ int ret; ++ ++ if (!priv->soft_md) ++ return UADK_HMAC_FAIL; ++ ++ ret = EVP_MAC_update(priv->soft_ctx, data, len); ++ if (!ret) ++ fprintf(stderr, "do soft hmac update failed!\n"); ++ ++ return ret; ++} ++ ++static int uadk_hmac_soft_final(struct hmac_priv_ctx *priv, unsigned char *out) ++{ ++ size_t hmac_length; ++ int ret; ++ ++ if (!priv->soft_md) ++ return UADK_HMAC_FAIL; ++ ++ ret = EVP_MAC_final(priv->soft_ctx, out, &hmac_length, priv->out_len); ++ if (!ret) ++ fprintf(stderr, "do soft hmac final failed!\n"); ++ ++ return ret; ++} ++ ++static void hmac_soft_cleanup(struct hmac_priv_ctx *priv) ++{ ++ if (priv->soft_ctx) { ++ EVP_MAC_CTX_free(priv->soft_ctx); ++ priv->soft_ctx = NULL; ++ } ++ ++ if (priv->soft_md) { ++ EVP_MAC_free(priv->soft_md); ++ priv->soft_md = NULL; ++ } ++ ++ if (priv->soft_libctx) { ++ OSSL_LIB_CTX_free(priv->soft_libctx); ++ priv->soft_libctx = NULL; ++ } ++ ++ priv->switch_flag = 0; ++} ++ ++static int uadk_hmac_soft_work(struct hmac_priv_ctx *priv, int inl, ++ unsigned char *out) ++{ ++ int ret; ++ ++ if (!priv->soft_md) ++ return UADK_HMAC_FAIL; ++ ++ if (!priv->switch_flag) { ++ ret = uadk_hmac_soft_init(priv); ++ if (unlikely(!ret)) ++ return UADK_HMAC_FAIL; ++ } ++ ++ if (inl) { ++ ret = uadk_hmac_soft_update(priv, priv->data, inl); ++ if (unlikely(!ret)) ++ goto out; ++ } ++ ++ ret = uadk_hmac_soft_final(priv, out); ++ ++out: ++ hmac_soft_cleanup(priv); ++ return ret; ++} ++ + static OSSL_FUNC_mac_newctx_fn uadk_prov_hmac_newctx; + static OSSL_FUNC_mac_dupctx_fn uadk_prov_hmac_dupctx; + static OSSL_FUNC_mac_freectx_fn uadk_prov_hmac_freectx; +@@ -181,6 +355,7 @@ static int uadk_get_hmac_info(struct hmac_priv_ctx *priv) + priv->setup.mode = WD_DIGEST_HMAC; + priv->req.out_buf_bytes = MAX_DIGEST_LENGTH; + priv->req.out_bytes = hmac_info_table[i].out_len; ++ priv->switch_threshold = hmac_info_table[i].threshold; + + return UADK_HMAC_SUCCESS; + } +@@ -312,9 +487,15 @@ static int uadk_hmac_ctx_init(struct hmac_priv_ctx *priv) + struct sched_params params = {0}; + int ret; + ++ if (enable_sw_offload) ++ uadk_create_hmac_soft_ctx(priv); ++ + ret = uadk_prov_hmac_dev_init(priv); +- if (unlikely(ret <= 0)) +- return UADK_HMAC_FAIL; ++ if (unlikely(ret <= 0)) { ++ fprintf(stderr, "uadk failed to initialize hmac%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); ++ goto soft_init; ++ } + + /* Use the default numa parameters */ + params.numa_id = -1; +@@ -325,13 +506,15 @@ static int uadk_hmac_ctx_init(struct hmac_priv_ctx *priv) + if (!priv->sess) { + priv->sess = wd_digest_alloc_sess(&setup); + if (unlikely(!priv->sess)) { +- fprintf(stderr, "uadk failed to alloc hmac sess.\n"); +- return UADK_HMAC_FAIL; ++ fprintf(stderr, "uadk failed to alloc hmac sess%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); ++ goto soft_init; + } + + ret = wd_digest_set_key(priv->sess, priv->key, priv->keylen); + if (ret) { +- fprintf(stderr, "uadk failed to set hmac key!\n"); ++ fprintf(stderr, "uadk failed to set hmac key%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); + goto free_sess; + } + } +@@ -341,7 +524,9 @@ static int uadk_hmac_ctx_init(struct hmac_priv_ctx *priv) + free_sess: + wd_digest_free_sess(priv->sess); + priv->sess = 0; +- return UADK_HMAC_FAIL; ++ ++soft_init: ++ return uadk_hmac_soft_init(priv); + } + + static void uadk_hmac_async_cb(struct wd_digest_req *req, void *data) +@@ -368,6 +553,11 @@ static int uadk_do_hmac_sync(struct hmac_priv_ctx *priv) + { + int ret; + ++ if (priv->soft_md && ++ priv->req.in_bytes <= priv->switch_threshold && ++ priv->state == SEC_DIGEST_INIT) ++ return UADK_HMAC_FAIL; ++ + ret = wd_do_digest_sync(priv->sess, &priv->req); + if (ret) { + fprintf(stderr, "do sec hmac sync failed.\n"); +@@ -383,6 +573,11 @@ static int uadk_do_hmac_async(struct hmac_priv_ctx *priv, struct async_op *op) + int idx, ret; + int cnt = 0; + ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { ++ fprintf(stderr, "soft switching is not supported in asynchronous mode.\n"); ++ return UADK_HMAC_FAIL; ++ } ++ + cb_param.op = op; + cb_param.priv = &priv->req; + priv->req.cb = (void *)uadk_hmac_async_cb; +@@ -465,8 +660,9 @@ static int uadk_hmac_update_inner(struct hmac_priv_ctx *priv, const void *data, + + ret = uadk_do_hmac_sync(priv); + if (!ret) { +- fprintf(stderr, "do sec digest update failed.\n"); +- return UADK_HMAC_FAIL; ++ fprintf(stderr, "do sec hmac update failed%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); ++ goto do_soft_hmac; + } + + remain_len -= processing_len; +@@ -477,6 +673,39 @@ static int uadk_hmac_update_inner(struct hmac_priv_ctx *priv, const void *data, + uadk_memcpy(priv->data, input_data, priv->last_update_bufflen); + + return UADK_HMAC_SUCCESS; ++ ++do_soft_hmac: ++ if (priv->state == SEC_DIGEST_FIRST_UPDATING) { ++ ret = uadk_hmac_soft_init(priv); ++ if (!ret) ++ return ret; ++ ++ /* ++ * If the hardware fails to process the data in the cache, ++ * the software computing needs to finish the cached data first. ++ */ ++ if (processing_len < HMAC_BLOCK_SIZE) { ++ ret = uadk_hmac_soft_update(priv, priv->data, HMAC_BLOCK_SIZE); ++ if (!ret) ++ goto err_out; ++ ++ remain_len -= processing_len; ++ input_data += processing_len; ++ } ++ ++ ret = uadk_hmac_soft_update(priv, input_data, remain_len); ++ if (!ret) ++ goto err_out; ++ ++ /* the soft ctx will be free in the final stage. */ ++ return ret; ++ } ++ ++ return UADK_HMAC_FAIL; ++ ++err_out: ++ hmac_soft_cleanup(priv); ++ return ret; + } + + static int uadk_hmac_update(struct hmac_priv_ctx *priv, const void *data, size_t data_len) +@@ -486,6 +715,9 @@ static int uadk_hmac_update(struct hmac_priv_ctx *priv, const void *data, size_t + return UADK_HMAC_FAIL; + } + ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) ++ goto soft_update; ++ + priv->total_data_len += data_len; + + if (priv->last_update_bufflen + data_len <= HMAC_BLOCK_SIZE) { +@@ -495,6 +727,9 @@ static int uadk_hmac_update(struct hmac_priv_ctx *priv, const void *data, size_t + } + + return uadk_hmac_update_inner(priv, data, data_len); ++ ++soft_update: ++ return uadk_hmac_soft_update(priv, data, data_len); + } + + static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) +@@ -507,9 +742,12 @@ static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) + return UADK_HMAC_FAIL; + } + +- ret = uadk_hmac_ctx_init(priv); +- if (!ret) +- return UADK_HMAC_FAIL; ++ /* It dose not need to be initialized again if the software calculation is applied. */ ++ if (priv->switch_flag != UADK_DO_SOFT) { ++ ret = uadk_hmac_ctx_init(priv); ++ if (!ret) ++ return UADK_HMAC_FAIL; ++ } + + priv->req.in = priv->data; + priv->req.out = priv->state == SEC_DIGEST_INIT ? digest : priv->out; +@@ -524,19 +762,37 @@ static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) + return UADK_HMAC_FAIL; + } + +- if (!op.job) ++ if (!op.job) { ++ /* Synchronous, only the synchronous mode supports soft computing */ ++ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { ++ ret = uadk_hmac_soft_final(priv, digest); ++ hmac_soft_cleanup(priv); ++ goto clear; ++ } ++ + ret = uadk_do_hmac_sync(priv); +- else ++ if (!ret) ++ goto do_hmac_err; ++ } else { + ret = uadk_do_hmac_async(priv, &op); +- +- if (!ret) +- goto clear; ++ if (!ret) ++ goto clear; ++ } + + if (priv->state != SEC_DIGEST_INIT) + memcpy(digest, priv->req.out, priv->req.out_bytes); + + return UADK_HMAC_SUCCESS; + ++do_hmac_err: ++ if (priv->state == SEC_DIGEST_INIT) { ++ fprintf(stderr, "do sec digest final failed%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); ++ ret = uadk_hmac_soft_work(priv, priv->req.in_bytes, digest); ++ } else { ++ ret = UADK_HMAC_FAIL; ++ fprintf(stderr, "do sec digest final failed.\n"); ++ } + clear: + async_clear_async_event_notification(); + return ret; +@@ -545,6 +801,7 @@ clear: + static void *uadk_prov_hmac_dupctx(void *hctx) + { + struct hmac_priv_ctx *dst_ctx, *src_ctx; ++ int ret; + + if (!hctx) + return NULL; +@@ -573,8 +830,23 @@ static void *uadk_prov_hmac_dupctx(void *hctx) + if (!dst_ctx->data) + goto free_ctx; + ++ if (dst_ctx->soft_ctx) { ++ dst_ctx->soft_libctx = NULL; ++ dst_ctx->soft_ctx = EVP_MAC_CTX_dup(src_ctx->soft_ctx); ++ if (!dst_ctx->soft_ctx) { ++ fprintf(stderr, "create soft_ctx failed in ctx copy.\n"); ++ goto free_data; ++ } ++ ++ ret = EVP_MAC_up_ref(dst_ctx->soft_md); ++ if (!ret) ++ goto free_dup; ++ } ++ + return dst_ctx; + ++free_dup: ++ EVP_MAC_CTX_free(dst_ctx->soft_ctx); + free_data: + OPENSSL_clear_free(dst_ctx->data, HMAC_BLOCK_SIZE); + free_ctx: +@@ -600,6 +872,7 @@ static void uadk_prov_hmac_freectx(void *hctx) + return; + } + ++ hmac_soft_cleanup(priv); + uadk_hmac_cleanup(priv); + OPENSSL_clear_free(priv, sizeof(*priv)); + } +@@ -640,6 +913,9 @@ static int uadk_prov_hmac_init(void *hctx, const unsigned char *key, + if (unlikely(!ret)) + return UADK_HMAC_FAIL; + ++ if (enable_sw_offload) ++ uadk_create_hmac_soft_ctx(hctx); ++ + if (key) { + ret = uadk_prov_hmac_setkey(priv, key, keylen); + if (!ret) +@@ -648,9 +924,14 @@ static int uadk_prov_hmac_init(void *hctx, const unsigned char *key, + + ret = uadk_prov_hmac_dev_init(priv); + if (unlikely(ret <= 0)) +- return UADK_HMAC_FAIL; ++ goto soft_init; + + return UADK_HMAC_SUCCESS; ++ ++soft_init: ++ fprintf(stderr, "uadk failed to initialize dev%s.\n", ++ SW_SWITCH_PRINT_ENABLE(enable_sw_offload)); ++ return uadk_hmac_soft_init(priv); + } + + static int uadk_prov_hmac_update(void *hctx, const unsigned char *data, size_t datalen) +-- +2.25.1 + diff --git a/0026-uadk_provider-dh-add-dh-switching-software-computati.patch b/0026-uadk_provider-dh-add-dh-switching-software-computati.patch new file mode 100644 index 0000000..93c36dd --- /dev/null +++ b/0026-uadk_provider-dh-add-dh-switching-software-computati.patch @@ -0,0 +1,241 @@ +From 7c8d039ebf6a2605709328804317a16c5d008383 Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 26/36] uadk_provider/dh: add dh switching software computation + function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch dh to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_dh.c | 86 ++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 71 insertions(+), 15 deletions(-) + +diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c +index f6262d4..c75c386 100644 +--- a/src/uadk_prov_dh.c ++++ b/src/uadk_prov_dh.c +@@ -60,6 +60,28 @@ UADK_PKEY_KEYMGMT_DESCR(dh, DH); + UADK_PKEY_KEYEXCH_DESCR(dh, DH); + + static pthread_mutex_t dh_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t dh_default_mutex = PTHREAD_MUTEX_INITIALIZER; ++static UADK_PKEY_KEYEXCH get_default_dh_keyexch(void) ++{ ++ static UADK_PKEY_KEYEXCH s_keyexch; ++ static int initilazed; ++ ++ pthread_mutex_lock(&dh_default_mutex); ++ if (!initilazed) { ++ UADK_PKEY_KEYEXCH *keyexch = ++ (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "dh", "provider=default"); ++ if (keyexch) { ++ s_keyexch = *keyexch; ++ EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "failed to EVP_KEYEXCH_fetch default dh provider\n"); ++ } ++ } ++ pthread_mutex_unlock(&dh_default_mutex); ++ ++ return s_keyexch; ++} + + struct dh_st { + /* +@@ -705,7 +727,7 @@ static int uadk_prov_dh_prepare_data(const BIGNUM *g, DH *dh, struct uadk_dh_ses + ret = check_dh_bit_useful(bits); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "invalid: dh%u is not supported by uadk provider\n", bits); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + *dh_sess = uadk_prov_dh_new_session(dh, bits, is_g2); +@@ -916,7 +938,7 @@ static int uadk_prov_dh_generate_key(DH *dh) + ret = uadk_prov_dh_init(); + if (ret) { + fprintf(stderr, "failed to init dh\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + uadk_DH_get0_pqg(dh, &p, NULL, &g); +@@ -927,7 +949,7 @@ static int uadk_prov_dh_generate_key(DH *dh) + + /* Get session and prepare private key */ + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); +- if (ret == UADK_P_FAIL) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; + } +@@ -939,8 +961,9 @@ static int uadk_prov_dh_generate_key(DH *dh) + } + + ret = uadk_prov_dh_do_crypto(dh_sess); +- if (ret == UADK_P_FAIL) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to generate DH key\n"); ++ ret = UADK_DO_SOFT; + goto free_req; + } + +@@ -964,7 +987,7 @@ free_req: + free_data: + uadk_prov_dh_free_prepare_data(dh_sess, prikey); + +- return UADK_P_FAIL; ++ return ret; + } + + static int dh_gencb(int p, int n, BN_GENCB *cb) +@@ -1081,7 +1104,7 @@ static DH *uadk_prov_dh_gen_params_with_group(PROV_DH_KEYMGMT_CTX *gctx, FFC_PAR + fprintf(stderr, "failed to get dh from libctx\n"); + return NULL; + } +- ++ dh->meth = DH_get_default_method(); + ossl_ffc_named_group_set(&dh->params, group); + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->dirty_cnt++; +@@ -1094,6 +1117,8 @@ static DH *uadk_prov_dh_gen_params_with_group(PROV_DH_KEYMGMT_CTX *gctx, FFC_PAR + return NULL; + } + ++ dh->meth = DH_get_default_method(); ++ + return dh; + } + +@@ -1234,6 +1259,15 @@ static void uadk_prov_dh_free_params(DH *dh, BN_GENCB *gencb) + uadk_prov_dh_free_params_cb(gencb); + } + ++static void *uadk_dh_sw_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) ++{ ++ if (!enable_sw_offload || !get_default_dh_keymgmt().gen) ++ return NULL; ++ ++ fprintf(stderr, "switch to openssl software calculation in dh generation.\n"); ++ return get_default_dh_keymgmt().gen(genctx, cb, cb_params); ++} ++ + static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) + { + PROV_DH_KEYMGMT_CTX *gctx = (PROV_DH_KEYMGMT_CTX *)genctx; +@@ -1256,9 +1290,10 @@ static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_param + gctx->gen_type = DH_PARAMGEN_TYPE_GROUP; + + dh = uadk_prov_dh_gen_params(gctx, &ffc, cb, cb_params, gencb); +- if (dh == NULL || ffc == NULL) +- return NULL; +- ++ if (dh == NULL || ffc == NULL) { ++ ret = UADK_DO_SOFT; ++ goto free_gen_params; ++ } + /* DH key generation */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + if (ffc->p == NULL || ffc->g == NULL) { +@@ -1273,7 +1308,7 @@ static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_param + gctx->gen_type == DH_PARAMGEN_TYPE_FIPS_186_2); + + ret = uadk_prov_dh_generate_key(dh); +- if (ret == UADK_P_FAIL) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to do dh generation key\n"); + goto free_gen_params; + } +@@ -1287,6 +1322,9 @@ static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_param + + free_gen_params: + uadk_prov_dh_free_params(dh, gencb); ++ ++ if (ret == UADK_DO_SOFT) ++ return uadk_dh_sw_gen(genctx, cb, cb_params); + return NULL; + } + +@@ -1525,11 +1563,11 @@ static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pubkey, DH *dh) + ret = uadk_prov_dh_init(); + if (ret) { + fprintf(stderr, "failed to init\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); +- if (ret == UADK_P_FAIL) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; + } +@@ -1541,8 +1579,9 @@ static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pubkey, DH *dh) + } + + ret = uadk_prov_dh_do_crypto(dh_sess); +- if (ret == UADK_P_FAIL) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to generate DH shared key\n"); ++ ret = UADK_DO_SOFT; + goto free_req; + } + +@@ -1712,12 +1751,14 @@ static int uadk_prov_dh_X9_42_kdf_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned c + return UADK_P_FAIL; + } + +- if (uadk_prov_dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, USE_PAD) == UADK_P_FAIL) ++ ret = uadk_prov_dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, USE_PAD); ++ if (ret != UADK_P_SUCCESS) + goto end; + + /* Do KDF stuff */ + if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) { + if (ossl_dh_kdf_X9_42_asn1(secret, pdhctx, stmp, stmplen, NULL) == UADK_P_FAIL) { ++ ret = UADK_P_FAIL; + fprintf(stderr, "failed to do ossl_dh_kdf_X9_42_asn1\n"); + goto end; + } +@@ -1732,6 +1773,16 @@ end: + return ret; + } + ++static int uadk_dh_sw_derive(void *dhctx, unsigned char *secret, ++ size_t *psecretlen, size_t outlen) ++{ ++ if (!enable_sw_offload || !get_default_dh_keyexch().derive) ++ return UADK_P_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in dh derivation.\n"); ++ return get_default_dh_keyexch().derive(dhctx, secret, psecretlen, outlen); ++} ++ + static int uadk_keyexch_dh_derive(void *dhctx, unsigned char *secret, + size_t *psecretlen, size_t outlen) + { +@@ -1752,10 +1803,15 @@ static int uadk_keyexch_dh_derive(void *dhctx, unsigned char *secret, + break; + default: + fprintf(stderr, "invalid: unsupport kdf type\n"); ++ ret = UADK_DO_SOFT; + break; + } + +- return ret; ++ if (ret == UADK_P_SUCCESS) ++ return UADK_P_SUCCESS; ++ if (ret == UADK_DO_SOFT) ++ return uadk_dh_sw_derive(dhctx, secret, psecretlen, outlen); ++ return UADK_P_FAIL; + } + + static void *uadk_keyexch_dh_dupctx(void *dhctx) +-- +2.25.1 + diff --git a/0027-uadk_provider-rsa-add-rsa-switching-software-computa.patch b/0027-uadk_provider-rsa-add-rsa-switching-software-computa.patch new file mode 100644 index 0000000..7bf4d52 --- /dev/null +++ b/0027-uadk_provider-rsa-add-rsa-switching-software-computa.patch @@ -0,0 +1,370 @@ +From 1cfa3b453034f0e53352063c9227ec5339da667a Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 27/36] uadk_provider/rsa: add rsa switching software + computation function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch rsa to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_rsa.c | 180 ++++++++++++++++++++++++++------------------ + 1 file changed, 105 insertions(+), 75 deletions(-) + +diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c +index 8f7d734..65e78c3 100644 +--- a/src/uadk_prov_rsa.c ++++ b/src/uadk_prov_rsa.c +@@ -62,7 +62,6 @@ + #define GENCB_NEXT 2 + #define GENCB_RETRY 3 + #define PRIME_CHECK_BIT_NUM 4 +-#define SOFT_SWITCH 0 + + UADK_PKEY_KEYMGMT_DESCR(rsa, RSA); + UADK_PKEY_SIGNATURE_DESCR(rsa, RSA); +@@ -284,11 +283,14 @@ enum { + MAX_CODE, + }; + ++static pthread_mutex_t sig_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t asym_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + static UADK_PKEY_SIGNATURE get_default_rsa_signature(void) + { + static UADK_PKEY_SIGNATURE s_signature; + static int initilazed; +- ++ pthread_mutex_lock(&sig_mutex); + if (!initilazed) { + UADK_PKEY_SIGNATURE *signature = + (UADK_PKEY_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "RSA", "provider=default"); +@@ -301,6 +303,7 @@ static UADK_PKEY_SIGNATURE get_default_rsa_signature(void) + fprintf(stderr, "failed to EVP_SIGNATURE_fetch default RSA provider\n"); + } + } ++ pthread_mutex_unlock(&sig_mutex); + return s_signature; + } + +@@ -308,7 +311,7 @@ static UADK_PKEY_ASYM_CIPHER get_default_rsa_asym_cipher(void) + { + static UADK_PKEY_ASYM_CIPHER s_asym_cipher; + static int initilazed; +- ++ pthread_mutex_lock(&asym_mutex); + if (!initilazed) { + UADK_PKEY_ASYM_CIPHER *asym_cipher = + (UADK_PKEY_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, "RSA", +@@ -322,6 +325,7 @@ static UADK_PKEY_ASYM_CIPHER get_default_rsa_asym_cipher(void) + fprintf(stderr, "failed to EVP_ASYM_CIPHER_fetch default RSA provider\n"); + } + } ++ pthread_mutex_unlock(&asym_mutex); + return s_asym_cipher; + } + +@@ -2001,6 +2005,17 @@ static int uadk_signature_rsa_verify_init(void *vprsactx, void *vrsa, + return uadk_rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); + } + ++static int uadk_rsa_sw_verify(void *vprsactx, const unsigned char *sig, ++ size_t siglen, const unsigned char *tbs, ++ size_t tbslen) ++{ ++ if (!enable_sw_offload || !get_default_rsa_signature().verify) ++ return UADK_E_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in verifaction.\n"); ++ return get_default_rsa_signature().verify(vprsactx, sig, siglen, tbs, tbslen); ++} ++ + static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen) +@@ -2008,10 +2023,10 @@ static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig, + PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; + size_t rslen = 0; + +- if (priv->soft && SOFT_SWITCH) +- goto soft; +- else if (priv->soft && !SOFT_SWITCH) +- return UADK_E_FAIL; ++ if (priv->soft) { ++ rslen = UADK_DO_SOFT; ++ goto exe_soft; ++ } + + /* todo call public_verify */ + if (priv->md != NULL) { +@@ -2021,12 +2036,8 @@ static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig, + return UADK_E_FAIL; + rslen = uadk_prov_rsa_public_verify(siglen, sig, priv->tbuf, + priv->rsa, priv->pad_mode); +- if (rslen == UADK_DO_SOFT || rslen == UADK_E_FAIL) { +- if (rslen == UADK_DO_SOFT && SOFT_SWITCH) +- goto soft; +- else +- return UADK_E_FAIL; +- } ++ if (rslen == UADK_DO_SOFT || rslen == UADK_E_FAIL) ++ goto exe_soft; + } + + if ((rslen != tbslen) || memcmp(tbs, priv->tbuf, rslen)) +@@ -2034,12 +2045,21 @@ static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig, + + return UADK_E_SUCCESS; + +-soft: +- fprintf(stderr, "switch to execute openssl software calculation.\n"); +- if (!get_default_rsa_signature().verify) ++exe_soft: ++ if (rslen == UADK_DO_SOFT) ++ return uadk_rsa_sw_verify(vprsactx, sig, siglen, tbs, tbslen); ++ return UADK_E_FAIL; ++} ++ ++static int uadk_rsa_sw_sign(void *vprsactx, unsigned char *sig, ++ size_t *siglen, size_t sigsize, ++ const unsigned char *tbs, size_t tbslen) ++{ ++ if (!enable_sw_offload || !get_default_rsa_signature().sign) + return UADK_E_FAIL; + +- return get_default_rsa_signature().verify(vprsactx, sig, siglen, tbs, tbslen); ++ fprintf(stderr, "switch to openssl software calculation in rsa signature.\n"); ++ return get_default_rsa_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); + } + + static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, +@@ -2050,10 +2070,10 @@ static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, + size_t rsasize = uadk_rsa_size(priv->rsa); + int ret; + +- if (priv->soft && SOFT_SWITCH) +- goto soft; +- else if (priv->soft && !SOFT_SWITCH) +- return UADK_E_FAIL; ++ if (priv->soft) { ++ ret = UADK_DO_SOFT; ++ goto exe_soft; ++ } + + if (sig == NULL) { + *siglen = rsasize; +@@ -2067,12 +2087,8 @@ static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, + } + + ret = uadk_prov_rsa_private_sign(tbslen, tbs, sig, priv->rsa, priv->pad_mode); +- if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { +- if (ret == UADK_DO_SOFT && SOFT_SWITCH) +- goto soft; +- else +- return UADK_E_FAIL; +- } ++ if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) ++ goto exe_soft; + + if (ret < 0) + return ret; +@@ -2080,12 +2096,10 @@ static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, + *siglen = ret; + + return UADK_E_SUCCESS; +-soft: +- fprintf(stderr, "switch to execute openssl software calculation.\n"); +- if (!get_default_rsa_signature().sign) +- return UADK_E_FAIL; +- +- return get_default_rsa_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_rsa_sw_sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); ++ return UADK_E_FAIL; + } + + static int uadk_signature_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) +@@ -2355,6 +2369,17 @@ static int uadk_asym_cipher_rsa_decrypt_init(void *vprsactx, void *vrsa, + return uadk_rsa_asym_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT); + } + ++static int uadk_rsa_sw_encrypt(void *vprsactx, unsigned char *out, ++ size_t *outlen, size_t outsize, ++ const unsigned char *in, size_t inlen) ++{ ++ if (!enable_sw_offload || !get_default_rsa_asym_cipher().encrypt) ++ return UADK_E_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in rsa encryption.\n"); ++ return get_default_rsa_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); ++} ++ + static int uadk_asym_cipher_rsa_encrypt(void *vprsactx, unsigned char *out, + size_t *outlen, size_t outsize, + const unsigned char *in, size_t inlen) +@@ -2363,10 +2388,10 @@ static int uadk_asym_cipher_rsa_encrypt(void *vprsactx, unsigned char *out, + size_t len; + int ret; + +- if (priv->soft && SOFT_SWITCH) +- goto soft; +- else if (priv->soft && !SOFT_SWITCH) +- return UADK_E_FAIL; ++ if (priv->soft) { ++ ret = UADK_DO_SOFT; ++ goto exe_soft; ++ } + + if (out == NULL) { + len = uadk_rsa_size(priv->rsa); +@@ -2379,22 +2404,27 @@ static int uadk_asym_cipher_rsa_encrypt(void *vprsactx, unsigned char *out, + } + + ret = uadk_prov_rsa_public_encrypt(inlen, in, out, priv->rsa, priv->pad_mode); +- if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { +- if (ret == UADK_DO_SOFT && SOFT_SWITCH) +- goto soft; +- else +- return UADK_E_FAIL; +- } ++ if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) ++ goto exe_soft; + + *outlen = ret; + + return UADK_E_SUCCESS; +-soft: +- fprintf(stderr, "switch to execute openssl software calculation.\n"); +- if (!get_default_rsa_asym_cipher().encrypt) ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_rsa_sw_encrypt(vprsactx, out, outlen, outsize, in, inlen); ++ return UADK_E_FAIL; ++} ++ ++static int uadk_rsa_sw_decrypt(void *vprsactx, unsigned char *out, ++ size_t *outlen, size_t outsize, ++ const unsigned char *in, size_t inlen) ++{ ++ if (!enable_sw_offload || !get_default_rsa_asym_cipher().decrypt) + return UADK_E_FAIL; + +- return get_default_rsa_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); ++ fprintf(stderr, "switch to openssl software calculation in rsa decryption.\n"); ++ return get_default_rsa_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); + } + + static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, +@@ -2405,10 +2435,10 @@ static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, + size_t len = uadk_rsa_size(priv->rsa); + int ret; + +- if (priv->soft && SOFT_SWITCH) +- goto soft; +- else if (priv->soft && !SOFT_SWITCH) +- return UADK_E_FAIL; ++ if (priv->soft) { ++ ret = UADK_DO_SOFT; ++ goto exe_soft; ++ } + + if (out == NULL) { + if (len == 0) { +@@ -2425,21 +2455,16 @@ static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, + } + + ret = uadk_prov_rsa_private_decrypt(inlen, in, out, priv->rsa, priv->pad_mode); +- if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { +- if (ret == UADK_DO_SOFT && SOFT_SWITCH) +- goto soft; +- else +- return UADK_E_FAIL; +- } ++ if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) ++ goto exe_soft; ++ + *outlen = ret; + + return UADK_E_SUCCESS; +-soft: +- fprintf(stderr, "switch to execute openssl software calculation.\n"); +- if (!get_default_rsa_asym_cipher().decrypt) +- return UADK_E_FAIL; +- +- return get_default_rsa_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_rsa_sw_decrypt(vprsactx, out, outlen, outsize, in, inlen); ++ return UADK_E_FAIL; + } + + static int uadk_asym_cipher_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) +@@ -2588,10 +2613,20 @@ static RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx) + } + + ret->libctx = libctx; ++ ret->meth = RSA_get_default_method(); + + return ret; + } + ++static void *uadk_rsa_sw_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ++{ ++ if (!enable_sw_offload || !get_default_rsa_keymgmt().gen) ++ return NULL; ++ ++ fprintf(stderr, "switch to openssl software calculation in rsa key generation.\n"); ++ return get_default_rsa_keymgmt().gen(genctx, osslcb, cbarg); ++} ++ + static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) + { + struct rsa_gen_ctx *gctx = genctx; +@@ -2603,10 +2638,10 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + return NULL; + + ret = uadk_prov_rsa_init(); +- if (ret && SOFT_SWITCH) ++ if (ret) { ++ ret = UADK_DO_SOFT; + goto exe_soft; +- else if (ret && !SOFT_SWITCH) +- return NULL; ++ } + + rsa = ossl_rsa_new_with_ctx(gctx->libctx); + if (rsa == NULL) +@@ -2622,11 +2657,7 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { + BN_GENCB_free(gencb); + uadk_keymgmt_rsa_free(rsa); +- +- if (ret == UADK_DO_SOFT && SOFT_SWITCH) +- goto exe_soft; +- else +- return NULL; ++ goto exe_soft; + } + + uadk_rsa_clear_flags(rsa, RSA_FLAG_TYPE_MASK); +@@ -2636,10 +2667,9 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + return rsa; + + exe_soft: +- fprintf(stderr, "switch to execute openssl software calculation.\n"); +- if (!get_default_rsa_keymgmt().gen) +- return NULL; +- return get_default_rsa_keymgmt().gen(genctx, osslcb, cbarg); ++ if (ret == UADK_DO_SOFT) ++ return uadk_rsa_sw_gen(genctx, osslcb, cbarg); ++ return NULL; + } + + static void uadk_keymgmt_rsa_gen_cleanup(void *genctx) +-- +2.25.1 + diff --git a/0028-uadk_provider-sm2-add-sm2-switching-software-computa.patch b/0028-uadk_provider-sm2-add-sm2-switching-software-computa.patch new file mode 100644 index 0000000..17a11db --- /dev/null +++ b/0028-uadk_provider-sm2-add-sm2-switching-software-computa.patch @@ -0,0 +1,551 @@ +From 3487bd712c8407e85aa5357746c97999de02ef47 Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 28/36] uadk_provider/sm2: add sm2 switching software + computation function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch sm2 to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_sm2.c | 241 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 214 insertions(+), 27 deletions(-) + +diff --git a/src/uadk_prov_sm2.c b/src/uadk_prov_sm2.c +index df753bd..9fcefc6 100644 +--- a/src/uadk_prov_sm2.c ++++ b/src/uadk_prov_sm2.c +@@ -144,11 +144,29 @@ typedef struct { + SM2_PROV_CTX *sm2_pctx; + } PROV_SM2_SIGN_CTX; + ++/* ++ * To stay same structure with openssl sm2 cipher context, ++ * add openssl PROV_DIGEST type to uadk provider. ++ * It will not be used in uadk provider, so set it all zero. ++ */ ++struct PROV_DIGEST { ++ const EVP_MD *md; ++ EVP_MD *alloc_md; ++ ++ ENGINE *engine; ++ ++ /* The resv is additional field, not in openssl structure. ++ * Add it to prevent possible field changes of openssl in future. ++ */ ++ char resv[OSSL_MAX_NAME_SIZE]; ++}; ++ + typedef struct { + OSSL_LIB_CTX *libctx; + /* Use EC_KEY refer to keymgmt */ + EC_KEY *key; +- char mdname[OSSL_MAX_NAME_SIZE]; ++ /* The md will used by openssl, but not used by uadk provider */ ++ struct PROV_DIGEST md; + + SM2_PROV_CTX *sm2_pctx; + } PROV_SM2_ASYM_CTX; +@@ -597,6 +615,16 @@ error: + return UADK_P_FAIL; + } + ++static void *uadk_keymgmt_sm2_gen_sw(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 keygen.\n"); ++ return get_default_sm2_keymgmt().gen(genctx, osslcb, cbarg); ++ } ++ ++ return NULL; ++} ++ + /** + * @brief Generate SM2 key pair. + * +@@ -632,14 +660,14 @@ static void *uadk_keymgmt_sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_SM2); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware sm2 keygen support\n"); +- goto free_ec_key; ++ goto do_soft; + } + + /* SM2 hardware init */ + ret = uadk_prov_ecc_init("sm2"); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); +- goto free_ec_key; ++ goto do_soft; + } + + /* Do sm2 keygen with hardware */ +@@ -651,17 +679,41 @@ static void *uadk_keymgmt_sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + ret = uadk_prov_sm2_keygen(ec); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to generate sm2 key\n"); +- goto free_ec_key; ++ goto do_soft; + } + + return ec; + ++do_soft: ++ EC_KEY_free(ec); ++ return uadk_keymgmt_sm2_gen_sw(genctx, osslcb, cbarg); + free_ec_key: + /* Something went wrong, throw the key away */ + EC_KEY_free(ec); + return NULL; + } + ++static UADK_PKEY_SIGNATURE get_default_sm2_signature(void) ++{ ++ static UADK_PKEY_SIGNATURE s_signature; ++ static int initilazed; ++ ++ if (__atomic_compare_exchange_n(&initilazed, &(int){0}, 1, false, __ATOMIC_SEQ_CST, ++ __ATOMIC_SEQ_CST)) { ++ UADK_PKEY_SIGNATURE *signature = ++ (UADK_PKEY_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "SM2", "provider=default"); ++ ++ if (signature) { ++ s_signature = *signature; ++ EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); ++ } else { ++ __atomic_store_n(&initilazed, 0, __ATOMIC_SEQ_CST); ++ fprintf(stderr, "failed to EVP_SIGNATURE_fetch default SM2 provider\n"); ++ } ++ } ++ return s_signature; ++} ++ + static void *uadk_signature_sm2_newctx(void *provctx, const char *propq) + { + PROV_SM2_SIGN_CTX *psm2ctx = OPENSSL_zalloc(sizeof(PROV_SM2_SIGN_CTX)); +@@ -919,6 +971,17 @@ static int uadk_prov_sm2_update_sess(SM2_PROV_CTX *smctx) + return UADK_P_SUCCESS; + } + ++static int uadk_signature_sm2_sign_init_sw(void *vpsm2ctx, void *ec, ++ const OSSL_PARAM params[]) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 sign_init.\n"); ++ return get_default_sm2_signature().sign_init(vpsm2ctx, ec, params); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_signature_sm2_sign_init(void *vpsm2ctx, void *ec, + const OSSL_PARAM params[]) + { +@@ -956,20 +1019,20 @@ static int uadk_signature_sm2_sign_init(void *vpsm2ctx, void *ec, + ret = uadk_signature_sm2_set_ctx_params((void *)psm2ctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to set sm2 sig ctx params\n"); +- return ret; ++ goto do_soft; + } + + ret = uadk_prov_signature_get_support_state(SIGNATURE_SM2); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware sm2 signature support\n"); +- return ret; ++ goto do_soft; + } + + /* Init with UADK */ + ret = uadk_prov_ecc_init("sm2"); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); +- return ret; ++ goto do_soft; + } + + psm2ctx->sm2_pctx->init_status = CTX_INIT_SUCC; +@@ -977,10 +1040,13 @@ static int uadk_signature_sm2_sign_init(void *vpsm2ctx, void *ec, + ret = uadk_prov_sm2_update_sess(psm2ctx->sm2_pctx); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to update sess in sign init\n"); +- return ret; ++ goto do_soft; + } + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_signature_sm2_sign_init_sw(vpsm2ctx, ec, params); + } + + static int uadk_signature_sm2_verify_init(void *vpsm2ctx, void *ec, +@@ -1124,9 +1190,11 @@ static int uadk_prov_sm2_sign_bin_to_ber(struct wd_dtb *r, struct wd_dtb *s, + sltmp = i2d_ECDSA_SIG(e_sig, &sig); + if (sltmp < 0) { + fprintf(stderr, "failed to i2d_ECDSA_SIG\n"); +- goto free_s; ++ /* bs and br set to e_sig, use unified interface to prevent double release. */ ++ goto free_sig; + } + *siglen = (size_t)sltmp; ++ ECDSA_SIG_free(e_sig); + + return UADK_P_SUCCESS; + +@@ -1248,6 +1316,18 @@ uninit_iot: + return UADK_P_FAIL; + } + ++static int uadk_signature_sm2_sign_sw(void *vpsm2ctx, unsigned char *sig, size_t *siglen, ++ size_t sigsize, const unsigned char *tbs, size_t tbslen) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to soft sm2 sign\n"); ++ return get_default_sm2_signature().sign(vpsm2ctx, sig, siglen, sigsize, ++ tbs, tbslen); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_signature_sm2_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen) + { +@@ -1283,24 +1363,27 @@ static int uadk_signature_sm2_sign(void *vpsm2ctx, unsigned char *sig, size_t *s + + if (sigsize < (size_t)ecsize) { + fprintf(stderr, "sigsize(%zu) < ecsize(%d)\n", sigsize, ecsize); +- return UADK_P_FAIL; ++ goto do_soft; + } + + ret = uadk_prov_sm2_check_tbs_params(psm2ctx, tbs, tbslen); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to check sm2 signature params\n"); +- return ret; ++ goto do_soft; + } + + ret = uadk_prov_sm2_sign(psm2ctx, sig, &sltmp, tbs, tbslen); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to do sm2 sign\n"); +- return ret; ++ goto do_soft; + } + + *siglen = sltmp; + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_signature_sm2_sign_sw(vpsm2ctx, sig, siglen, sigsize, tbs, tbslen); + } + + static int uadk_prov_sm2_verify_init_iot(handle_t sess, struct wd_ecc_req *req, +@@ -1415,6 +1498,17 @@ uninit_iot: + return UADK_P_FAIL; + } + ++static int uadk_signature_sm2_verify_sw(void *vpsm2ctx, const unsigned char *sig, size_t siglen, ++ const unsigned char *tbs, size_t tbslen) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to soft sm2 verify\n"); ++ return get_default_sm2_signature().verify(vpsm2ctx, sig, siglen, tbs, tbslen); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_signature_sm2_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { +@@ -1435,10 +1529,13 @@ static int uadk_signature_sm2_verify(void *vpsm2ctx, const unsigned char *sig, s + ret = uadk_prov_sm2_verify(psm2ctx, sig, siglen, tbs, tbslen); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to do sm2 verify\n"); +- return ret; ++ goto do_soft; + } + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_signature_sm2_verify_sw(vpsm2ctx, sig, siglen, tbs, tbslen); + } + + static int uadk_signature_sm2_digest_sign_init(void *vpsm2ctx, const char *mdname, +@@ -2076,6 +2173,16 @@ static int uadk_prov_sm2_locate_id_digest(PROV_SM2_SIGN_CTX *psm2ctx, const OSS + return UADK_P_SUCCESS; + } + ++static int uadk_signature_sm2_set_ctx_params_sw(void *vpsm2ctx, const OSSL_PARAM params[]) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 set_ctx_params\n"); ++ return get_default_sm2_signature().set_ctx_params(vpsm2ctx, params); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_signature_sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) + { + PROV_SM2_SIGN_CTX *psm2ctx = (PROV_SM2_SIGN_CTX *)vpsm2ctx; +@@ -2110,11 +2217,14 @@ static int uadk_signature_sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM pa + ret = uadk_prov_sm2_update_sess(smctx); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to update sess in set_ctx\n"); +- return ret; ++ goto do_soft; + } + } + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_signature_sm2_set_ctx_params_sw(vpsm2ctx, params); + } + + static int uadk_signature_sm2_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params) +@@ -2250,6 +2360,28 @@ static int uadk_signature_sm2_verify_recover(void *vpsm2ctx, unsigned char *rout + return UADK_P_SUCCESS; + } + ++static UADK_PKEY_ASYM_CIPHER get_default_sm2_asym_cipher(void) ++{ ++ static UADK_PKEY_ASYM_CIPHER s_asym_cipher; ++ static int initilazed; ++ ++ if (__atomic_compare_exchange_n(&initilazed, &(int){0}, 1, false, __ATOMIC_SEQ_CST, ++ __ATOMIC_SEQ_CST)) { ++ UADK_PKEY_ASYM_CIPHER *asym_cipher = ++ (UADK_PKEY_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, "SM2", ++ "provider=default"); ++ ++ if (asym_cipher) { ++ s_asym_cipher = *asym_cipher; ++ EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); ++ } else { ++ __atomic_store_n(&initilazed, 0, __ATOMIC_SEQ_CST); ++ fprintf(stderr, "failed to EVP_ASYM_CIPHER_fetch default SM2 provider\n"); ++ } ++ } ++ return s_asym_cipher; ++} ++ + static void *uadk_asym_cipher_sm2_newctx(void *provctx) + { + PROV_SM2_ASYM_CTX *psm2ctx = OPENSSL_zalloc(sizeof(PROV_SM2_ASYM_CTX)); +@@ -2275,7 +2407,6 @@ static void *uadk_asym_cipher_sm2_newctx(void *provctx) + } + /* Use SM3 in default, other digest can be set with set_ctx_params API. */ + smctx->sm2_md->mdsize = SM3_DIGEST_LENGTH; +- strcpy(psm2ctx->mdname, OSSL_DIGEST_NAME_SM3); + + smctx->sm2_pd = OPENSSL_zalloc(sizeof(SM2_PKEY_DATA)); + if (smctx->sm2_pd == NULL) { +@@ -2332,6 +2463,17 @@ static void uadk_prov_sm2_set_default_md(PROV_SM2_ASYM_CTX *psm2ctx) + smd->md_nid = NID_sm3; + } + ++static int uadk_asym_cipher_sm2_encrypt_init_sw(void *vpsm2ctx, void *vkey, ++ const OSSL_PARAM params[]) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 encrypt init\n"); ++ return get_default_sm2_asym_cipher().encrypt_init(vpsm2ctx, vkey, params); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_asym_cipher_sm2_encrypt_init(void *vpsm2ctx, void *vkey, + const OSSL_PARAM params[]) + { +@@ -2363,20 +2505,20 @@ static int uadk_asym_cipher_sm2_encrypt_init(void *vpsm2ctx, void *vkey, + ret = uadk_asym_cipher_sm2_set_ctx_params(psm2ctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to set_ctx_params\n"); +- return ret; ++ goto do_soft; + } + + ret = uadk_prov_asym_cipher_get_support_state(SIGNATURE_SM2); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware sm2 signature support\n"); +- return ret; ++ goto do_soft; + } + + /* Init with UADK */ + ret = uadk_prov_ecc_init("sm2"); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); +- return ret; ++ goto do_soft; + } + + smctx->init_status = CTX_INIT_SUCC; +@@ -2384,10 +2526,13 @@ static int uadk_asym_cipher_sm2_encrypt_init(void *vpsm2ctx, void *vkey, + ret = uadk_prov_sm2_update_sess(smctx); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to update sess\n"); +- return ret; ++ goto do_soft; + } + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_asym_cipher_sm2_encrypt_init_sw(vpsm2ctx, vkey, params); + } + + static int uadk_prov_sm2_encrypt_check(PROV_SM2_ASYM_CTX *psm2ctx, +@@ -2524,6 +2669,18 @@ free_x1: + return ret; + } + ++static int uadk_prov_sm2_encrypt_sw(PROV_SM2_ASYM_CTX *vpsm2ctx, ++ unsigned char *out, size_t *outlen, ++ const unsigned char *in, size_t inlen) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 encrypt\n"); ++ return get_default_sm2_asym_cipher().encrypt(vpsm2ctx, out, outlen, 0, in, inlen); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_prov_sm2_encrypt(PROV_SM2_ASYM_CTX *vpsm2ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +@@ -2538,7 +2695,7 @@ static int uadk_prov_sm2_encrypt(PROV_SM2_ASYM_CTX *vpsm2ctx, + + ret = uadk_prov_sm2_encrypt_init_iot(smctx->sess, &req, (void *)in, inlen); + if (ret == UADK_P_FAIL) +- return ret; ++ goto do_soft; + + ret = uadk_prov_sm2_update_public_key(smctx, vpsm2ctx->key); + if (ret == UADK_P_FAIL) +@@ -2551,8 +2708,10 @@ static int uadk_prov_sm2_encrypt(PROV_SM2_ASYM_CTX *vpsm2ctx, + } + + wd_sm2_get_enc_out_params(req.dst, &c1, &c2, &c3); +- if (c1 == NULL || c2 == NULL || c3 == NULL) ++ if (c1 == NULL || c2 == NULL || c3 == NULL) { ++ ret = UADK_P_FAIL; + goto uninit_iot; ++ } + + ret = uadk_prov_sm2_asym_bin_to_ber(c1, c2, c3, out, outlen); + if (ret == UADK_P_FAIL) +@@ -2562,6 +2721,7 @@ static int uadk_prov_sm2_encrypt(PROV_SM2_ASYM_CTX *vpsm2ctx, + 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); ++ ret = UADK_P_FAIL; + goto uninit_iot; + } + +@@ -2573,8 +2733,8 @@ static int uadk_prov_sm2_encrypt(PROV_SM2_ASYM_CTX *vpsm2ctx, + uninit_iot: + wd_ecc_del_in(smctx->sess, req.src); + wd_ecc_del_out(smctx->sess, req.dst); +- +- return UADK_P_FAIL; ++do_soft: ++ return uadk_prov_sm2_encrypt_sw(vpsm2ctx, out, outlen, in, inlen); + } + + static size_t uadk_prov_ec_field_size(const EC_GROUP *group) +@@ -2792,10 +2952,23 @@ static int uadk_prov_sm2_get_plaintext(struct wd_ecc_req *req, + return UADK_P_SUCCESS; + } + ++static int uadk_prov_sm2_decrypt_sw(PROV_SM2_ASYM_CTX *ctx, ++ unsigned char *out, size_t *outlen, ++ const unsigned char *in, size_t inlen) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 decrypt\n"); ++ return get_default_sm2_asym_cipher().decrypt(ctx, out, outlen, 0, in, inlen); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_prov_sm2_decrypt(PROV_SM2_ASYM_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { ++ const unsigned char *original_in = in; + SM2_PROV_CTX *smctx = ctx->sm2_pctx; + struct sm2_ciphertext *ctext; + struct wd_ecc_req req = {0}; +@@ -2806,11 +2979,11 @@ static int uadk_prov_sm2_decrypt(PROV_SM2_ASYM_CTX *ctx, + + ret = uadk_prov_sm2_decrypt_check(smctx, out, outlen, in, inlen); + if (ret == UADK_P_FAIL) +- return ret; ++ goto do_soft; + + ctext = d2i_SM2_Ciphertext(NULL, &in, inlen); + if (ctext == NULL) +- return UADK_P_FAIL; ++ goto do_soft; + + md = (smctx->sm2_md->md == NULL) ? EVP_sm3() : smctx->sm2_md->md; + ret = uadk_prov_sm2_asym_ber_to_bin(md, ctext, &c1, &c2, &c3); +@@ -2849,7 +3022,8 @@ free_c1: + free(c1.x.data); + free_ctext: + SM2_Ciphertext_free(ctext); +- return UADK_P_FAIL; ++do_soft: ++ return uadk_prov_sm2_decrypt_sw(ctx, out, outlen, original_in, inlen); + } + + static int uadk_prov_sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size) +@@ -3043,6 +3217,16 @@ static EVP_MD *uadk_prov_load_digest_from_params(SM2_MD_DATA *smd, const OSSL_PA + return smd->md; + } + ++static int uadk_asym_cipher_sm2_set_ctx_params_sw(void *vpsm2ctx, const OSSL_PARAM params[]) ++{ ++ if (uadk_get_sw_offload_state()) { ++ fprintf(stderr, "switch to software sm2 set ctx params\n"); ++ return get_default_sm2_asym_cipher().set_ctx_params(vpsm2ctx, params); ++ } ++ ++ return UADK_P_FAIL; ++} ++ + static int uadk_asym_cipher_sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) + { + PROV_SM2_ASYM_CTX *psm2ctx = (PROV_SM2_ASYM_CTX *)vpsm2ctx; +@@ -3084,11 +3268,14 @@ static int uadk_asym_cipher_sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM + ret = uadk_prov_sm2_update_sess(smctx); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to update sess\n"); +- return ret; ++ goto do_soft; + } + } + + return UADK_P_SUCCESS; ++ ++do_soft: ++ return uadk_asym_cipher_sm2_set_ctx_params_sw(vpsm2ctx, params); + } + + static const OSSL_PARAM *uadk_asym_cipher_sm2_gettable_ctx_params(ossl_unused void *vpsm2ctx, +-- +2.25.1 + diff --git a/0029-uadk_provider-ecx-add-x448-and-x25519-switching-soft.patch b/0029-uadk_provider-ecx-add-x448-and-x25519-switching-soft.patch new file mode 100644 index 0000000..dc20326 --- /dev/null +++ b/0029-uadk_provider-ecx-add-x448-and-x25519-switching-soft.patch @@ -0,0 +1,426 @@ +From 36bbae98f24427a18c668500071e645462893fc3 Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 29/36] uadk_provider/ecx: add x448 and x25519 switching + software computation function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch ecx to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_ecx.c | 242 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 166 insertions(+), 76 deletions(-) + +diff --git a/src/uadk_prov_ecx.c b/src/uadk_prov_ecx.c +index 47fe1a9..3cc7fa1 100644 +--- a/src/uadk_prov_ecx.c ++++ b/src/uadk_prov_ecx.c +@@ -50,14 +50,56 @@ static inline int UADK_CRYPTO_DOWN_REF(int *val, int *ret, + __atomic_thread_fence(__ATOMIC_ACQUIRE); + return 1; + } ++static pthread_mutex_t x25519_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t x448_mutex = PTHREAD_MUTEX_INITIALIZER; + + UADK_PKEY_KEYMGMT_DESCR(x448, X448); + UADK_PKEY_KEYEXCH_DESCR(x448, X448); ++static UADK_PKEY_KEYEXCH get_default_x448_keyexch(void) ++{ ++ static UADK_PKEY_KEYEXCH s_keyexch; ++ static int initilazed; ++ ++ pthread_mutex_lock(&x448_mutex); ++ if (!initilazed) { ++ UADK_PKEY_KEYEXCH *keyexch = ++ (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "X448", "provider=default"); ++ if (keyexch) { ++ s_keyexch = *keyexch; ++ EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "failed to EVP_KEYEXCH_fetch default X448 provider\n"); ++ } ++ } ++ pthread_mutex_unlock(&x448_mutex); ++ ++ return s_keyexch; ++} ++ + UADK_PKEY_KEYMGMT_DESCR(x25519, X25519); + UADK_PKEY_KEYEXCH_DESCR(x25519, X25519); ++static UADK_PKEY_KEYEXCH get_default_x25519_keyexch(void) ++{ ++ static UADK_PKEY_KEYEXCH s_keyexch; ++ static int initilazed; + +-static pthread_mutex_t x25519_mutex = PTHREAD_MUTEX_INITIALIZER; +-static pthread_mutex_t x448_mutex = PTHREAD_MUTEX_INITIALIZER; ++ pthread_mutex_lock(&x25519_mutex); ++ if (!initilazed) { ++ UADK_PKEY_KEYEXCH *keyexch = ++ (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "X25519", "provider=default"); ++ if (keyexch) { ++ s_keyexch = *keyexch; ++ EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "failed to EVP_KEYEXCH_fetch default X25519 provider\n"); ++ } ++ } ++ pthread_mutex_unlock(&x25519_mutex); ++ ++ return s_keyexch; ++} + + typedef enum { + ECX_KEY_TYPE_X25519 = 0x0, +@@ -706,44 +748,89 @@ static int uadk_prov_ecx_keygen_set_prikey(PROV_ECX_KEYMGMT_CTX *gctx, ECX_KEY * + return UADK_P_SUCCESS; + } + +-static void *uadk_prov_ecx_keygen(PROV_ECX_KEYMGMT_CTX *gctx) ++static int uadk_prov_ecx_keygen(PROV_ECX_KEYMGMT_CTX *gctx, ECX_KEY **ecx_key) + { + struct wd_ecc_req req = {0}; +- ECX_KEY *ecx_key = NULL; + int ret; + +- ecx_key = uadk_prov_ecx_create_prikey(gctx); + if (ecx_key == NULL) +- return NULL; ++ return UADK_P_FAIL; ++ ++ *ecx_key = uadk_prov_ecx_create_prikey(gctx); ++ if (*ecx_key == NULL) ++ return UADK_P_FAIL; + + ret = uadk_prov_ecx_keygen_init_iot(gctx->sess, &req); + if (ret == UADK_P_FAIL) + goto free_prikey; + +- ret = uadk_prov_ecx_keygen_set_prikey(gctx, ecx_key); ++ ret = uadk_prov_ecx_keygen_set_prikey(gctx, *ecx_key); + if (ret == UADK_P_FAIL) + goto uninit_iot; + + ret = uadk_prov_ecc_crypto(gctx->sess, &req, (void *)gctx->sess); +- if (ret == UADK_P_FAIL) ++ if (ret != UADK_P_SUCCESS) { ++ ret = UADK_DO_SOFT; + goto uninit_iot; +- +- ret = uadk_prov_ecx_set_pkey(gctx, &req, ecx_key); ++ } ++ ret = uadk_prov_ecx_set_pkey(gctx, &req, *ecx_key); + if (ret == UADK_P_FAIL) + goto uninit_iot; + +- ecx_key->haspubkey = 1; ++ (*ecx_key)->haspubkey = 1; + + uadk_prov_ecx_keygen_uninit_iot(gctx->sess, &req); + +- return ecx_key; ++ return UADK_P_SUCCESS; + + uninit_iot: + uadk_prov_ecx_keygen_uninit_iot(gctx->sess, &req); + free_prikey: +- uadk_prov_ecx_free_prikey(ecx_key); ++ uadk_prov_ecx_free_prikey(*ecx_key); + +- return NULL; ++ return ret; ++} ++ ++static void *uadk_ecx_sw_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params, ++ ECX_KEY_TYPE alg_type) ++{ ++ if (!enable_sw_offload) ++ return NULL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecx generation.\n"); ++ switch (alg_type) { ++ case ECX_KEY_TYPE_X448: ++ if (!get_default_x448_keymgmt().gen) ++ return NULL; ++ return get_default_x448_keymgmt().gen(genctx, cb, cb_params); ++ case ECX_KEY_TYPE_X25519: ++ if (!get_default_x25519_keymgmt().gen) ++ return NULL; ++ return get_default_x25519_keymgmt().gen(genctx, cb, cb_params); ++ default: ++ return NULL; ++ } ++} ++ ++static int uadk_ecx_sw_derive(void *vecxctx, unsigned char *secret, size_t *secretlen, ++ size_t outlen, ECX_KEY_TYPE alg_type) ++{ ++ if (!enable_sw_offload) ++ return UADK_P_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecx derivation.\n"); ++ switch (alg_type) { ++ case ECX_KEY_TYPE_X448: ++ if (!get_default_x448_keyexch().derive) ++ return UADK_P_FAIL; ++ return get_default_x448_keyexch().derive(vecxctx, secret, secretlen, outlen); ++ case ECX_KEY_TYPE_X25519: ++ if (!get_default_x25519_keyexch().derive) ++ return UADK_P_FAIL; ++ return get_default_x25519_keyexch().derive(vecxctx, secret, secretlen, outlen); ++ default: ++ return UADK_P_FAIL; ++ } + } + + static void *uadk_keymgmt_x448_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) +@@ -765,50 +852,39 @@ static void *uadk_keymgmt_x448_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_par + ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_X448); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware x448 keygen support\n"); +- return NULL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ret = uadk_prov_ecc_init("x448"); + if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to init x448\n"); +- return NULL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + gctx->sess = uadk_prov_ecx_alloc_sess(ECX_KEY_TYPE_X448); + if (gctx->sess == (handle_t)0) { + fprintf(stderr, "failed to alloc x448 sess\n"); +- return NULL; ++ ret = UADK_P_FAIL; ++ goto exe_soft; + } + +- ecx_key = uadk_prov_ecx_keygen(gctx); +- if (ecx_key == NULL) ++ ret = uadk_prov_ecx_keygen(gctx, &ecx_key); ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to generate x448 key\n"); ++ uadk_prov_ecx_free_sess(gctx->sess); ++ goto exe_soft; ++ } + + uadk_prov_ecx_free_sess(gctx->sess); + + return ecx_key; +-} +- +-static UADK_PKEY_KEYEXCH get_default_x448_keyexch(void) +-{ +- static UADK_PKEY_KEYEXCH s_keyexch; +- static int initilazed; +- +- pthread_mutex_lock(&x448_mutex); +- if (!initilazed) { +- UADK_PKEY_KEYEXCH *keyexch = +- (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "X448", "provider=default"); +- if (keyexch) { +- s_keyexch = *keyexch; +- EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); +- initilazed = 1; +- } else { +- fprintf(stderr, "failed to EVP_KEYEXCH_fetch default X448 provider\n"); +- } +- } +- pthread_mutex_unlock(&x448_mutex); + +- return s_keyexch; ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_ecx_sw_gen(genctx, cb, cb_params, ECX_KEY_TYPE_X448); ++ return NULL; + } + + static void *uadk_keyexch_x448_newctx(void *provctx) +@@ -1101,12 +1177,15 @@ static int uadk_prov_ecx_derive(PROV_ECX_KEYEXCH_CTX *ecxctx, unsigned char *key + goto uninit_iot; + + ret = uadk_prov_ecc_crypto(ecxctx->sess, &req, (void *)ecxctx); +- if (ret == UADK_P_FAIL) ++ if (ret != UADK_P_SUCCESS) { ++ ret = UADK_DO_SOFT; + goto uninit_iot; +- ++ } + wd_ecxdh_get_out_params(req.dst, &s_key); +- if (!s_key) ++ if (!s_key) { ++ ret = UADK_P_FAIL; + goto uninit_iot; ++ } + + ret = uadk_prov_reverse_bytes((unsigned char *)s_key->x.data, s_key->x.dsize); + if (ret == UADK_P_FAIL) +@@ -1155,30 +1234,41 @@ static int uadk_keyexch_x448_derive(void *vecxctx, unsigned char *secret, size_t + ret = uadk_prov_keyexch_get_support_state(KEYEXCH_X448); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware x448 keyexch support\n"); +- return UADK_P_FAIL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ret = uadk_prov_ecc_init("x448"); + if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to init x448\n"); +- return UADK_P_FAIL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ecxctx->sess = uadk_prov_ecx_alloc_sess(ECX_KEY_TYPE_X448); + if (ecxctx->sess == (handle_t)0) { + fprintf(stderr, "failed to alloc sess\n"); +- return UADK_P_FAIL; ++ ret = UADK_P_FAIL; ++ goto exe_soft; + } + + ret = uadk_prov_ecx_derive(ecxctx, secret, &ecxctx->keylen); +- if (ret == UADK_P_FAIL) ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to do x448 derive\n"); ++ uadk_prov_ecx_free_sess(ecxctx->sess); ++ goto exe_soft; ++ } + + *secretlen = ecxctx->keylen; + + uadk_prov_ecx_free_sess(ecxctx->sess); + + return ret; ++ ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_ecx_sw_derive(vecxctx, secret, secretlen, outlen, ECX_KEY_TYPE_X448); ++ return UADK_P_FAIL; + } + + static void *uadk_keyexch_ecx_dupctx(void *vecxctx) +@@ -1409,50 +1499,39 @@ static void *uadk_keymgmt_x25519_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_p + ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_X25519); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware x25519 keygen support\n"); +- return NULL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ret = uadk_prov_ecc_init("x25519"); + if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to init x25519\n"); +- return NULL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + gctx->sess = uadk_prov_ecx_alloc_sess(ECX_KEY_TYPE_X25519); + if (gctx->sess == (handle_t)0) { + fprintf(stderr, "failed to alloc x25519 sess\n"); ++ ret = UADK_P_FAIL; + return NULL; + } + +- ecx_key = uadk_prov_ecx_keygen(gctx); +- if (ecx_key == NULL) ++ ret = uadk_prov_ecx_keygen(gctx, &ecx_key); ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to generate x25519 key\n"); ++ uadk_prov_ecx_free_sess(gctx->sess); ++ goto exe_soft; ++ } + + uadk_prov_ecx_free_sess(gctx->sess); + + return ecx_key; +-} +- +-static UADK_PKEY_KEYEXCH get_default_x25519_keyexch(void) +-{ +- static UADK_PKEY_KEYEXCH s_keyexch; +- static int initilazed; +- +- pthread_mutex_lock(&x25519_mutex); +- if (!initilazed) { +- UADK_PKEY_KEYEXCH *keyexch = +- (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "X25519", "provider=default"); +- if (keyexch) { +- s_keyexch = *keyexch; +- EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); +- initilazed = 1; +- } else { +- fprintf(stderr, "failed to EVP_KEYEXCH_fetch default X25519 provider\n"); +- } +- } +- pthread_mutex_unlock(&x25519_mutex); + +- return s_keyexch; ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_ecx_sw_gen(genctx, cb, cb_params, ECX_KEY_TYPE_X25519); ++ return NULL; + } + + static void *uadk_keyexch_x25519_newctx(void *provctx) +@@ -1559,30 +1638,41 @@ static int uadk_keyexch_x25519_derive(void *vecxctx, unsigned char *secret, size + ret = uadk_prov_keyexch_get_support_state(KEYEXCH_X25519); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get hardware x25519 keyexch support\n"); +- return UADK_P_FAIL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ret = uadk_prov_ecc_init("x25519"); + if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to init x25519\n"); +- return UADK_P_FAIL; ++ ret = UADK_DO_SOFT; ++ goto exe_soft; + } + + ecxctx->sess = uadk_prov_ecx_alloc_sess(ECX_KEY_TYPE_X25519); + if (ecxctx->sess == (handle_t)0) { + fprintf(stderr, "failed to alloc sess\n"); +- return UADK_P_FAIL; ++ ret = UADK_P_FAIL; ++ goto exe_soft; + } + + ret = uadk_prov_ecx_derive(ecxctx, secret, &ecxctx->keylen); +- if (ret == UADK_P_FAIL) ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to do x25519 derive\n"); ++ uadk_prov_ecx_free_sess(ecxctx->sess); ++ goto exe_soft; ++ } + + *secretlen = ecxctx->keylen; + + uadk_prov_ecx_free_sess(ecxctx->sess); + + return ret; ++ ++exe_soft: ++ if (ret == UADK_DO_SOFT) ++ return uadk_ecx_sw_derive(vecxctx, secret, secretlen, outlen, ECX_KEY_TYPE_X25519); ++ return UADK_P_FAIL; + } + + static void *uadk_keyexch_x25519_dupctx(void *vecxctx) +-- +2.25.1 + diff --git a/0030-uadk_provider-ecdsa-add-ecdsa-switching-software-com.patch b/0030-uadk_provider-ecdsa-add-ecdsa-switching-software-com.patch new file mode 100644 index 0000000..937e332 --- /dev/null +++ b/0030-uadk_provider-ecdsa-add-ecdsa-switching-software-com.patch @@ -0,0 +1,171 @@ +From e58b650bdb0314703facd9a932fce183a51cc734 Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 30/36] uadk_provider/ecdsa: add ecdsa switching software + computation function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch ecdsa to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_ecdsa.c | 69 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +diff --git a/src/uadk_prov_ecdsa.c b/src/uadk_prov_ecdsa.c +index 774e8ee..7ea5567 100644 +--- a/src/uadk_prov_ecdsa.c ++++ b/src/uadk_prov_ecdsa.c +@@ -344,6 +344,37 @@ static int uadk_signature_ecdsa_verify_init(void *vctx, void *ec, const OSSL_PAR + return ecdsa_signverify_init(vctx, ec, params, EVP_PKEY_OP_VERIFY); + } + ++static int ecdsa_soft_sign(struct ecdsa_ctx *ctx, unsigned char *sig, size_t *siglen, ++ size_t sigsize, const unsigned char *tbs, size_t tbslen) ++{ ++ unsigned int tmplen; ++ int ret; ++ ++ if (!enable_sw_offload) ++ return UADK_P_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecdsa signature.\n"); ++ ++ ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &tmplen, ctx->kinv, ctx->r, ctx->ec); ++ if (ret <= 0) ++ return UADK_P_FAIL; ++ ++ *siglen = (size_t)tmplen; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdsa_soft_verify(struct ecdsa_ctx *ctx, const unsigned char *sig, size_t siglen, ++ const unsigned char *tbs, size_t tbslen) ++{ ++ if (!enable_sw_offload) ++ return UADK_P_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecdsa verification.\n"); ++ ++ return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec); ++} ++ + static int ecdsa_common_params_check(struct ecdsa_ctx *ctx, + struct ecdsa_opdata *opdata) + { +@@ -371,7 +402,7 @@ static int ecdsa_common_params_check(struct ecdsa_ctx *ctx, + type = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + if (type != NID_X9_62_prime_field) { + fprintf(stderr, "invalid: uadk unsupport Field GF(2m)!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + opdata->ec = ctx->ec; +@@ -563,7 +594,7 @@ static int ecdsa_hw_sign(struct ecdsa_opdata *opdata) + sess = ecdsa_alloc_sess(opdata->ec); + if (unlikely(!sess)) { + fprintf(stderr, "failed to alloc ecdsa sess!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + ret = ecdsa_sign_init_iot(sess, &req, opdata); +@@ -579,8 +610,9 @@ static int ecdsa_hw_sign(struct ecdsa_opdata *opdata) + } + + ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); +- if (unlikely(!ret)) { +- fprintf(stderr, "failed to sign!\n"); ++ if (unlikely(!ret || req.status)) { ++ fprintf(stderr, "failed to hardware sign!\n"); ++ ret = UADK_DO_SOFT; + goto free_iot; + } + +@@ -639,13 +671,13 @@ static int uadk_signature_ecdsa_sign(void *vctx, unsigned char *sig, size_t *sig + ret = ecdsa_sign_params_check(ctx, &opdata, sig, siglen, sigsize); + if (ret == UADK_SIGN_SIG_NULL) { + return UADK_P_SUCCESS; +- } else if (unlikely(!ret)) { ++ } else if (unlikely(ret != UADK_P_SUCCESS)) { + fprintf(stderr, "failed to check params to sign!\n"); + goto err; + } + + ret = ecdsa_hw_sign(&opdata); +- if (unlikely(!ret)) ++ if (unlikely(ret != UADK_P_SUCCESS)) + goto err; + ret = i2d_ECDSA_SIG(opdata.sig, &sig); + /* ECDSA_SIG_free will free br and bs applied for in ecdsa_get_sign_data() */ +@@ -659,6 +691,10 @@ static int uadk_signature_ecdsa_sign(void *vctx, unsigned char *sig, size_t *sig + err: + if (siglen) + *siglen = 0; ++ ++ if (ret == UADK_DO_SOFT) ++ return ecdsa_soft_sign(ctx, sig, siglen, sigsize, tbs, tbslen); ++ + return UADK_P_FAIL; + } + +@@ -706,20 +742,24 @@ static int ecdsa_hw_verify(struct ecdsa_opdata *opdata) + int ret; + + sess = ecdsa_alloc_sess(opdata->ec); +- if (!sess) { ++ if (unlikely(!sess)) { + fprintf(stderr, "failed to alloc ecdsa sess!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + ret = ecdsa_verify_init_iot(sess, &req, opdata); +- if (!ret) ++ if (unlikely(!ret)) + goto free_sess; + + ret = uadk_prov_ecc_set_public_key(sess, opdata->ec); +- if (!ret) ++ if (unlikely(!ret)) + goto free_iot; + + ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); ++ if (unlikely(ret != UADK_P_SUCCESS || req.status)) { ++ fprintf(stderr, "failed to hardware verify!\n"); ++ ret = UADK_DO_SOFT; ++ } + + free_iot: + ecdsa_uninit_req_iot(sess, &req); +@@ -791,9 +831,9 @@ static int uadk_signature_ecdsa_verify(void *vctx, const unsigned char *sig, + opdata.tbs = tbs; + opdata.tbslen = tbslen; + ret = ecdsa_verify_params_check(ctx, &opdata, sig, siglen); +- if (!ret) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to check params to sign!\n"); +- return UADK_P_FAIL; ++ goto err; + } + + opdata.sig = ecdsa_create_sig(sig, siglen); +@@ -805,6 +845,11 @@ static int uadk_signature_ecdsa_verify(void *vctx, const unsigned char *sig, + ret = ecdsa_hw_verify(&opdata); + + ECDSA_SIG_free(opdata.sig); ++ ++err: ++ if (ret == UADK_DO_SOFT) ++ return ecdsa_soft_verify(ctx, sig, siglen, tbs, tbslen); ++ + return ret; + } + +-- +2.25.1 + diff --git a/0031-uadk_provider-ecdh-add-ecdh-switching-software-compu.patch b/0031-uadk_provider-ecdh-add-ecdh-switching-software-compu.patch new file mode 100644 index 0000000..1814dad --- /dev/null +++ b/0031-uadk_provider-ecdh-add-ecdh-switching-software-compu.patch @@ -0,0 +1,243 @@ +From b3dc1f476db3600d0713b6771f25fe9b9c0f6196 Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 31/36] uadk_provider/ecdh: add ecdh switching software + computation function + +When hardware failures occur, or in cases of insufficient +queue resources or unsupported algorithm specifications, +the uadk provider can switch ecdh to openssl soft computation. + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_ec_kmgmt.c | 27 +++++++++++++---- + src/uadk_prov_ecdh_exch.c | 61 +++++++++++++++++++++++++++++++++------ + 2 files changed, 73 insertions(+), 15 deletions(-) + +diff --git a/src/uadk_prov_ec_kmgmt.c b/src/uadk_prov_ec_kmgmt.c +index 355d601..01bcc50 100644 +--- a/src/uadk_prov_ec_kmgmt.c ++++ b/src/uadk_prov_ec_kmgmt.c +@@ -54,10 +54,12 @@ static int ec_param_check(struct ec_gen_ctx *gctx, EC_KEY *ec) + type = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + if (type != NID_X9_62_prime_field) { + fprintf(stderr, "invalid: uadk unsupport Field GF(2m)!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + +- return uadk_prov_ecc_bit_check(group); ++ ret = uadk_prov_ecc_bit_check(group); ++ ++ return ret; + } + + static int ec_set_public_key(EC_KEY *ec, struct wd_ecc_out *ec_out) +@@ -235,7 +237,7 @@ static int ec_hw_keygen(EC_KEY *ec, BIGNUM *priv_key) + sess = ec_alloc_sess(ec, &ec_out); + if (!sess) { + fprintf(stderr, "failed to alloc sess!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + ret = ec_update_private_key(ec, sess, priv_key); +@@ -246,8 +248,9 @@ static int ec_hw_keygen(EC_KEY *ec, BIGNUM *priv_key) + + uadk_prov_ecc_fill_req(&req, WD_ECXDH_GEN_KEY, NULL, ec_out); + ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); +- if (!ret) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to generate key!\n"); ++ ret = UADK_DO_SOFT; + goto free_sess; + } + +@@ -319,6 +322,15 @@ static int ec_set_check_group_type(EC_KEY *ec, const char *name) + return UADK_P_SUCCESS; + } + ++static void *uadk_ec_sw_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ++{ ++ if (!enable_sw_offload || !get_default_ec_keymgmt().gen) ++ return NULL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecx generation.\n"); ++ return get_default_ec_keymgmt().gen(genctx, osslcb, cbarg); ++} ++ + static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) + { + struct ec_gen_ctx *gctx = genctx; +@@ -337,7 +349,7 @@ static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbar + } + + ret = ec_param_check(genctx, ec); +- if (!ret) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to check genctx!\n"); + goto free_ec_key; + } +@@ -345,7 +357,7 @@ static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbar + /* Whether you want it or not, you get a keypair, not just one half */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + ret = ec_hw_keygen(ec, gctx->priv_key); +- if (!ret) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to gen public key!\n"); + goto free_ec_key; + } +@@ -367,6 +379,9 @@ static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbar + + free_ec_key: + EC_KEY_free(ec); ++ ++ if (ret == UADK_DO_SOFT) ++ return uadk_ec_sw_gen(genctx, osslcb, cbarg); + return NULL; + } + +diff --git a/src/uadk_prov_ecdh_exch.c b/src/uadk_prov_ecdh_exch.c +index 9ac8e58..f3b2e68 100644 +--- a/src/uadk_prov_ecdh_exch.c ++++ b/src/uadk_prov_ecdh_exch.c +@@ -72,6 +72,28 @@ struct ecdh_sess_ctx { + }; + + UADK_PKEY_KEYEXCH_DESCR(ecdh, ECDH); ++static pthread_mutex_t ecdh_mutex = PTHREAD_MUTEX_INITIALIZER; ++static UADK_PKEY_KEYEXCH get_default_ecdh_keyexch(void) ++{ ++ static UADK_PKEY_KEYEXCH s_keyexch; ++ static int initilazed; ++ ++ pthread_mutex_lock(&ecdh_mutex); ++ if (!initilazed) { ++ UADK_PKEY_KEYEXCH *keyexch = ++ (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "ecdh", "provider=default"); ++ if (keyexch) { ++ s_keyexch = *keyexch; ++ EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); ++ initilazed = 1; ++ } else { ++ fprintf(stderr, "failed to EVP_KEYEXCH_fetch default X448 provider\n"); ++ } ++ } ++ pthread_mutex_unlock(&ecdh_mutex); ++ ++ return s_keyexch; ++} + + static size_t ecdh_get_ec_size(const EC_GROUP *group) + { +@@ -114,12 +136,15 @@ static int ecdh_param_check(struct ecdh_ctx *pecdhctx, struct ecdh_sess_ctx *ses + type = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + if (type != NID_X9_62_prime_field) { + fprintf(stderr, "invalid: uadk unsupport Field GF(2m)!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + sess_ctx->group = group; + +- return uadk_prov_ecc_bit_check(group); ++ if (uadk_prov_ecc_bit_check(group) != UADK_P_SUCCESS) ++ return UADK_DO_SOFT; ++ ++ return UADK_P_SUCCESS; + } + + static int ecdh_set_privk(struct ecdh_ctx *pecdhctx, +@@ -276,7 +301,7 @@ static int ecdh_compute_key(struct ecdh_sess_ctx *sess_ctx, + sess = ecdh_alloc_sess(sess_ctx->privk); + if (!sess) { + fprintf(stderr, "failed to alloc sess to compute key!\n"); +- return UADK_P_FAIL; ++ return UADK_DO_SOFT; + } + + ret = uadk_prov_ecc_set_private_key(sess, sess_ctx->privk); +@@ -292,8 +317,9 @@ static int ecdh_compute_key(struct ecdh_sess_ctx *sess_ctx, + } + + ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); +- if (!ret) { ++ if (ret != UADK_P_SUCCESS) { + fprintf(stderr, "failed to calculate shared key!\n"); ++ ret = UADK_DO_SOFT; + goto uninit_req; + } + +@@ -315,7 +341,7 @@ static int ecdh_plain_derive(struct ecdh_ctx *pecdhctx, + int ret; + + ret = ecdh_param_check(pecdhctx, &sess_ctx); +- if (!ret) ++ if (ret != UADK_P_SUCCESS) + return ret; + + ec_size = ecdh_get_ec_size(sess_ctx.group); +@@ -389,13 +415,13 @@ static int ecdh_X9_63_kdf_derive(struct ecdh_ctx *pecdhctx, unsigned char *secre + } + + if (outlen < pecdhctx->kdf_outlen) { +- fprintf(stderr, "invalid: outlen %lu is less than kdf_outlen %lu!\n", ++ fprintf(stderr, "invalid: outlen %zu is less than kdf_outlen %zu!\n", + outlen, pecdhctx->kdf_outlen); + return UADK_P_FAIL; + } + + ret = ecdh_plain_derive(pecdhctx, NULL, &stmplen, 0); +- if (!ret) ++ if (ret != UADK_P_SUCCESS) + return ret; + + stmp = OPENSSL_secure_malloc(stmplen); +@@ -419,10 +445,21 @@ static int ecdh_X9_63_kdf_derive(struct ecdh_ctx *pecdhctx, unsigned char *secre + return ret; + } + ++static int uadk_ecdh_sw_derive(void *vpecdhctx, unsigned char *secret, ++ size_t *psecretlen, size_t outlen) ++{ ++ if (!enable_sw_offload || !get_default_ecdh_keyexch().derive) ++ return UADK_P_FAIL; ++ ++ fprintf(stderr, "switch to openssl software calculation in ecdh derivation.\n"); ++ return get_default_ecdh_keyexch().derive(vpecdhctx, secret, psecretlen, outlen); ++} ++ + static int uadk_keyexch_ecdh_derive(void *vpecdhctx, unsigned char *secret, + size_t *psecretlen, size_t outlen) + { + struct ecdh_ctx *pecdhctx = vpecdhctx; ++ int ret; + + if (!pecdhctx) { + fprintf(stderr, "invalid: vpecdhctx is NULL to derive!\n"); +@@ -431,13 +468,19 @@ static int uadk_keyexch_ecdh_derive(void *vpecdhctx, unsigned char *secret, + + switch (pecdhctx->kdf_type) { + case PROV_ECDH_KDF_NONE: +- return ecdh_plain_derive(pecdhctx, secret, psecretlen, outlen); ++ ret = ecdh_plain_derive(pecdhctx, secret, psecretlen, outlen); ++ break; + case PROV_ECDH_KDF_X9_63: +- return ecdh_X9_63_kdf_derive(pecdhctx, secret, psecretlen, outlen); ++ ret = ecdh_X9_63_kdf_derive(pecdhctx, secret, psecretlen, outlen); ++ break; + default: + break; + } + ++ if (ret == UADK_P_SUCCESS) ++ return UADK_P_SUCCESS; ++ if (ret == UADK_DO_SOFT) ++ return uadk_ecdh_sw_derive(vpecdhctx, secret, psecretlen, outlen); + return UADK_P_FAIL; + } + +-- +2.25.1 + diff --git a/0032-digest-fix-for-digest-soft-work.patch b/0032-digest-fix-for-digest-soft-work.patch new file mode 100644 index 0000000..7179110 --- /dev/null +++ b/0032-digest-fix-for-digest-soft-work.patch @@ -0,0 +1,161 @@ +From ee32097634473a8481a1a915b3e0f88f9654ba71 Mon Sep 17 00:00:00 2001 +From: Wenkai Lin +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 32/36] digest: fix for digest soft work + +In the event of a soft failure, an error should be +returned to avoid errors such as empty addresses in +subsequent steps. + +Signed-off-by: Wenkai Lin +Signed-off-by: JiangShui Yang +--- + src/uadk_digest.c | 38 ++++++++++++++++++++++++++++---------- + src/uadk_prov_digest.c | 40 ++++++++++++++++++++++++++++++---------- + 2 files changed, 58 insertions(+), 20 deletions(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index ed68ee2..cb593a8 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -321,16 +321,23 @@ static void digest_soft_cleanup(struct digest_priv_ctx *md_ctx) + static int uadk_e_digest_soft_work(struct digest_priv_ctx *md_ctx, int len, + unsigned char *digest) + { +- (void)digest_soft_init(md_ctx); ++ int ret; + +- if (len != 0) +- (void)digest_soft_update(md_ctx, md_ctx->data, len); ++ ret = digest_soft_init(md_ctx); ++ if (unlikely(!ret)) ++ return 0; + +- (void)digest_soft_final(md_ctx, digest); ++ if (len != 0) { ++ ret = digest_soft_update(md_ctx, md_ctx->data, len); ++ if (unlikely(!ret)) ++ goto out; ++ } + +- digest_soft_cleanup(md_ctx); ++ ret = digest_soft_final(md_ctx, digest); + +- return 1; ++out: ++ digest_soft_cleanup(md_ctx); ++ return ret; + } + + static int uadk_engine_digests(ENGINE *e, const EVP_MD **digest, +@@ -730,19 +737,30 @@ static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_le + do_soft_digest: + if (priv->state == SEC_DIGEST_FIRST_UPDATING) { + priv->switch_flag = UADK_DO_SOFT; +- (void)digest_soft_init(priv); ++ ret = digest_soft_init(priv); ++ if (!ret) ++ return ret; + /* filling buf has been executed */ + if (processing_len < DIGEST_BLOCK_SIZE) { + ret = digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); +- if (ret != 1) +- return ret; ++ if (!ret) ++ goto out; + } + +- return digest_soft_update(priv, tmpdata, left_len); ++ ret = digest_soft_update(priv, tmpdata, left_len); ++ if (!ret) ++ goto out; ++ ++ /* the soft ctx will be free in the final stage. */ ++ return ret; + } + + fprintf(stderr, "do soft digest failed during updating!\n"); + return 0; ++ ++out: ++ digest_soft_cleanup(priv); ++ return ret; + } + + static int uadk_e_digest_update(EVP_MD_CTX *ctx, const void *data, size_t data_len) +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index 562e786..a2a5f09 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -218,18 +218,26 @@ 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) + { ++ int ret; ++ + if (!priv->soft_md) + return UADK_DIGEST_FAIL; + +- uadk_digest_soft_init(priv); ++ ret = uadk_digest_soft_init(priv); ++ if (unlikely(ret == UADK_DIGEST_FAIL)) ++ return UADK_DIGEST_FAIL; + +- if (len != 0) +- uadk_digest_soft_update(priv, priv->data, len); ++ if (len != 0) { ++ ret = uadk_digest_soft_update(priv, priv->data, len); ++ if (unlikely(ret == UADK_DIGEST_FAIL)) ++ goto out; ++ } + +- uadk_digest_soft_final(priv, digest); +- digest_soft_cleanup(priv); ++ ret = uadk_digest_soft_final(priv, digest); + +- return UADK_DIGEST_SUCCESS; ++out: ++ digest_soft_cleanup(priv); ++ return ret; + } + + static int uadk_digest_poll(void *ctx) +@@ -455,19 +463,31 @@ static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *da + do_soft_digest: + if (priv->state == SEC_DIGEST_FIRST_UPDATING) { + priv->switch_flag = UADK_DO_SOFT; +- uadk_digest_soft_init(priv); ++ ret = uadk_digest_soft_init(priv); ++ if (!ret) ++ return ret; ++ + /* filling buf has been executed */ + if (processing_len < DIGEST_BLOCK_SIZE) { + ret = uadk_digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); +- if (ret != 1) +- return ret; ++ if (!ret) ++ goto out; + } + +- return uadk_digest_soft_update(priv, input_data, remain_len); ++ ret = uadk_digest_soft_update(priv, input_data, remain_len); ++ if (!ret) ++ goto out; ++ ++ /* the soft ctx will be free in the final stage. */ ++ return ret; + } + + fprintf(stderr, "do soft digest failed during updating!\n"); + return UADK_DIGEST_FAIL; ++ ++out: ++ digest_soft_cleanup(priv); ++ return ret; + } + + static int uadk_digest_update(struct digest_priv_ctx *priv, const void *data, size_t data_len) +-- +2.25.1 + diff --git a/0033-digest-fix-for-digest-soft-init.patch b/0033-digest-fix-for-digest-soft-init.patch new file mode 100644 index 0000000..b9958a1 --- /dev/null +++ b/0033-digest-fix-for-digest-soft-init.patch @@ -0,0 +1,135 @@ +From 4357e696446cc385c17b023b6254be7b69d2fdfe Mon Sep 17 00:00:00 2001 +From: Wenkai Lin +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 33/36] digest: fix for digest soft init + +Ensure that soft_ctx is initialized before +invoking software calculation and reduces +repeated judgments for digest soft init. + +Signed-off-by: Wenkai Lin +Signed-off-by: JiangShui Yang +--- + src/uadk_digest.c | 62 ++++++++++++++++++----------------------------- + 1 file changed, 24 insertions(+), 38 deletions(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index cb593a8..c93b0ca 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -187,72 +187,55 @@ static EVP_MD *uadk_sha256; + static EVP_MD *uadk_sha384; + static EVP_MD *uadk_sha512; + ++/* OpenSSL 3.0 has no app_datasize, need set manually, ++ * check crypto/evp/legacy_md5.c: md5_md as example. ++ */ ++#define SET_APP_DATASIZE(ctx_type) \ ++do {\ ++ app_datasize = EVP_MD_meth_get_app_datasize(priv->soft_md); \ ++ if (!app_datasize) \ ++ app_datasize = sizeof(EVP_MD *) + sizeof(ctx_type); \ ++} while (0) ++ + static int uadk_e_digests_soft_md(struct digest_priv_ctx *priv) + { +- int app_datasize = 0; ++ int app_datasize; + +- if (priv->soft_md) ++ if (priv->soft_md && priv->soft_ctx) + return 1; + + switch (priv->e_nid) { + case NID_sm3: + priv->soft_md = EVP_sm3(); ++ SET_APP_DATASIZE(SM3_CTX); + break; + case NID_md5: + priv->soft_md = EVP_md5(); ++ SET_APP_DATASIZE(MD5_CTX); + break; + case NID_sha1: + priv->soft_md = EVP_sha1(); ++ SET_APP_DATASIZE(SHA_CTX); + break; + case NID_sha224: + priv->soft_md = EVP_sha224(); ++ SET_APP_DATASIZE(SHA256_CTX); + break; + case NID_sha256: + priv->soft_md = EVP_sha256(); ++ SET_APP_DATASIZE(SHA256_CTX); + break; + case NID_sha384: + priv->soft_md = EVP_sha384(); ++ SET_APP_DATASIZE(SHA512_CTX); + break; + case NID_sha512: + priv->soft_md = EVP_sha512(); ++ SET_APP_DATASIZE(SHA512_CTX); + break; + default: +- break; +- } +- +- if (unlikely(priv->soft_md == NULL)) ++ fprintf(stderr, "digest nid %d is invalid.\n", priv->e_nid); + return 0; +- +- app_datasize = EVP_MD_meth_get_app_datasize(priv->soft_md); +- if (app_datasize == 0) { +- /* OpenSSL 3.0 has no app_datasize, need set manually +- * check crypto/evp/legacy_md5.c: md5_md as example +- */ +- switch (priv->e_nid) { +- case NID_sm3: +- app_datasize = sizeof(EVP_MD *) + sizeof(SM3_CTX); +- break; +- case NID_md5: +- app_datasize = sizeof(EVP_MD *) + sizeof(MD5_CTX); +- break; +- case NID_sha1: +- app_datasize = sizeof(EVP_MD *) + sizeof(SHA_CTX); +- break; +- case NID_sha224: +- app_datasize = sizeof(EVP_MD *) + sizeof(SHA256_CTX); +- break; +- case NID_sha256: +- app_datasize = sizeof(EVP_MD *) + sizeof(SHA256_CTX); +- break; +- case NID_sha384: +- app_datasize = sizeof(EVP_MD *) + sizeof(SHA512_CTX); +- break; +- case NID_sha512: +- app_datasize = sizeof(EVP_MD *) + sizeof(SHA512_CTX); +- break; +- default: +- break; +- } + } + + if (priv->soft_ctx == NULL) { +@@ -262,8 +245,10 @@ static int uadk_e_digests_soft_md(struct digest_priv_ctx *priv) + return 0; + + ctx->md_data = OPENSSL_malloc(app_datasize); +- if (ctx->md_data == NULL) ++ if (ctx->md_data == NULL) { ++ EVP_MD_CTX_free(ctx); + return 0; ++ } + + priv->soft_ctx = ctx; + priv->app_datasize = app_datasize; +@@ -1033,6 +1018,7 @@ static int uadk_e_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) + } + + if (t->soft_ctx) { ++ t->soft_md = NULL; + t->soft_ctx = NULL; + ret = digest_soft_init(t); + if (!ret) +-- +2.25.1 + diff --git a/0034-uadk_engine-fix-print-format.patch b/0034-uadk_engine-fix-print-format.patch new file mode 100644 index 0000000..53e80f6 --- /dev/null +++ b/0034-uadk_engine-fix-print-format.patch @@ -0,0 +1,58 @@ +From 58744be426ee62c0564a9e9a8448266d50551d73 Mon Sep 17 00:00:00 2001 +From: Junchong Pan +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 34/36] uadk_engine - fix print format + +Fix printf format issues and Null pointer dereference. + +Signed-off-by: Junchong Pan +Signed-off-by: Weili Qian +Signed-off-by: JiangShui Yang +--- + src/uadk_digest.c | 2 +- + src/uadk_ec.c | 2 +- + src/uadk_prov_aead.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index c93b0ca..01d05ee 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -234,7 +234,7 @@ static int uadk_e_digests_soft_md(struct digest_priv_ctx *priv) + SET_APP_DATASIZE(SHA512_CTX); + break; + default: +- fprintf(stderr, "digest nid %d is invalid.\n", priv->e_nid); ++ fprintf(stderr, "digest nid %u is invalid.\n", priv->e_nid); + return 0; + } + +diff --git a/src/uadk_ec.c b/src/uadk_ec.c +index b1dbdfe..aaf0127 100644 +--- a/src/uadk_ec.c ++++ b/src/uadk_ec.c +@@ -1192,7 +1192,7 @@ static int ecdh_get_shared_key(const EC_KEY *ecdh, + + *out = OPENSSL_zalloc(*outlen); + if (!*out) { +- fprintf(stderr, "failed to alloc output key, outlen = %lu\n", ++ fprintf(stderr, "failed to alloc output key, outlen = %zu\n", + *outlen); + return 0; + } +diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c +index 6f33f43..ce71c15 100644 +--- a/src/uadk_prov_aead.c ++++ b/src/uadk_prov_aead.c +@@ -421,7 +421,7 @@ static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char + int ret; + + if (inlen > MAX_AAD_LEN) { +- fprintf(stderr, "the aad len is out of range, aad len = %lu.\n", inlen); ++ fprintf(stderr, "the aad len is out of range, aad len = %zu.\n", inlen); + return UADK_AEAD_FAIL; + } + +-- +2.25.1 + diff --git a/0035-uadk_prov-sec-support-switching-to-soft-calculation.patch b/0035-uadk_prov-sec-support-switching-to-soft-calculation.patch new file mode 100644 index 0000000..7c70ab2 --- /dev/null +++ b/0035-uadk_prov-sec-support-switching-to-soft-calculation.patch @@ -0,0 +1,1156 @@ +From 902100b4275f2cf2ac4a3b60eb54e153c853a718 Mon Sep 17 00:00:00 2001 +From: Qi Tao +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 35/36] uadk_prov: sec support switching to soft calculation + +When hardware failures, insufficient queue resources, +or small packet lengths occur, the service can switch +to OpenSSL soft calculation. + +Signed-off-by: Qi Tao +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_aead.c | 312 ++++++++++++++++++++++++++++++++++------- + src/uadk_prov_cipher.c | 83 +++++++---- + src/uadk_prov_digest.c | 153 ++++++++++++-------- + 3 files changed, 416 insertions(+), 132 deletions(-) + +diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c +index ce71c15..54e0115 100644 +--- a/src/uadk_prov_aead.c ++++ b/src/uadk_prov_aead.c +@@ -40,6 +40,7 @@ + + #define UADK_OSSL_FAIL 0 + #define UADK_AEAD_SUCCESS 1 ++#define SWITCH_TO_SOFT 2 + #define UADK_AEAD_FAIL (-1) + + #define UNINITIALISED_SIZET ((size_t)-1) +@@ -52,6 +53,8 @@ + #define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 + #define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) + ++#define UADK_DO_SOFT (-0xE0) ++#define UADK_DO_HW (-0xF0) + #define UADK_AEAD_DEF_CTXS 2 + #define UADK_AEAD_OP_NUM 1 + +@@ -94,6 +97,10 @@ struct aead_priv_ctx { + struct wd_aead_req req; + enum uadk_aead_mode mode; + handle_t sess; ++ ++ int stream_switch_flag; /* soft calculation switch flag for stream mode */ ++ EVP_CIPHER_CTX *sw_ctx; ++ EVP_CIPHER *sw_aead; + }; + + struct aead_info { +@@ -108,6 +115,18 @@ static struct aead_info aead_info_table[] = { + { NID_aes_256_gcm, WD_CIPHER_AES, WD_CIPHER_GCM } + }; + ++static EVP_CIPHER_CTX *EVP_CIPHER_CTX_dup(const EVP_CIPHER_CTX *in) ++{ ++ EVP_CIPHER_CTX *out = EVP_CIPHER_CTX_new(); ++ ++ if (out != NULL && !EVP_CIPHER_CTX_copy(out, in)) { ++ EVP_CIPHER_CTX_free(out); ++ out = NULL; ++ } ++ ++ return out; ++} ++ + static int uadk_aead_poll(void *ctx) + { + __u64 rx_cnt = 0; +@@ -134,6 +153,128 @@ static void uadk_aead_mutex_infork(void) + pthread_mutex_unlock(&aead_mutex); + } + ++static int uadk_fetch_sw_aead(struct aead_priv_ctx *priv) ++{ ++ if (priv->sw_aead) ++ return UADK_AEAD_SUCCESS; ++ ++ switch (priv->nid) { ++ case NID_aes_128_gcm: ++ priv->sw_aead = EVP_CIPHER_fetch(NULL, "AES-128-GCM", "provider=default"); ++ break; ++ case NID_aes_192_gcm: ++ priv->sw_aead = EVP_CIPHER_fetch(NULL, "AES-192-GCM", "provider=default"); ++ break; ++ case NID_aes_256_gcm: ++ priv->sw_aead = EVP_CIPHER_fetch(NULL, "AES-256-GCM", "provider=default"); ++ break; ++ default: ++ break; ++ } ++ ++ if (unlikely(priv->sw_aead == NULL)) { ++ fprintf(stderr, "aead failed to fetch\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static int uadk_prov_aead_soft_init(struct aead_priv_ctx *priv, const unsigned char *key, ++ const unsigned char *iv, const OSSL_PARAM *params) ++{ ++ int ret; ++ ++ if (!priv->sw_aead || !priv->sw_ctx) ++ return UADK_AEAD_FAIL; ++ ++ if (priv->req.op_type == WD_CIPHER_ENCRYPTION_DIGEST) ++ ret = EVP_EncryptInit_ex2(priv->sw_ctx, priv->sw_aead, key, iv, params); ++ else ++ ret = EVP_DecryptInit_ex2(priv->sw_ctx, priv->sw_aead, key, iv, params); ++ ++ if (!ret) { ++ fprintf(stderr, "aead soft init error!\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ priv->stream_switch_flag = UADK_DO_SOFT; ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static int uadk_aead_soft_update(struct aead_priv_ctx *priv, unsigned char *out, ++ int *outl, const unsigned char *in, size_t len) ++{ ++ int ret; ++ ++ if (!priv->sw_aead || !priv->sw_ctx) ++ return UADK_AEAD_FAIL; ++ ++ if (priv->req.op_type == WD_CIPHER_ENCRYPTION_DIGEST) ++ ret = EVP_EncryptUpdate(priv->sw_ctx, out, outl, in, len); ++ else ++ ret = EVP_DecryptUpdate(priv->sw_ctx, out, outl, in, len); ++ ++ if (!ret) { ++ fprintf(stderr, "aead soft update error.\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ priv->stream_switch_flag = UADK_DO_SOFT; ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static int uadk_aead_soft_final(struct aead_priv_ctx *priv, unsigned char *digest, size_t *outl) ++{ ++ int ret; ++ ++ if (!priv->sw_aead || !priv->sw_ctx) ++ goto error; ++ ++ if (priv->req.op_type == WD_CIPHER_ENCRYPTION_DIGEST) { ++ ret = EVP_EncryptFinal_ex(priv->sw_ctx, digest, (int *)outl); ++ if (!ret) ++ goto error; ++ ++ ret = EVP_CIPHER_CTX_ctrl(priv->sw_ctx, EVP_CTRL_GCM_GET_TAG, ++ priv->taglen, priv->buf); ++ if (!ret) ++ goto error; ++ } else { ++ ret = EVP_CIPHER_CTX_ctrl(priv->sw_ctx, EVP_CTRL_GCM_SET_TAG, ++ priv->taglen, priv->buf); ++ if (!ret) ++ goto error; ++ ++ ret = EVP_DecryptFinal_ex(priv->sw_ctx, digest, (int *)outl); ++ if (!ret) ++ goto error; ++ } ++ ++ priv->stream_switch_flag = 0; ++ ++ return UADK_AEAD_SUCCESS; ++ ++error: ++ fprintf(stderr, "aead soft final failed.\n"); ++ return UADK_AEAD_FAIL; ++} ++ ++static void uadk_aead_soft_cleanup(struct aead_priv_ctx *priv) ++{ ++ if (priv->sw_ctx) { ++ EVP_CIPHER_CTX_free(priv->sw_ctx); ++ priv->sw_ctx = NULL; ++ } ++ ++ if (priv->sw_aead) { ++ EVP_CIPHER_free(priv->sw_aead); ++ priv->sw_aead = NULL; ++ } ++} ++ + static int uadk_prov_aead_dev_init(struct aead_priv_ctx *priv) + { + struct wd_ctx_nums ctx_set_num; +@@ -293,7 +434,8 @@ static void uadk_do_aead_async_prepare(struct aead_priv_ctx *priv, unsigned char + } + + static int uadk_do_aead_sync_inner(struct aead_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t inlen, enum wd_aead_msg_state state) ++ const unsigned char *in, size_t inlen, ++ enum wd_aead_msg_state state) + { + int ret; + +@@ -315,21 +457,17 @@ static int uadk_do_aead_sync_inner(struct aead_priv_ctx *priv, unsigned char *ou + return UADK_AEAD_FAIL; + } + +- return inlen; ++ return UADK_AEAD_SUCCESS; + } + + static int uadk_do_aead_sync(struct aead_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t inlen) ++ const unsigned char *in, size_t inlen) + { + size_t nbytes, tail, processing_len, max_mid_len; + const unsigned char *in_block = in; + unsigned char *out_block = out; + int ret; + +- /* Due to a hardware limitation, zero-length aad using block mode. */ +- if (!priv->req.assoc_bytes) +- return uadk_do_aead_sync_inner(priv, out, in, inlen, AEAD_MSG_BLOCK); +- + tail = inlen % AES_BLOCK_SIZE; + nbytes = inlen - tail; + max_mid_len = AEAD_BLOCK_SIZE - priv->req.assoc_bytes; +@@ -354,11 +492,11 @@ static int uadk_do_aead_sync(struct aead_priv_ctx *priv, unsigned char *out, + return UADK_AEAD_FAIL; + } + +- return inlen; ++ return UADK_AEAD_SUCCESS; + } + + static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, +- unsigned char *out, const unsigned char *in, size_t inlen) ++ unsigned char *out, const unsigned char *in, size_t inlen) + { + struct uadk_e_cb_info cb_param; + int cnt = 0; +@@ -416,11 +554,14 @@ static int uadk_do_aead_async(struct aead_priv_ctx *priv, struct async_op *op, + } + + static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t inlen) ++ const unsigned char *in, size_t inlen) + { + int ret; + + if (inlen > MAX_AAD_LEN) { ++ if (priv->mode != ASYNC_MODE) ++ return SWITCH_TO_SOFT; ++ + fprintf(stderr, "the aad len is out of range, aad len = %zu.\n", inlen); + return UADK_AEAD_FAIL; + } +@@ -428,20 +569,23 @@ static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char + priv->req.assoc_bytes = inlen; + + /* Asynchronous jobs use the block mode. */ +- if (priv->mode == ASYNC_MODE || !priv->req.assoc_bytes) { ++ if (priv->mode == ASYNC_MODE) { + memcpy(priv->data, in, inlen); + return UADK_AEAD_SUCCESS; + } + ++ if (!priv->req.assoc_bytes) ++ return SWITCH_TO_SOFT; ++ + ret = uadk_do_aead_sync_inner(priv, out, in, inlen, AEAD_MSG_FIRST); + if (unlikely(ret < 0)) +- return UADK_AEAD_FAIL; ++ return SWITCH_TO_SOFT; + + return UADK_AEAD_SUCCESS; + } + + static int uadk_prov_do_aes_gcm_update(struct aead_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t inlen) ++ const unsigned char *in, size_t inlen) + { + struct async_op *op; + int ret; +@@ -464,9 +608,12 @@ static int uadk_prov_do_aes_gcm_update(struct aead_priv_ctx *priv, unsigned char + } + + free(op); +- return inlen; ++ return UADK_AEAD_SUCCESS; + } + ++ if (priv->stream_switch_flag == UADK_DO_SOFT) ++ return SWITCH_TO_SOFT; ++ + return uadk_do_aead_sync(priv, out, in, inlen); + + free_notification: +@@ -477,7 +624,7 @@ free_op: + } + + static int uadk_prov_do_aes_gcm_final(struct aead_priv_ctx *priv, unsigned char *out, +- const unsigned char *in, size_t inlen) ++ const unsigned char *in, size_t inlen) + { + int ret; + +@@ -500,8 +647,8 @@ out: + } + + static int uadk_prov_do_aes_gcm(struct aead_priv_ctx *priv, unsigned char *out, +- size_t *outl, size_t outsize, +- const unsigned char *in, size_t inlen) ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inlen) + { + int ret; + +@@ -543,8 +690,8 @@ static OSSL_FUNC_cipher_set_ctx_params_fn uadk_prov_aead_set_ctx_params; + static OSSL_FUNC_cipher_settable_ctx_params_fn uadk_prov_aead_settable_ctx_params; + + static int uadk_prov_aead_cipher(void *vctx, unsigned char *out, size_t *outl, +- size_t outsize, const unsigned char *in, +- size_t inl) ++ size_t outsize, const unsigned char *in, ++ size_t inl) + { + struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; + int ret; +@@ -566,11 +713,11 @@ static int uadk_prov_aead_cipher(void *vctx, unsigned char *out, size_t *outl, + } + + static int uadk_prov_aead_stream_update(void *vctx, unsigned char *out, +- size_t *outl, size_t outsize, +- const unsigned char *in, size_t inl) ++ size_t *outl, size_t outsize, ++ const unsigned char *in, size_t inl) + { + struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; +- int ret; ++ int ret, outlen; + + if (!vctx) + return UADK_OSSL_FAIL; +@@ -580,18 +727,36 @@ static int uadk_prov_aead_stream_update(void *vctx, unsigned char *out, + return UADK_OSSL_FAIL; + } + ++ if (priv->stream_switch_flag == UADK_DO_SOFT) ++ goto do_soft; + ret = uadk_prov_do_aes_gcm(priv, out, outl, outsize, in, inl); +- if (ret < 0) { ++ if (ret == SWITCH_TO_SOFT) ++ goto do_soft; ++ else if (ret < 0) { + fprintf(stderr, "stream data update failed.\n"); + return UADK_OSSL_FAIL; ++ } else { ++ *outl = inl; ++ return UADK_AEAD_SUCCESS; + } + +- *outl = inl; ++do_soft: ++ if (priv->stream_switch_flag != UADK_DO_SOFT) { ++ ret = uadk_prov_aead_soft_init(priv, priv->key, priv->iv, NULL); ++ if (ret <= 0) ++ return UADK_OSSL_FAIL; ++ } ++ ++ ret = uadk_aead_soft_update(priv, out, &outlen, in, inl); ++ if (ret <= 0) ++ return UADK_OSSL_FAIL; ++ ++ *outl = outlen; + return UADK_AEAD_SUCCESS; + } + + static int uadk_prov_aead_stream_final(void *vctx, unsigned char *out, +- size_t *outl, size_t outsize) ++ size_t *outl, size_t outsize) + { + struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; + int ret; +@@ -599,6 +764,9 @@ static int uadk_prov_aead_stream_final(void *vctx, unsigned char *out, + if (!vctx || !out || !outl) + return UADK_OSSL_FAIL; + ++ if (priv->stream_switch_flag == UADK_DO_SOFT) ++ goto do_soft; ++ + ret = uadk_prov_do_aes_gcm(priv, out, outl, outsize, NULL, 0); + if (ret < 0) { + fprintf(stderr, "stream data final failed, ret = %d\n", ret); +@@ -607,6 +775,15 @@ static int uadk_prov_aead_stream_final(void *vctx, unsigned char *out, + + *outl = 0; + return UADK_AEAD_SUCCESS; ++ ++do_soft: ++ ret = uadk_aead_soft_final(priv, out, outl); ++ if (ret) { ++ *outl = 0; ++ return UADK_AEAD_SUCCESS; ++ } ++ ++ return UADK_OSSL_FAIL; + } + + static int uadk_get_aead_info(struct aead_priv_ctx *priv) +@@ -630,9 +807,8 @@ static int uadk_get_aead_info(struct aead_priv_ctx *priv) + return UADK_AEAD_SUCCESS; + } + +-static int uadk_prov_aead_init(struct aead_priv_ctx *priv, +- const unsigned char *key, size_t keylen, +- const unsigned char *iv, size_t ivlen) ++static int uadk_prov_aead_init(struct aead_priv_ctx *priv, const unsigned char *key, size_t keylen, ++ const unsigned char *iv, size_t ivlen, const OSSL_PARAM *params) + { + int ret; + +@@ -655,16 +831,26 @@ static int uadk_prov_aead_init(struct aead_priv_ctx *priv, + priv->key_set = KEY_STATE_SET; + } + ++ priv->stream_switch_flag = 0; ++ ++ if (uadk_get_sw_offload_state()) ++ uadk_fetch_sw_aead(priv); ++ + ret = uadk_prov_aead_dev_init(priv); +- if (unlikely(ret < 0)) +- return UADK_OSSL_FAIL; ++ if (unlikely(ret < 0)) { ++ if (ASYNC_get_current_job()) ++ return UADK_OSSL_FAIL; ++ ++ fprintf(stderr, "aead switch to soft init.!\n"); ++ return uadk_prov_aead_soft_init(priv, key, iv, params); ++ } + + return UADK_AEAD_SUCCESS; + } + + static int uadk_prov_aead_einit(void *vctx, const unsigned char *key, size_t keylen, +- const unsigned char *iv, size_t ivlen, +- const OSSL_PARAM params[]) ++ const unsigned char *iv, size_t ivlen, ++ const OSSL_PARAM params[]) + { + struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; + +@@ -674,12 +860,12 @@ static int uadk_prov_aead_einit(void *vctx, const unsigned char *key, size_t key + priv->req.op_type = WD_CIPHER_ENCRYPTION_DIGEST; + priv->enc = 1; + +- return uadk_prov_aead_init(priv, key, keylen, iv, ivlen); ++ return uadk_prov_aead_init(priv, key, keylen, iv, ivlen, params); + } + + static int uadk_prov_aead_dinit(void *vctx, const unsigned char *key, size_t keylen, +- const unsigned char *iv, size_t ivlen, +- const OSSL_PARAM params[]) ++ const unsigned char *iv, size_t ivlen, ++ const OSSL_PARAM params[]) + { + struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; + +@@ -689,7 +875,7 @@ static int uadk_prov_aead_dinit(void *vctx, const unsigned char *key, size_t key + priv->req.op_type = WD_CIPHER_DECRYPTION_DIGEST; + priv->enc = 0; + +- return uadk_prov_aead_init(priv, key, keylen, iv, ivlen); ++ return uadk_prov_aead_init(priv, key, keylen, iv, ivlen, params); + } + + static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { +@@ -869,8 +1055,8 @@ static const OSSL_PARAM *uadk_prov_aead_gettable_params(ossl_unused void *provct + } + + static int uadk_cipher_aead_get_params(OSSL_PARAM params[], unsigned int md, +- uint64_t flags, size_t kbits, +- size_t blkbits, size_t ivbits) ++ uint64_t flags, size_t kbits, ++ size_t blkbits, size_t ivbits) + { + OSSL_PARAM *p; + +@@ -910,24 +1096,46 @@ static int uadk_cipher_aead_get_params(OSSL_PARAM params[], unsigned int md, + + static void *uadk_prov_aead_dupctx(void *ctx) + { +- struct aead_priv_ctx *priv, *ret; ++ struct aead_priv_ctx *dst_ctx, *src_ctx; ++ int ret; + +- priv = (struct aead_priv_ctx *)ctx; +- if (!priv) ++ src_ctx = (struct aead_priv_ctx *)ctx; ++ if (!src_ctx) + return NULL; + +- ret = OPENSSL_memdup(priv, sizeof(*priv)); +- if (!ret) ++ dst_ctx = OPENSSL_memdup(src_ctx, sizeof(*src_ctx)); ++ if (!dst_ctx) + return NULL; + +- ret->sess = 0; +- ret->data = OPENSSL_memdup(priv->data, AEAD_BLOCK_SIZE << 1); +- if (!ret->data) { +- OPENSSL_clear_free(ret, sizeof(*ret)); +- return NULL; ++ dst_ctx->sess = 0; ++ dst_ctx->data = OPENSSL_memdup(src_ctx->data, AEAD_BLOCK_SIZE << 1); ++ if (!dst_ctx->data) ++ goto free_ctx; ++ ++ if (dst_ctx->sw_ctx) { ++ dst_ctx->sw_ctx = EVP_CIPHER_CTX_dup(src_ctx->sw_ctx); ++ if (!dst_ctx->sw_ctx) { ++ fprintf(stderr, "EVP_CIPHER_CTX_dup failed in ctx copy.\n"); ++ goto free_data; ++ } + } + +- return ret; ++ if (dst_ctx->sw_aead) { ++ ret = EVP_CIPHER_up_ref(dst_ctx->sw_aead); ++ if (!ret) ++ goto free_dup; ++ } ++ ++ return dst_ctx; ++ ++free_dup: ++ if (dst_ctx->sw_ctx) ++ EVP_CIPHER_CTX_free(dst_ctx->sw_ctx); ++free_data: ++ OPENSSL_clear_free(dst_ctx->data, AEAD_BLOCK_SIZE << 1); ++free_ctx: ++ OPENSSL_clear_free(dst_ctx, sizeof(*dst_ctx)); ++ return NULL; + } + + static void uadk_prov_aead_freectx(void *ctx) +@@ -943,6 +1151,9 @@ static void uadk_prov_aead_freectx(void *ctx) + if (priv->data) + OPENSSL_clear_free(priv->data, AEAD_BLOCK_SIZE << 1); + ++ if (priv->sw_ctx) ++ uadk_aead_soft_cleanup(priv); ++ + OPENSSL_clear_free(priv, sizeof(*priv)); + } + +@@ -965,6 +1176,9 @@ static void *uadk_##nm##_newctx(void *provctx) \ + ctx->ivlen = iv_len; \ + ctx->nid = e_nid; \ + ctx->taglen = tag_len; \ ++ ctx->sw_ctx = EVP_CIPHER_CTX_new(); \ ++ if (ctx->sw_ctx == NULL) \ ++ fprintf(stderr, "EVP_AEAD_CTX_new failed.\n"); \ + strncpy(ctx->alg_name, #algnm, ALG_NAME_SIZE - 1); \ + \ + return ctx; \ +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index f4c73e5..f3ab94b 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -180,7 +180,7 @@ static struct cts_mode_name2id_st cts_modes[] = { + { WD_CIPHER_CBC_CS3, OSSL_CIPHER_CTS_MODE_CS3, UADK_CIPHER_CTS_CS3_NAME }, + }; + +-const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id) ++static const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id) + { + size_t i; + +@@ -191,7 +191,7 @@ const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id) + return NULL; + } + +-int ossl_cipher_cbc_cts_mode_name2id(const char *name) ++static int ossl_cipher_cbc_cts_mode_name2id(const char *name) + { + size_t i; + +@@ -283,12 +283,20 @@ static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) + case ID_sm4_ctr: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CTR", "provider=default"); + break; ++ case ID_aes_128_xts: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-XTS", "provider=default"); ++ break; ++ case ID_aes_256_xts: ++ priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-XTS", "provider=default"); ++ break; + default: + break; + } + +- if (unlikely(priv->sw_cipher == NULL)) ++ if (unlikely(priv->sw_cipher == NULL)) { ++ fprintf(stderr, "cipher failed to fetch\n"); + return UADK_P_FAIL; ++ } + + return UADK_P_SUCCESS; + } +@@ -297,28 +305,34 @@ 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)) ++ if (!priv->sw_cipher || !priv->sw_ctx) + return UADK_P_FAIL; + + if (!EVP_CipherInit_ex2(priv->sw_ctx, priv->sw_cipher, key, iv, + priv->enc, NULL)) { +- fprintf(stderr, "SW cipher init error!\n"); ++ fprintf(stderr, "cipher soft init failed!\n"); + return UADK_P_FAIL; + } + +- priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT; ++ priv->switch_flag = UADK_DO_SOFT; + + return UADK_P_SUCCESS; + } + +-static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned char *out, +- int *outl, const unsigned char *in, size_t len) ++static int uadk_prov_cipher_soft_update(struct cipher_priv_ctx *priv, unsigned char *out, ++ int *outl, const unsigned char *in, size_t len) + { +- if (priv->sw_cipher == NULL) ++ if (!priv->sw_cipher || !priv->sw_ctx) + return UADK_P_FAIL; + ++ if (!EVP_CipherInit_ex2(priv->sw_ctx, priv->sw_cipher, priv->key, priv->iv, ++ priv->enc, NULL)) { ++ fprintf(stderr, "cipher soft init error!\n"); ++ return UADK_P_FAIL; ++ } ++ + if (!EVP_CipherUpdate(priv->sw_ctx, out, outl, in, len)) { +- fprintf(stderr, "EVP_CipherUpdate sw_ctx failed.\n"); ++ fprintf(stderr, "cipher soft update error!\n"); + return UADK_P_FAIL; + } + +@@ -328,22 +342,25 @@ static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned cha + } + + static int uadk_prov_cipher_soft_final(struct cipher_priv_ctx *priv, unsigned char *out, +- size_t *outl) ++ size_t *outl) + { + int sw_final_len = 0; + +- if (priv->sw_cipher == NULL) ++ if (!priv->sw_cipher || !priv->sw_ctx) + return UADK_P_FAIL; + + if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { +- fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); ++ fprintf(stderr, "cipher soft final failed.\n"); + return UADK_P_FAIL; + } ++ + *outl = sw_final_len; ++ priv->switch_flag = 0; ++ + return UADK_P_SUCCESS; + } + +-static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv); ++static int uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv); + + static int uadk_cipher_poll(void *ctx) + { +@@ -407,10 +424,17 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, + priv->key_set = 1; + } + +- if (enable_sw_offload) +- return uadk_prov_cipher_sw_init(priv, key, iv); ++ priv->switch_flag = 0; ++ priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT; + +- uadk_prov_cipher_dev_init(priv); ++ if (uadk_get_sw_offload_state()) ++ uadk_fetch_sw_cipher(priv); ++ ++ ret = uadk_prov_cipher_dev_init(priv); ++ if (unlikely(ret <= 0)) { ++ fprintf(stderr, "cipher switch to soft init!\n"); ++ return uadk_prov_cipher_sw_init(priv, key, iv); ++ } + + return UADK_P_SUCCESS; + } +@@ -488,7 +512,7 @@ static void uadk_cipher_mutex_infork(void) + pthread_mutex_unlock(&cipher_mutex); + } + +-static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) ++static int uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) + { + int ret; + +@@ -501,6 +525,7 @@ static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) + ctx_set_num = calloc(UADK_CIPHER_OP_NUM, sizeof(*ctx_set_num)); + if (!ctx_set_num) { + fprintf(stderr, "failed to alloc ctx_set_size!\n"); ++ ret = UADK_P_FAIL; + goto init_err; + } + +@@ -510,6 +535,7 @@ static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) + if (!cparams.bmp) { + fprintf(stderr, "failed to create nodemask!\n"); + free(ctx_set_num); ++ ret = UADK_P_FAIL; + goto init_err; + } + +@@ -524,6 +550,7 @@ static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) + + if (unlikely(ret)) { + fprintf(stderr, "failed to init cipher!\n"); ++ ret = UADK_P_FAIL; + goto init_err; + } + +@@ -531,8 +558,11 @@ static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) + async_register_poll_fn(ASYNC_TASK_CIPHER, uadk_cipher_poll); + } + ++ ret = UADK_P_SUCCESS; ++ + init_err: + pthread_mutex_unlock(&cipher_mutex); ++ return ret; + } + + static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) +@@ -551,7 +581,9 @@ static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) + if (priv->switch_flag == UADK_DO_SOFT) + return UADK_P_FAIL; + +- uadk_prov_cipher_dev_init(priv); ++ ret = uadk_prov_cipher_dev_init(priv); ++ if (ret <= 0) ++ return UADK_P_FAIL; + + /* dec and enc use the same op */ + params.type = 0; +@@ -799,13 +831,12 @@ do_soft: + * 1. small packets + * 2. already choose DO_SOFT, can be hw fail case or following sw case + */ +- ret = uadk_prov_cipher_soft_work(priv, out, &outlint, in, inlen); ++ ret = uadk_prov_cipher_soft_update(priv, out, &outlint, in, inlen); + if (ret) { + *outl = outlint; + return UADK_P_SUCCESS; + } + +- fprintf(stderr, "do soft ciphers failed.\n"); + return UADK_P_FAIL; + } + +@@ -856,8 +887,8 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *output, size_t *ou + return UADK_P_SUCCESS; + } + +-static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, +- unsigned char *out, size_t *outl, size_t outsize) ++static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, unsigned char *out, ++ size_t *outl, size_t outsize) + { + size_t blksz = priv->blksize; + int ret; +@@ -888,8 +919,8 @@ static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, + return UADK_P_SUCCESS; + } + +-static int uadk_prov_cipher_block_decrypto(struct cipher_priv_ctx *priv, +- unsigned char *out, size_t *outl, size_t outsize) ++static int uadk_prov_cipher_block_decrypto(struct cipher_priv_ctx *priv, unsigned char *out, ++ size_t *outl, size_t outsize) + { + size_t blksz = priv->blksize; + int ret; +@@ -1009,7 +1040,7 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *output, + + do_soft: + /* have isseu if both using hw and soft partly */ +- ret = uadk_prov_cipher_soft_work(priv, output, &len, input, inl); ++ ret = uadk_prov_cipher_soft_update(priv, output, &len, input, inl); + if (ret) { + *outl = len; + return UADK_P_SUCCESS; +diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c +index a2a5f09..7a5bfff 100644 +--- a/src/uadk_prov_digest.c ++++ b/src/uadk_prov_digest.c +@@ -70,18 +70,6 @@ struct digest_prov { + static struct digest_prov dprov; + static pthread_mutex_t digest_mutex = PTHREAD_MUTEX_INITIALIZER; + +-struct evp_md_ctx_st { +- const EVP_MD *digest; +- /* Functional reference if 'digest' is ENGINE-provided */ +- ENGINE *engine; +- unsigned long flags; +- void *md_data; +- /* Public key context for sign/verify */ +- EVP_PKEY_CTX *pctx; +- /* Update function: usually copied from EVP_MD */ +- int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); +-}; +- + struct digest_priv_ctx { + handle_t sess; + struct wd_digest_sess_setup setup; +@@ -131,6 +119,17 @@ static struct digest_info digest_info_table[] = { + 32, SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, + }; + ++static EVP_MD_CTX *EVP_MD_CTX_dup(const EVP_MD_CTX *in) ++{ ++ EVP_MD_CTX *out = EVP_MD_CTX_new(); ++ ++ if (out != NULL && !EVP_MD_CTX_copy_ex(out, in)) { ++ EVP_MD_CTX_free(out); ++ out = NULL; ++ } ++ return out; ++} ++ + static int uadk_digests_soft_md(struct digest_priv_ctx *priv) + { + if (priv->soft_md) +@@ -147,53 +146,83 @@ static int uadk_digests_soft_md(struct digest_priv_ctx *priv) + priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA1, "provider=default"); + break; + case NID_sha224: +- priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA3_224, "provider=default"); ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_224, "provider=default"); + break; + case NID_sha256: +- priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA3_256, "provider=default"); ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_256, "provider=default"); + break; + case NID_sha384: +- priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA3_384, "provider=default"); ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_384, "provider=default"); + break; + case NID_sha512: +- priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA3_512, "provider=default"); ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_512, "provider=default"); ++ break; ++ case NID_sha512_224: ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_512_224, ++ "provider=default"); ++ break; ++ case NID_sha512_256: ++ priv->soft_md = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA2_512_256, ++ "provider=default"); + break; + default: + break; + } + +- if (unlikely(priv->soft_md == NULL)) ++ if (unlikely(priv->soft_md == NULL)) { ++ fprintf(stderr, "digest failed to fetch\n"); + return UADK_DIGEST_FAIL; ++ } + + return UADK_DIGEST_SUCCESS; + } + + static int uadk_digest_soft_init(struct digest_priv_ctx *priv) + { +- if (priv->soft_md) +- return EVP_DigestInit_ex(priv->soft_ctx, priv->soft_md, NULL); ++ if (!priv->soft_md || !priv->soft_ctx) ++ return UADK_DIGEST_FAIL; + +- return UADK_DIGEST_FAIL; ++ if (!EVP_DigestInit_ex(priv->soft_ctx, priv->soft_md, NULL)) { ++ fprintf(stderr, "soft digest init failed.\n"); ++ return UADK_DIGEST_FAIL; ++ } ++ ++ priv->switch_flag = UADK_DO_SOFT; ++ ++ return UADK_DIGEST_SUCCESS; + } + + static int uadk_digest_soft_update(struct digest_priv_ctx *priv, + const void *data, size_t len) + { +- if (priv->soft_md) +- return EVP_DigestUpdate(priv->soft_ctx, data, len); ++ if (priv->soft_md == NULL) ++ return UADK_DIGEST_FAIL; + +- return UADK_DIGEST_FAIL; ++ if (!EVP_DigestUpdate(priv->soft_ctx, data, len)) { ++ fprintf(stderr, "soft digest update failed.\n"); ++ return UADK_DIGEST_FAIL; ++ } ++ ++ priv->switch_flag = UADK_DO_SOFT; ++ ++ return UADK_DIGEST_SUCCESS; + } + + static int uadk_digest_soft_final(struct digest_priv_ctx *priv, unsigned char *digest) + { +- if (priv->soft_md) { +- unsigned int digest_length; ++ unsigned int digest_length; + +- return EVP_DigestFinal_ex(priv->soft_ctx, digest, &digest_length); ++ if (priv->soft_md == NULL) ++ return UADK_DIGEST_FAIL; ++ ++ if (!EVP_DigestFinal_ex(priv->soft_ctx, digest, &digest_length)) { ++ fprintf(stderr, "soft digest final failed.\n"); ++ return UADK_DIGEST_FAIL; + } + +- return UADK_DIGEST_FAIL; ++ priv->switch_flag = 0; ++ ++ return UADK_DIGEST_SUCCESS; + } + + static void digest_soft_cleanup(struct digest_priv_ctx *priv) +@@ -201,12 +230,8 @@ static void digest_soft_cleanup(struct digest_priv_ctx *priv) + EVP_MD_CTX *ctx = priv->soft_ctx; + + if (ctx != NULL) { +- if (ctx->md_data) { +- OPENSSL_free(ctx->md_data); +- ctx->md_data = NULL; +- } + EVP_MD_CTX_free(ctx); +- ctx = NULL; ++ priv->soft_ctx = NULL; + } + + if (priv->soft_md) { +@@ -216,7 +241,7 @@ 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) ++ unsigned char *digest) + { + int ret; + +@@ -341,7 +366,7 @@ static int uadk_digest_ctx_init(struct digest_priv_ctx *priv) + + ret = uadk_prov_digest_dev_init(priv); + if (unlikely(ret <= 0)) +- goto soft_init; ++ return UADK_DIGEST_FAIL; + + /* Use the default numa parameters */ + params.numa_id = -1; +@@ -357,15 +382,7 @@ static int uadk_digest_ctx_init(struct digest_priv_ctx *priv) + } + } + +- if (enable_sw_offload) +- uadk_digests_soft_md(priv); +- + return UADK_DIGEST_SUCCESS; +- +-soft_init: +- pthread_mutex_unlock(&digest_mutex); +- fprintf(stderr, "uadk failed to initialize digest.\n"); +- return uadk_digest_soft_init(priv); + } + + static void uadk_fill_mac_buffer_len(struct digest_priv_ctx *priv, bool is_end) +@@ -445,14 +462,15 @@ static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *da + priv->state = SEC_DIGEST_DOING; + + priv->req.out = priv->out; +- remain_len -= processing_len; +- input_data += processing_len; + + ret = wd_do_digest_sync(priv->sess, &priv->req); + if (ret) { + fprintf(stderr, "do sec digest update failed, switch to soft digest.\n"); + goto do_soft_digest; + } ++ ++ remain_len -= processing_len; ++ input_data += processing_len; + } while (remain_len > DIGEST_BLOCK_SIZE); + + priv->last_update_bufflen = remain_len; +@@ -462,7 +480,6 @@ static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *da + + do_soft_digest: + if (priv->state == SEC_DIGEST_FIRST_UPDATING) { +- priv->switch_flag = UADK_DO_SOFT; + ret = uadk_digest_soft_init(priv); + if (!ret) + return ret; +@@ -472,6 +489,9 @@ do_soft_digest: + ret = uadk_digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); + if (!ret) + goto out; ++ ++ remain_len -= processing_len; ++ input_data += processing_len; + } + + ret = uadk_digest_soft_update(priv, input_data, remain_len); +@@ -548,6 +568,7 @@ static int uadk_do_digest_sync(struct digest_priv_ctx *priv) + fprintf(stderr, "do sec digest sync failed, switch to soft digest.\n"); + return UADK_DIGEST_FAIL; + } ++ + return UADK_DIGEST_SUCCESS; + } + +@@ -558,7 +579,7 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o + int cnt = 0; + + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { +- fprintf(stderr, "async cipher init failed.\n"); ++ fprintf(stderr, "digest soft switching is not supported in asynchronous mode.\n"); + return UADK_DIGEST_FAIL; + } + +@@ -608,9 +629,11 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest + return UADK_DIGEST_FAIL; + } + +- ret = uadk_digest_ctx_init(priv); +- if (ret != UADK_DIGEST_SUCCESS) +- return UADK_DIGEST_FAIL; ++ if (unlikely(priv->switch_flag != UADK_DO_SOFT)) { ++ ret = uadk_digest_ctx_init(priv); ++ if (ret != UADK_DIGEST_SUCCESS) ++ return UADK_DIGEST_FAIL; ++ } + + priv->req.in = priv->data; + priv->req.out = priv->out; +@@ -657,8 +680,8 @@ clear: + return ret; + } + +-static int uadk_digest_digest(struct digest_priv_ctx *priv, const void *data, size_t data_len, +- unsigned char *digest) ++static int uadk_digest_digest(struct digest_priv_ctx *priv, const void *data, ++ size_t data_len, unsigned char *digest) + { + struct async_op op; + int ret; +@@ -706,8 +729,7 @@ static void uadk_digest_cleanup(struct digest_priv_ctx *priv) + if (priv->data) + OPENSSL_clear_free(priv->data, DIGEST_BLOCK_SIZE); + +- if (priv->soft_ctx) +- OPENSSL_clear_free(priv->soft_ctx, sizeof(EVP_MD_CTX)); ++ digest_soft_cleanup(priv); + } + + static OSSL_FUNC_digest_freectx_fn uadk_prov_freectx; +@@ -780,6 +802,7 @@ static void uadk_prov_freectx(void *dctx) + static void *uadk_prov_dupctx(void *dctx) + { + struct digest_priv_ctx *dst_ctx, *src_ctx; ++ int ret; + + src_ctx = (struct digest_priv_ctx *)dctx; + if (!dctx) +@@ -809,15 +832,24 @@ static void *uadk_prov_dupctx(void *dctx) + goto free_ctx; + + if (dst_ctx->soft_ctx) { +- dst_ctx->soft_ctx = EVP_MD_CTX_new(); ++ dst_ctx->soft_ctx = EVP_MD_CTX_dup(src_ctx->soft_ctx); + if (!dst_ctx->soft_ctx) { + fprintf(stderr, "EVP_MD_CTX_new failed in ctx copy.\n"); + goto free_data; + } + } + ++ if (dst_ctx->soft_md) { ++ ret = EVP_MD_up_ref(dst_ctx->soft_md); ++ if (!ret) ++ goto free_dup; ++ } ++ + return dst_ctx; + ++free_dup: ++ if (dst_ctx->soft_ctx) ++ EVP_MD_CTX_free(dst_ctx->soft_ctx); + free_data: + OPENSSL_clear_free(dst_ctx->data, DIGEST_BLOCK_SIZE); + free_ctx: +@@ -835,13 +867,20 @@ static int uadk_prov_init(void *dctx, const OSSL_PARAM params[]) + return UADK_DIGEST_FAIL; + } + ++ if (uadk_get_sw_offload_state()) ++ uadk_digests_soft_md(priv); ++ + ret = uadk_get_digest_info(priv); + if (unlikely(!ret)) + return UADK_DIGEST_FAIL; + ++ priv->state = SEC_DIGEST_INIT; ++ + ret = uadk_prov_digest_dev_init(priv); +- if (unlikely(ret <= 0)) +- return UADK_DIGEST_FAIL; ++ if (unlikely(ret <= 0)) { ++ fprintf(stderr, "digest switch to soft init!\n"); ++ return uadk_digest_soft_init(priv); ++ } + + return UADK_DIGEST_SUCCESS; + } +@@ -879,7 +918,7 @@ static int uadk_prov_final(void *dctx, unsigned char *out, + return ret; + } + +- if (unlikely(outl != NULL)) ++ if (outl) + *outl = priv->md_size; + + return UADK_DIGEST_SUCCESS; +-- +2.25.1 + diff --git a/0036-uadk_engine-fix-a-digest-software-switching-issue-in.patch b/0036-uadk_engine-fix-a-digest-software-switching-issue-in.patch new file mode 100644 index 0000000..63d357e --- /dev/null +++ b/0036-uadk_engine-fix-a-digest-software-switching-issue-in.patch @@ -0,0 +1,50 @@ +From f4947b9add8e2b4f00d2896311c7ac7151a9eb27 Mon Sep 17 00:00:00 2001 +From: Chenghai Huang +Date: Mon, 21 Apr 2025 16:18:30 +0800 +Subject: [PATCH 36/36] uadk_engine: fix a digest software switching issue + inupdate + +The length information needs to be updated during software +calculation. + +Signed-off-by: Chenghai Huang +Signed-off-by: JiangShui Yang +--- + src/uadk_digest.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/uadk_digest.c b/src/uadk_digest.c +index 01d05ee..e07667d 100644 +--- a/src/uadk_digest.c ++++ b/src/uadk_digest.c +@@ -705,14 +705,15 @@ static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_le + priv->state = SEC_DIGEST_DOING; + + priv->req.out = priv->out; +- left_len -= processing_len; +- tmpdata += processing_len; + + ret = wd_do_digest_sync(priv->sess, &priv->req); + if (ret) { + fprintf(stderr, "do sec digest sync failed, switch to soft digest.\n"); + goto do_soft_digest; + } ++ ++ left_len -= processing_len; ++ tmpdata += processing_len; + } while (left_len > DIGEST_BLOCK_SIZE); + + priv->last_update_bufflen = left_len; +@@ -730,6 +731,9 @@ do_soft_digest: + ret = digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); + if (!ret) + goto out; ++ ++ left_len -= processing_len; ++ tmpdata += processing_len; + } + + ret = digest_soft_update(priv, tmpdata, left_len); +-- +2.25.1 + diff --git a/0037-uadk_prov-default-to-turn-on-the-soft-switch.patch b/0037-uadk_prov-default-to-turn-on-the-soft-switch.patch new file mode 100644 index 0000000..eda2c54 --- /dev/null +++ b/0037-uadk_prov-default-to-turn-on-the-soft-switch.patch @@ -0,0 +1,29 @@ +From b317bc6b371561f9d42c43d9ac043704fca418cb Mon Sep 17 00:00:00 2001 +From: Qi Tao +Date: Fri, 25 Apr 2025 17:25:51 +0800 +Subject: [PATCH] uadk_prov: default to turn on the soft switch + +Set enable_sw_offload to 1 to enable the soft switch by default + +Signed-off-by: Qi Tao +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index c29500b..e9d9f92 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -45,7 +45,7 @@ struct uadk_provider_params { + } uadk_params; + + /* offload small packets to sw */ +-int enable_sw_offload; ++int enable_sw_offload = 1; + + const OSSL_ALGORITHM uadk_prov_digests[] = { + { PROV_NAMES_MD5, UADK_DEFAULT_PROPERTIES, +-- +2.25.1 + diff --git a/uadk_engine.spec b/uadk_engine.spec index 54bed1f..71db4db 100644 --- a/uadk_engine.spec +++ b/uadk_engine.spec @@ -2,7 +2,7 @@ Name: uadk_engine Summary: UADK Accelerator Engine Version: 1.5.0 -Release: 2 +Release: 3 License: Apache-2.0 Source: %{name}-%{version}.tar.gz ExclusiveOS: linux @@ -33,6 +33,24 @@ Patch0016: 0016-uadk_engine_rsa-fix-memory-leak-of-pkey-meth.patch Patch0017: 0017-uadk_engine-fix-memory-leak-in-fork-scene.patch Patch0018: 0018-uadk_provider-support-X25519.patch Patch0019: 0019-uadk_engine_rsa-add-rsa-finish-method.patch +Patch0020: 0020-uadk_provider-fix-a-memory-leak-issue-in-BIO_meth.patch +Patch0021: 0021-uadk_provider-fix-atomic-compare-parameter.patch +Patch0022: 0022-uadk_provider-support-switching-to-software-in-init.patch +Patch0023: 0023-uadk_provider-fix-async-packet-reception-timeout-err.patch +Patch0024: 0024-uadk_provider-add-hmac-alg-for-uadk_provider-in-open.patch +Patch0025: 0025-uadk_provider-add-soft-mac-switching-function-for-ua.patch +Patch0026: 0026-uadk_provider-dh-add-dh-switching-software-computati.patch +Patch0027: 0027-uadk_provider-rsa-add-rsa-switching-software-computa.patch +Patch0028: 0028-uadk_provider-sm2-add-sm2-switching-software-computa.patch +Patch0029: 0029-uadk_provider-ecx-add-x448-and-x25519-switching-soft.patch +Patch0030: 0030-uadk_provider-ecdsa-add-ecdsa-switching-software-com.patch +Patch0031: 0031-uadk_provider-ecdh-add-ecdh-switching-software-compu.patch +Patch0032: 0032-digest-fix-for-digest-soft-work.patch +Patch0033: 0033-digest-fix-for-digest-soft-init.patch +Patch0034: 0034-uadk_engine-fix-print-format.patch +Patch0035: 0035-uadk_prov-sec-support-switching-to-soft-calculation.patch +Patch0036: 0036-uadk_engine-fix-a-digest-software-switching-issue-in.patch +Patch0037: 0037-uadk_prov-default-to-turn-on-the-soft-switch.patch %description This package contains the UADK Accelerator Engine. @@ -92,7 +110,11 @@ rm -rf ${RPM_BUILD_ROOT} %postun /sbin/ldconfig +Fri 25 Apr 2025 05:05:04 PM CST %changelog +* Fri Apr 25 2025 JiangShui Yang 1.5.0-3 + - uadk_provider: add soft switching function for uadk_provider + * Thu Feb 27 2025 JiangShui Yang 1.5.0-2 - uadk_provider: the x25519 and ecdsa algorithms are supported. -- Gitee