diff --git a/0001-uadk_provider-add-aead-alg-for-uadk_provider-in-open.patch b/0001-uadk_provider-add-aead-alg-for-uadk_provider-in-open.patch new file mode 100644 index 0000000000000000000000000000000000000000..218936c7bf6a4693006b2dece34a93962ddd78df --- /dev/null +++ b/0001-uadk_provider-add-aead-alg-for-uadk_provider-in-open.patch @@ -0,0 +1,1118 @@ +From 4bd88135df61ce9844ac5487198c02a49d4ef748 Mon Sep 17 00:00:00 2001 +From: Chenghai Huang +Date: Thu, 19 Dec 2024 15:57:48 +0800 +Subject: [PATCH 01/10] uadk_provider: add aead alg for uadk_provider in + openssl3 + +The following 3 AES algorithms are added: +AES-128-GCM AES-192-GCM AES-256-GCM + +Signed-off-by: Chenghai Huang +Signed-off-by: JiangShui Yang +--- + src/Makefile.am | 2 +- + src/uadk_prov.h | 4 + + src/uadk_prov_aead.c | 1030 ++++++++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 7 + + 4 files changed, 1042 insertions(+), 1 deletion(-) + create mode 100644 src/uadk_prov_aead.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 54c00e7..921305b 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -65,7 +65,7 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_prov_rsa.c uadk_prov_dh.c \ + uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.c \ + uadk_prov_pkey.c uadk_prov_sm2.c \ +- uadk_prov_ffc.c ++ uadk_prov_ffc.c uadk_prov_aead.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 8756fc6..ac82245 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -162,6 +162,9 @@ extern const OSSL_DISPATCH uadk_sm4_ecb_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm4_ofb128_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm4_cfb128_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm4_ctr_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_aes_128_gcm_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_aes_192_gcm_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_aes_256_gcm_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_des_ede3_cbc_functions[]; + extern const OSSL_DISPATCH uadk_des_ede3_ecb_functions[]; + +@@ -178,6 +181,7 @@ extern const OSSL_DISPATCH uadk_sm2_asym_cipher_functions[FUNC_MAX_NUM]; + + void uadk_prov_destroy_digest(void); + void uadk_prov_destroy_cipher(void); ++void uadk_prov_destroy_aead(void); + void uadk_prov_destroy_rsa(void); + void uadk_prov_destroy_dh(void); + void uadk_prov_sm2_uninit(void); +diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c +new file mode 100644 +index 0000000..d6e90ca +--- /dev/null ++++ b/src/uadk_prov_aead.c +@@ -0,0 +1,1030 @@ ++// 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 "uadk.h" ++#include "uadk_async.h" ++#include "uadk_prov.h" ++ ++#define MAX_IV_LEN 16 ++#define MAX_KEY_LEN 64 ++#define MAX_AAD_LEN 0xFFFF ++#define ALG_NAME_SIZE 128 ++#define AES_GCM_TAG_LEN 16 ++/* The max data length is 16M-512B */ ++#define AEAD_BLOCK_SIZE 0xFFFE00 ++ ++#define UADK_OSSL_FAIL 0 ++#define UADK_AEAD_SUCCESS 1 ++#define UADK_AEAD_FAIL (-1) ++ ++#define UNINITIALISED_SIZET ((size_t)-1) ++#define IV_STATE_UNINITIALISED 0 ++#define IV_STATE_SET 1 ++#define KEY_STATE_SET 1 ++ ++/* Internal flags that can be queried */ ++#define PROV_CIPHER_FLAG_AEAD 0x0001 ++#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 ++#define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) ++ ++#define UADK_AEAD_DEF_CTXS 2 ++#define UADK_AEAD_OP_NUM 1 ++ ++struct aead_prov { ++ int pid; ++}; ++static struct aead_prov aprov; ++static pthread_mutex_t aead_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++enum uadk_aead_mode { ++ UNINIT_MODE, ++ ASYNC_MODE, ++ SYNC_MODE ++}; ++ ++enum aead_tag_status { ++ INIT_TAG, ++ READ_TAG, /* The MAC has been read. */ ++ SET_TAG /* The MAC has been set to req. */ ++}; ++ ++struct aead_priv_ctx { ++ int nid; ++ char alg_name[ALG_NAME_SIZE]; ++ size_t keylen; ++ size_t ivlen; ++ size_t taglen; ++ ++ unsigned int enc : 1; ++ unsigned int key_set : 1; /* Whether key is copied to priv key buffers */ ++ unsigned int iv_set : 1; /* Whether iv is copied to priv iv buffers */ ++ enum aead_tag_status tag_set; /* Whether mac is copied to priv mac buffers */ ++ ++ unsigned char iv[MAX_IV_LEN]; ++ unsigned char key[MAX_KEY_LEN]; ++ unsigned char buf[AES_GCM_TAG_LEN]; /* mac buffers */ ++ unsigned char *data; /* store input and output when block mode */ ++ ++ struct wd_aead_sess_setup setup; ++ struct wd_aead_req req; ++ enum uadk_aead_mode mode; ++ handle_t sess; ++}; ++ ++struct aead_info { ++ int nid; ++ enum wd_cipher_alg alg; ++ enum wd_cipher_mode mode; ++}; ++ ++static struct aead_info aead_info_table[] = { ++ { NID_aes_128_gcm, WD_CIPHER_AES, WD_CIPHER_GCM }, ++ { NID_aes_192_gcm, WD_CIPHER_AES, WD_CIPHER_GCM }, ++ { NID_aes_256_gcm, WD_CIPHER_AES, WD_CIPHER_GCM } ++}; ++ ++static int uadk_aead_poll(void *ctx) ++{ ++ __u64 rx_cnt = 0; ++ __u32 recv = 0; ++ /* Poll one packet currently */ ++ int expt = 1; ++ int ret; ++ ++ do { ++ ret = wd_aead_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_aead_mutex_infork(void) ++{ ++ /* Release the replication lock of the child process */ ++ pthread_mutex_unlock(&aead_mutex); ++} ++ ++static int uadk_prov_aead_dev_init(struct aead_priv_ctx *priv) ++{ ++ struct wd_ctx_nums ctx_set_num; ++ struct wd_ctx_params cparams = {0}; ++ int ret = UADK_AEAD_SUCCESS; ++ ++ pthread_atfork(NULL, NULL, uadk_aead_mutex_infork); ++ pthread_mutex_lock(&aead_mutex); ++ if (aprov.pid == getpid()) ++ goto mutex_unlock; ++ ++ cparams.op_type_num = UADK_AEAD_OP_NUM; ++ cparams.ctx_set_num = &ctx_set_num; ++ cparams.bmp = numa_allocate_nodemask(); ++ if (!cparams.bmp) { ++ ret = UADK_AEAD_FAIL; ++ fprintf(stderr, "failed to create nodemask!\n"); ++ goto mutex_unlock; ++ } ++ ++ numa_bitmask_setall(cparams.bmp); ++ ++ ctx_set_num.sync_ctx_num = UADK_AEAD_DEF_CTXS; ++ ctx_set_num.async_ctx_num = UADK_AEAD_DEF_CTXS; ++ ++ ret = wd_aead_init2_(priv->alg_name, TASK_MIX, SCHED_POLICY_RR, &cparams); ++ if (unlikely(ret)) { ++ ret = UADK_AEAD_FAIL; ++ fprintf(stderr, "failed to init aead!\n"); ++ goto free_nodemask; ++ } ++ ++ aprov.pid = getpid(); ++ async_register_poll_fn(ASYNC_TASK_AEAD, uadk_aead_poll); ++ ++free_nodemask: ++ numa_free_nodemask(cparams.bmp); ++mutex_unlock: ++ pthread_mutex_unlock(&aead_mutex); ++ return ret; ++} ++ ++static int uadk_prov_aead_ctx_init(struct aead_priv_ctx *priv) ++{ ++ struct wd_aead_sess_setup setup = {0}; ++ struct sched_params params = {0}; ++ int ret; ++ ++ if (!priv->key_set || !priv->iv_set) { ++ fprintf(stderr, "key or iv is not set yet!\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ priv->req.iv_bytes = priv->ivlen; ++ priv->req.iv = priv->iv; ++ priv->req.out_bytes = 0; ++ priv->req.mac = priv->buf; ++ priv->req.mac_bytes = priv->taglen; ++ ++ ret = uadk_prov_aead_dev_init(priv); ++ if (unlikely(ret < 0)) ++ return UADK_AEAD_FAIL; ++ ++ /* dec and enc use the same op */ ++ params.type = 0; ++ /* Use the default numa parameters */ ++ params.numa_id = -1; ++ memcpy(&setup, &priv->setup, sizeof(struct wd_aead_sess_setup)); ++ setup.sched_param = ¶ms; ++ ++ if (!priv->sess) { ++ priv->sess = wd_aead_alloc_sess(&setup); ++ if (!priv->sess) { ++ fprintf(stderr, "uadk failed to alloc session!\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ ret = wd_aead_set_authsize(priv->sess, priv->taglen); ++ if (ret) { ++ fprintf(stderr, "uadk failed to set authsize!\n"); ++ goto free_sess; ++ } ++ ++ ret = wd_aead_set_ckey(priv->sess, priv->key, priv->keylen); ++ if (ret) { ++ fprintf(stderr, "uadk failed to set key!\n"); ++ goto free_sess; ++ } ++ } ++ ++ return UADK_AEAD_SUCCESS; ++ ++free_sess: ++ wd_aead_free_sess(priv->sess); ++ priv->sess = 0; ++ return UADK_AEAD_FAIL; ++} ++ ++static void *uadk_prov_aead_cb(struct wd_aead_req *req, void *data) ++{ ++ struct uadk_e_cb_info *cb_param; ++ struct wd_aead_req *req_origin; ++ struct async_op *op; ++ ++ if (!req) ++ return NULL; ++ ++ cb_param = req->cb_param; ++ if (!cb_param) ++ return NULL; ++ ++ req_origin = cb_param->priv; ++ req_origin->state = req->state; ++ ++ op = cb_param->op; ++ if (op && op->job && !op->done) { ++ op->done = 1; ++ async_free_poll_task(op->idx, 1); ++ async_wake_job(op->job); ++ } ++ ++ return NULL; ++} ++ ++static int do_aes_gcm_prepare(struct aead_priv_ctx *priv) ++{ ++ if (priv->mode == UNINIT_MODE) { ++ if (ASYNC_get_current_job()) ++ priv->mode = ASYNC_MODE; ++ else ++ priv->mode = SYNC_MODE; ++ } ++ ++ if (!priv->enc && priv->tag_set == READ_TAG) { ++ if (likely(priv->taglen == AES_GCM_TAG_LEN)) { ++ memcpy(priv->req.mac, priv->buf, AES_GCM_TAG_LEN); ++ priv->tag_set = SET_TAG; ++ } else { ++ fprintf(stderr, "invalid: aead gcm mac length only support 16B.\n"); ++ return UADK_AEAD_FAIL; ++ } ++ } ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static void uadk_do_aead_async_prepare(struct aead_priv_ctx *priv, unsigned char *out, ++ const unsigned char *in, size_t inlen) ++{ ++ priv->req.in_bytes = inlen; ++ /* AAD data is input or output together with plaintext or ciphertext. */ ++ if (priv->req.assoc_bytes) { ++ memcpy(priv->data + priv->req.assoc_bytes, in, inlen); ++ priv->req.src = priv->data; ++ priv->req.dst = priv->data + AEAD_BLOCK_SIZE; ++ } else { ++ priv->req.src = (unsigned char *)in; ++ priv->req.dst = out; ++ } ++} ++ ++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) ++{ ++ int ret; ++ ++ if ((state == AEAD_MSG_BLOCK || state == AEAD_MSG_END) ++ && !priv->enc && priv->tag_set != SET_TAG) { ++ fprintf(stderr, "The tag for synchronous decryption is not set.\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ priv->req.msg_state = state; ++ priv->req.src = (unsigned char *)in; ++ priv->req.dst = out; ++ priv->req.in_bytes = inlen; ++ priv->req.state = 0; ++ ret = wd_do_aead_sync(priv->sess, &priv->req); ++ if (unlikely(ret < 0 || priv->req.state)) { ++ fprintf(stderr, "do aead task failed, msg state: %u, ret: %d, state: %u!\n", ++ state, ret, priv->req.state); ++ return UADK_AEAD_FAIL; ++ } ++ ++ return inlen; ++} ++ ++static int uadk_do_aead_sync(struct aead_priv_ctx *priv, unsigned char *out, ++ 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; ++ ++ /* If the data length is not 16-byte aligned, it is split according to the protocol. */ ++ while (nbytes > 0) { ++ processing_len = nbytes > max_mid_len ? max_mid_len : nbytes; ++ processing_len -= (processing_len % AES_BLOCK_SIZE); ++ ++ ret = uadk_do_aead_sync_inner(priv, out_block, in_block, ++ processing_len, AEAD_MSG_MIDDLE); ++ if (ret < 0) ++ return UADK_AEAD_FAIL; ++ nbytes -= processing_len; ++ in_block = in_block + processing_len; ++ out_block = out_block + processing_len; ++ } ++ ++ if (tail) { ++ ret = uadk_do_aead_sync_inner(priv, out_block, in_block, tail, AEAD_MSG_END); ++ if (ret < 0) ++ return UADK_AEAD_FAIL; ++ } ++ ++ return inlen; ++} ++ ++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; ++ int cnt = 0; ++ int ret; ++ ++ if (!priv->enc && priv->tag_set != SET_TAG) { ++ fprintf(stderr, "The tag for asynchronous decryption is not set.\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ if (unlikely(priv->req.assoc_bytes + inlen > AEAD_BLOCK_SIZE)) { ++ fprintf(stderr, "aead input data length is too long!\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ 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; ++ priv->req.cb = uadk_prov_aead_cb; ++ priv->req.cb_param = cb_param; ++ priv->req.msg_state = AEAD_MSG_BLOCK; ++ priv->req.state = UADK_AEAD_FAIL; ++ ++ ret = async_get_free_task(&op->idx); ++ if (unlikely(!ret)) ++ goto free_cb_param; ++ ++ do { ++ ret = wd_do_aead_async(priv->sess, &priv->req); ++ if (unlikely(ret < 0)) { ++ if (unlikely(ret != -EBUSY)) ++ fprintf(stderr, "do aead async operation failed ret = %d.\n", ret); ++ else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) ++ fprintf(stderr, "do aead async operation timeout.\n"); ++ else ++ continue; ++ ++ async_free_poll_task(op->idx, 0); ++ ret = UADK_AEAD_FAIL; ++ goto free_cb_param; ++ } ++ } while (ret == -EBUSY); ++ ++ ret = async_pause_job(priv, op, ASYNC_TASK_AEAD); ++ 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; ++ } ++ ++ if (priv->req.assoc_bytes) ++ memcpy(out, priv->req.dst + priv->req.assoc_bytes, inlen); ++ ++free_cb_param: ++ free(cb_param); ++ return ret; ++} ++ ++static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char *out, ++ const unsigned char *in, size_t inlen) ++{ ++ int ret; ++ ++ if (inlen > MAX_AAD_LEN) { ++ fprintf(stderr, "the aad len is out of range, aad len = %lu.\n", inlen); ++ return UADK_AEAD_FAIL; ++ } ++ ++ priv->req.assoc_bytes = inlen; ++ ++ /* Asynchronous jobs use the block mode. */ ++ if (priv->mode == ASYNC_MODE || !priv->req.assoc_bytes) { ++ memcpy(priv->data, in, inlen); ++ return UADK_AEAD_SUCCESS; ++ } ++ ++ ret = uadk_do_aead_sync_inner(priv, out, in, inlen, AEAD_MSG_FIRST); ++ if (unlikely(ret < 0)) ++ return UADK_AEAD_FAIL; ++ ++ 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) ++{ ++ struct async_op *op; ++ int ret; ++ ++ if (priv->mode == ASYNC_MODE) { ++ op = malloc(sizeof(struct async_op)); ++ if (unlikely(!op)) ++ return UADK_AEAD_FAIL; ++ ++ ret = async_setup_async_event_notification(op); ++ if (unlikely(!ret)) { ++ fprintf(stderr, "failed to setup async event notification.\n"); ++ goto free_op; ++ } ++ ++ ret = uadk_do_aead_async(priv, op, out, in, inlen); ++ if (unlikely(ret < 0)) { ++ fprintf(stderr, "uadk_do_aead_async failed ret = %d.\n", ret); ++ goto free_notification; ++ } ++ ++ free(op); ++ return inlen; ++ } ++ ++ return uadk_do_aead_sync(priv, out, in, inlen); ++ ++free_notification: ++ (void)async_clear_async_event_notification(); ++free_op: ++ free(op); ++ return UADK_AEAD_FAIL; ++} ++ ++static int uadk_prov_do_aes_gcm_final(struct aead_priv_ctx *priv, unsigned char *out, ++ const unsigned char *in, size_t inlen) ++{ ++ int ret; ++ ++ if (priv->mode == ASYNC_MODE || !priv->req.assoc_bytes || ++ priv->req.msg_state == AEAD_MSG_END) ++ goto out; ++ ++ ret = uadk_do_aead_sync_inner(priv, out, in, inlen, AEAD_MSG_END); ++ if (unlikely(ret < 0)) ++ return UADK_AEAD_FAIL; ++ ++out: ++ if (priv->enc) ++ memcpy(priv->buf, priv->req.mac, priv->taglen); ++ else ++ priv->tag_set = INIT_TAG; ++ ++ priv->mode = UNINIT_MODE; ++ return UADK_AEAD_SUCCESS; ++} ++ ++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) ++{ ++ int ret; ++ ++ ret = uadk_prov_aead_ctx_init(priv); ++ if (ret != UADK_AEAD_SUCCESS) ++ return UADK_AEAD_FAIL; ++ ++ ret = do_aes_gcm_prepare(priv); ++ if (unlikely(ret < 0)) ++ return UADK_AEAD_FAIL; ++ ++ if (in) { ++ if (!out) ++ return uadk_prov_do_aes_gcm_first(priv, out, in, inlen); ++ ++ return uadk_prov_do_aes_gcm_update(priv, out, in, inlen); ++ } ++ ++ return uadk_prov_do_aes_gcm_final(priv, out, NULL, 0); ++} ++ ++void uadk_prov_destroy_aead(void) ++{ ++ pthread_mutex_lock(&aead_mutex); ++ if (aprov.pid == getpid()) { ++ wd_aead_uninit2(); ++ aprov.pid = 0; ++ } ++ pthread_mutex_unlock(&aead_mutex); ++} ++ ++static OSSL_FUNC_cipher_encrypt_init_fn uadk_prov_aead_einit; ++static OSSL_FUNC_cipher_decrypt_init_fn uadk_prov_aead_dinit; ++static OSSL_FUNC_cipher_freectx_fn uadk_prov_aead_freectx; ++static OSSL_FUNC_cipher_dupctx_fn uadk_prov_aead_dupctx; ++static OSSL_FUNC_cipher_get_ctx_params_fn uadk_prov_aead_get_ctx_params; ++static OSSL_FUNC_cipher_gettable_ctx_params_fn uadk_prov_aead_gettable_ctx_params; ++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) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ int ret; ++ ++ if (!vctx || !out || !outl) ++ return UADK_OSSL_FAIL; ++ ++ if (outsize < inl) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return UADK_OSSL_FAIL; ++ } ++ ++ ret = uadk_prov_do_aes_gcm(priv, out, outl, outsize, in, inl); ++ if (ret < 0) ++ return UADK_OSSL_FAIL; ++ ++ *outl = inl; ++ return UADK_AEAD_SUCCESS; ++} ++ ++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) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ int ret; ++ ++ if (!vctx) ++ return UADK_OSSL_FAIL; ++ ++ if (outsize < inl) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return UADK_OSSL_FAIL; ++ } ++ ++ ret = uadk_prov_do_aes_gcm(priv, out, outl, outsize, in, inl); ++ if (ret < 0) { ++ fprintf(stderr, "stream data update failed.\n"); ++ return UADK_OSSL_FAIL; ++ } ++ ++ *outl = inl; ++ return UADK_AEAD_SUCCESS; ++} ++ ++static int uadk_prov_aead_stream_final(void *vctx, unsigned char *out, ++ size_t *outl, size_t outsize) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ int ret; ++ ++ if (!vctx || !out || !outl) ++ return UADK_OSSL_FAIL; ++ ++ 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); ++ return UADK_OSSL_FAIL; ++ } ++ ++ *outl = 0; ++ return UADK_AEAD_SUCCESS; ++} ++ ++static int uadk_get_aead_info(struct aead_priv_ctx *priv) ++{ ++ int aead_counts = ARRAY_SIZE(aead_info_table); ++ int i; ++ ++ for (i = 0; i < aead_counts; i++) { ++ if (priv->nid == aead_info_table[i].nid) { ++ priv->setup.calg = aead_info_table[i].alg; ++ priv->setup.cmode = aead_info_table[i].mode; ++ break; ++ } ++ } ++ ++ if (unlikely(i == aead_counts)) { ++ fprintf(stderr, "failed to setup the private ctx.\n"); ++ return UADK_AEAD_FAIL; ++ } ++ ++ 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) ++{ ++ int ret; ++ ++ if (ivlen > MAX_IV_LEN || keylen > MAX_KEY_LEN) { ++ fprintf(stderr, "invalid keylen or ivlen.\n"); ++ return UADK_OSSL_FAIL; ++ } ++ ++ if (iv) { ++ memcpy(priv->iv, iv, ivlen); ++ priv->iv_set = IV_STATE_SET; ++ } ++ ++ ret = uadk_get_aead_info(priv); ++ if (unlikely(ret < 0)) ++ return UADK_OSSL_FAIL; ++ ++ if (key) { ++ memcpy(priv->key, key, keylen); ++ priv->key_set = KEY_STATE_SET; ++ } ++ ++ ret = uadk_prov_aead_dev_init(priv); ++ if (unlikely(ret < 0)) ++ return UADK_OSSL_FAIL; ++ ++ 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[]) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ ++ if (!vctx) ++ return UADK_OSSL_FAIL; ++ ++ priv->req.op_type = WD_CIPHER_ENCRYPTION_DIGEST; ++ priv->enc = 1; ++ ++ return uadk_prov_aead_init(priv, key, keylen, iv, ivlen); ++} ++ ++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[]) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ ++ if (!vctx) ++ return UADK_OSSL_FAIL; ++ ++ priv->req.op_type = WD_CIPHER_DECRYPTION_DIGEST; ++ priv->enc = 0; ++ ++ return uadk_prov_aead_init(priv, key, keylen, iv, ivlen); ++} ++ ++static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++const OSSL_PARAM *uadk_prov_aead_settable_ctx_params(ossl_unused void *cctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_settable_ctx_params; ++} ++ ++static int uadk_prov_aead_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ const OSSL_PARAM *p; ++ size_t sz = 0; ++ void *vp; ++ ++ if (!vctx) ++ return UADK_OSSL_FAIL; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); ++ if (p) { ++ vp = priv->buf; ++ if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ ++ if (sz == 0 || priv->enc) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); ++ return UADK_OSSL_FAIL; ++ } ++ priv->tag_set = READ_TAG; ++ priv->taglen = sz; ++ } ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p) { ++ size_t keylen; ++ ++ if (!OSSL_PARAM_get_size_t(p, &keylen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ if (priv->keylen != keylen) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); ++ return UADK_OSSL_FAIL; ++ } ++ } ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); ++ if (p) { ++ if (!OSSL_PARAM_get_size_t(p, &sz)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ if (sz == 0 || sz > priv->ivlen) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); ++ return UADK_OSSL_FAIL; ++ } ++ priv->ivlen = sz; ++ } ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static const OSSL_PARAM uadk_prov_aead_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_prov_aead_gettable_ctx_params(ossl_unused void *cctx, ++ ossl_unused void *provctx) ++{ ++ return uadk_prov_aead_ctx_params; ++} ++ ++static int uadk_prov_aead_get_ctx_params(void *vctx, OSSL_PARAM params[]) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)vctx; ++ OSSL_PARAM *p; ++ ++ if (!vctx || !params) ++ return UADK_OSSL_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); ++ if (p && !OSSL_PARAM_set_size_t(p, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p && !OSSL_PARAM_set_size_t(p, priv->keylen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); ++ if (p) { ++ size_t taglen = (priv->taglen != UNINITIALISED_SIZET) ? ++ priv->taglen : AES_GCM_TAG_LEN; ++ ++ if (!OSSL_PARAM_set_size_t(p, taglen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ } ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); ++ if (p) { ++ if (priv->iv_set == IV_STATE_UNINITIALISED) ++ return UADK_OSSL_FAIL; ++ if (priv->ivlen > p->data_size) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); ++ return UADK_OSSL_FAIL; ++ } ++ if (!OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) ++ && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ } ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); ++ if (p) { ++ if (priv->iv_set == IV_STATE_UNINITIALISED) ++ return UADK_OSSL_FAIL; ++ if (priv->ivlen > p->data_size) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); ++ return UADK_OSSL_FAIL; ++ } ++ if (!OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) ++ && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ } ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); ++ if (p) { ++ size_t sz = p->data_size; ++ ++ if (sz == 0 || sz > EVP_GCM_TLS_TAG_LEN || !priv->enc ++ || priv->taglen == UNINITIALISED_SIZET) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); ++ return UADK_OSSL_FAIL; ++ } ++ ++ if (!OSSL_PARAM_set_octet_string(p, priv->buf, sz)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ } ++ return UADK_AEAD_SUCCESS; ++} ++ ++static const OSSL_PARAM aead_known_gettable_params[] = { ++ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), ++ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), ++ OSSL_PARAM_END ++}; ++ ++static const OSSL_PARAM *uadk_prov_aead_gettable_params(ossl_unused void *provctx) ++{ ++ return aead_known_gettable_params; ++} ++ ++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) ++{ ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); ++ if (p && !OSSL_PARAM_set_uint(p, md)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); ++ if (p && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); ++ if (p && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); ++ if (p && !OSSL_PARAM_set_size_t(p, kbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); ++ if (p && !OSSL_PARAM_set_size_t(p, blkbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); ++ if (p && !OSSL_PARAM_set_size_t(p, ivbits)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return UADK_OSSL_FAIL; ++ } ++ ++ return UADK_AEAD_SUCCESS; ++} ++ ++static void *uadk_prov_aead_dupctx(void *ctx) ++{ ++ struct aead_priv_ctx *priv, *ret; ++ ++ priv = (struct aead_priv_ctx *)ctx; ++ if (!priv) ++ return NULL; ++ ++ ret = OPENSSL_memdup(priv, sizeof(*priv)); ++ if (!ret) ++ 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; ++ } ++ ++ return ret; ++} ++ ++static void uadk_prov_aead_freectx(void *ctx) ++{ ++ struct aead_priv_ctx *priv = (struct aead_priv_ctx *)ctx; ++ ++ if (!ctx) ++ return; ++ ++ if (priv->sess) { ++ wd_aead_free_sess(priv->sess); ++ priv->sess = 0; ++ } ++ ++ if (priv->data) { ++ OPENSSL_clear_free(priv->data, AEAD_BLOCK_SIZE << 1); ++ priv->data = NULL; ++ } ++ OPENSSL_clear_free(priv, sizeof(*priv)); ++} ++ ++#define UADK_AEAD_DESCR(nm, tag_len, key_len, iv_len, blk_size, \ ++ flags, e_nid, algnm, mode) \ ++static OSSL_FUNC_cipher_newctx_fn uadk_##nm##_newctx; \ ++static void *uadk_##nm##_newctx(void *provctx) \ ++{ \ ++ struct aead_priv_ctx *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ ++ if (!ctx) \ ++ return NULL; \ ++ \ ++ ctx->data = OPENSSL_zalloc(AEAD_BLOCK_SIZE << 1); \ ++ if (!ctx->data) { \ ++ OPENSSL_clear_free(ctx, sizeof(*ctx)); \ ++ return NULL; \ ++ } \ ++ \ ++ ctx->keylen = key_len; \ ++ ctx->ivlen = iv_len; \ ++ ctx->nid = e_nid; \ ++ ctx->taglen = tag_len; \ ++ strncpy(ctx->alg_name, #algnm, ALG_NAME_SIZE - 1); \ ++ \ ++ return ctx; \ ++} \ ++static OSSL_FUNC_cipher_get_params_fn uadk_##nm##_get_params; \ ++static int uadk_##nm##_get_params(OSSL_PARAM params[]) \ ++{ \ ++ return uadk_cipher_aead_get_params(params, mode, flags, \ ++ key_len, blk_size, iv_len); \ ++} \ ++const OSSL_DISPATCH uadk_##nm##_functions[] = { \ ++ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))uadk_##nm##_newctx }, \ ++ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))uadk_prov_aead_freectx }, \ ++ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))uadk_prov_aead_dupctx }, \ ++ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, \ ++ (void (*)(void))uadk_prov_aead_einit }, \ ++ { OSSL_FUNC_CIPHER_DECRYPT_INIT, \ ++ (void (*)(void))uadk_prov_aead_dinit }, \ ++ { OSSL_FUNC_CIPHER_UPDATE, \ ++ (void (*)(void))uadk_prov_aead_stream_update }, \ ++ { OSSL_FUNC_CIPHER_FINAL, \ ++ (void (*)(void))uadk_prov_aead_stream_final }, \ ++ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))uadk_prov_aead_cipher }, \ ++ { OSSL_FUNC_CIPHER_GET_PARAMS, \ ++ (void (*)(void))uadk_##nm##_get_params }, \ ++ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ ++ (void (*)(void))uadk_prov_aead_gettable_params }, \ ++ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_aead_get_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_aead_gettable_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_aead_set_ctx_params }, \ ++ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ ++ (void (*)(void))uadk_prov_aead_settable_ctx_params }, \ ++ { 0, NULL } \ ++} ++ ++UADK_AEAD_DESCR(aes_128_gcm, AES_GCM_TAG_LEN, 16, 12, 8, AEAD_FLAGS, NID_aes_128_gcm, gcm(aes), ++ EVP_CIPH_GCM_MODE); ++UADK_AEAD_DESCR(aes_192_gcm, AES_GCM_TAG_LEN, 24, 12, 8, AEAD_FLAGS, NID_aes_192_gcm, gcm(aes), ++ EVP_CIPH_GCM_MODE); ++UADK_AEAD_DESCR(aes_256_gcm, AES_GCM_TAG_LEN, 32, 12, 8, AEAD_FLAGS, NID_aes_256_gcm, gcm(aes), ++ EVP_CIPH_GCM_MODE); +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 972f953..772ddbb 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -137,6 +137,12 @@ const OSSL_ALGORITHM uadk_prov_ciphers_v3[] = { + uadk_aes_192_cfb128_functions, "uadk_provider aes-192-cfb" }, + { "AES-256-CFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_256_cfb128_functions, "uadk_provider aes-256-cfb" }, ++ { "AES-128-GCM", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_128_gcm_functions, "uadk_provider aes-128-gcm" }, ++ { "AES-192-GCM", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_192_gcm_functions, "uadk_provider aes-192-gcm" }, ++ { "AES-256-GCM", UADK_DEFAULT_PROPERTIES, ++ uadk_aes_256_gcm_functions, "uadk_provider aes-256-gcm" }, + { "SM4-CBC", UADK_DEFAULT_PROPERTIES, + uadk_sm4_cbc_functions, "uadk_provider sm4-cbc" }, + { "SM4-ECB", UADK_DEFAULT_PROPERTIES, +@@ -232,6 +238,7 @@ static void uadk_teardown(void *provctx) + + uadk_prov_destroy_digest(); + uadk_prov_destroy_cipher(); ++ uadk_prov_destroy_aead(); + uadk_prov_destroy_rsa(); + uadk_prov_sm2_uninit(); + uadk_prov_dh_uninit(); +-- +2.25.1 + diff --git a/0001-v1-dh-add-iova_map-and-iova_unmap-ops.patch b/0001-v1-dh-add-iova_map-and-iova_unmap-ops.patch deleted file mode 100644 index 42a28b23b6ba4576cdc1be6eaba14879bcb4a9d1..0000000000000000000000000000000000000000 --- a/0001-v1-dh-add-iova_map-and-iova_unmap-ops.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 984b503e018ebc6964e47c3784fd0f204b0c28fd Mon Sep 17 00:00:00 2001 -From: Liulongfang -Date: Tue, 9 Jan 2024 17:28:20 +0800 -Subject: [PATCH 1/3] v1/dh: add iova_map and iova_unmap ops - -If iova_map and iova_unmap ops are not registered, -wcrypto_create_dh_ctx() will return fail since parameters check fails. - -Signed-off-by: Weili Qian ---- - src/v1/alg/dh/hpre_dh_wd.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/v1/alg/dh/hpre_dh_wd.c b/src/v1/alg/dh/hpre_dh_wd.c -index b8ca9a1..556e744 100644 ---- a/src/v1/alg/dh/hpre_dh_wd.c -+++ b/src/v1/alg/dh/hpre_dh_wd.c -@@ -314,6 +314,8 @@ static int hpre_dh_init_eng_ctx(hpre_dh_engine_ctx_t *eng_ctx, int bits, bool is - eng_ctx->dh_setup.cb = hpre_dh_cb; - eng_ctx->dh_setup.br.alloc = kae_wd_alloc_blk; - eng_ctx->dh_setup.br.free = kae_wd_free_blk; -+ eng_ctx->dh_setup.br.iova_map = kae_dma_map; -+ eng_ctx->dh_setup.br.iova_unmap = kae_dma_unmap; - eng_ctx->dh_setup.br.usr = pool; - eng_ctx->dh_setup.is_g2 = is_g2; - eng_ctx->ctx = wcrypto_create_dh_ctx(q, &eng_ctx->dh_setup); --- -2.25.1 - diff --git a/0002-uadk_provider-move-functions-to-uadk_prov_pkey.patch b/0002-uadk_provider-move-functions-to-uadk_prov_pkey.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a7bec3f085bf1b47aef96eab0ffe54812578a01 --- /dev/null +++ b/0002-uadk_provider-move-functions-to-uadk_prov_pkey.patch @@ -0,0 +1,236 @@ +From eca4ec079ef076296c791cea431f01b04dda412a Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 19 Dec 2024 15:57:51 +0800 +Subject: [PATCH 02/10] uadk_provider: move functions to uadk_prov_pkey + +The ecc algorithm initialization and resource release +processes are the same. Therefore, the functions uadk_prov_sm2_init() +and uadk_prov_sm2_uninit() functions are moved from uadk_prov_sm2.c to +uadk_prov_pkey.c and change the functions name. + +Signed-off-by: Weili Qian +Signed-off-by: JiangShui Yang +--- + src/uadk_prov.h | 2 +- + src/uadk_prov_init.c | 2 +- + src/uadk_prov_pkey.c | 44 ++++++++++++++++++++++++++++++++ + src/uadk_prov_pkey.h | 2 +- + src/uadk_prov_sm2.c | 61 ++++++-------------------------------------- + 5 files changed, 55 insertions(+), 56 deletions(-) + +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index ac82245..e85aff8 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -184,7 +184,7 @@ void uadk_prov_destroy_cipher(void); + void uadk_prov_destroy_aead(void); + void uadk_prov_destroy_rsa(void); + void uadk_prov_destroy_dh(void); +-void uadk_prov_sm2_uninit(void); ++void uadk_prov_ecc_uninit(void); + void uadk_prov_dh_uninit(void); + int uadk_prov_cipher_version(void); + +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 772ddbb..55202ae 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -240,7 +240,7 @@ static void uadk_teardown(void *provctx) + uadk_prov_destroy_cipher(); + uadk_prov_destroy_aead(); + uadk_prov_destroy_rsa(); +- uadk_prov_sm2_uninit(); ++ uadk_prov_ecc_uninit(); + uadk_prov_dh_uninit(); + OPENSSL_free(ctx); + OSSL_PROVIDER_unload(prov); +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index d1f7afe..6e0612e 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -34,6 +34,13 @@ static int p_keymgmt_support_state[KEYMGMT_TYPE]; + static int p_signature_support_state[SIGNATURE_TYPE]; + static int p_asym_cipher_support_state[ASYM_CIPHER_TYPE]; + ++struct ecc_prov { ++ int pid; ++}; ++ ++static struct ecc_prov g_ecc_prov; ++static pthread_mutex_t ecc_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + /* Mapping between a flag and a name */ + static const OSSL_ITEM encoding_nameid_map[] = { + { OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT }, +@@ -767,3 +774,40 @@ void uadk_prov_asym_cipher_alg(void) + uadk_prov_asym_cipher_set_support_state(i, PROV_SUPPORT); + } + } ++ ++static void uadk_prov_ecc_mutex_infork(void) ++{ ++ /* Release the replication lock of the child process */ ++ pthread_mutex_unlock(&ecc_mutex); ++} ++ ++int uadk_prov_ecc_init(const char *alg_name) ++{ ++ int ret; ++ ++ pthread_atfork(NULL, NULL, uadk_prov_ecc_mutex_infork); ++ pthread_mutex_lock(&ecc_mutex); ++ if (g_ecc_prov.pid != getpid()) { ++ ret = wd_ecc_init2((char *)alg_name, SCHED_POLICY_RR, TASK_HW); ++ if (unlikely(ret)) { ++ pthread_mutex_unlock(&ecc_mutex); ++ return UADK_P_FAIL; ++ } ++ g_ecc_prov.pid = getpid(); ++ async_register_poll_fn(ASYNC_TASK_ECC, uadk_prov_ecc_poll); ++ } ++ pthread_mutex_unlock(&ecc_mutex); ++ ++ return UADK_P_SUCCESS; ++} ++ ++/* Uninit only when the process exits, will not uninit when thread exits. */ ++void uadk_prov_ecc_uninit(void) ++{ ++ pthread_mutex_lock(&ecc_mutex); ++ if (g_ecc_prov.pid == getpid()) { ++ wd_ecc_uninit2(); ++ g_ecc_prov.pid = 0; ++ } ++ pthread_mutex_unlock(&ecc_mutex); ++} +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index 0e27fcb..3eb9667 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -41,7 +41,6 @@ + #define UADK_ECC_MAX_KEY_BITS 521 + #define UADK_ECC_MAX_KEY_BYTES 66 + #define UADK_ECC_CV_PARAM_NUM 6 +-#define UADK_P_INTI_SUCCESS 0 + #define UADK_P_SUCCESS 1 + #define UADK_P_FAIL 0 + #define UADK_P_INVALID (-1) +@@ -440,5 +439,6 @@ int uadk_prov_ecc_set_public_key(handle_t sess, const EC_KEY *eckey); + void uadk_prov_signature_alg(void); + void uadk_prov_asym_cipher_alg(void); + int uadk_prov_asym_cipher_get_support_state(int alg_tag); ++int uadk_prov_ecc_init(const char *alg_name); + + #endif +diff --git a/src/uadk_prov_sm2.c b/src/uadk_prov_sm2.c +index b6d5d01..e27cccb 100644 +--- a/src/uadk_prov_sm2.c ++++ b/src/uadk_prov_sm2.c +@@ -36,8 +36,6 @@ UADK_PKEY_KEYMGMT_DESCR(sm2, SM2); + UADK_PKEY_SIGNATURE_DESCR(sm2, SM2); + UADK_PKEY_ASYM_CIPHER_DESCR(sm2, SM2); + +-static pthread_mutex_t sm2_mutex = PTHREAD_MUTEX_INITIALIZER; +- + static const OSSL_PARAM sm2_asym_cipher_known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PROPERTIES, NULL, 0), +@@ -64,12 +62,6 @@ static const OSSL_PARAM sm2_sig_known_gettable_ctx_params[] = { + OSSL_PARAM_END + }; + +-struct sm2_prov { +- int pid; +-}; +- +-static struct sm2_prov g_sm2_prov; +- + enum { + CTX_INIT_FAIL = -1, + CTX_UNINIT, +@@ -457,43 +449,6 @@ static const OSSL_PARAM *uadk_keymgmt_sm2_gen_settable_params(ossl_unused void * + return get_default_sm2_keymgmt().gen_settable_params(genctx, provctx); + } + +-static void uadk_prov_sm2_mutex_infork(void) +-{ +- /* Release the replication lock of the child process */ +- pthread_mutex_unlock(&sm2_mutex); +-} +- +-int uadk_prov_sm2_init(void) +-{ +- int ret; +- +- pthread_atfork(NULL, NULL, uadk_prov_sm2_mutex_infork); +- pthread_mutex_lock(&sm2_mutex); +- if (g_sm2_prov.pid != getpid()) { +- ret = wd_ecc_init2("sm2", SCHED_POLICY_RR, TASK_HW); +- if (unlikely(ret)) { +- pthread_mutex_unlock(&sm2_mutex); +- return ret; +- } +- g_sm2_prov.pid = getpid(); +- async_register_poll_fn(ASYNC_TASK_ECC, uadk_prov_ecc_poll); +- } +- pthread_mutex_unlock(&sm2_mutex); +- +- return UADK_P_INTI_SUCCESS; +-} +- +-/* Uninit only when the process exits, will not uninit when thread exits. */ +-void uadk_prov_sm2_uninit(void) +-{ +- pthread_mutex_lock(&sm2_mutex); +- if (g_sm2_prov.pid == getpid()) { +- wd_ecc_uninit2(); +- g_sm2_prov.pid = 0; +- } +- pthread_mutex_unlock(&sm2_mutex); +-} +- + static int uadk_prov_sm2_keygen_init_iot(handle_t sess, struct wd_ecc_req *req) + { + struct wd_ecc_out *ecc_out = wd_sm2_new_kg_out(sess); +@@ -671,8 +626,8 @@ static void *uadk_keymgmt_sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba + } + + /* SM2 hardware init */ +- ret = uadk_prov_sm2_init(); +- if (ret) { ++ ret = uadk_prov_ecc_init("sm2"); ++ if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); + goto free_ec_key; + } +@@ -1001,10 +956,10 @@ static int uadk_signature_sm2_sign_init(void *vpsm2ctx, void *ec, + } + + /* Init with UADK */ +- ret = uadk_prov_sm2_init(); +- if (ret) { ++ ret = uadk_prov_ecc_init("sm2"); ++ if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); +- return UADK_P_FAIL; ++ return ret; + } + + psm2ctx->sm2_pctx->init_status = CTX_INIT_SUCC; +@@ -2408,10 +2363,10 @@ static int uadk_asym_cipher_sm2_encrypt_init(void *vpsm2ctx, void *vkey, + } + + /* Init with UADK */ +- ret = uadk_prov_sm2_init(); +- if (ret) { ++ ret = uadk_prov_ecc_init("sm2"); ++ if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to init sm2\n"); +- return UADK_P_FAIL; ++ return ret; + } + + smctx->init_status = CTX_INIT_SUCC; +-- +2.25.1 + diff --git a/0002-uadk_util-fix-clang-build-error.patch b/0002-uadk_util-fix-clang-build-error.patch deleted file mode 100644 index 66198b2379e3456d03ef50dc6287946a7a8fd957..0000000000000000000000000000000000000000 --- a/0002-uadk_util-fix-clang-build-error.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0f4d9a02e3a2984a48535e6a38107a0f61631e5d Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Wed, 17 Jan 2024 14:09:11 +0000 -Subject: [PATCH 2/3] uadk_util: fix clang build error - -autoreconf -i -./configure CC=clang -make -j8 - -reports error: -uadk_utils.c:53:33: error: unknown register name 'q0' in asm -uadk_utils.c:53:39: error: unknown register name 'q1' in asm - -Fix with "v0", "v1", instead of "q0", "q1" - -Signed-off-by: Zhangfei Gao ---- - src/uadk_utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/uadk_utils.c b/src/uadk_utils.c -index 275a124..4a50bc4 100644 ---- a/src/uadk_utils.c -+++ b/src/uadk_utils.c -@@ -50,7 +50,7 @@ static void *memcpy_large(void *dstpp, const void *srcpp, size_t len) - - : [res] "+r"(dstpp) - : [src] "r"(srcpp), [count] "r"(len) -- : "x3", "x4", "x5", "x14", "q0", "q1" -+ : "x3", "x4", "x5", "x14", "v0", "v1" - ); - - return dstpp; --- -2.25.1 - diff --git a/0003-uadk_engine-add-secure-compilation-option.patch b/0003-uadk_engine-add-secure-compilation-option.patch deleted file mode 100644 index 78eb436561407c4dbf4161d9a98c23f95c68f336..0000000000000000000000000000000000000000 --- a/0003-uadk_engine-add-secure-compilation-option.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 638ee431907af6e9f4916e95a4f367e14499e819 Mon Sep 17 00:00:00 2001 -From: Qi Tao -Date: Thu, 18 Jan 2024 21:12:11 +0800 -Subject: [PATCH 3/3] uadk_engine: add secure compilation option -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add PIE, PIC, BIND_NOW, SP, NO Rpath/RunPath, FS, -Ftrapv and Strip compilation options. - -PIC(-fPIC): - Generate position-Independent-Code and andomly load - dynamic libraries. -PIE(-fPIE -pie): - Generate location-independent executables,which - reduces the probability of fixed address attacks - and buffer overflow attacks. -BIND_NOW(-Wl,-z,relro,-z,now): - GOT table redirects all read-only,which defends - against ret2plt attacks. -SP(-fstack-protector-strong/all): - Determine whether an overflow attack occurs. -Strip(-Wl,-s): - Deleting symbol tables defends against hacker - attacks and reduces the file size. -FS(-D_FORTIFY_SOURCE=2 -O2): - Provides access checks for fixed-size buffers - at compile time and at run time. -Ftrapv(-ftrapv): - Detects integer overflow. -NO Rpath/RunPath(hardcode_into_libs=no): - Eliminates dynamic library search paths, - which defense against attacks by replacing - dynamic libraries with the same name. - -Signed-off-by: Qi Tao ---- - configure.ac | 1 + - src/Makefile.am | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/configure.ac b/configure.ac -index 6c5369e..99b85e9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -7,6 +7,7 @@ AC_CONFIG_HEADERS([config.h]) - - AC_PROG_CC - LT_INIT -+AC_SUBST([hardcode_into_libs], [no]) - - AC_ARG_ENABLE(kae, - AS_HELP_STRING([--enable-kae],[Enable kae support])) -diff --git a/src/Makefile.am b/src/Makefile.am -index c4b8aa9..e014052 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -18,6 +18,8 @@ uadk_engine_la_LIBADD=-ldl $(WD_LIBS) -lpthread - uadk_engine_la_LDFLAGS=-module -version-number $(VERSION) - uadk_engine_la_CFLAGS=$(WD_CFLAGS) $(libcrypto_CFLAGS) - uadk_engine_la_CFLAGS+=-DCRYPTO -+uadk_engine_la_CFLAGS+=-fPIC -fPIE -pie -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -+ -O2 -ftrapv -Wl,-z,relro,-z,now -Wl,-s - - AUTOMAKE_OPTIONS = subdir-objects - --- -2.25.1 - diff --git a/0003-uadk_provider-add-query_operation_name-callback-for-.patch b/0003-uadk_provider-add-query_operation_name-callback-for-.patch new file mode 100644 index 0000000000000000000000000000000000000000..a93c5744daba1ac5c9fb44605a2a540903319471 --- /dev/null +++ b/0003-uadk_provider-add-query_operation_name-callback-for-.patch @@ -0,0 +1,101 @@ +From 7c975126c71002a87ec91e5e58e84e7009ecd69b Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 19 Dec 2024 15:57:54 +0800 +Subject: [PATCH 03/10] uadk_provider: add query_operation_name callback for + keymgmt + +The key generation process may query the name of the algorithm +supported by operation_id. If callback is not implemented, task will fail. + +Signed-off-by: Weili Qian +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_dh.c | 8 ++++++++ + src/uadk_prov_pkey.h | 3 +++ + src/uadk_prov_rsa.c | 8 ++++++++ + src/uadk_prov_sm2.c | 10 ++++++++++ + 4 files changed, 29 insertions(+) + +diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c +index e5c956c..8d2c6f6 100644 +--- a/src/uadk_prov_dh.c ++++ b/src/uadk_prov_dh.c +@@ -190,6 +190,14 @@ typedef struct { + char *kdf_cekalg; + } PROV_DH_KEYEXCH_CTX; + ++static const char *uadk_keymgmt_dh_query_operation_name(int operation_id) ++{ ++ if (get_default_dh_keymgmt().query_operation_name == NULL) ++ return NULL; ++ ++ return get_default_dh_keymgmt().query_operation_name(operation_id); ++} ++ + static void *uadk_keymgmt_dh_new(void *provctx) + { + if (get_default_dh_keymgmt().new_fun == NULL) +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index 3eb9667..c9ddba1 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -168,6 +168,7 @@ static OSSL_FUNC_keymgmt_import_types_fn uadk_keymgmt_##nm##_import_types; \ + static OSSL_FUNC_keymgmt_export_fn uadk_keymgmt_##nm##_export; \ + static OSSL_FUNC_keymgmt_export_types_fn uadk_keymgmt_##nm##_export_types; \ + static OSSL_FUNC_keymgmt_dup_fn uadk_keymgmt_##nm##_dup; \ ++static OSSL_FUNC_keymgmt_query_operation_name_fn uadk_keymgmt_##nm##_query_operation_name; \ + static UADK_PKEY_KEYMGMT get_default_##nm##_keymgmt(void) \ + { \ + static UADK_PKEY_KEYMGMT s_keymgmt; \ +@@ -215,6 +216,8 @@ const OSSL_DISPATCH uadk_##nm##_keymgmt_functions[] = { \ + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))uadk_keymgmt_##nm##_export }, \ + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))uadk_keymgmt_##nm##_export_types }, \ + { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))uadk_keymgmt_##nm##_dup }, \ ++ { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, \ ++ (void (*)(void))uadk_keymgmt_##nm##_query_operation_name }, \ + { 0, NULL } \ + } \ + +diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c +index 9872b27..d1ec153 100644 +--- a/src/uadk_prov_rsa.c ++++ b/src/uadk_prov_rsa.c +@@ -2476,6 +2476,14 @@ static const OSSL_PARAM *uadk_asym_cipher_rsa_settable_ctx_params(void *vprsactx + return get_default_rsa_asym_cipher().settable_ctx_params(vprsactx, provctx); + } + ++static const char *uadk_keymgmt_rsa_query_operation_name(int operation_id) ++{ ++ if (!get_default_rsa_keymgmt().query_operation_name) ++ return NULL; ++ ++ return get_default_rsa_keymgmt().query_operation_name(operation_id); ++} ++ + static void *uadk_keymgmt_rsa_new(void *provctx) + { + if (!get_default_rsa_keymgmt().new_fun) +diff --git a/src/uadk_prov_sm2.c b/src/uadk_prov_sm2.c +index e27cccb..df753bd 100644 +--- a/src/uadk_prov_sm2.c ++++ b/src/uadk_prov_sm2.c +@@ -191,6 +191,16 @@ ASN1_SEQUENCE(SM2_Ciphertext) = { + + IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext) + ++static const char *uadk_keymgmt_sm2_query_operation_name(int operation_id) ++{ ++ if (!get_default_sm2_keymgmt().query_operation_name) { ++ fprintf(stderr, "failed to get keymgmt query_operation_name function\n"); ++ return NULL; ++ } ++ ++ return get_default_sm2_keymgmt().query_operation_name(operation_id); ++} ++ + /** + * Create an uadk provider side sm2 key object. + * +-- +2.25.1 + diff --git a/0004-uadk_engine-cleanup-code-style-of-async-functions.patch b/0004-uadk_engine-cleanup-code-style-of-async-functions.patch deleted file mode 100644 index 68be9126fa53c276df6c5129676af94d548c254b..0000000000000000000000000000000000000000 --- a/0004-uadk_engine-cleanup-code-style-of-async-functions.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 54e2cf93c7a362031e7dacf550afe286b5a4656a Mon Sep 17 00:00:00 2001 -From: Zhiqi Song -Date: Fri, 29 Mar 2024 10:13:22 +0800 -Subject: [PATCH 4/7] uadk_engine: cleanup code style of async functions - -Cleanup the return value and judgment code style -of async mode functions. - -Signed-off-by: Zhiqi Song -Signed-off-by: JiangShui Yang ---- - src/uadk_async.c | 126 +++++++++++++++++++++++------------------------ - src/uadk_async.h | 3 ++ - 2 files changed, 64 insertions(+), 65 deletions(-) - -diff --git a/src/uadk_async.c b/src/uadk_async.c -index 726ee09..1558996 100644 ---- a/src/uadk_async.c -+++ b/src/uadk_async.c -@@ -50,83 +50,79 @@ static void async_fd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, - int async_setup_async_event_notification(struct async_op *op) - { - ASYNC_WAIT_CTX *waitctx; -+ void *custom = NULL; - OSSL_ASYNC_FD efd; -- void *custom; - - memset(op, 0, sizeof(struct async_op)); - op->job = ASYNC_get_current_job(); -- if (op->job == NULL) -- return 1; -+ if (!op->job) -+ return DO_SYNC; - - waitctx = ASYNC_get_wait_ctx(op->job); -- if (waitctx == NULL) -- return 0; -+ if (!waitctx) -+ return UADK_E_FAIL; - -- if (ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, -- &efd, &custom) == 0) { -+ if (!ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, &efd, &custom)) { - efd = eventfd(0, EFD_NONBLOCK); - if (efd == -1) -- return 0; -+ return UADK_E_FAIL; - -- if (ASYNC_WAIT_CTX_set_wait_fd(waitctx, uadk_async_key, efd, -- custom, async_fd_cleanup) == 0) { -+ if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, uadk_async_key, efd, -+ custom, async_fd_cleanup)) { - async_fd_cleanup(waitctx, uadk_async_key, efd, NULL); -- return 0; -+ return UADK_E_FAIL; - } - } - -- return 1; -+ return UADK_E_SUCCESS; - } - - int async_clear_async_event_notification(void) - { -- ASYNC_JOB *job; -+ size_t num_add_fds, num_del_fds; - ASYNC_WAIT_CTX *waitctx; -- OSSL_ASYNC_FD efd; -- size_t num_add_fds; -- size_t num_del_fds; - void *custom = NULL; -+ OSSL_ASYNC_FD efd; -+ ASYNC_JOB *job; - - job = ASYNC_get_current_job(); -- if (job == NULL) -- return 0; -+ if (!job) -+ return UADK_E_FAIL; - - waitctx = ASYNC_get_wait_ctx(job); -- if (waitctx == NULL) -- return 0; -+ if (!waitctx) -+ return UADK_E_FAIL; - -- if (ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &num_add_fds, -- NULL, &num_del_fds) == 0) -- return 0; -+ if (!ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &num_add_fds, NULL, &num_del_fds)) -+ return UADK_E_FAIL; - - if (num_add_fds > 0) { -- if (ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, -- &efd, &custom) == 0) -- return 0; -+ if (!ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, &efd, &custom)) -+ return UADK_E_FAIL; - - async_fd_cleanup(waitctx, uadk_async_key, efd, NULL); - -- if (ASYNC_WAIT_CTX_clear_fd(waitctx, uadk_async_key) == 0) -- return 0; -+ if (!ASYNC_WAIT_CTX_clear_fd(waitctx, uadk_async_key)) -+ return UADK_E_FAIL; - } - -- return 1; -+ return UADK_E_SUCCESS; - } - - void async_poll_task_free(void) - { -- int error; - struct async_poll_task *task; -+ int error; - - /* Disable async poll state first */ - uadk_e_set_async_poll_state(DISABLE_ASYNC_POLLING); - - error = pthread_mutex_lock(&poll_queue.async_task_mutex); -- if (error != 0) -+ if (error) - return; - - task = poll_queue.head; -- if (task != NULL) -+ if (task) - OPENSSL_free(task); - - poll_queue.head = NULL; -@@ -146,13 +142,13 @@ static int async_get_poll_task(int *id) - while (!poll_queue.status[idx]) { - idx = (idx + 1) % ASYNC_QUEUE_TASK_NUM; - if (cnt++ == ASYNC_QUEUE_TASK_NUM) -- return 0; -+ return UADK_E_FAIL; - } - - *id = idx; - poll_queue.rid = (idx + 1) % ASYNC_QUEUE_TASK_NUM; - -- return 1; -+ return UADK_E_SUCCESS; - } - - static struct async_poll_task *async_get_queue_task(void) -@@ -161,11 +157,11 @@ static struct async_poll_task *async_get_queue_task(void) - struct async_poll_task *task_queue; - int idx, ret; - -- if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) -+ if (pthread_mutex_lock(&poll_queue.async_task_mutex)) - return NULL; - - ret = async_get_poll_task(&idx); -- if (!ret) -+ if (ret == UADK_E_FAIL) - goto err; - - task_queue = poll_queue.head; -@@ -173,10 +169,10 @@ static struct async_poll_task *async_get_queue_task(void) - poll_queue.is_recv = 0; - - err: -- if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) -+ if (pthread_mutex_unlock(&poll_queue.async_task_mutex)) - return NULL; - -- if (cur_task && cur_task->op == NULL) -+ if (cur_task && !cur_task->op) - return NULL; - - return cur_task; -@@ -184,7 +180,7 @@ err: - - void async_free_poll_task(int id, bool is_cb) - { -- if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) -+ if (pthread_mutex_lock(&poll_queue.async_task_mutex)) - return; - - poll_queue.status[id] = 0; -@@ -192,7 +188,7 @@ void async_free_poll_task(int id, bool is_cb) - if (is_cb) - poll_queue.is_recv = 1; - -- if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) -+ if (pthread_mutex_unlock(&poll_queue.async_task_mutex)) - return; - - (void)sem_post(&poll_queue.empty_sem); -@@ -205,17 +201,17 @@ int async_get_free_task(int *id) - int idx, ret; - int cnt = 0; - -- if (sem_wait(&poll_queue.empty_sem) != 0) -- return 0; -+ if (sem_wait(&poll_queue.empty_sem)) -+ return UADK_E_FAIL; - -- if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) -- return 0; -+ if (pthread_mutex_lock(&poll_queue.async_task_mutex)) -+ return UADK_E_FAIL; - - idx = poll_queue.sid; - while (poll_queue.status[idx]) { - idx = (idx + 1) % ASYNC_QUEUE_TASK_NUM; - if (cnt++ == ASYNC_QUEUE_TASK_NUM) { -- ret = 0; -+ ret = UADK_E_FAIL; - goto out; - } - } -@@ -226,11 +222,11 @@ int async_get_free_task(int *id) - task_queue = poll_queue.head; - task = &task_queue[idx]; - task->op = NULL; -- ret = 1; -+ ret = UADK_E_SUCCESS; - - out: -- if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) -- return 0; -+ if (pthread_mutex_unlock(&poll_queue.async_task_mutex)) -+ return UADK_E_FAIL; - - return ret; - } -@@ -249,9 +245,9 @@ static int async_add_poll_task(void *ctx, struct async_op *op, enum task_type ty - - ret = sem_post(&poll_queue.full_sem); - if (ret) -- return 0; -+ return UADK_E_FAIL; - -- return 1; -+ return UADK_E_SUCCESS; - } - - int async_pause_job(void *ctx, struct async_op *op, enum task_type type) -@@ -263,16 +259,16 @@ int async_pause_job(void *ctx, struct async_op *op, enum task_type type) - int ret; - - ret = async_add_poll_task(ctx, op, type); -- if (ret == 0) -+ if (!ret) - return ret; - - waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)op->job); -- if (waitctx == NULL) -- return 0; -+ if (!waitctx) -+ return UADK_E_FAIL; - - do { -- if (ASYNC_pause_job() == 0) -- return 0; -+ if (!ASYNC_pause_job()) -+ return UADK_E_FAIL; - - ret = ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, &efd, &custom); - if (ret <= 0) -@@ -293,13 +289,13 @@ int async_wake_job(ASYNC_JOB *job) - { - ASYNC_WAIT_CTX *waitctx; - OSSL_ASYNC_FD efd; -- void *custom; - uint64_t buf = 1; -+ void *custom; - int ret; - - waitctx = ASYNC_get_wait_ctx(job); -- if (waitctx == NULL) -- return 0; -+ if (!waitctx) -+ return UADK_E_FAIL; - - ret = ASYNC_WAIT_CTX_get_fd(waitctx, uadk_async_key, &efd, &custom); - if (ret > 0) { -@@ -329,7 +325,7 @@ static void *async_poll_process_func(void *args) - int ret, idx; - - while (uadk_e_get_async_poll_state()) { -- if (sem_wait(&poll_queue.full_sem) != 0) { -+ if (sem_wait(&poll_queue.full_sem)) { - if (errno == EINTR) { - /* sem_wait is interrupted by interrupt, continue */ - continue; -@@ -337,7 +333,7 @@ static void *async_poll_process_func(void *args) - } - - task = async_get_queue_task(); -- if (task == NULL) { -+ if (!task) { - (void)sem_post(&poll_queue.full_sem); - usleep(1); - continue; -@@ -364,11 +360,11 @@ int async_module_init(void) - memset(&poll_queue, 0, sizeof(struct async_poll_queue)); - - if (pthread_mutex_init(&(poll_queue.async_task_mutex), NULL) < 0) -- return 0; -+ return UADK_E_FAIL; - - poll_queue.head = OPENSSL_malloc(ASYNC_QUEUE_TASK_NUM * sizeof(struct async_poll_task)); -- if (poll_queue.head == NULL) -- return 0; -+ if (!poll_queue.head) -+ return UADK_E_FAIL; - - if (sem_init(&poll_queue.empty_sem, 0, ASYNC_QUEUE_TASK_NUM) != 0) - goto err; -@@ -384,9 +380,9 @@ int async_module_init(void) - goto err; - - poll_queue.thread_id = thread_id; -- return 1; -+ return UADK_E_SUCCESS; - - err: - async_poll_task_free(); -- return 0; -+ return UADK_E_FAIL; - } -diff --git a/src/uadk_async.h b/src/uadk_async.h -index 6857927..5d73b60 100644 ---- a/src/uadk_async.h -+++ b/src/uadk_async.h -@@ -23,6 +23,9 @@ - #include - - #define ASYNC_QUEUE_TASK_NUM 1024 -+#define UADK_E_SUCCESS 1 -+#define UADK_E_FAIL 0 -+#define DO_SYNC 1 - - struct async_op { - ASYNC_JOB *job; --- -2.25.1 - diff --git a/0004-uadk_provider-support-ec-keymgmt-hardware-accelerati.patch b/0004-uadk_provider-support-ec-keymgmt-hardware-accelerati.patch new file mode 100644 index 0000000000000000000000000000000000000000..853b77d1e41c5911b874930f4f8aa6ed705ade5b --- /dev/null +++ b/0004-uadk_provider-support-ec-keymgmt-hardware-accelerati.patch @@ -0,0 +1,902 @@ +From f124acb1af235ecd30249f903573175c1ea624a2 Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 19 Dec 2024 15:57:57 +0800 +Subject: [PATCH 04/10] uadk_provider: support ec keymgmt hardware acceleration + +Support ECDH key generation. + +Signed-off-by: Weili Qian +Signed-off-by: JiangShui Yang +--- + src/Makefile.am | 3 +- + src/uadk_prov.h | 2 + + src/uadk_prov_ec_kmgmt.c | 746 +++++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 2 + + src/uadk_prov_pkey.c | 26 +- + src/uadk_prov_pkey.h | 9 + + 6 files changed, 785 insertions(+), 3 deletions(-) + create mode 100644 src/uadk_prov_ec_kmgmt.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 921305b..b2e2c06 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -65,7 +65,8 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_prov_rsa.c uadk_prov_dh.c \ + uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.c \ + uadk_prov_pkey.c uadk_prov_sm2.c \ +- uadk_prov_ffc.c uadk_prov_aead.c ++ uadk_prov_ffc.c uadk_prov_aead.c \ ++ uadk_prov_ec_kmgmt.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index e85aff8..9c310b7 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -179,6 +179,8 @@ extern const OSSL_DISPATCH uadk_sm2_keymgmt_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm2_signature_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm2_asym_cipher_functions[FUNC_MAX_NUM]; + ++extern const OSSL_DISPATCH uadk_ec_keymgmt_functions[FUNC_MAX_NUM]; ++ + void uadk_prov_destroy_digest(void); + void uadk_prov_destroy_cipher(void); + void uadk_prov_destroy_aead(void); +diff --git a/src/uadk_prov_ec_kmgmt.c b/src/uadk_prov_ec_kmgmt.c +new file mode 100644 +index 0000000..86182bd +--- /dev/null ++++ b/src/uadk_prov_ec_kmgmt.c +@@ -0,0 +1,746 @@ ++// SPDX-License-Identifier: Apache-2.0 ++/* ++ * Copyright 2024 Huawei Technologies Co.,Ltd. All rights reserved. ++ * ++ * 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 "uadk_async.h" ++#include "uadk_prov.h" ++#include "uadk_prov_pkey.h" ++ ++#define UADK_PROV_ECC_PADDING 7 ++#define UADK_PROV_RAND_MAX_CNT 1000 ++#define UADK_EC_DEFAULT_FLAGS 0 ++#define UADK_EC_FLAGS_ERROR (-1) ++ ++static const OSSL_ITEM check_group_type_nameid_map[] = { ++ {0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT}, ++ {EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED}, ++ {EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST}, ++}; ++ ++UADK_PKEY_KEYMGMT_DESCR(ec, EC); ++ ++static int ec_param_check(struct ec_gen_ctx *gctx, EC_KEY *ec) ++{ ++ const EC_GROUP *group; ++ int type, ret; ++ ++ ret = uadk_prov_ecc_genctx_check(gctx, ec); ++ if (!ret) { ++ fprintf(stderr, "failed to check genctx!\n"); ++ return ret; ++ } ++ ++ group = EC_KEY_get0_group(ec); ++ /* Field GF(2m) is not supported by uadk */ ++ 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_prov_ecc_bit_check(group); ++} ++ ++static int ec_set_public_key(EC_KEY *ec, struct wd_ecc_out *ec_out) ++{ ++ int key_size_std, key_size_x, key_size_y; ++ struct wd_ecc_point *pubkey = NULL; ++ int ret = UADK_P_FAIL; ++ const EC_GROUP *group; ++ int x_shift, y_shift; ++ unsigned char *buff; ++ EC_POINT *point; ++ int buff_size; ++ ++ wd_ecxdh_get_out_params(ec_out, &pubkey); ++ if (!pubkey) { ++ fprintf(stderr, "failed to get pubkey!\n"); ++ return ret; ++ } ++ ++ group = EC_KEY_get0_group(ec); ++ point = EC_POINT_new(group); ++ if (!point) { ++ fprintf(stderr, "failed to new ec point!\n"); ++ return ret; ++ } ++ ++ key_size_std = (unsigned int)(EC_GROUP_get_degree(group) + ++ UADK_PROV_ECC_PADDING) >> TRANS_BITS_BYTES_SHIFT; ++ key_size_x = pubkey->x.dsize; ++ key_size_y = pubkey->y.dsize; ++ if (key_size_x > key_size_std || key_size_y > key_size_std) { ++ fprintf(stderr, "invalid: key size is error!\n"); ++ goto free_point; ++ } ++ ++ /* ++ * The public key is composed as: tag + point_x + point_y ++ * tag - 1 byte ++ * point_x - [key_size_std] bytes ++ * point_y - [key_size_std] bytes ++ */ ++ buff_size = ECC_POINT_SIZE(key_size_std) + 1; ++ x_shift = key_size_std - key_size_x + 1; ++ y_shift = buff_size - key_size_y; ++ buff = (unsigned char *)OPENSSL_zalloc(buff_size); ++ if (!buff) { ++ fprintf(stderr, "failed to alloc buf, buff_size = %d!\n", ++ buff_size); ++ goto free_point; ++ } ++ ++ buff[0] = UADK_OCTET_STRING; ++ memcpy(buff + x_shift, pubkey->x.data, key_size_x); ++ memcpy(buff + y_shift, pubkey->y.data, key_size_y); ++ ++ ret = EC_POINT_oct2point(group, point, buff, buff_size, NULL); ++ if (!ret) { ++ fprintf(stderr, "failed to do EC_POINT_oct2point!\n"); ++ goto free_buf; ++ } ++ ++ ret = EC_KEY_set_public_key(ec, point); ++ if (!ret) ++ fprintf(stderr, "failed to do EC_KEY_set_public_key!\n"); ++ ++free_buf: ++ OPENSSL_free(buff); ++free_point: ++ EC_POINT_free(point); ++ ++ return ret; ++} ++ ++static handle_t ec_alloc_sess(EC_KEY *ec, struct wd_ecc_out **ec_out) ++{ ++ handle_t sess; ++ int ret; ++ ++ ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_EC); ++ if (!ret) { ++ fprintf(stderr, "failed to get hardware ecdh keygen support!\n"); ++ return ret; ++ } ++ ++ ret = uadk_prov_ecc_init("ecdh"); ++ if (!ret) { ++ fprintf(stderr, "failed to init ecdh!\n"); ++ return ret; ++ } ++ ++ sess = uadk_prov_ecc_alloc_sess(ec, "ecdh"); ++ if (!sess) { ++ fprintf(stderr, "failed to alloc ec sess!\n"); ++ return ret; ++ } ++ ++ *ec_out = wd_ecxdh_new_out(sess); ++ if (!(*ec_out)) { ++ fprintf(stderr, "failed to new sign out\n"); ++ wd_ecc_free_sess(sess); ++ return UADK_P_FAIL; ++ } ++ ++ return sess; ++} ++ ++static void ec_free_sess(handle_t sess, struct wd_ecc_out *ec_out) ++{ ++ wd_ecc_del_out(sess, ec_out); ++ wd_ecc_free_sess(sess); ++} ++ ++static int ec_set_private_key(EC_KEY *ec, BIGNUM *priv_key) ++{ ++ BIGNUM *priv_k = priv_key; ++ int ret = UADK_P_FAIL; ++ const EC_GROUP *group; ++ const BIGNUM *order; ++ int cnt = 0; ++ ++ if (priv_k) ++ goto set_key; ++ ++ priv_k = BN_new(); ++ if (!priv_k) { ++ fprintf(stderr, "failed to BN_new priv_k!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ group = EC_KEY_get0_group(ec); ++ order = EC_GROUP_get0_order(group); ++ ++ do { ++ cnt++; ++ if (cnt > UADK_PROV_RAND_MAX_CNT) { ++ fprintf(stderr, "failed to get appropriate prikey, timeout\n"); ++ goto free_priv_k; ++ } ++ ++ if (!BN_priv_rand_range(priv_k, order)) { ++ fprintf(stderr, "failed to get rand data!\n"); ++ goto free_priv_k; ++ } ++ } while (BN_is_zero(priv_k) || BN_is_one(priv_k)); ++ ++set_key: ++ ret = EC_KEY_set_private_key(ec, priv_k); ++ if (!ret) ++ fprintf(stderr, "failed to set private key!\n"); ++ ++free_priv_k: ++ if (!priv_key) ++ BN_clear_free(priv_k); ++ return ret; ++} ++ ++static int ec_update_private_key(EC_KEY *ec, handle_t sess, BIGNUM *priv_key) ++{ ++ int ret; ++ ++ ret = ec_set_private_key(ec, priv_key); ++ if (!ret) ++ return ret; ++ ++ return uadk_prov_ecc_set_private_key(sess, ec); ++} ++ ++static int ec_hw_keygen(EC_KEY *ec, BIGNUM *priv_key) ++{ ++ struct wd_ecc_out *ec_out = NULL; ++ struct wd_ecc_req req = {0}; ++ handle_t sess; ++ int ret; ++ ++ sess = ec_alloc_sess(ec, &ec_out); ++ if (!sess) { ++ fprintf(stderr, "failed to alloc sess!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ec_update_private_key(ec, sess, priv_key); ++ if (!ret) { ++ fprintf(stderr, "failed to update private key!\n"); ++ goto free_sess; ++ } ++ ++ uadk_prov_ecc_fill_req(&req, WD_ECXDH_GEN_KEY, NULL, ec_out); ++ ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); ++ if (!ret) { ++ fprintf(stderr, "failed to generate key!\n"); ++ goto free_sess; ++ } ++ ++ ret = ec_set_public_key(ec, ec_out); ++ ++free_sess: ++ ec_free_sess(sess, ec_out); ++ return ret; ++} ++ ++static int ec_set_cofactor_mode(EC_KEY *ec, int mode) ++{ ++ const EC_GROUP *group = EC_KEY_get0_group(ec); ++ const BIGNUM *cofactor; ++ /* ++ * mode can be only 0 for disable, or 1 for enable here. ++ * ++ * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that ++ * also supports mode == -1 with the meaning of "reset to the default for ++ * the associated key". ++ */ ++ if (mode < COFACTOR_MODE_DISABLED || mode > COFACTOR_MODE_ENABLED) ++ return UADK_P_FAIL; ++ ++ cofactor = EC_GROUP_get0_cofactor(group); ++ if (!cofactor) ++ return UADK_P_FAIL; ++ ++ /* ECDH cofactor mode has no effect if cofactor is 1 */ ++ if (BN_is_one(cofactor)) ++ return UADK_P_SUCCESS; ++ ++ if (mode == COFACTOR_MODE_ENABLED) ++ EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH); ++ else ++ EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH); ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ec_check_group_type_name2id(const char *name) ++{ ++ size_t size = OSSL_NELEM(check_group_type_nameid_map); ++ size_t i; ++ ++ /* Return the default value if there is no name */ ++ if (!name) ++ return UADK_EC_DEFAULT_FLAGS; ++ ++ for (i = 0; i < size; i++) { ++ if (!OPENSSL_strcasecmp(name, check_group_type_nameid_map[i].ptr)) ++ return check_group_type_nameid_map[i].id; ++ } ++ ++ return UADK_EC_FLAGS_ERROR; ++} ++ ++static int ec_set_check_group_type(EC_KEY *ec, const char *name) ++{ ++ int flags; ++ ++ flags = ec_check_group_type_name2id(name); ++ if (flags == UADK_EC_FLAGS_ERROR) ++ return UADK_P_FAIL; ++ ++ EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK); ++ EC_KEY_set_flags(ec, flags); ++ ++ return UADK_P_SUCCESS; ++} ++ ++static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ++{ ++ struct ec_gen_ctx *gctx = genctx; ++ EC_KEY *ec; ++ int ret; ++ ++ if (!gctx) { ++ fprintf(stderr, "invalid: gctx is NULL to ec gen!\n"); ++ return NULL; ++ } ++ ++ ec = EC_KEY_new_ex(gctx->libctx, NULL); ++ if (!ec) { ++ fprintf(stderr, "failed to new ec key!\n"); ++ return NULL; ++ } ++ ++ ret = ec_param_check(genctx, ec); ++ if (!ret) { ++ fprintf(stderr, "failed to check genctx!\n"); ++ goto free_ec_key; ++ } ++ ++ /* 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) { ++ fprintf(stderr, "failed to gen public key!\n"); ++ goto free_ec_key; ++ } ++ } ++ ++ if (gctx->ecdh_mode != COFACTOR_MODE_USE_KEY) { ++ ret = ec_set_cofactor_mode(ec, gctx->ecdh_mode); ++ if (!ret) ++ goto free_ec_key; ++ } ++ ++ if (gctx->group_check) { ++ ret = ec_set_check_group_type(ec, gctx->group_check); ++ if (!ret) ++ goto free_ec_key; ++ } ++ ++ return ec; ++ ++free_ec_key: ++ EC_KEY_free(ec); ++ return NULL; ++} ++ ++static void uadk_keymgmt_ec_gen_cleanup(void *genctx) ++{ ++ struct ec_gen_ctx *gctx = genctx; ++ ++ if (!gctx) ++ return; ++ ++ EC_GROUP_free(gctx->gen_group); ++ BN_free(gctx->p); ++ BN_free(gctx->a); ++ BN_free(gctx->b); ++ BN_free(gctx->order); ++ BN_free(gctx->cofactor); ++ BN_clear_free(gctx->priv_key); ++ OPENSSL_free(gctx->group_name); ++ OPENSSL_free(gctx->field_type); ++ OPENSSL_free(gctx->pt_format); ++ OPENSSL_free(gctx->encoding); ++ OPENSSL_free(gctx->seed); ++ OPENSSL_free(gctx->gen); ++ OPENSSL_free(gctx); ++} ++ ++static void *uadk_keymgmt_ec_gen_init(void *provctx, int selection, ++ const OSSL_PARAM params[]) ++{ ++ struct ec_gen_ctx *gctx; ++ int ret; ++ ++ if (!provctx) ++ return NULL; ++ ++ if (!(selection & OSSL_KEYMGMT_SELECT_ALL)) ++ return NULL; ++ ++ gctx = OPENSSL_zalloc(sizeof(*gctx)); ++ if (!gctx) ++ return NULL; ++ ++ gctx->libctx = prov_libctx_of(provctx); ++ gctx->selection = selection; ++ ++ ret = uadk_keymgmt_ec_gen_set_params(gctx, params); ++ if (!ret) { ++ OPENSSL_free(gctx); ++ return NULL; ++ } ++ ++ return gctx; ++} ++ ++static int uadk_keymgmt_ec_gen_set_template(void *genctx, void *templ) ++{ ++ struct ec_gen_ctx *gctx = genctx; ++ const EC_GROUP *src_group; ++ EC_GROUP *dst_group; ++ EC_KEY *ec = templ; ++ ++ if (!gctx || !ec) { ++ fprintf(stderr, "invalid: genctx or templ is NULL!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ src_group = EC_KEY_get0_group(ec); ++ if (!src_group) { ++ fprintf(stderr, "failed to get source group!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ dst_group = EC_GROUP_dup(src_group); ++ if (!dst_group) { ++ fprintf(stderr, "failed to copy group!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ EC_GROUP_free(gctx->gen_group); ++ gctx->gen_group = dst_group; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ec_set_int_param(const char *key, int *val, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, key); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ return OSSL_PARAM_get_int(p, val); ++} ++ ++static int ec_set_utf8_param(const char *key, char **val, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, key); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ if (p->data_type != OSSL_PARAM_UTF8_STRING) ++ return UADK_P_FAIL; ++ ++ OPENSSL_free(*val); ++ *val = OPENSSL_strdup(p->data); ++ if (!(*val)) ++ return UADK_P_FAIL; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ec_set_bn_param(const char *key, BIGNUM **val, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, key); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ if (!(*val)) ++ *val = BN_new(); ++ ++ if (!(*val)) ++ return UADK_P_FAIL; ++ ++ return OSSL_PARAM_get_BN(p, val); ++} ++ ++static int ec_set_octet_param(const char *key, unsigned char **val, ++ size_t *val_len, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, key); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ if (p->data_type != OSSL_PARAM_OCTET_STRING) ++ return UADK_P_FAIL; ++ ++ OPENSSL_free(*val); ++ *val = OPENSSL_memdup(p->data, p->data_size); ++ if (!(*val)) ++ return UADK_P_FAIL; ++ ++ *val_len = p->data_size; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_keymgmt_ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) ++{ ++ struct ec_gen_ctx *gctx = genctx; ++ int ret; ++ ++ if (!gctx) { ++ fprintf(stderr, "invalid: gctx is NULL to set params!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ec_set_int_param(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, &gctx->ecdh_mode, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_GROUP_NAME, &gctx->group_name, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_FIELD_TYPE, &gctx->field_type, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_ENCODING, &gctx->encoding, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, ++ &gctx->pt_format, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, ++ &gctx->group_check, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_P, &gctx->p, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_A, &gctx->a, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_B, &gctx->b, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_ORDER, &gctx->order, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_PRIV_KEY, &gctx->priv_key, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_COFACTOR, &gctx->cofactor, params); ++ if (!ret) ++ return ret; ++ ++ ret = ec_set_octet_param(OSSL_PKEY_PARAM_EC_SEED, &gctx->seed, ++ &gctx->seed_len, params); ++ if (!ret) ++ return ret; ++ ++ return ec_set_octet_param(OSSL_PKEY_PARAM_EC_GENERATOR, ++ &gctx->gen, &gctx->gen_len, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_ec_gen_settable_params(ossl_unused void *genctx, ++ ossl_unused void *provctx) ++{ ++ static OSSL_PARAM settable[] = { ++ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), ++ OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), ++ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, ++ NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), ++ OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), ++ OSSL_PARAM_END ++ }; ++ ++ return settable; ++} ++ ++static void *uadk_keymgmt_ec_new(void *provctx) ++{ ++ if (!get_default_ec_keymgmt().new_fun) ++ return NULL; ++ ++ return get_default_ec_keymgmt().new_fun(provctx); ++} ++ ++static void uadk_keymgmt_ec_free(void *keydata) ++{ ++ if (!get_default_ec_keymgmt().free) ++ return; ++ ++ return get_default_ec_keymgmt().free(keydata); ++} ++ ++static int uadk_keymgmt_ec_get_params(void *key, OSSL_PARAM params[]) ++{ ++ if (!get_default_ec_keymgmt().get_params) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().get_params(key, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_ec_gettable_params(void *provctx) ++{ ++ if (!get_default_ec_keymgmt().gettable_params) ++ return NULL; ++ ++ return get_default_ec_keymgmt().gettable_params(provctx); ++} ++ ++static int uadk_keymgmt_ec_set_params(void *key, const OSSL_PARAM params[]) ++{ ++ if (!get_default_ec_keymgmt().set_params) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().set_params(key, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_ec_settable_params(void *provctx) ++{ ++ if (!get_default_ec_keymgmt().settable_params) ++ return NULL; ++ ++ return get_default_ec_keymgmt().settable_params(provctx); ++} ++ ++static void *uadk_keymgmt_ec_load(const void *reference, size_t reference_sz) ++{ ++ if (!get_default_ec_keymgmt().load) ++ return NULL; ++ ++ return get_default_ec_keymgmt().load(reference, reference_sz); ++} ++ ++static int uadk_keymgmt_ec_has(const void *keydata, int selection) ++{ ++ if (!get_default_ec_keymgmt().has) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().has(keydata, selection); ++} ++ ++static int uadk_keymgmt_ec_validate(const void *keydata, ++ int selection, int checktype) ++{ ++ if (!get_default_ec_keymgmt().validate) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().validate(keydata, selection, checktype); ++} ++ ++static int uadk_keymgmt_ec_match(const void *keydata1, ++ const void *keydata2, int selection) ++{ ++ if (!get_default_ec_keymgmt().match) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().match(keydata1, keydata2, selection); ++} ++ ++static int uadk_keymgmt_ec_import(void *keydata, int selection, ++ const OSSL_PARAM params[]) ++{ ++ if (!get_default_ec_keymgmt().import) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().import(keydata, selection, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_ec_import_types(int selection) ++{ ++ if (!get_default_ec_keymgmt().import_types) ++ return NULL; ++ ++ return get_default_ec_keymgmt().import_types(selection); ++} ++ ++static int uadk_keymgmt_ec_export(void *keydata, int selection, ++ OSSL_CALLBACK *param_cb, void *cbarg) ++{ ++ if (!get_default_ec_keymgmt().export_fun) ++ return UADK_P_FAIL; ++ ++ return get_default_ec_keymgmt().export_fun(keydata, selection, param_cb, cbarg); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_ec_export_types(int selection) ++{ ++ if (!get_default_ec_keymgmt().export_types) ++ return NULL; ++ ++ return get_default_ec_keymgmt().export_types(selection); ++} ++ ++static void *uadk_keymgmt_ec_dup(const void *keydata_from, int selection) ++{ ++ if (!get_default_ec_keymgmt().dup) ++ return NULL; ++ ++ return get_default_ec_keymgmt().dup(keydata_from, selection); ++} ++ ++static const char *uadk_keymgmt_ec_query_operation_name(int operation_id) ++{ ++ if (!get_default_ec_keymgmt().query_operation_name) ++ return NULL; ++ ++ return get_default_ec_keymgmt().query_operation_name(operation_id); ++} +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 55202ae..b5d3df5 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -174,6 +174,8 @@ static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { + { "DH", UADK_DEFAULT_PROPERTIES, uadk_dh_keymgmt_functions }, + { "SM2", UADK_DEFAULT_PROPERTIES, + uadk_sm2_keymgmt_functions, "uadk SM2 Keymgmt implementation." }, ++ { "EC", UADK_DEFAULT_PROPERTIES, ++ uadk_ec_keymgmt_functions, "uadk EC Keymgmt implementation."}, + { NULL, NULL, NULL } + }; + +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index 6e0612e..170c30b 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -628,7 +628,7 @@ int uadk_prov_ecc_genctx_check(struct ec_gen_ctx *gctx, EC_KEY *ec) + return UADK_P_SUCCESS; + } + +-static bool uadk_prov_support_algorithm(const char *alg) ++bool uadk_prov_support_algorithm(const char *alg) + { + struct uacce_dev_list *list = wd_get_accel_list(alg); + +@@ -642,7 +642,7 @@ static bool uadk_prov_support_algorithm(const char *alg) + + void uadk_prov_keymgmt_alg(void) + { +- static const char * const keymgmt_alg[] = {"sm2"}; ++ static const char * const keymgmt_alg[] = {"sm2", "ecdh"}; + __u32 i, size; + bool sp; + +@@ -811,3 +811,25 @@ void uadk_prov_ecc_uninit(void) + } + pthread_mutex_unlock(&ecc_mutex); + } ++ ++int uadk_prov_ecc_bit_check(const EC_GROUP *group) ++{ ++ int bits = EC_GROUP_order_bits(group); ++ ++ switch (bits) { ++ case ECC128BITS: ++ case ECC192BITS: ++ case ECC224BITS: ++ case ECC256BITS: ++ case ECC320BITS: ++ case ECC384BITS: ++ case ECC521BITS: ++ return UADK_P_SUCCESS; ++ default: ++ break; ++ } ++ ++ fprintf(stderr, "invalid: unsupport key bits %d!\n", bits); ++ ++ return UADK_P_FAIL; ++} +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index c9ddba1..1d4911c 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -68,6 +68,7 @@ + + enum { + KEYMGMT_SM2 = 0x0, ++ KEYMGMT_EC = 0x1, + KEYMGMT_MAX = 0x6 + }; + +@@ -76,6 +77,12 @@ enum { + SIGNATURE_MAX = 0x3 + }; + ++enum { ++ COFACTOR_MODE_USE_KEY = -1, ++ COFACTOR_MODE_DISABLED = 0, ++ COFACTOR_MODE_ENABLED = 1, ++}; ++ + struct curve_param { + /* Prime */ + BIGNUM *p; +@@ -102,6 +109,7 @@ struct ec_gen_ctx { + int selection; + int ecdh_mode; + EC_GROUP *gen_group; ++ BIGNUM *priv_key; + }; + + typedef struct { +@@ -443,5 +451,6 @@ void uadk_prov_signature_alg(void); + void uadk_prov_asym_cipher_alg(void); + int uadk_prov_asym_cipher_get_support_state(int alg_tag); + int uadk_prov_ecc_init(const char *alg_name); ++int uadk_prov_ecc_bit_check(const EC_GROUP *group); + + #endif +-- +2.25.1 + diff --git a/0005-cipher-cleanup-repeated-function-invoking.patch b/0005-cipher-cleanup-repeated-function-invoking.patch deleted file mode 100644 index edf968d05f2b9ab3cf93ecfb14a2031b357eb676..0000000000000000000000000000000000000000 --- a/0005-cipher-cleanup-repeated-function-invoking.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 1cfb48c6d086fc82ea6b72bd9b8cb3c5cacac2b8 Mon Sep 17 00:00:00 2001 -From: Zhiqi Song -Date: Fri, 29 Mar 2024 10:13:23 +0800 -Subject: [PATCH 5/7] cipher: cleanup repeated function invoking - -Cleanup repeated function invoking of EVP_CIPHER_CTX_nid(). - -Signed-off-by: Zhiqi Song -Signed-off-by: JiangShui Yang ---- - src/uadk_cipher.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c -index 7b4ebd8..b506c22 100644 ---- a/src/uadk_cipher.c -+++ b/src/uadk_cipher.c -@@ -39,6 +39,7 @@ - #define IV_LEN 16 - #define ENV_ENABLED 1 - #define MAX_KEY_LEN 64 -+#define SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT 192 - - struct cipher_engine { - struct wd_ctx_config ctx_cfg; -@@ -75,8 +76,6 @@ struct cipher_info { - __u32 out_bytes; - }; - --#define SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT 192 -- - static EVP_CIPHER *uadk_aes_128_cbc; - static EVP_CIPHER *uadk_aes_192_cbc; - static EVP_CIPHER *uadk_aes_256_cbc; -@@ -189,9 +188,9 @@ static int uadk_e_cipher_sw_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - return 0; - } - -- sw_cipher = sec_ciphers_get_cipher_sw_impl(EVP_CIPHER_CTX_nid(ctx)); -+ nid = EVP_CIPHER_CTX_nid(ctx); -+ sw_cipher = sec_ciphers_get_cipher_sw_impl(nid); - if (unlikely(sw_cipher == NULL)) { -- nid = EVP_CIPHER_CTX_nid(ctx); - fprintf(stderr, "get openssl software cipher failed, nid = %d.\n", nid); - return 0; - } --- -2.25.1 - diff --git a/0005-uadk_provider-support-ecdh-keyexch-hardware-accelera.patch b/0005-uadk_provider-support-ecdh-keyexch-hardware-accelera.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6c86b3bb6817d4658f2e457d0a9c3e342f0a0cf --- /dev/null +++ b/0005-uadk_provider-support-ecdh-keyexch-hardware-accelera.patch @@ -0,0 +1,1082 @@ +From 8b0bd5f9f9cfd2e2435df8bc8b2aac9379b6b2c9 Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 19 Dec 2024 15:58:01 +0800 +Subject: [PATCH 05/10] uadk_provider: support ecdh keyexch hardware + acceleration + +Support ECDH key exchange. + +Test: + openssl speed -provider uadk_provider ecdhp192 + openssl speed -provider uadk_provider ecdhp224 + openssl speed -provider uadk_provider ecdhp256 + openssl speed -provider uadk_provider ecdhp384 + openssl speed -provider uadk_provider ecdhp521 + +Signed-off-by: Weili Qian +Signed-off-by: JiangShui Yang +--- + src/Makefile.am | 2 +- + src/uadk_prov.h | 1 + + src/uadk_prov_ecdh_exch.c | 889 ++++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 9 +- + src/uadk_prov_pkey.c | 68 +++ + src/uadk_prov_pkey.h | 6 + + 6 files changed, 971 insertions(+), 4 deletions(-) + create mode 100644 src/uadk_prov_ecdh_exch.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index b2e2c06..5a1abe7 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -66,7 +66,7 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.c \ + uadk_prov_pkey.c uadk_prov_sm2.c \ + uadk_prov_ffc.c uadk_prov_aead.c \ +- uadk_prov_ec_kmgmt.c ++ uadk_prov_ec_kmgmt.c uadk_prov_ecdh_exch.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 9c310b7..7975884 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -180,6 +180,7 @@ extern const OSSL_DISPATCH uadk_sm2_signature_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_sm2_asym_cipher_functions[FUNC_MAX_NUM]; + + extern const OSSL_DISPATCH uadk_ec_keymgmt_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_ecdh_keyexch_functions[FUNC_MAX_NUM]; + + void uadk_prov_destroy_digest(void); + void uadk_prov_destroy_cipher(void); +diff --git a/src/uadk_prov_ecdh_exch.c b/src/uadk_prov_ecdh_exch.c +new file mode 100644 +index 0000000..f549d25 +--- /dev/null ++++ b/src/uadk_prov_ecdh_exch.c +@@ -0,0 +1,889 @@ ++// SPDX-License-Identifier: Apache-2.0 ++/* ++ * Copyright 2024 Huawei Technologies Co.,Ltd. All rights reserved. ++ * ++ * 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 "uadk_async.h" ++#include "uadk_prov.h" ++#include "uadk_prov_der_writer.h" ++#include "uadk_prov_pkey.h" ++ ++#define UADK_PROV_MAX_PARAM_LEN 80 ++ ++enum kdf_type { ++ PROV_ECDH_KDF_NONE = 0, ++ PROV_ECDH_KDF_X9_63 ++}; ++ ++/* ++ * What's passed as an actual key is defined by the KEYMGMT interface. ++ * We happen to know that our KEYMGMT simply passes EC_KEY structures, so ++ * we use that here too. ++ */ ++struct ecdh_ctx { ++ OSSL_LIB_CTX *libctx; ++ ++ EC_KEY *k; ++ EC_KEY *peerk; ++ ++ /* ++ * ECDH cofactor mode: ++ * ++ * . 0 disabled ++ * . 1 enabled ++ * . -1 use cofactor mode set for k ++ */ ++ int cofactor_mode; ++ /* KDF (if any) to use for ECDH */ ++ enum kdf_type kdf_type; ++ /* Message digest to use for key derivation */ ++ EVP_MD *kdf_md; ++ /* User key material */ ++ unsigned char *kdf_ukm; ++ size_t kdf_ukmlen; ++ /* KDF output length */ ++ size_t kdf_outlen; ++}; ++ ++struct ecdh_sess_ctx { ++ EC_KEY *privk; ++ const EC_POINT *pub_key; ++ const BIGNUM *cofactor; ++ const EC_GROUP *group; ++}; ++ ++UADK_PKEY_KEYEXCH_DESCR(ecdh, ECDH); ++static bool g_keyexch_ecdh_support; ++ ++void uadk_prov_keyexch_alg(void) ++{ ++ g_keyexch_ecdh_support = uadk_prov_support_algorithm("ecdh"); ++} ++ ++static size_t ecdh_get_ec_size(const EC_GROUP *group) ++{ ++ size_t degree; ++ ++ degree = EC_GROUP_get_degree(group); ++ ++ return BITS_TO_BYTES(degree); ++} ++ ++static int ecdh_param_check(struct ecdh_ctx *pecdhctx, struct ecdh_sess_ctx *sess_ctx) ++{ ++ const EC_GROUP *group; ++ int type; ++ ++ if (!pecdhctx->k || !pecdhctx->peerk) { ++ fprintf(stderr, "invalid: k or peerk is NULL.\n"); ++ return UADK_P_FAIL; ++ } ++ ++ sess_ctx->pub_key = EC_KEY_get0_public_key(pecdhctx->peerk); ++ if (!sess_ctx->pub_key) { ++ fprintf(stderr, "invalid: public key is NULL.\n"); ++ return UADK_P_FAIL; ++ } ++ ++ group = EC_KEY_get0_group(pecdhctx->k); ++ if (!group) { ++ fprintf(stderr, "invalid: group is 0.\n"); ++ return UADK_P_FAIL; ++ } ++ ++ sess_ctx->cofactor = EC_GROUP_get0_cofactor(group); ++ if (!sess_ctx->cofactor) { ++ fprintf(stderr, "invalid: cofactor is NULL!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ /* Field GF(2m) is not supported by uadk */ ++ 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; ++ } ++ ++ sess_ctx->group = group; ++ ++ return uadk_prov_ecc_bit_check(group); ++} ++ ++static int ecdh_set_privk(struct ecdh_ctx *pecdhctx, ++ struct ecdh_sess_ctx *sess_ctx) ++{ ++ int key_cofactor_mode; ++ ++ /* ++ * The ctx->cofactor_mode flag has precedence over the ++ * cofactor_mode flag set on ctx->k. ++ * ++ * - if ctx->cofactor_mode == -1, use ctx->k directly ++ * - if ctx->cofactor_mode == key_cofactor_mode, use ctx->k directly ++ * - if ctx->cofactor_mode != key_cofactor_mode: ++ * - if ctx->k->cofactor == 1, the cofactor_mode flag is irrelevant, use ++ * ctx->k directly ++ * - if ctx->k->cofactor != 1, use a duplicate of ctx->k with the flag ++ * set to ctx->cofactor_mode ++ */ ++ key_cofactor_mode = (EC_KEY_get_flags(pecdhctx->k) & EC_FLAG_COFACTOR_ECDH) ? ++ COFACTOR_MODE_ENABLED : COFACTOR_MODE_DISABLED; ++ if (pecdhctx->cofactor_mode != COFACTOR_MODE_USE_KEY && ++ pecdhctx->cofactor_mode != key_cofactor_mode && ++ !BN_is_one(sess_ctx->cofactor)) { ++ sess_ctx->privk = EC_KEY_dup(pecdhctx->k); ++ if (!sess_ctx->privk) ++ return UADK_P_FAIL; ++ ++ if (pecdhctx->cofactor_mode == COFACTOR_MODE_ENABLED) ++ EC_KEY_set_flags(sess_ctx->privk, EC_FLAG_COFACTOR_ECDH); ++ else ++ EC_KEY_clear_flags(sess_ctx->privk, EC_FLAG_COFACTOR_ECDH); ++ } else { ++ sess_ctx->privk = pecdhctx->k; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static handle_t ecdh_alloc_sess(EC_KEY *privk) ++{ ++ int ret; ++ ++ if (!g_keyexch_ecdh_support) { ++ fprintf(stderr, "invalid: hardware not support ecdh!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = uadk_prov_ecc_init("ecdh"); ++ if (!ret) { ++ fprintf(stderr, "failed to init ecdh to compute key!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ return uadk_prov_ecc_alloc_sess(privk, "ecdh"); ++} ++ ++static void ecdh_free_sess(handle_t sess) ++{ ++ wd_ecc_free_sess(sess); ++} ++ ++static int ecdh_init_req(struct ecdh_sess_ctx *sess_ctx, ++ struct wd_ecc_req *req, handle_t sess) ++{ ++ char buf_x[UADK_ECC_MAX_KEY_BYTES]; ++ char buf_y[UADK_ECC_MAX_KEY_BYTES]; ++ struct wd_ecc_point in_pkey; ++ struct wd_ecc_out *ecdh_out; ++ struct wd_ecc_in *ecdh_in; ++ BIGNUM *pkey_x, *pkey_y; ++ int ret = UADK_P_FAIL; ++ BN_CTX *ctx; ++ ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return -ENOMEM; ++ ++ BN_CTX_start(ctx); ++ pkey_x = BN_CTX_get(ctx); ++ if (!pkey_x) ++ goto free_ctx; ++ ++ pkey_y = BN_CTX_get(ctx); ++ if (!pkey_y) ++ goto free_ctx; ++ ++ uadk_prov_get_affine_coordinates(sess_ctx->group, sess_ctx->pub_key, pkey_x, pkey_y, ctx); ++ in_pkey.x.data = buf_x; ++ in_pkey.y.data = buf_y; ++ in_pkey.x.dsize = BN_bn2bin(pkey_x, (unsigned char *)in_pkey.x.data); ++ in_pkey.y.dsize = BN_bn2bin(pkey_y, (unsigned char *)in_pkey.y.data); ++ ++ /* Set public key */ ++ ecdh_in = wd_ecxdh_new_in(sess, &in_pkey); ++ if (!ecdh_in) { ++ fprintf(stderr, "failed to new ecxdh in\n"); ++ goto free_ctx; ++ } ++ ++ ecdh_out = wd_ecxdh_new_out(sess); ++ if (!ecdh_out) { ++ fprintf(stderr, "failed to new ecxdh out\n"); ++ wd_ecc_del_in(sess, ecdh_in); ++ goto free_ctx; ++ } ++ ++ uadk_prov_ecc_fill_req(req, WD_ECXDH_COMPUTE_KEY, ecdh_in, ecdh_out); ++ ++ ret = UADK_P_SUCCESS; ++ ++free_ctx: ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ ++ return ret; ++} ++ ++static void ecdh_uninit_req(struct wd_ecc_req *req, handle_t sess) ++{ ++ wd_ecc_del_in(sess, req->src); ++ wd_ecc_del_out(sess, req->dst); ++} ++ ++static int ecdh_get_shared_key(unsigned char *secret, ++ size_t size, size_t *psecretlen, ++ struct wd_ecc_req *req) ++{ ++ struct wd_ecc_point *shared_key = NULL; ++ ++ wd_ecxdh_get_out_params(req->dst, &shared_key); ++ if (!shared_key) { ++ fprintf(stderr, "failed to get ecdh shared key\n"); ++ return UADK_P_FAIL; ++ } ++ ++ size = size < shared_key->x.dsize ? size : shared_key->x.dsize; ++ *psecretlen = size; ++ ++ memcpy(secret, (unsigned char *)shared_key->x.data, size); ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdh_compute_key(struct ecdh_sess_ctx *sess_ctx, ++ unsigned char *secret, ++ size_t *psecretlen, size_t size) ++{ ++ struct wd_ecc_req req = {0}; ++ handle_t sess; ++ int ret; ++ ++ sess = ecdh_alloc_sess(sess_ctx->privk); ++ if (!sess) { ++ fprintf(stderr, "failed to alloc sess to compute key!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = uadk_prov_ecc_set_private_key(sess, sess_ctx->privk); ++ if (!ret) { ++ fprintf(stderr, "failed to set private key!\n"); ++ goto free_sess; ++ } ++ ++ ret = ecdh_init_req(sess_ctx, &req, sess); ++ if (!ret) { ++ fprintf(stderr, "failed to init req!\n"); ++ goto free_sess; ++ } ++ ++ ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess); ++ if (!ret) { ++ fprintf(stderr, "failed to calculate shared key!\n"); ++ goto uninit_req; ++ } ++ ++ ret = ecdh_get_shared_key(secret, size, psecretlen, &req); ++ ++uninit_req: ++ ecdh_uninit_req(&req, sess); ++free_sess: ++ ecdh_free_sess(sess); ++ return ret; ++} ++ ++static int ecdh_plain_derive(struct ecdh_ctx *pecdhctx, ++ unsigned char *secret, ++ size_t *psecretlen, size_t outlen) ++{ ++ struct ecdh_sess_ctx sess_ctx = {0}; ++ size_t size, ec_size; ++ int ret; ++ ++ ret = ecdh_param_check(pecdhctx, &sess_ctx); ++ if (!ret) ++ return ret; ++ ++ ec_size = ecdh_get_ec_size(sess_ctx.group); ++ if (!secret) { ++ *psecretlen = ec_size; ++ return UADK_P_SUCCESS; ++ } ++ ++ ret = ecdh_set_privk(pecdhctx, &sess_ctx); ++ if (!ret) { ++ fprintf(stderr, "failed to set private key!\n"); ++ return ret; ++ } ++ ++ size = outlen < ec_size ? outlen : ec_size; ++ ret = ecdh_compute_key(&sess_ctx, secret, psecretlen, size); ++ if (sess_ctx.privk != pecdhctx->k) ++ EC_KEY_free(sess_ctx.privk); ++ ++ return ret; ++} ++ ++/* Key derivation function from X9.63/SECG */ ++static int ecdh_kdf_X9_63(unsigned char *out, struct ecdh_ctx *pecdhctx, ++ unsigned char *stmp, size_t stmplen) ++{ ++ EVP_KDF *kdf = EVP_KDF_fetch(pecdhctx->libctx, OSSL_KDF_NAME_X963KDF, NULL); ++ const char *mdname = EVP_MD_get0_name(pecdhctx->kdf_md); ++ OSSL_PARAM params[4], *p = params; ++ int ret = UADK_P_FAIL; ++ EVP_KDF_CTX *kctx; ++ ++ if (!kdf) { ++ fprintf(stderr, "failed to fetch kdf!\n"); ++ return ret; ++ } ++ ++ kctx = EVP_KDF_CTX_new(kdf); ++ if (!kctx) { ++ fprintf(stderr, "failed to new kctx!\n"); ++ goto free_kdf; ++ } ++ ++ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); ++ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)stmp, stmplen); ++ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, ++ (void *)pecdhctx->kdf_ukm, pecdhctx->kdf_ukmlen); ++ *p = OSSL_PARAM_construct_end(); ++ ++ ret = EVP_KDF_derive(kctx, out, pecdhctx->kdf_outlen, params); ++ ret = ret <= 0 ? UADK_P_FAIL : UADK_P_SUCCESS; ++ ++ EVP_KDF_CTX_free(kctx); ++ ++free_kdf: ++ EVP_KDF_free(kdf); ++ ++ return ret; ++} ++ ++static int ecdh_X9_63_kdf_derive(struct ecdh_ctx *pecdhctx, unsigned char *secret, ++ size_t *psecretlen, size_t outlen) ++{ ++ unsigned char *stmp; ++ size_t stmplen = 0; ++ int ret; ++ ++ if (!secret) { ++ *psecretlen = pecdhctx->kdf_outlen; ++ return UADK_P_SUCCESS; ++ } ++ ++ if (outlen < pecdhctx->kdf_outlen) { ++ fprintf(stderr, "invalid: outlen %lu is less than kdf_outlen %lu!\n", ++ outlen, pecdhctx->kdf_outlen); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ecdh_plain_derive(pecdhctx, NULL, &stmplen, 0); ++ if (!ret) ++ return ret; ++ ++ stmp = OPENSSL_secure_malloc(stmplen); ++ if (!stmp) { ++ fprintf(stderr, "failed to alloc stmp!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ecdh_plain_derive(pecdhctx, stmp, &stmplen, stmplen); ++ if (!ret) ++ goto free_stmp; ++ ++ ret = ecdh_kdf_X9_63(secret, pecdhctx, stmp, stmplen); ++ if (!ret) ++ goto free_stmp; ++ ++ *psecretlen = pecdhctx->kdf_outlen; ++ ++ free_stmp: ++ OPENSSL_secure_clear_free(stmp, stmplen); ++ return ret; ++} ++ ++static int uadk_keyexch_ecdh_derive(void *vpecdhctx, unsigned char *secret, ++ size_t *psecretlen, size_t outlen) ++{ ++ struct ecdh_ctx *pecdhctx = vpecdhctx; ++ ++ if (!pecdhctx) { ++ fprintf(stderr, "invalid: vpecdhctx is NULL to derive!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ switch (pecdhctx->kdf_type) { ++ case PROV_ECDH_KDF_NONE: ++ return ecdh_plain_derive(pecdhctx, secret, psecretlen, outlen); ++ case PROV_ECDH_KDF_X9_63: ++ return ecdh_X9_63_kdf_derive(pecdhctx, secret, psecretlen, outlen); ++ default: ++ break; ++ } ++ ++ return UADK_P_FAIL; ++} ++ ++static void *uadk_keyexch_ecdh_newctx(void *provctx) ++{ ++ struct ecdh_ctx *pectx; ++ ++ pectx = OPENSSL_zalloc(sizeof(*pectx)); ++ if (!pectx) ++ return NULL; ++ ++ pectx->libctx = prov_libctx_of(provctx); ++ pectx->cofactor_mode = COFACTOR_MODE_USE_KEY; ++ pectx->kdf_type = PROV_ECDH_KDF_NONE; ++ ++ return pectx; ++} ++ ++static void uadk_keyexch_ecdh_freectx(void *vpecdhctx) ++{ ++ struct ecdh_ctx *pecdhctx = vpecdhctx; ++ ++ if (!pecdhctx) ++ return; ++ ++ EC_KEY_free(pecdhctx->k); ++ EC_KEY_free(pecdhctx->peerk); ++ EVP_MD_free(pecdhctx->kdf_md); ++ OPENSSL_clear_free(pecdhctx->kdf_ukm, pecdhctx->kdf_ukmlen); ++ OPENSSL_free(pecdhctx); ++} ++ ++static int uadk_keyexch_ecdh_init(void *vpecdhctx, void *vecdh, const OSSL_PARAM params[]) ++{ ++ struct ecdh_ctx *pecdhctx = vpecdhctx; ++ int ret; ++ ++ if (!pecdhctx || !vecdh) { ++ fprintf(stderr, "invalid: pecdhctx or vecdh is to init!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (!EC_KEY_up_ref(vecdh)) ++ return UADK_P_FAIL; ++ ++ EC_KEY_free(pecdhctx->k); ++ pecdhctx->k = vecdh; ++ pecdhctx->cofactor_mode = COFACTOR_MODE_USE_KEY; ++ pecdhctx->kdf_type = PROV_ECDH_KDF_NONE; ++ ++ ret = uadk_keyexch_ecdh_set_ctx_params(pecdhctx, params); ++ if (!ret) { ++ fprintf(stderr, "failed to set_ctx_params!\n"); ++ return ret; ++ } ++ ++ return uadk_prov_ecc_check_key(pecdhctx->libctx, vecdh, 1); ++} ++ ++static int ecdh_match_params(const EC_KEY *privk, const EC_KEY *pubk) ++{ ++ const EC_GROUP *group_privk = EC_KEY_get0_group(privk); ++ const EC_GROUP *group_pubk = EC_KEY_get0_group(pubk); ++ int ret = UADK_P_SUCCESS; ++ BN_CTX *ctx; ++ ++ ctx = BN_CTX_new_ex(privk->libctx); ++ if (!ctx) { ++ fprintf(stderr, "failed to new ctx!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (group_privk && group_pubk) { ++ if (EC_GROUP_cmp(group_privk, group_pubk, ctx)) { ++ fprintf(stderr, "invalid: privk is not match pubk!\n"); ++ ret = UADK_P_FAIL; ++ } ++ } ++ ++ BN_CTX_free(ctx); ++ ++ return ret; ++} ++ ++static int uadk_keyexch_ecdh_set_peer(void *vpecdhctx, void *vecdh) ++{ ++ struct ecdh_ctx *pecdhctx = vpecdhctx; ++ int ret; ++ ++ if (!pecdhctx || !vecdh) { ++ fprintf(stderr, "invalid: vpecdhctx or vecdh is NULL to set_peer!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ecdh_match_params(pecdhctx->k, vecdh); ++ if (!ret) ++ return ret; ++ ++ ret = uadk_prov_ecc_check_key(pecdhctx->libctx, vecdh, 1); ++ if (!ret) ++ return ret; ++ ++ if (!EC_KEY_up_ref(vecdh)) ++ return UADK_P_FAIL; ++ ++ EC_KEY_free(pecdhctx->peerk); ++ pecdhctx->peerk = vecdh; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static void *uadk_keyexch_ecdh_dupctx(void *vpecdhctx) ++{ ++ struct ecdh_ctx *srcctx = vpecdhctx; ++ struct ecdh_ctx *dstctx; ++ ++ if (!srcctx) { ++ fprintf(stderr, "invalid: source ecdh ctx is NULL!\n"); ++ return NULL; ++ } ++ ++ dstctx = OPENSSL_zalloc(sizeof(*srcctx)); ++ if (!dstctx) { ++ fprintf(stderr, "failed to alloc dst ctx!\n"); ++ return NULL; ++ } ++ ++ memcpy(dstctx, srcctx, sizeof(*dstctx)); ++ ++ dstctx->k = NULL; ++ dstctx->peerk = NULL; ++ dstctx->kdf_md = NULL; ++ dstctx->kdf_ukm = NULL; ++ ++ /* up-ref all ref-counted objects referenced in dstctx */ ++ if (srcctx->k && !EC_KEY_up_ref(srcctx->k)) ++ goto err; ++ else ++ dstctx->k = srcctx->k; ++ ++ if (srcctx->peerk && !EC_KEY_up_ref(srcctx->peerk)) ++ goto err; ++ else ++ dstctx->peerk = srcctx->peerk; ++ ++ if (srcctx->kdf_md && !EVP_MD_up_ref(srcctx->kdf_md)) ++ goto err; ++ else ++ dstctx->kdf_md = srcctx->kdf_md; ++ ++ /* Duplicate UKM data if present */ ++ if (srcctx->kdf_ukm && srcctx->kdf_ukmlen > 0) { ++ dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, ++ srcctx->kdf_ukmlen); ++ if (!dstctx->kdf_ukm) ++ goto err; ++ } ++ ++ return dstctx; ++ ++err: ++ uadk_keyexch_ecdh_freectx(dstctx); ++ return NULL; ++} ++ ++static int ecdh_set_cofactor_mode(struct ecdh_ctx *pectx, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ int mode, ret; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ ret = OSSL_PARAM_get_int(p, &mode); ++ if (!ret) ++ return UADK_P_FAIL; ++ ++ if (mode < COFACTOR_MODE_USE_KEY || mode > COFACTOR_MODE_ENABLED) ++ return UADK_P_FAIL; ++ ++ pectx->cofactor_mode = mode; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdh_get_cofactor_mode(struct ecdh_ctx *pectx, OSSL_PARAM params[]) ++{ ++ int mode = pectx->cofactor_mode; ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ if (mode == COFACTOR_MODE_USE_KEY) ++ /* Check what is the default for pecdhctx->k */ ++ mode = EC_KEY_get_flags(pectx->k) & EC_FLAG_COFACTOR_ECDH ? ++ COFACTOR_MODE_ENABLED : COFACTOR_MODE_DISABLED; ++ ++ return OSSL_PARAM_set_int(p, mode); ++} ++ ++static int ecdh_set_kdf_type(struct ecdh_ctx *pectx, const OSSL_PARAM params[]) ++{ ++ char name[UADK_PROV_MAX_PARAM_LEN] = {'\0'}; ++ const OSSL_PARAM *p; ++ char *str = name; ++ int ret; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ ret = OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)); ++ if (!ret) ++ return UADK_P_FAIL; ++ ++ if (name[0] == '\0') ++ pectx->kdf_type = PROV_ECDH_KDF_NONE; ++ else if (!strcmp(name, OSSL_KDF_NAME_X963KDF)) ++ pectx->kdf_type = PROV_ECDH_KDF_X9_63; ++ else ++ return UADK_P_FAIL; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdh_get_kdf_type(struct ecdh_ctx *pectx, OSSL_PARAM params[]) ++{ ++ const char *kdf_type; ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ switch (pectx->kdf_type) { ++ case PROV_ECDH_KDF_NONE: ++ kdf_type = ""; ++ break; ++ case PROV_ECDH_KDF_X9_63: ++ kdf_type = OSSL_KDF_NAME_X963KDF; ++ break; ++ default: ++ return UADK_P_FAIL; ++ } ++ ++ return OSSL_PARAM_set_utf8_string(p, kdf_type); ++} ++ ++static int ecdh_set_kdf_digest(struct ecdh_ctx *pectx, const OSSL_PARAM params[]) ++{ ++ char mdprops[UADK_PROV_MAX_PARAM_LEN] = {'\0'}; ++ char name[UADK_PROV_MAX_PARAM_LEN] = {'\0'}; ++ const OSSL_PARAM *p; ++ char *str = name; ++ int ret; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ ret = OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)); ++ if (!ret) ++ return UADK_P_FAIL; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); ++ if (p) { ++ str = mdprops; ++ ret = OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops)); ++ if (!ret) ++ return UADK_P_FAIL; ++ } ++ ++ EVP_MD_free(pectx->kdf_md); ++ pectx->kdf_md = EVP_MD_fetch(pectx->libctx, name, mdprops); ++ if (!pectx->kdf_md) ++ return UADK_P_FAIL; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdh_get_kdf_digest(struct ecdh_ctx *pectx, OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ if (!pectx->kdf_md) ++ return OSSL_PARAM_set_utf8_string(p, ""); ++ ++ return OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(pectx->kdf_md)); ++} ++ ++static int ecdh_set_kdf_outlen(struct ecdh_ctx *pectx, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ return OSSL_PARAM_get_size_t(p, &pectx->kdf_outlen); ++} ++ ++static int ecdh_get_kdf_outlen(struct ecdh_ctx *pectx, OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ return OSSL_PARAM_set_size_t(p, pectx->kdf_outlen); ++} ++ ++static int ecdh_set_kdf_ukm(struct ecdh_ctx *pectx, const OSSL_PARAM params[]) ++{ ++ const OSSL_PARAM *p; ++ void *tmp_ukm = NULL; ++ size_t tmp_ukmlen; ++ int ret; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ ret = OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen); ++ if (!ret) ++ return ret; ++ ++ OPENSSL_free(pectx->kdf_ukm); ++ pectx->kdf_ukm = tmp_ukm; ++ pectx->kdf_ukmlen = tmp_ukmlen; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ecdh_get_kdf_ukm(struct ecdh_ctx *pectx, OSSL_PARAM params[]) ++{ ++ OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); ++ if (!p) ++ return UADK_P_SUCCESS; ++ ++ return OSSL_PARAM_set_octet_ptr(p, pectx->kdf_ukm, pectx->kdf_ukmlen); ++} ++ ++static int uadk_keyexch_ecdh_set_ctx_params(void *vpecdhctx, const OSSL_PARAM params[]) ++{ ++ struct ecdh_ctx *pectx = (struct ecdh_ctx *)vpecdhctx; ++ int ret; ++ ++ if (!pectx) { ++ fprintf(stderr, "invalid: pectx is NULL to set_ctx_params!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (!params) ++ return UADK_P_SUCCESS; ++ ++ ret = ecdh_set_cofactor_mode(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_set_kdf_type(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_set_kdf_digest(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_set_kdf_outlen(pectx, params); ++ if (!ret) ++ return ret; ++ ++ return ecdh_set_kdf_ukm(pectx, params); ++} ++ ++static int uadk_keyexch_ecdh_get_ctx_params(void *vpecdhctx, OSSL_PARAM params[]) ++{ ++ struct ecdh_ctx *pectx = vpecdhctx; ++ int ret; ++ ++ if (!pectx) { ++ fprintf(stderr, "invalid: pectx is NULL to get_ctx_params!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = ecdh_get_cofactor_mode(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_get_kdf_type(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_get_kdf_digest(pectx, params); ++ if (!ret) ++ return ret; ++ ++ ret = ecdh_get_kdf_outlen(pectx, params); ++ if (!ret) ++ return ret; ++ ++ return ecdh_get_kdf_ukm(pectx, params); ++} ++ ++static const OSSL_PARAM *uadk_keyexch_ecdh_settable_ctx_params(ossl_unused void *vpecdhctx, ++ ossl_unused void *provctx) ++{ ++ static const OSSL_PARAM known_settable_ctx_params[] = { ++ OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, NULL), ++ OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), ++ OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), ++ OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), ++ OSSL_PARAM_END ++ }; ++ ++ return known_settable_ctx_params; ++} ++ ++static const OSSL_PARAM *uadk_keyexch_ecdh_gettable_ctx_params(ossl_unused void *vpecdhctx, ++ ossl_unused void *provctx) ++{ ++ static const OSSL_PARAM known_gettable_ctx_params[] = { ++ OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, NULL), ++ OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), ++ OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), ++ OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), ++ OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, ++ NULL, 0), ++ OSSL_PARAM_END ++ }; ++ ++ return known_gettable_ctx_params; ++} +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index b5d3df5..42e1272 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -190,6 +190,8 @@ static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { + static const OSSL_ALGORITHM uadk_prov_keyexch[] = { + { "DH", UADK_DEFAULT_PROPERTIES, + uadk_dh_keyexch_functions, "UADK DH keyexch implementation"}, ++ { "ECDH", UADK_DEFAULT_PROPERTIES, ++ uadk_ecdh_keyexch_functions, "uadk_provider ecdh_keyexch" }, + { NULL, NULL, NULL } + }; + +@@ -218,15 +220,16 @@ static const OSSL_ALGORITHM *uadk_query(void *provctx, int operation_id, + return uadk_prov_ciphers_v3; + return uadk_prov_ciphers_v2; + case OSSL_OP_SIGNATURE: +- (void)uadk_prov_signature_alg(); ++ uadk_prov_signature_alg(); + return uadk_prov_signature; + case OSSL_OP_KEYMGMT: +- (void)uadk_prov_keymgmt_alg(); ++ uadk_prov_keymgmt_alg(); + return uadk_prov_keymgmt; + case OSSL_OP_ASYM_CIPHER: +- (void)uadk_prov_asym_cipher_alg(); ++ uadk_prov_asym_cipher_alg(); + return uadk_prov_asym_cipher; + 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); +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index 170c30b..a861551 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -29,6 +29,9 @@ + #define PROV_SUPPORT 1 + #define SIGNATURE_TYPE 3 + #define ASYM_CIPHER_TYPE 3 ++#define SECURITY_CHECK_DISABLE 0 ++#define UADK_PROV_MIN_BITS 112 ++#define UADK_PROV_SECURITY_BITS 80 + + static int p_keymgmt_support_state[KEYMGMT_TYPE]; + static int p_signature_support_state[SIGNATURE_TYPE]; +@@ -833,3 +836,68 @@ int uadk_prov_ecc_bit_check(const EC_GROUP *group) + + return UADK_P_FAIL; + } ++ ++/* Currently, disable the security checks in the default provider and uadk provider */ ++int uadk_prov_securitycheck_enabled(OSSL_LIB_CTX *ctx) ++{ ++ return SECURITY_CHECK_DISABLE; ++} ++ ++#ifdef OPENSSL_NO_FIPS_SECURITYCHECKS ++int uadk_prov_ecc_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) ++{ ++ return UADK_P_SUCCESS; ++} ++#else ++int uadk_prov_ecc_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) ++{ ++ const EC_GROUP *group = EC_KEY_get0_group(ec); ++ const char *curve_name; ++ int nid, strength; ++ ++ if (!uadk_prov_securitycheck_enabled(ctx)) ++ return UADK_P_SUCCESS; ++ ++ if (!group) { ++ fprintf(stderr, "invalid: group is NULL!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ nid = EC_GROUP_get_curve_name(group); ++ if (nid == NID_undef) { ++ fprintf(stderr, "invalid: explicit curves are not allowed in fips mode!\n"); ++ return UADK_P_FAIL; ++ } ++ ++ curve_name = EC_curve_nid2nist(nid); ++ if (!curve_name) { ++ fprintf(stderr, "invalid: Curve %s is not approved in FIPS mode!\n", ++ curve_name); ++ return UADK_P_FAIL; ++ } ++ ++ /* ++ * For EC the security strength is the (order_bits / 2) ++ * e.g. P-224 is 112 bits. ++ */ ++ strength = (unsigned int)EC_GROUP_order_bits(group) >> 1; ++ /* The min security strength allowed for legacy verification is 80 bits */ ++ if (strength < UADK_PROV_SECURITY_BITS) { ++ fprintf(stderr, "invalid: Curve %s strength %d is not approved in FIPS mode!\n", ++ curve_name, strength); ++ return UADK_P_FAIL; ++ } ++ ++ /* ++ * For signing or key agreement only allow curves with at least 112 bits of ++ * security strength ++ */ ++ if (protect && strength < UADK_PROV_MIN_BITS) { ++ fprintf(stderr, "invalid: Curve %s strength %d cannot be used for signing\n", ++ curve_name, strength); ++ return UADK_P_FAIL; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index 1d4911c..fbec388 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -452,5 +452,11 @@ void uadk_prov_asym_cipher_alg(void); + int uadk_prov_asym_cipher_get_support_state(int alg_tag); + int uadk_prov_ecc_init(const char *alg_name); + int uadk_prov_ecc_bit_check(const EC_GROUP *group); ++bool uadk_prov_support_algorithm(const char *alg); ++int uadk_prov_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, ++ BIGNUM *x, BIGNUM *y, BN_CTX *ctx); ++void uadk_prov_keyexch_alg(void); ++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); + + #endif +-- +2.25.1 + diff --git a/0006-digest-add-ctx-allocation-check.patch b/0006-digest-add-ctx-allocation-check.patch deleted file mode 100644 index 707ae3ad722e8b81443515a0941735f596685302..0000000000000000000000000000000000000000 --- a/0006-digest-add-ctx-allocation-check.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 07324a0cdcad935e7d3449b8ff8907ca1c2a6b58 Mon Sep 17 00:00:00 2001 -From: Zhiqi Song -Date: Fri, 29 Mar 2024 10:13:24 +0800 -Subject: [PATCH 6/7] digest: add ctx allocation check - -Add result check of EVP_MD_CTX_new(). - -Signed-off-by: Zhiqi Song -Signed-off-by: JiangShui Yang ---- - src/uadk_digest.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/uadk_digest.c b/src/uadk_digest.c -index 8ab1b83..43bbf60 100644 ---- a/src/uadk_digest.c -+++ b/src/uadk_digest.c -@@ -204,6 +204,8 @@ static int digest_soft_init(struct digest_priv_ctx *md_ctx) - /* Allocate a soft ctx for hardware engine */ - if (md_ctx->soft_ctx == NULL) - md_ctx->soft_ctx = EVP_MD_CTX_new(); -+ if (md_ctx->soft_ctx == NULL) -+ return 0; - - ctx = md_ctx->soft_ctx; - --- -2.25.1 - diff --git a/0006-uadk_provider-support-x448-alg.patch b/0006-uadk_provider-support-x448-alg.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d18301f9b364639673d8a1bd1b067f7ee3e3434 --- /dev/null +++ b/0006-uadk_provider-support-x448-alg.patch @@ -0,0 +1,1506 @@ +From 1bd3dba1cf677fc7a23be78b4aad8979348c9871 Mon Sep 17 00:00:00 2001 +From: Zhiqi Song +Date: Thu, 19 Dec 2024 15:58:05 +0800 +Subject: [PATCH 06/10] uadk_provider: support x448 alg + +Test: +openssl genpkey -provider uadk_provider -algorithm X448 \ + -out a_prikey_x448.pem +openssl pkey -in a_prikey_x448.pem -text +openssl pkey -in a_prikey_x448.pem -pubout -out a_pubkey_x448.pub +openssl genpkey -provider uadk_provider -algorithm x448 \ + -out b_prikey_x448.pem +openssl pkey -in b_prikey_x448.pem -text +openssl pkey -in b_prikey_x448.pem -pubout -out b_pubkey_x448.pub +openssl pkeyutl -derive -out ab_x448.key -inkey a_prikey_x448.pem \ + -peerkey b_pubkey_x448.pub -provider uadk_provider +openssl pkeyutl -derive -out ba_x448.key -inkey b_prikey_x448.pem \ + -peerkey a_pubkey_x448.pub -provider uadk_provider + +cmp ab_x448.key ba_x448.key +xxd ab_x448.key +xxd ba_x448.key + +Signed-off-by: Zhiqi Song +Signed-off-by: JiangShui Yang +--- + src/Makefile.am | 3 +- + src/uadk_prov.h | 3 + + src/uadk_prov_ec_kmgmt.c | 2 +- + src/uadk_prov_ecdh_exch.c | 9 +- + src/uadk_prov_ecx.c | 1192 +++++++++++++++++++++++++++++++++++++ + src/uadk_prov_init.c | 4 + + src/uadk_prov_pkey.c | 51 +- + src/uadk_prov_pkey.h | 12 +- + 8 files changed, 1256 insertions(+), 20 deletions(-) + create mode 100644 src/uadk_prov_ecx.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 5a1abe7..a165d3a 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -66,7 +66,8 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ + uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.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_ec_kmgmt.c uadk_prov_ecdh_exch.c \ ++ uadk_prov_ecx.c + + uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) + uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread +diff --git a/src/uadk_prov.h b/src/uadk_prov.h +index 7975884..84a3f01 100644 +--- a/src/uadk_prov.h ++++ b/src/uadk_prov.h +@@ -182,6 +182,9 @@ extern const OSSL_DISPATCH uadk_sm2_asym_cipher_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_ec_keymgmt_functions[FUNC_MAX_NUM]; + extern const OSSL_DISPATCH uadk_ecdh_keyexch_functions[FUNC_MAX_NUM]; + ++extern const OSSL_DISPATCH uadk_x448_keymgmt_functions[FUNC_MAX_NUM]; ++extern const OSSL_DISPATCH uadk_x448_keyexch_functions[FUNC_MAX_NUM]; ++ + void uadk_prov_destroy_digest(void); + void uadk_prov_destroy_cipher(void); + void uadk_prov_destroy_aead(void); +diff --git a/src/uadk_prov_ec_kmgmt.c b/src/uadk_prov_ec_kmgmt.c +index 86182bd..355d601 100644 +--- a/src/uadk_prov_ec_kmgmt.c ++++ b/src/uadk_prov_ec_kmgmt.c +@@ -136,7 +136,7 @@ static handle_t ec_alloc_sess(EC_KEY *ec, struct wd_ecc_out **ec_out) + handle_t sess; + int ret; + +- ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_EC); ++ ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_ECDH); + if (!ret) { + fprintf(stderr, "failed to get hardware ecdh keygen support!\n"); + return ret; +diff --git a/src/uadk_prov_ecdh_exch.c b/src/uadk_prov_ecdh_exch.c +index f549d25..9ac8e58 100644 +--- a/src/uadk_prov_ecdh_exch.c ++++ b/src/uadk_prov_ecdh_exch.c +@@ -72,12 +72,6 @@ struct ecdh_sess_ctx { + }; + + UADK_PKEY_KEYEXCH_DESCR(ecdh, ECDH); +-static bool g_keyexch_ecdh_support; +- +-void uadk_prov_keyexch_alg(void) +-{ +- g_keyexch_ecdh_support = uadk_prov_support_algorithm("ecdh"); +-} + + static size_t ecdh_get_ec_size(const EC_GROUP *group) + { +@@ -169,7 +163,8 @@ static handle_t ecdh_alloc_sess(EC_KEY *privk) + { + int ret; + +- if (!g_keyexch_ecdh_support) { ++ ret = uadk_prov_keyexch_get_support_state(KEYEXCH_ECDH); ++ if (!ret) { + fprintf(stderr, "invalid: hardware not support ecdh!\n"); + return UADK_P_FAIL; + } +diff --git a/src/uadk_prov_ecx.c b/src/uadk_prov_ecx.c +new file mode 100644 +index 0000000..302dc48 +--- /dev/null ++++ b/src/uadk_prov_ecx.c +@@ -0,0 +1,1192 @@ ++// SPDX-License-Identifier: Apache-2.0 ++/* ++ * Copyright 2024 Huawei Technologies Co.,Ltd. All rights reserved. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "uadk_async.h" ++#include "uadk_prov.h" ++#include "uadk_prov_pkey.h" ++ ++#define X448_KEYLEN 56 ++#define X448_KEYBITS 448 ++#define ECX_MAX_KEYLEN 57 ++#define X448_SECURITY_BITS 224 ++ ++#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) ++ ++#define UADK_CRYPTO_UP_REF(val, ret, lock) CRYPTO_atomic_add(val, 1, ret, lock) ++ ++static inline int UADK_CRYPTO_DOWN_REF(int *val, int *ret, ++ ossl_unused void *lock) ++{ ++ *ret = __atomic_fetch_sub(val, 1, __ATOMIC_RELAXED) - 1; ++ if (*ret == 0) ++ __atomic_thread_fence(__ATOMIC_ACQUIRE); ++ return 1; ++} ++ ++UADK_PKEY_KEYMGMT_DESCR(x448, X448); ++UADK_PKEY_KEYEXCH_DESCR(x448, X448); ++ ++typedef enum { ++ ECX_KEY_TYPE_X25519 = 0x0, ++ ECX_KEY_TYPE_X448 = 0x1, ++} ECX_KEY_TYPE; ++ ++typedef struct { ++ OSSL_LIB_CTX *libctx; ++ char *propq; ++ unsigned int haspubkey:1; ++ unsigned char pubkey[ECX_MAX_KEYLEN]; ++ unsigned char *privkey; ++ size_t keylen; ++ ECX_KEY_TYPE type; ++ int references; ++ void *lock; ++} ECX_KEY; ++ ++typedef struct { ++ OSSL_LIB_CTX *libctx; ++ char *propq; ++ ECX_KEY_TYPE type; ++ int selection; ++ size_t keylen; ++ /* uadk sesssion */ ++ handle_t sess; ++} PROV_ECX_KEYMGMT_CTX; ++ ++typedef struct { ++ size_t keylen; ++ ECX_KEY *key; ++ ECX_KEY *peerkey; ++ OSSL_LIB_CTX *libctx; ++ char *propq; ++ /* uadk sesssion */ ++ handle_t sess; ++} PROV_ECX_KEYEXCH_CTX; ++ ++static const OSSL_PARAM ecx_key_types[] = { ++ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), ++ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), ++ OSSL_PARAM_END ++}; ++ ++struct x448_res { ++ int pid; ++} g_x448_prov; ++ ++static void *uadk_keymgmt_x448_new(void *provctx) ++{ ++ if (get_default_x448_keymgmt().new_fun == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().new_fun(provctx); ++} ++ ++void uadk_keymgmt_x448_free(void *keydata) ++{ ++ if (get_default_x448_keymgmt().free == NULL) ++ return; ++ ++ get_default_x448_keymgmt().free(keydata); ++} ++ ++static int uadk_keymgmt_x448_has(const void *keydata, int selection) ++{ ++ if (get_default_x448_keymgmt().has == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().has(keydata, selection); ++} ++ ++static int uadk_keymgmt_x448_match(const void *keydata1, const void *keydata2, int selection) ++{ ++ if (get_default_x448_keymgmt().match == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().match(keydata1, keydata2, selection); ++} ++ ++static int uadk_keymgmt_x448_import(void *keydata, int selection, const OSSL_PARAM params[]) ++{ ++ if (get_default_x448_keymgmt().import == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().import(keydata, selection, params); ++} ++ ++static int uadk_keymgmt_x448_export(void *keydata, int selection, ++ OSSL_CALLBACK *cb, void *cb_params) ++{ ++ if (get_default_x448_keymgmt().export_fun == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().export_fun(keydata, selection, cb, cb_params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_x448_import_types(int selection) ++{ ++ if (get_default_x448_keymgmt().import_types == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().import_types(selection); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_x448_export_types(int selection) ++{ ++ if (get_default_x448_keymgmt().export_types == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().export_types(selection); ++} ++ ++void *uadk_keymgmt_x448_load(const void *reference, size_t reference_sz) ++{ ++ if (get_default_x448_keymgmt().load == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().load(reference, reference_sz); ++} ++ ++static void *uadk_keymgmt_x448_dup(const void *keydata_from, int selection) ++{ ++ if (get_default_x448_keymgmt().dup == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().dup(keydata_from, selection); ++} ++ ++static int uadk_keymgmt_x448_validate(const void *keydata, int selection, int checktype) ++{ ++ if (get_default_x448_keymgmt().validate == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().validate(keydata, selection, checktype); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_x448_gettable_params(void *provctx) ++{ ++ if (get_default_x448_keymgmt().gettable_params == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().gettable_params(provctx); ++} ++ ++static int uadk_keymgmt_x448_set_params(void *key, const OSSL_PARAM params[]) ++{ ++ if (get_default_x448_keymgmt().set_params == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().set_params(key, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_x448_settable_params(void *provctx) ++{ ++ if (get_default_x448_keymgmt().settable_params == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().settable_params(provctx); ++} ++ ++static int uadk_keymgmt_x448_gen_set_params(void *genctx, ++ const OSSL_PARAM params[]) ++{ ++ if (get_default_x448_keymgmt().gen_set_params == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().gen_set_params(genctx, params); ++} ++ ++static const OSSL_PARAM *uadk_keymgmt_x448_gen_settable_params(ossl_unused void *genctx, ++ ossl_unused void *provctx) ++{ ++ if (get_default_x448_keymgmt().gen_settable_params == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().gen_settable_params(genctx, provctx); ++} ++ ++static int uadk_keymgmt_x448_gen_set_template(void *genctx, void *templ) ++{ ++ if (get_default_x448_keymgmt().gen_set_template == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keymgmt().gen_set_template(genctx, templ); ++} ++ ++static const char *uadk_keymgmt_x448_query_operation_name(int operation_id) ++{ ++ if (get_default_x448_keymgmt().query_operation_name == NULL) ++ return NULL; ++ ++ return get_default_x448_keymgmt().query_operation_name(operation_id); ++} ++ ++static int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, const char *key, ++ const unsigned char *data, size_t data_len) ++{ ++ if (bld != NULL) ++ return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len); ++ ++ p = OSSL_PARAM_locate(p, key); ++ if (p != NULL) ++ return OSSL_PARAM_set_octet_string(p, data, data_len); ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, ++ const char *key, const BIGNUM *bn, size_t sz) ++{ ++ if (bld != NULL) ++ return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, sz); ++ ++ p = OSSL_PARAM_locate(p, key); ++ if (p != NULL) { ++ if (sz > p->data_size) ++ return UADK_P_FAIL; ++ p->data_size = sz; ++ return OSSL_PARAM_set_BN(p, bn); ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_prov_key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl, ++ OSSL_PARAM params[], int include_private) ++{ ++ if (!ossl_param_build_set_octet_string(tmpl, params, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ key->pubkey, key->keylen)) ++ return UADK_P_FAIL; ++ ++ if (include_private && key->privkey != NULL ++ && !ossl_param_build_set_octet_string(tmpl, params, ++ OSSL_PKEY_PARAM_PRIV_KEY, ++ key->privkey, key->keylen)) ++ return UADK_P_FAIL; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_prov_ecx_get_params(void *key, OSSL_PARAM params[], ++ int bits, int secbits, int size) ++{ ++ ECX_KEY *ecx = key; ++ OSSL_PARAM *p; ++ ++ if (ecx == NULL) ++ return UADK_P_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS); ++ if (p && !OSSL_PARAM_set_int(p, bits)) ++ return UADK_P_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS); ++ if (p && !OSSL_PARAM_set_int(p, secbits)) ++ return UADK_P_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE); ++ if (p && !OSSL_PARAM_set_int(p, size)) ++ return UADK_P_FAIL; ++ ++ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); ++ if (p && (ecx->type == ECX_KEY_TYPE_X25519 || ecx->type == ECX_KEY_TYPE_X448)) { ++ if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen)) ++ return UADK_P_FAIL; ++ } ++ ++ return uadk_prov_key_to_params(ecx, NULL, params, 1); ++} ++ ++static int uadk_keymgmt_x448_get_params(void *key, OSSL_PARAM params[]) ++{ ++ return uadk_prov_ecx_get_params(key, params, X448_KEYBITS, X448_SECURITY_BITS, ++ X448_KEYLEN); ++} ++ ++static int ossl_ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) ++{ ++ PROV_ECX_KEYMGMT_CTX *gctx = (PROV_ECX_KEYMGMT_CTX *)genctx; ++ const char *groupname = NULL; ++ const OSSL_PARAM *p; ++ ++ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); ++ if (p != NULL) { ++ /* ++ * We optionally allow setting a group name - but each algorithm only ++ * support one such name, so all we do is verify that it is the one we ++ * expected. ++ */ ++ switch (gctx->type) { ++ case ECX_KEY_TYPE_X25519: ++ groupname = "x25519"; ++ break; ++ case ECX_KEY_TYPE_X448: ++ groupname = "x448"; ++ break; ++ default: ++ /* We only support this for key exchange at the moment */ ++ break; ++ } ++ if (p->data_type != OSSL_PARAM_UTF8_STRING || groupname == NULL || ++ OPENSSL_strcasecmp(p->data, groupname) != 0) { ++ fprintf(stderr, "invalid ecx params\n"); ++ return UADK_P_FAIL; ++ } ++ } ++ p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); ++ if (p != NULL) { ++ if (p->data_type != OSSL_PARAM_UTF8_STRING) ++ return UADK_P_FAIL; ++ ++ OPENSSL_free(gctx->propq); ++ gctx->propq = OPENSSL_strdup(p->data); ++ if (gctx->propq == NULL) ++ return UADK_P_FAIL; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static handle_t uadk_prov_x448_alloc_sess(void) ++{ ++ struct wd_ecc_sess_setup setup = {0}; ++ struct sched_params params = {0}; ++ ++ setup.alg = "x448"; ++ setup.key_bits = X448_KEYBITS; ++ params.numa_id = -1; ++ setup.sched_param = ¶ms; ++ ++ return wd_ecc_alloc_sess(&setup); ++} ++ ++static void uadk_prov_x448_free_sess(handle_t sess) ++{ ++ if (sess) ++ wd_ecc_free_sess(sess); ++} ++ ++static void *ossl_ecx_gen_init(void *provctx, int selection, const OSSL_PARAM params[], ++ ECX_KEY_TYPE type) ++{ ++ OSSL_LIB_CTX *libctx = prov_libctx_of(provctx); ++ PROV_ECX_KEYMGMT_CTX *gctx = NULL; ++ int ret; ++ ++ gctx = OPENSSL_zalloc(sizeof(PROV_ECX_KEYMGMT_CTX)); ++ if (gctx == NULL) { ++ fprintf(stderr, "failed to alloc ecx gctx\n"); ++ return NULL; ++ } ++ ++ gctx->libctx = libctx; ++ gctx->type = type; ++ gctx->selection = selection; ++ ++ ret = ossl_ecx_gen_set_params(gctx, params); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to set ecx params\n"); ++ OPENSSL_free(gctx); ++ gctx = NULL; ++ } ++ ++ return gctx; ++} ++ ++static void uadk_keymgmt_x448_gen_cleanup(void *genctx) ++{ ++ /* genctx will be freed in cleanup function */ ++ if (get_default_x448_keymgmt().gen_cleanup == NULL) ++ return; ++ ++ get_default_x448_keymgmt().gen_cleanup(genctx); ++} ++ ++static void *uadk_keymgmt_x448_gen_init(void *provctx, int selection, ++ const OSSL_PARAM params[]) ++{ ++ PROV_ECX_KEYMGMT_CTX *gctx = NULL; ++ int ret; ++ ++ if (provctx == NULL) { ++ fprintf(stderr, "invalid: provctx is NULL\n"); ++ return NULL; ++ } ++ ++ return ossl_ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448); ++} ++ ++ECX_KEY *uadk_prov_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, ++ const char *propq) ++{ ++ ECX_KEY *ecx_key = OPENSSL_zalloc(sizeof(ECX_KEY)); ++ ++ if (ecx_key == NULL) { ++ fprintf(stderr, "failed to alloc ecx key"); ++ return NULL; ++ } ++ ++ ecx_key->libctx = libctx; ++ ecx_key->haspubkey = haspubkey; ++ ++ switch (type) { ++ case ECX_KEY_TYPE_X448: ++ ecx_key->keylen = X448_KEYLEN; ++ ecx_key->type = type; ++ ecx_key->references = 1; ++ break; ++ default: ++ fprintf(stderr, "invalid: unsupported ecx type\n"); ++ goto free_ecx_key; ++ } ++ ++ if (propq) { ++ ecx_key->propq = OPENSSL_strdup(propq); ++ if (ecx_key->propq == NULL) ++ goto free_ecx_key; ++ } ++ ++ ecx_key->lock = CRYPTO_THREAD_lock_new(); ++ if (ecx_key->lock == NULL) ++ goto err; ++ ++ return ecx_key; ++ ++err: ++ if (propq) ++ OPENSSL_free(ecx_key->propq); ++free_ecx_key: ++ OPENSSL_free(ecx_key); ++ return NULL; ++} ++ ++static void uadk_prov_ecx_key_free(ECX_KEY *ecx_key) ++{ ++ int i = 0; ++ ++ if (ecx_key == NULL) ++ return; ++ ++ UADK_CRYPTO_DOWN_REF(&ecx_key->references, &i, ecx_key->lock); ++ if (i > 0) ++ return; ++ ++ if (ecx_key->propq) ++ OPENSSL_free(ecx_key->propq); ++ ++ if (ecx_key->privkey) ++ OPENSSL_secure_free(ecx_key->privkey); ++ ++ if (ecx_key->lock) ++ CRYPTO_THREAD_lock_free(ecx_key->lock); ++ ++ OPENSSL_free(ecx_key); ++} ++ ++static ECX_KEY *uadk_prov_ecx_create_prikey(PROV_ECX_KEYMGMT_CTX *gctx) ++{ ++ unsigned char *prikey = NULL; ++ ECX_KEY *ecx_key = NULL; ++ int ret; ++ ++ ecx_key = uadk_prov_ecx_key_new(gctx->libctx, gctx->type, 0, gctx->propq); ++ if (ecx_key == NULL) { ++ fprintf(stderr, "failed to new ecx_key\n"); ++ return UADK_P_FAIL; ++ } ++ gctx->keylen = X448_KEYLEN; ++ ++ /* If we're doing parameter generation then we just return a blank key */ ++ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) ++ return ecx_key; ++ ++ prikey = OPENSSL_secure_malloc(ecx_key->keylen); ++ if (prikey == NULL) { ++ fprintf(stderr, "failed to alloc prikey\n"); ++ goto free_ecx_key; ++ } ++ ++ ret = RAND_priv_bytes(prikey, ecx_key->keylen); ++ if (ret <= 0) { ++ fprintf(stderr, "failed to set rand bytes to prikey\n"); ++ goto free_pri; ++ } ++ ecx_key->privkey = prikey; ++ ++ return ecx_key; ++ ++free_pri: ++ OPENSSL_secure_free(prikey); ++free_ecx_key: ++ uadk_prov_ecx_key_free(ecx_key); ++ ++ return NULL; ++} ++ ++static void uadk_prov_ecx_free_prikey(ECX_KEY *ecx_key) ++{ ++ if (ecx_key == NULL) ++ return; ++ ++ if (ecx_key->privkey) { ++ OPENSSL_secure_free(ecx_key->privkey); ++ ecx_key->privkey = NULL; ++ } ++ ++ uadk_prov_ecx_key_free(ecx_key); ++} ++ ++static int uadk_prov_ecx_keygen_init_iot(handle_t sess, struct wd_ecc_req *req) ++{ ++ struct wd_ecc_out *ecx_out; ++ ++ ecx_out = wd_ecxdh_new_out(sess); ++ if (ecx_out == NULL) { ++ fprintf(stderr, "failed to new sign out\n"); ++ return UADK_P_FAIL; ++ } ++ ++ uadk_prov_ecc_fill_req(req, WD_ECXDH_GEN_KEY, NULL, ecx_out); ++ ++ return UADK_P_SUCCESS; ++} ++ ++static void uadk_prov_ecx_keygen_uninit_iot(handle_t sess, struct wd_ecc_req *req) ++{ ++ wd_ecc_del_out(sess, req->dst); ++} ++ ++static int uadk_prov_reverse_bytes(unsigned char *to_buf, __u32 size) ++{ ++ unsigned char *tmp_buf = NULL; ++ unsigned char tmp; ++ ++ if (size == 0) { ++ fprintf(stderr, "invalid size, size = %u\n", size); ++ return UADK_P_FAIL; ++ } ++ ++ if (to_buf == NULL) { ++ fprintf(stderr, "to_buf is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ tmp_buf = to_buf + size - 1; ++ while (to_buf < tmp_buf) { ++ tmp = *tmp_buf; ++ *tmp_buf-- = *to_buf; ++ *to_buf++ = tmp; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_prov_reverse_bytes_ex(unsigned char *src_buf, unsigned char *dst_buf, __u32 size) ++{ ++ __u32 i; ++ ++ if (size == 0) { ++ fprintf(stderr, "invalid size, size = %u\n", size); ++ return UADK_P_FAIL; ++ } ++ ++ if (src_buf == NULL) { ++ fprintf(stderr, "src_buf is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (dst_buf == NULL) { ++ fprintf(stderr, "dst_buf is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ for (i = 0; i < size; i++) ++ dst_buf[i] = src_buf[size - i - 1]; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_prov_ecx_set_pkey(PROV_ECX_KEYMGMT_CTX *gctx, struct wd_ecc_req *req, ++ ECX_KEY *ecx_key) ++{ ++ struct wd_ecc_point *pubkey = NULL; ++ int ret; ++ ++ wd_ecxdh_get_out_params(req->dst, &pubkey); ++ if (pubkey == NULL) { ++ fprintf(stderr, "failed to get pubkey\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (pubkey->x.dsize >= ECX_MAX_KEYLEN) { ++ fprintf(stderr, "invalid: pubkey->x.dsize = %u\n", ++ pubkey->x.dsize); ++ return UADK_P_FAIL; ++ } ++ ++ /* Trans public key from big-endian to little-endian */ ++ ret = uadk_prov_reverse_bytes_ex((unsigned char *)pubkey->x.data, ++ ecx_key->pubkey, pubkey->x.dsize); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to transform pubkey\n"); ++ return ret; ++ } ++ /* Trans private key from big-endian to little-endian */ ++ ret = uadk_prov_reverse_bytes(ecx_key->privkey, gctx->keylen); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to transform prikey\n"); ++ return ret; ++ } ++ /* ++ * This is a pretreatment of X448 described in RFC 7748. ++ * In order to decode the random bytes as an integer scaler, there ++ * are some special data processing. And use little-endian mode for ++ * decoding. ++ */ ++ if (gctx->type == ECX_KEY_TYPE_X448) { ++ /* Set the two LSB of the first byte to 0 */ ++ ecx_key->privkey[0] &= 0xFC; ++ ++ /* Set the MSB of the last byte to 1 */ ++ ecx_key->privkey[X448_KEYLEN - 1] |= 0x80; ++ } else { ++ fprintf(stderr, "invalid: unsupported ecx type\n"); ++ return UADK_P_FAIL; ++ } ++ ++ return ret; ++} ++ ++static int uadk_prov_ecx_keygen_set_prikey(PROV_ECX_KEYMGMT_CTX *gctx, ECX_KEY *ecx_key) ++{ ++ struct wd_ecc_key *ecc_key = NULL; ++ struct wd_dtb prikey = {0}; ++ handle_t sess = gctx->sess; ++ int ret; ++ ++ prikey.data = (char *)ecx_key->privkey; ++ prikey.dsize = ecx_key->keylen; ++ ++ ecc_key = wd_ecc_get_key(sess); ++ ret = wd_ecc_set_prikey(ecc_key, &prikey); ++ if (ret) { ++ fprintf(stderr, "failed to set ecc prikey, ret = %d\n", ret); ++ return UADK_P_FAIL; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static void *uadk_prov_ecx_keygen(PROV_ECX_KEYMGMT_CTX *gctx) ++{ ++ 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; ++ ++ 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); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ ret = uadk_prov_ecc_crypto(gctx->sess, &req, (void *)gctx->sess); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ ret = uadk_prov_ecx_set_pkey(gctx, &req, ecx_key); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ ecx_key->haspubkey = 1; ++ ++ uadk_prov_ecx_keygen_uninit_iot(gctx->sess, &req); ++ ++ return ecx_key; ++ ++uninit_iot: ++ uadk_prov_ecx_keygen_uninit_iot(gctx->sess, &req); ++free_prikey: ++ uadk_prov_ecx_free_prikey(ecx_key); ++ ++ return NULL; ++} ++ ++static void *uadk_keymgmt_x448_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) ++{ ++ PROV_ECX_KEYMGMT_CTX *gctx = (PROV_ECX_KEYMGMT_CTX *)genctx; ++ ECX_KEY *ecx_key = NULL; ++ int ret; ++ ++ if (gctx == NULL) { ++ fprintf(stderr, "invalid: ecx keygen ctx is NULL\n"); ++ return NULL; ++ } ++ ++ if (gctx->type != ECX_KEY_TYPE_X448) { ++ fprintf(stderr, "invalid: unsupported ecx type\n"); ++ return NULL; ++ } ++ ++ 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_prov_ecc_init("x448"); ++ if (ret != UADK_P_SUCCESS) { ++ fprintf(stderr, "failed to init x448\n"); ++ return NULL; ++ } ++ ++ gctx->sess = uadk_prov_x448_alloc_sess(); ++ if (gctx->sess == (handle_t)0) { ++ fprintf(stderr, "failed to alloc x448 sess\n"); ++ return NULL; ++ } ++ ++ ecx_key = uadk_prov_ecx_keygen(gctx); ++ if (ecx_key == NULL) ++ fprintf(stderr, "failed to generate x448 key\n"); ++ ++ uadk_prov_x448_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; ++ ++ 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"); ++ } ++ } ++ return s_keyexch; ++} ++ ++static void *uadk_keyexch_x448_newctx(void *provctx) ++{ ++ PROV_ECX_KEYEXCH_CTX *ecxctx = NULL; ++ int ret; ++ ++ ecxctx = OPENSSL_zalloc(sizeof(PROV_ECX_KEYEXCH_CTX)); ++ if (ecxctx == NULL) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ ecxctx->keylen = X448_KEYLEN; ++ ++ return ecxctx; ++} ++ ++static void uadk_keyexch_x448_freectx(void *vecxctx) ++{ ++ PROV_ECX_KEYEXCH_CTX *ecxctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; ++ ++ if (ecxctx == NULL) ++ return; ++ ++ OPENSSL_free(ecxctx); ++ ecxctx = NULL; ++} ++ ++static int uadk_keyexch_x448_set_ctx_params(void *ecxctx, const OSSL_PARAM params[]) ++{ ++ if (get_default_x448_keyexch().set_ctx_params == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keyexch().set_ctx_params(ecxctx, params); ++} ++ ++static const OSSL_PARAM *uadk_keyexch_x448_settable_ctx_params(ossl_unused void *ecxctx, ++ ossl_unused void *provctx) ++{ ++ if (get_default_x448_keyexch().settable_ctx_params == NULL) ++ return NULL; ++ ++ return get_default_x448_keyexch().settable_ctx_params(ecxctx, provctx); ++} ++ ++static const OSSL_PARAM *uadk_keyexch_x448_gettable_ctx_params(ossl_unused void *ecxctx, ++ ossl_unused void *provctx) ++{ ++ if (get_default_x448_keyexch().gettable_ctx_params == NULL) ++ return NULL; ++ ++ return get_default_x448_keyexch().gettable_ctx_params(ecxctx, provctx); ++} ++ ++static int uadk_keyexch_x448_get_ctx_params(void *ecxctx, OSSL_PARAM params[]) ++{ ++ if (get_default_x448_keyexch().get_ctx_params == NULL) ++ return UADK_P_FAIL; ++ ++ return get_default_x448_keyexch().get_ctx_params(ecxctx, params); ++} ++ ++static int uadk_keyexch_x448_init(void *vecxctx, void *vkey, ++ ossl_unused const OSSL_PARAM params[]) ++{ ++ PROV_ECX_KEYEXCH_CTX *ecxctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; ++ ECX_KEY *key = vkey; ++ int ret; ++ ++ if (ecxctx == NULL) { ++ fprintf(stderr, "invalid: ecxctx is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (key == NULL) { ++ fprintf(stderr, "invalid: key is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (key->keylen != ecxctx->keylen) { ++ fprintf(stderr, "invalid: key->keylen(%zu) != ecxctx->keylen(%zu)\n", ++ key->keylen, ecxctx->keylen); ++ return UADK_P_FAIL; ++ } ++ ++ uadk_prov_ecx_key_free(ecxctx->key); ++ ecxctx->key = key; ++ ++ return UADK_P_SUCCESS; ++} ++ ++int ossl_ecx_key_up_ref(ECX_KEY *key) ++{ ++ int i = 0; ++ ++ if (UADK_CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0) ++ return UADK_P_FAIL; ++ ++ return ((i > 1) ? UADK_P_SUCCESS : UADK_P_FAIL); ++} ++ ++static int uadk_keyexch_x448_set_peer(void *vecxctx, void *vkey) ++{ ++ PROV_ECX_KEYEXCH_CTX *ecxctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; ++ ECX_KEY *key = vkey; ++ ++ if (ecxctx == NULL) { ++ fprintf(stderr, "invalid: ecxctx is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (key == NULL) { ++ fprintf(stderr, "invalid: key is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (key->keylen != ecxctx->keylen || !ossl_ecx_key_up_ref(key)) { ++ fprintf(stderr, "invalid: key->keylen(%zu) != ecxctx->keylen(%zu)\n", ++ key->keylen, ecxctx->keylen); ++ return UADK_P_FAIL; ++ } ++ ++ uadk_prov_ecx_key_free(ecxctx->peerkey); ++ ecxctx->peerkey = key; ++ ++ return UADK_P_SUCCESS; ++} ++ ++static int uadk_prov_ecx_compkey_init_iot(PROV_ECX_KEYEXCH_CTX *ecxctx, struct wd_ecc_req *req) ++{ ++ char buffer_y[ECX_MAX_KEYLEN] = {0}; ++ handle_t sess = ecxctx->sess; ++ struct wd_ecc_point in_pubkey; ++ struct wd_ecc_out *ecx_out; ++ struct wd_ecc_in *ecx_in; ++ int ret; ++ ++ /* Trans public key from little-endian to big-endian */ ++ ret = uadk_prov_reverse_bytes(ecxctx->peerkey->pubkey, ecxctx->keylen); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to trans public key\n"); ++ return UADK_P_FAIL; ++ } ++ ++ in_pubkey.x.data = (char *)ecxctx->peerkey->pubkey; ++ in_pubkey.x.dsize = ecxctx->keylen; ++ in_pubkey.y.data = buffer_y; ++ in_pubkey.y.dsize = 1; ++ ++ ecx_in = wd_ecxdh_new_in(sess, &in_pubkey); ++ if (ecx_in == NULL) { ++ fprintf(stderr, "failed to new ecxdh in\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ecx_out = wd_ecxdh_new_out(sess); ++ if (ecx_out == NULL) { ++ fprintf(stderr, "failed to new ecxdh out\n"); ++ ret = UADK_P_FAIL; ++ goto del_in; ++ } ++ ++ uadk_prov_ecc_fill_req(req, WD_ECXDH_COMPUTE_KEY, ecx_in, ecx_out); ++ ++ /* Trans public key from big-endian to little-endian */ ++ ret = uadk_prov_reverse_bytes(ecxctx->peerkey->pubkey, ecxctx->keylen); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to trans public key\n"); ++ goto del_out; ++ } ++ ++ return ret; ++ ++del_out: ++ wd_ecc_del_out(sess, ecx_out); ++del_in: ++ wd_ecc_del_in(sess, ecx_in); ++ ++ return ret; ++} ++ ++static void uadk_prov_ecx_compkey_uninit_iot(PROV_ECX_KEYEXCH_CTX *ecxctx, struct wd_ecc_req *req) ++{ ++ wd_ecc_del_in(ecxctx->sess, req->src); ++ wd_ecc_del_out(ecxctx->sess, req->dst); ++} ++ ++static int uadk_prov_ecx_derive_set_prikey(PROV_ECX_KEYEXCH_CTX *ecxctx) ++{ ++ handle_t sess = ecxctx->sess; ++ struct wd_ecc_key *ecc_key; ++ struct wd_dtb prikey; ++ int ret; ++ ++ /* Trans private key from little-endian to big-endian */ ++ ret = uadk_prov_reverse_bytes(ecxctx->key->privkey, ecxctx->keylen); ++ if (!ret) { ++ fprintf(stderr, "failed to trans private key\n"); ++ return UADK_P_FAIL; ++ } ++ ++ prikey.data = (char *)ecxctx->key->privkey; ++ prikey.dsize = ecxctx->keylen; ++ ecc_key = wd_ecc_get_key(sess); ++ ret = wd_ecc_set_prikey(ecc_key, &prikey); ++ if (ret) { ++ fprintf(stderr, "failed to set ecc prikey, ret = %d\n", ret); ++ return UADK_P_FAIL; ++ } ++ ++ /* Trans private key from big-endian to little-endian */ ++ ret = uadk_prov_reverse_bytes(ecxctx->key->privkey, ecxctx->keylen); ++ if (ret == UADK_P_FAIL) { ++ fprintf(stderr, "failed to trans private key\n"); ++ return UADK_P_FAIL; ++ } ++ ++ return UADK_P_SUCCESS; ++} ++ ++static void uadk_prov_x448_pad_out_key(unsigned char *dst_key, unsigned char *src_key, ++ size_t len) ++{ ++ unsigned char x448_pad_key[X448_KEYLEN] = {0}; ++ ++ if (len != X448_KEYLEN) { ++ memcpy(x448_pad_key, src_key, len); ++ memcpy(dst_key, x448_pad_key, X448_KEYLEN); ++ } else { ++ memcpy(dst_key, src_key, X448_KEYLEN); ++ } ++} ++ ++static void uadk_prov_ecx_pad_out_key(unsigned char *dst_key, unsigned char *src_key, ++ size_t len, int type) ++{ ++ if (type == ECX_KEY_TYPE_X448) { ++ uadk_prov_x448_pad_out_key(dst_key, src_key, len); ++ return; ++ } ++} ++ ++static int uadk_prov_ecx_derive(PROV_ECX_KEYEXCH_CTX *ecxctx, unsigned char *key, size_t *keylen) ++{ ++ struct wd_ecc_point *s_key = NULL; ++ ECX_KEY *peer_ecx_key = NULL; ++ struct wd_ecc_req req = {0}; ++ ECX_KEY *ecx_key = NULL; ++ int ret; ++ ++ if (ecxctx == NULL) { ++ fprintf(stderr, "invalid: ctx is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ peer_ecx_key = ecxctx->peerkey; ++ ecx_key = ecxctx->key; ++ if (peer_ecx_key == NULL || ecx_key == NULL) { ++ fprintf(stderr, "invalid: peer_ecx_key or ecx_key is NULL\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (key == NULL || *keylen == 0) { ++ *keylen = (size_t)ecxctx->keylen; ++ return UADK_P_SUCCESS; ++ } ++ ++ ret = uadk_prov_ecx_compkey_init_iot(ecxctx, &req); ++ if (ret == UADK_P_FAIL) ++ return UADK_P_FAIL; ++ ++ ret = uadk_prov_ecx_derive_set_prikey(ecxctx); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ ret = uadk_prov_ecc_crypto(ecxctx->sess, &req, (void *)ecxctx); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ wd_ecxdh_get_out_params(req.dst, &s_key); ++ if (!s_key) ++ goto uninit_iot; ++ ++ ret = uadk_prov_reverse_bytes((unsigned char *)s_key->x.data, s_key->x.dsize); ++ if (ret == UADK_P_FAIL) ++ goto uninit_iot; ++ ++ uadk_prov_ecx_pad_out_key(key, (unsigned char *)s_key->x.data, ++ s_key->x.dsize, ecx_key->type); ++ ++uninit_iot: ++ uadk_prov_ecx_compkey_uninit_iot(ecxctx, &req); ++ ++ return ret; ++} ++ ++static int uadk_keyexch_x448_derive(void *vecxctx, unsigned char *secret, size_t *secretlen, ++ size_t outlen) ++{ ++ PROV_ECX_KEYEXCH_CTX *ecxctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; ++ int ret; ++ ++ if (ecxctx == NULL) { ++ fprintf(stderr, "invalid: ecxctx is NULL in derive op\n"); ++ return UADK_P_FAIL; ++ } ++ ++ if (ecxctx->key == NULL || ecxctx->key->privkey == NULL || ++ ecxctx->peerkey == NULL) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); ++ return UADK_P_FAIL; ++ } ++ ++ if (ecxctx->keylen != X448_KEYLEN) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); ++ return UADK_P_FAIL; ++ } ++ ++ if (secret == NULL) { ++ *secretlen = ecxctx->keylen; ++ return UADK_P_SUCCESS; ++ } ++ ++ if (outlen < ecxctx->keylen) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); ++ return UADK_P_FAIL; ++ } ++ ++ 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_prov_ecc_init("x448"); ++ if (ret != UADK_P_SUCCESS) { ++ fprintf(stderr, "failed to init x448\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ecxctx->sess = uadk_prov_x448_alloc_sess(); ++ if (ecxctx->sess == (handle_t)0) { ++ fprintf(stderr, "failed to alloc sess\n"); ++ return UADK_P_FAIL; ++ } ++ ++ ret = uadk_prov_ecx_derive(ecxctx, secret, &ecxctx->keylen); ++ if (ret == UADK_P_FAIL) ++ fprintf(stderr, "failed to do x448 derive\n"); ++ ++ *secretlen = ecxctx->keylen; ++ ++ uadk_prov_x448_free_sess(ecxctx->sess); ++ ++ return ret; ++} ++ ++static void *uadk_keyexch_x448_dupctx(void *vecxctx) ++{ ++ PROV_ECX_KEYEXCH_CTX *srcctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; ++ PROV_ECX_KEYEXCH_CTX *dstctx; ++ ++ if (srcctx == NULL) ++ return NULL; ++ ++ dstctx = OPENSSL_zalloc(sizeof(PROV_ECX_KEYEXCH_CTX)); ++ if (dstctx == NULL) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ++ return NULL; ++ } ++ ++ *dstctx = *srcctx; ++ if (dstctx->key != NULL && !ossl_ecx_key_up_ref(dstctx->key)) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); ++ OPENSSL_free(dstctx); ++ return NULL; ++ } ++ ++ if (dstctx->peerkey != NULL && !ossl_ecx_key_up_ref(dstctx->peerkey)) { ++ ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); ++ uadk_prov_ecx_key_free(dstctx->key); ++ OPENSSL_free(dstctx); ++ return NULL; ++ } ++ ++ return dstctx; ++} +diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c +index 42e1272..9a2baeb 100644 +--- a/src/uadk_prov_init.c ++++ b/src/uadk_prov_init.c +@@ -176,6 +176,8 @@ static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { + uadk_sm2_keymgmt_functions, "uadk SM2 Keymgmt implementation." }, + { "EC", UADK_DEFAULT_PROPERTIES, + uadk_ec_keymgmt_functions, "uadk EC Keymgmt implementation."}, ++ { "X448", UADK_DEFAULT_PROPERTIES, ++ uadk_x448_keymgmt_functions, "uadk X448 Keymgmt implementation."}, + { NULL, NULL, NULL } + }; + +@@ -192,6 +194,8 @@ static const OSSL_ALGORITHM uadk_prov_keyexch[] = { + uadk_dh_keyexch_functions, "UADK DH keyexch implementation"}, + { "ECDH", UADK_DEFAULT_PROPERTIES, + uadk_ecdh_keyexch_functions, "uadk_provider ecdh_keyexch" }, ++ { "X448", UADK_DEFAULT_PROPERTIES, ++ uadk_x448_keyexch_functions, "uadk X448 keyexch implementation."}, + { NULL, NULL, NULL } + }; + +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index a861551..0615b61 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -29,6 +29,7 @@ + #define PROV_SUPPORT 1 + #define SIGNATURE_TYPE 3 + #define ASYM_CIPHER_TYPE 3 ++#define KEYEXCH_TYPE 4 + #define SECURITY_CHECK_DISABLE 0 + #define UADK_PROV_MIN_BITS 112 + #define UADK_PROV_SECURITY_BITS 80 +@@ -36,6 +37,7 @@ + static int p_keymgmt_support_state[KEYMGMT_TYPE]; + static int p_signature_support_state[SIGNATURE_TYPE]; + static int p_asym_cipher_support_state[ASYM_CIPHER_TYPE]; ++static int p_keyexch_support_state[KEYEXCH_TYPE]; + + struct ecc_prov { + int pid; +@@ -85,6 +87,16 @@ static void uadk_prov_asym_cipher_set_support_state(int alg_tag, int value) + p_asym_cipher_support_state[alg_tag] = value; + } + ++int uadk_prov_keyexch_get_support_state(int alg_tag) ++{ ++ return p_keyexch_support_state[alg_tag]; ++} ++ ++static void uadk_prov_keyexch_set_support_state(int alg_tag, int value) ++{ ++ p_keyexch_support_state[alg_tag] = value; ++} ++ + static int uadk_prov_ecc_get_hw_keybits(int key_bits) + { + if (key_bits > ECC384BITS) +@@ -358,7 +370,7 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) + { + struct uadk_e_cb_info cb_param; + struct async_op op; +- int idx, ret; ++ int idx, ret, cnt; + + ret = async_setup_async_event_notification(&op); + if (ret == 0) { +@@ -385,11 +397,17 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) + goto err; + + op.idx = idx; ++ cnt = 0; + do { + ret = wd_do_ecc_async(sess, req); + if (ret < 0 && ret != -EBUSY) { +- async_free_poll_task(op.idx, 0); +- goto err; ++ fprintf(stderr, "failed to do ecc async\n"); ++ goto free_poll_task; ++ } ++ ++ if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { ++ fprintf(stderr, "do ecc async operation timeout\n"); ++ goto free_poll_task; + } + } while (ret == -EBUSY); + +@@ -398,10 +416,12 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) + goto err; + + if (req->status) +- return UADK_P_FAIL; ++ goto err; + + return UADK_P_SUCCESS; + ++free_poll_task: ++ async_free_poll_task(op.idx, 0); + err: + (void)async_clear_async_event_notification(); + return UADK_P_FAIL; +@@ -631,7 +651,7 @@ int uadk_prov_ecc_genctx_check(struct ec_gen_ctx *gctx, EC_KEY *ec) + return UADK_P_SUCCESS; + } + +-bool uadk_prov_support_algorithm(const char *alg) ++static bool uadk_prov_support_algorithm(const char *alg) + { + struct uacce_dev_list *list = wd_get_accel_list(alg); + +@@ -645,7 +665,7 @@ bool uadk_prov_support_algorithm(const char *alg) + + void uadk_prov_keymgmt_alg(void) + { +- static const char * const keymgmt_alg[] = {"sm2", "ecdh"}; ++ static const char * const keymgmt_alg[] = {"sm2", "x448", "ecdh"}; + __u32 i, size; + bool sp; + +@@ -664,7 +684,7 @@ void uadk_prov_signature_alg(void) + __u32 i, size; + bool sp; + +- /* Enumerate keymgmt algs to check whether it is supported and set tags */ ++ /* Enumerate signature algs to check whether it is supported and set tags */ + size = ARRAY_SIZE(signature_alg); + for (i = 0; i < size; i++) { + sp = uadk_prov_support_algorithm(*(signature_alg + i)); +@@ -769,7 +789,7 @@ void uadk_prov_asym_cipher_alg(void) + __u32 i, size; + bool sp; + +- /* Enumerate keymgmt algs to check whether it is supported and set tags */ ++ /* Enumerate asym_cipher algs to check whether it is supported and set tags */ + size = ARRAY_SIZE(asym_cipher_alg); + for (i = 0; i < size; i++) { + sp = uadk_prov_support_algorithm(*(asym_cipher_alg + i)); +@@ -815,6 +835,21 @@ void uadk_prov_ecc_uninit(void) + pthread_mutex_unlock(&ecc_mutex); + } + ++void uadk_prov_keyexch_alg(void) ++{ ++ static const char * const keyexch_alg[] = {"x448", "ecdh"}; ++ __u32 i, size; ++ bool sp; ++ ++ /* Enumerate keyexch algs to check whether it is supported and set tags */ ++ size = ARRAY_SIZE(keyexch_alg); ++ for (i = 0; i < size; i++) { ++ sp = uadk_prov_support_algorithm(*(keyexch_alg + i)); ++ if (sp) ++ uadk_prov_keyexch_set_support_state(i, PROV_SUPPORT); ++ } ++} ++ + int uadk_prov_ecc_bit_check(const EC_GROUP *group) + { + int bits = EC_GROUP_order_bits(group); +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index fbec388..e79fc52 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -68,7 +68,8 @@ + + enum { + KEYMGMT_SM2 = 0x0, +- KEYMGMT_EC = 0x1, ++ KEYMGMT_X448 = 0x1, ++ KEYMGMT_ECDH = 0x2, + KEYMGMT_MAX = 0x6 + }; + +@@ -83,6 +84,11 @@ enum { + COFACTOR_MODE_ENABLED = 1, + }; + ++enum { ++ KEYEXCH_X448 = 0x0, ++ KEYEXCH_ECDH = 0x1, ++}; ++ + struct curve_param { + /* Prime */ + BIGNUM *p; +@@ -451,11 +457,11 @@ void uadk_prov_signature_alg(void); + void uadk_prov_asym_cipher_alg(void); + int uadk_prov_asym_cipher_get_support_state(int alg_tag); + int uadk_prov_ecc_init(const char *alg_name); ++void uadk_prov_keyexch_alg(void); ++int uadk_prov_keyexch_get_support_state(int alg_tag); + int uadk_prov_ecc_bit_check(const EC_GROUP *group); +-bool uadk_prov_support_algorithm(const char *alg); + int uadk_prov_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); +-void uadk_prov_keyexch_alg(void); + 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); + +-- +2.25.1 + diff --git a/0007-sm2-add-ctx-allocation-check.patch b/0007-sm2-add-ctx-allocation-check.patch deleted file mode 100644 index fe0356ca9789a2941dad5022e0f5b07a324354c2..0000000000000000000000000000000000000000 --- a/0007-sm2-add-ctx-allocation-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 75ee064d69f687aa43cff40ce2061db1afe75f85 Mon Sep 17 00:00:00 2001 -From: Zhiqi Song -Date: Fri, 29 Mar 2024 10:13:25 +0800 -Subject: [PATCH 7/7] sm2: add ctx allocation check - -Add result check of EVP_MD_CTX_new(). - -Signed-off-by: Zhiqi Song -Signed-off-by: JiangShui Yang ---- - src/uadk_sm2.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c -index 8421931..c0a5303 100644 ---- a/src/uadk_sm2.c -+++ b/src/uadk_sm2.c -@@ -152,9 +152,13 @@ static int compute_hash(const char *in, size_t in_len, - char *out, size_t out_len, void *usr) - { - const EVP_MD *digest = (const EVP_MD *)usr; -- EVP_MD_CTX *hash = EVP_MD_CTX_new(); -+ EVP_MD_CTX *hash; - int ret = 0; - -+ hash = EVP_MD_CTX_new(); -+ if (!hash) -+ return -1; -+ - if (EVP_DigestInit(hash, digest) == 0 || - EVP_DigestUpdate(hash, in, in_len) == 0 || - EVP_DigestFinal(hash, (void *)out, NULL) == 0) { --- -2.25.1 - diff --git a/0007-uadk_engine-Clear-some-compilation-warnings-specific.patch b/0007-uadk_engine-Clear-some-compilation-warnings-specific.patch new file mode 100644 index 0000000000000000000000000000000000000000..213689d09352248a72c95b50922940b336e96f77 --- /dev/null +++ b/0007-uadk_engine-Clear-some-compilation-warnings-specific.patch @@ -0,0 +1,302 @@ +From e0f1bbc6c981318b2a99f3af85a93767222c2c2b Mon Sep 17 00:00:00 2001 +From: lizhi +Date: Wed, 27 Nov 2024 16:27:05 +0800 +Subject: [PATCH 07/10] uadk_engine: Clear some compilation warnings, specific + cleanup is as follows + + 1. Wformat, solve format dismatch + 2. Wdiffarded qualifiers, const pointer lost const qualifier + 3. Wmissing prototypes, use static to limit scope of internal function + 4. Wunused, unused functions and variables + 5. Wswitch, add default branch and break to switch + 6. Redundant decls, duplicate declarations in macro definitions + +Signed-off-by: lizhi +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_bio.c | 2 ++ + src/uadk_prov_cipher.c | 2 +- + src/uadk_prov_der_writer.c | 2 +- + src/uadk_prov_dh.c | 9 +++++---- + src/uadk_prov_ecx.c | 34 +++------------------------------- + src/uadk_prov_ffc.c | 24 ++++++++++++------------ + src/uadk_prov_ffc.h | 1 - + src/uadk_prov_pkey.c | 6 +++--- + src/uadk_prov_pkey.h | 2 +- + 9 files changed, 28 insertions(+), 54 deletions(-) + +diff --git a/src/uadk_prov_bio.c b/src/uadk_prov_bio.c +index 5be3e8a..d419a6a 100644 +--- a/src/uadk_prov_bio.c ++++ b/src/uadk_prov_bio.c +@@ -71,6 +71,8 @@ void ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) + if (c_bio_vprintf == NULL) + c_bio_vprintf = OSSL_FUNC_BIO_vprintf(fns); + break; ++ default: ++ break; + } + fns++; + } +diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c +index e511b71..f4a182e 100644 +--- a/src/uadk_prov_cipher.c ++++ b/src/uadk_prov_cipher.c +@@ -124,7 +124,7 @@ struct cipher_priv_ctx { + unsigned int pad : 1; /* Whether padding should be used or not */ + unsigned int cts_mode; /* Use to set the type for CTS modes */ + unsigned int key_set : 1; /* Whether key is copied to priv key buffers */ +- unsigned int iv_set : 1; /* Whether key is copied to priv iv buffers */ ++ unsigned int iv_set : 1; /* Whether iv is copied to priv iv buffers */ + size_t blksize; + size_t keylen; + size_t ivlen; +diff --git a/src/uadk_prov_der_writer.c b/src/uadk_prov_der_writer.c +index 3876d49..e7e7e49 100644 +--- a/src/uadk_prov_der_writer.c ++++ b/src/uadk_prov_der_writer.c +@@ -139,7 +139,7 @@ int ossl_DER_w_uint32(WPACKET *pkt, int tag, uint32_t v) + return int_der_w_integer(pkt, tag, int_put_bytes_uint32, &v); + } + +-BN_ULONG *bn_get_words(const BIGNUM *a) ++static BN_ULONG *bn_get_words(const BIGNUM *a) + { + return a->d; + } +diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c +index 8d2c6f6..f3724ac 100644 +--- a/src/uadk_prov_dh.c ++++ b/src/uadk_prov_dh.c +@@ -1629,7 +1629,7 @@ static int uadk_prov_dh_plain_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char + else + ret = uadk_dh_compute_key(secret, pubkey, pdhctx->dh); + if (ret <= 0) { +- fprintf(stderr, "failed to do dh compute, pad(%d)\n", pad); ++ fprintf(stderr, "failed to do dh compute, pad(%u)\n", pad); + return ret; + } + +@@ -1639,9 +1639,9 @@ static int uadk_prov_dh_plain_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char + } + + /* Key derivation function from X9.63/SECG */ +-int ossl_dh_kdf_X9_42_asn1(unsigned char *out, PROV_DH_KEYEXCH_CTX *pdhctx, +- const unsigned char *z, size_t z_len, +- const char *propq) ++static int ossl_dh_kdf_X9_42_asn1(unsigned char *out, PROV_DH_KEYEXCH_CTX *pdhctx, ++ const unsigned char *z, size_t z_len, ++ const char *propq) + { + OSSL_LIB_CTX *libctx = pdhctx->libctx; + const char *cek_alg = pdhctx->kdf_cekalg; +@@ -1749,6 +1749,7 @@ static int uadk_keyexch_dh_derive(void *dhctx, unsigned char *secret, + break; + case PROV_DH_KDF_X9_42_ASN1: + ret = uadk_prov_dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen); ++ break; + default: + fprintf(stderr, "invalid: unsupport kdf type\n"); + break; +diff --git a/src/uadk_prov_ecx.c b/src/uadk_prov_ecx.c +index 302dc48..d7954b7 100644 +--- a/src/uadk_prov_ecx.c ++++ b/src/uadk_prov_ecx.c +@@ -88,12 +88,6 @@ typedef struct { + handle_t sess; + } PROV_ECX_KEYEXCH_CTX; + +-static const OSSL_PARAM ecx_key_types[] = { +- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), +- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), +- OSSL_PARAM_END +-}; +- + struct x448_res { + int pid; + } g_x448_prov; +@@ -258,23 +252,6 @@ static int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + return UADK_P_SUCCESS; + } + +-static int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, +- const char *key, const BIGNUM *bn, size_t sz) +-{ +- if (bld != NULL) +- return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, sz); +- +- p = OSSL_PARAM_locate(p, key); +- if (p != NULL) { +- if (sz > p->data_size) +- return UADK_P_FAIL; +- p->data_size = sz; +- return OSSL_PARAM_set_BN(p, bn); +- } +- +- return UADK_P_SUCCESS; +-} +- + static int uadk_prov_key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], int include_private) + { +@@ -430,9 +407,6 @@ static void uadk_keymgmt_x448_gen_cleanup(void *genctx) + static void *uadk_keymgmt_x448_gen_init(void *provctx, int selection, + const OSSL_PARAM params[]) + { +- PROV_ECX_KEYMGMT_CTX *gctx = NULL; +- int ret; +- + if (provctx == NULL) { + fprintf(stderr, "invalid: provctx is NULL\n"); + return NULL; +@@ -441,8 +415,8 @@ static void *uadk_keymgmt_x448_gen_init(void *provctx, int selection, + return ossl_ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448); + } + +-ECX_KEY *uadk_prov_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, +- const char *propq) ++static ECX_KEY *uadk_prov_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, ++ const char *propq) + { + ECX_KEY *ecx_key = OPENSSL_zalloc(sizeof(ECX_KEY)); + +@@ -807,7 +781,6 @@ static UADK_PKEY_KEYEXCH get_default_x448_keyexch(void) + static void *uadk_keyexch_x448_newctx(void *provctx) + { + PROV_ECX_KEYEXCH_CTX *ecxctx = NULL; +- int ret; + + ecxctx = OPENSSL_zalloc(sizeof(PROV_ECX_KEYEXCH_CTX)); + if (ecxctx == NULL) { +@@ -870,7 +843,6 @@ static int uadk_keyexch_x448_init(void *vecxctx, void *vkey, + { + PROV_ECX_KEYEXCH_CTX *ecxctx = (PROV_ECX_KEYEXCH_CTX *)vecxctx; + ECX_KEY *key = vkey; +- int ret; + + if (ecxctx == NULL) { + fprintf(stderr, "invalid: ecxctx is NULL\n"); +@@ -894,7 +866,7 @@ static int uadk_keyexch_x448_init(void *vecxctx, void *vkey, + return UADK_P_SUCCESS; + } + +-int ossl_ecx_key_up_ref(ECX_KEY *key) ++static int ossl_ecx_key_up_ref(ECX_KEY *key) + { + int i = 0; + +diff --git a/src/uadk_prov_ffc.c b/src/uadk_prov_ffc.c +index ed5e037..015c1b9 100644 +--- a/src/uadk_prov_ffc.c ++++ b/src/uadk_prov_ffc.c +@@ -937,7 +937,7 @@ err: + return ret; + } + +-OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx) ++static OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx) + { + if (ctx == NULL) + return NULL; +@@ -1064,9 +1064,9 @@ static int ffc_validate_LN(size_t L, size_t N, int type, int verify) + } + #endif /* FIPS_MODULE */ + +-int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, +- const unsigned char *seed, +- size_t seedlen, int counter) ++static int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, ++ const unsigned char *seed, ++ size_t seedlen, int counter) + { + if (!ossl_ffc_params_set_seed(params, seed, seedlen)) + return 0; +@@ -1086,10 +1086,10 @@ static const char *default_mdname(size_t N) + } + + /* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */ +-int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, +- const BIGNUM *p, const BIGNUM *q, +- const BIGNUM *g, BIGNUM *tmp, +- int *ret) ++static int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, ++ const BIGNUM *p, const BIGNUM *q, ++ const BIGNUM *g, BIGNUM *tmp, ++ int *ret) + { + /* + * A.2.2 Step (1) AND +@@ -1574,10 +1574,10 @@ static int generate_canonical_g(BN_CTX *ctx, BN_MONT_CTX *mont, + * - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded, + * but G is unverifiable. + */ +-int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, +- FFC_PARAMS *params, int mode, int type, +- size_t L, size_t N, int *res, +- BN_GENCB *cb) ++static int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, ++ FFC_PARAMS *params, int mode, ++ int type, size_t L, size_t N, ++ int *res, BN_GENCB *cb) + { + int ok = FFC_PARAM_RET_STATUS_FAILED; + unsigned char *seed = NULL, *seed_tmp = NULL; +diff --git a/src/uadk_prov_ffc.h b/src/uadk_prov_ffc.h +index 92102d3..d63a5ce 100644 +--- a/src/uadk_prov_ffc.h ++++ b/src/uadk_prov_ffc.h +@@ -99,7 +99,6 @@ + #define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) + /* Macro to make a BIGNUM from static data */ + #define make_dh_bn(x) \ +- extern const BIGNUM ossl_bignum_##x; \ + const BIGNUM ossl_bignum_##x = { \ + (BN_ULONG *) x, \ + OSSL_NELEM(x), \ +diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c +index 0615b61..f654dd6 100644 +--- a/src/uadk_prov_pkey.c ++++ b/src/uadk_prov_pkey.c +@@ -178,7 +178,7 @@ static void uadk_prov_init_dtb_param(void *dtb, char *start, + } + + int uadk_prov_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, +- BIGNUM *x, BIGNUM *y, BN_CTX *ctx) ++ BIGNUM *x, BIGNUM *y, BN_CTX *ctx) + { + # if OPENSSL_VERSION_NUMBER > 0x10101000L + if (!EC_POINT_get_affine_coordinates(group, p, x, y, ctx)) +@@ -190,7 +190,7 @@ int uadk_prov_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + return UADK_P_SUCCESS; + } + +-int uadk_prov_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, ++static int uadk_prov_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) + { + # if OPENSSL_VERSION_NUMBER > 0x10101000L +@@ -293,7 +293,7 @@ free_ctx: + return ret; + } + +-handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, char *alg) ++handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, const char *alg) + { + char buff[UADK_ECC_MAX_KEY_BYTES * UADK_ECC_CV_PARAM_NUM]; + struct sched_params sch_p = {0}; +diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h +index e79fc52..f40313d 100644 +--- a/src/uadk_prov_pkey.h ++++ b/src/uadk_prov_pkey.h +@@ -439,7 +439,7 @@ const OSSL_DISPATCH uadk_##nm##_keyexch_functions[] = { \ + { 0, NULL } \ + } \ + +-handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, char *alg); ++handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, const char *alg); + int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr); + int uadk_prov_keymgmt_get_support_state(int alg_tag); + int uadk_prov_ecc_get_numa_id(void); +-- +2.25.1 + diff --git a/0008-uadk_prov_cipher-enable-padding-for-block-mode.patch b/0008-uadk_prov_cipher-enable-padding-for-block-mode.patch deleted file mode 100644 index 5f8d0b55c99b256f51318d3f964327b7a780810e..0000000000000000000000000000000000000000 --- a/0008-uadk_prov_cipher-enable-padding-for-block-mode.patch +++ /dev/null @@ -1,70 +0,0 @@ -From f7b123a4b93a70390c97b7118d25b1ae32fbba2a Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Fri, 22 Mar 2024 11:41:34 +0000 -Subject: [PATCH] uadk_prov_cipher: enable padding for block mode - -Enable padding by default for block mode - -Signed-off-by: Zhangfei Gao ---- - src/uadk_prov_cipher.c | 29 ++++++++++++++++------------- - 1 file changed, 16 insertions(+), 13 deletions(-) - -diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c -index 5cb91f6..fc41104 100644 ---- a/src/uadk_prov_cipher.c -+++ b/src/uadk_prov_cipher.c -@@ -679,27 +679,28 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - out += blksz; - } - -- if (nextblocks == 0) -- goto out; -+ if (nextblocks > 0) { -+ if (!priv->enc && priv->pad && nextblocks == inlen) -+ nextblocks -= blksz; -+ outlint += nextblocks; -+ } - -- if (!priv->enc && priv->pad && nextblocks == inlen) -- nextblocks -= blksz; -+ if (nextblocks > 0) { -+ ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); -+ if (ret != 1) { -+ fprintf(stderr, "do hw ciphers failed.\n"); -+ return ret; -+ } - -- ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); -- if (ret != 1) { -- fprintf(stderr, "do hw ciphers failed.\n"); -- return ret; -+ in += nextblocks; -+ inlen -= nextblocks; - } - -- outlint += nextblocks; -- in += nextblocks; -- inlen -= nextblocks; -- - if (inlen != 0 - && !ossl_cipher_trailingdata(priv->buf, &priv->bufsz, - blksz, &in, &inlen)) - return 0; --out: -+ - *outl = outlint; - return inlen == 0; - } -@@ -1125,6 +1126,8 @@ static void *uadk_##nm##_newctx(void *provctx) \ - if (ctx->sw_ctx == NULL) \ - fprintf(stderr, "EVP_CIPHER_CTX_new failed.\n"); \ - strncpy(ctx->alg_name, #algnm, ALG_NAME_SIZE - 1); \ -+ if (strcmp(#typ, "block") == 0) \ -+ ctx->pad = 1;\ - return ctx; \ - } \ - static OSSL_FUNC_cipher_get_params_fn uadk_##nm##_get_params; \ --- -2.43.0 - diff --git a/0008-uadk_provider_rsa-cleanup-variable-definition-and-re.patch b/0008-uadk_provider_rsa-cleanup-variable-definition-and-re.patch new file mode 100644 index 0000000000000000000000000000000000000000..1122b176b3590ce5c7a13fed3d14f1b296d86bd1 --- /dev/null +++ b/0008-uadk_provider_rsa-cleanup-variable-definition-and-re.patch @@ -0,0 +1,931 @@ +From ec9e8beb2e1464695412ab424ca43f40998f7be5 Mon Sep 17 00:00:00 2001 +From: Qi Tao +Date: Thu, 19 Dec 2024 15:58:20 +0800 +Subject: [PATCH 08/10] uadk_provider_rsa: cleanup variable definition and + return value + +Cleanup variable definition and return value, make the function +clearer. + +Signed-off-by: Qi Tao +Signed-off-by: JiangShui Yang +--- + src/uadk_prov_rsa.c | 318 ++++++++++++++++++++++---------------------- + 1 file changed, 159 insertions(+), 159 deletions(-) + +diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c +index d1ec153..eac4e46 100644 +--- a/src/uadk_prov_rsa.c ++++ b/src/uadk_prov_rsa.c +@@ -32,17 +32,17 @@ + + #define UN_SET 0 + #define IS_SET 1 ++#define RSA_MAX_PRIME_NUM 2 + #define BIT_BYTES_SHIFT 3 + #define RSA_MIN_MODULUS_BITS 512 +-#define RSA_MAX_PRIME_NUM 2 + #define RSA1024BITS 1024 + #define RSA2048BITS 2048 + #define RSA3072BITS 3072 + #define RSA4096BITS 4096 + #define OPENSSLRSA7680BITS 7680 + #define OPENSSLRSA15360BITS 15360 +-#define CTX_ASYNC 1 + #define CTX_SYNC 0 ++#define CTX_ASYNC 1 + #define CTX_NUM 2 + #define BN_CONTINUE 1 + #define BN_VALID 0 +@@ -50,11 +50,11 @@ + #define BN_REDO (-2) + #define GET_ERR_FINISH 0 + #define UNUSED(x) ((void)(x)) +-#define UADK_E_SUCCESS 1 + #define UADK_E_FAIL 0 ++#define UADK_E_SUCCESS 1 + #define UADK_DO_SOFT (-0xE0) +-#define UADK_E_POLL_SUCCESS 0 + #define UADK_E_POLL_FAIL (-1) ++#define UADK_E_POLL_SUCCESS 0 + #define UADK_E_INIT_SUCCESS 0 + #define CHECK_PADDING_FAIL (-1) + #define ENV_ENABLED 1 +@@ -67,15 +67,6 @@ + UADK_PKEY_KEYMGMT_DESCR(rsa, RSA); + UADK_PKEY_SIGNATURE_DESCR(rsa, RSA); + UADK_PKEY_ASYM_CIPHER_DESCR(rsa, RSA); +- +-struct bignum_st { +- BN_ULONG *d; +- int top; +- int dmax; +- int neg; +- int flags; +-}; +- + struct rsa_keypair { + struct wd_rsa_pubkey *pubkey; + struct wd_rsa_prikey *prikey; +@@ -87,17 +78,20 @@ struct rsa_keygen_param { + struct wd_dtb *wd_q; + }; + ++struct bignum_st { ++ BN_ULONG *d; ++ int top; ++ int dmax; ++ int neg; ++ int flags; ++}; ++ + struct rsa_keygen_param_bn { + BIGNUM *e; + BIGNUM *p; + BIGNUM *q; + }; + +-struct rsa_pubkey_param { +- const BIGNUM *e; +- const BIGNUM *n; +-}; +- + struct rsa_prikey_param { + const BIGNUM *n; + const BIGNUM *e; +@@ -118,6 +112,16 @@ struct rsa_prime_param { + BIGNUM *prime; + }; + ++struct rsa_pubkey_param { ++ const BIGNUM *e; ++ const BIGNUM *n; ++}; ++ ++struct rsa_sched { ++ int sched_type; ++ struct wd_sched wd_sched; ++}; ++ + struct uadk_rsa_sess { + handle_t sess; + struct wd_rsa_sess_setup setup; +@@ -128,11 +132,6 @@ struct uadk_rsa_sess { + int key_size; + }; + +-struct rsa_sched { +- int sched_type; +- struct wd_sched wd_sched; +-}; +- + struct rsa_prov { + int pid; + }; +@@ -506,11 +505,10 @@ static void free_tbuf(PROV_RSA_SIG_CTX *ctx) + + static int rsa_check_bit_useful(const int bits, int flen) + { +- if (flen > (bits >> BIT_BYTES_SHIFT)) +- return UADK_DO_SOFT; +- + if (bits < RSA_MIN_MODULUS_BITS) + return UADK_E_FAIL; ++ if (flen > (bits >> BIT_BYTES_SHIFT)) ++ return UADK_DO_SOFT; + + switch (bits) { + case RSA1024BITS: +@@ -554,6 +552,7 @@ static int check_rsa_prime_sufficient(int *num, const int *bitsr, + ret = rsa_prime_mul_res(*num, param, ctx, cb); + if (ret) + return ret; ++ + /* + * If |r1|, product of factors so far, is not as long as expected + * (by checking the first 4 bits are less than 0x9 or greater than +@@ -572,10 +571,10 @@ static int check_rsa_prime_sufficient(int *num, const int *bitsr, + return BN_ERR; + + bitst = BN_get_word(param->r2); +- if (bitst < 0x9 || bitst > 0xF) { ++ if (bitst > 0xF || bitst < 0x9) { + /* +- * For keys with more than 4 primes, we attempt longer factor to +- * meet length requirement. ++ * For keys with more than 4 primes, we attempt longer factor ++ * to meet length requirement. + * Otherwise, we just re-generate the prime with the same length. + * This strategy has the following goals: + * 1. 1024-bit factors are efficient when using 3072 and 4096-bit key +@@ -586,15 +585,14 @@ static int check_rsa_prime_sufficient(int *num, const int *bitsr, + else + return BN_ERR; + +- ret = BN_GENCB_call(cb, GENCB_NEXT, *n); +- (*n)++; ++ ret = BN_GENCB_call(cb, GENCB_NEXT, (*n)++); + if (!ret) + return BN_ERR; + + if (retries == PRIME_RETRY_COUNT) { +- *num = -1; +- *bitse = 0; + retries = 0; ++ *bitse = 0; ++ *num = -1; + return BN_CONTINUE; + } + retries++; +@@ -616,6 +614,7 @@ static void rsa_set_primes(int num, BIGNUM *rsa_p, BIGNUM *rsa_q, + *prime = rsa_p; + else + *prime = rsa_q; ++ + /* Set BN_FLG_CONSTTIME to prime exponent */ + BN_set_flags(*prime, BN_FLG_CONSTTIME); + } +@@ -624,18 +623,19 @@ static int check_rsa_prime_equal(int num, BIGNUM *rsa_p, BIGNUM *rsa_q, + BIGNUM *prime) + { + BIGNUM *prev_prime; +- int j; ++ int k; + +- for (j = 0; j < num; j++) { ++ for (k = 0; k < num; k++) { + prev_prime = NULL; +- if (j == 0) ++ if (k == 0) + prev_prime = rsa_p; + else + prev_prime = rsa_q; ++ + /* +- * BN_cmp(a,b) returns -1 if a < b; +- * returns 0 if a == b; +- * returns 1 if a > b. ++ * BN_cmp(a,b) return -1 if a < b; ++ * return 0 if a == b; ++ * return 1 if a > b. + */ + if (!BN_cmp(prime, prev_prime)) + return UADK_E_FAIL; +@@ -660,10 +660,11 @@ static int check_rsa_prime_useful(int * const n, struct rsa_prime_param *param, + return BN_ERR; + ERR_set_mark(); + BN_set_flags(param->r2, BN_FLG_CONSTTIME); ++ + /* + * BN_mod_inverse(r, a, n, ctx) used to compute inverse modulo n. +- * Precisely, it computes the inverse of "a" modulo "n", and places +- * the result in "r", which means (a * r) % n == 1. ++ * Precisely, it computes the inverse of a modulo n, and places ++ * the result in r, which means (a * r) % n == 1. + * If r == NULL, error. If r != NULL, success. + * The expected result: (r2 * r1) % e_pub == 1, + * the inverse of r2 exist, that is r1. +@@ -678,8 +679,7 @@ static int check_rsa_prime_useful(int * const n, struct rsa_prime_param *param, + else + return BN_ERR; + +- ret = BN_GENCB_call(cb, GENCB_NEXT, *n); +- (*n)++; ++ ret = BN_GENCB_call(cb, GENCB_NEXT, (*n)++); + if (!ret) + return BN_ERR; + +@@ -694,6 +694,7 @@ static int get_rsa_prime_once(int num, const int *bitsr, int * const n, + + if (num >= RSA_MAX_PRIME_NUM) + return ret; ++ + while (1) { + /* Generate prime with bitsr[num] len. */ + if (!BN_generate_prime_ex(param->prime, bitsr[num], +@@ -702,6 +703,7 @@ static int get_rsa_prime_once(int num, const int *bitsr, int * const n, + if (!check_rsa_prime_equal(num, param->rsa_p, param->rsa_q, + param->prime)) + continue; ++ + ret = check_rsa_prime_useful(n, param, e_pub, ctx, cb); + if (ret == BN_ERR) + return BN_ERR; +@@ -722,8 +724,8 @@ static void rsa_switch_p_q(BIGNUM *rsa_p, BIGNUM *rsa_q, BIGNUM *p, BIGNUM *q) + rsa_q = tmp; + } + +- BN_copy(q, rsa_q); + BN_copy(p, rsa_p); ++ BN_copy(q, rsa_q); + } + + static int check_rsa_is_crt(RSA *rsa) +@@ -755,23 +757,23 @@ static int get_rsa_prime_param(struct rsa_prime_param *param, BN_CTX *ctx) + { + param->r1 = BN_CTX_get(ctx); + if (!param->r1) +- goto end; ++ goto error; + + param->r2 = BN_CTX_get(ctx); + if (!param->r2) +- goto end; +- +- param->rsa_p = BN_CTX_get(ctx); +- if (!param->rsa_p) +- goto end; ++ goto error; + + param->rsa_q = BN_CTX_get(ctx); + if (!param->rsa_q) +- goto end; ++ goto error; ++ ++ param->rsa_p = BN_CTX_get(ctx); ++ if (!param->rsa_p) ++ goto error; + + return UADK_E_SUCCESS; + +-end: ++error: + fprintf(stderr, "failed to allocate rsa prime params\n"); + return -ENOMEM; + } +@@ -781,31 +783,31 @@ static int rsa_primes_gen(int bits, BIGNUM *e_pub, BIGNUM *p, + { + struct rsa_prime_param *param = NULL; + int bitsr[RSA_MAX_PRIME_NUM] = {0}; +- int flag, quo, rmd, i; +- BN_CTX *ctx; ++ int flag, quot, rmd, i; ++ BN_CTX *bnctx; + int bitse = 0; + int ret = 0; + /* n: modulo n, a part of public key */ + int n = 0; + +- ctx = BN_CTX_new(); +- if (!ctx) ++ bnctx = BN_CTX_new(); ++ if (!bnctx) + return ret; + +- BN_CTX_start(ctx); ++ BN_CTX_start(bnctx); + param = OPENSSL_zalloc(sizeof(struct rsa_prime_param)); + if (!param) + goto free_ctx; + +- ret = get_rsa_prime_param(param, ctx); ++ ret = get_rsa_prime_param(param, bnctx); + if (ret != UADK_E_SUCCESS) + goto free_param; + + /* Divide bits into 'primes' pieces evenly */ +- quo = bits / RSA_MAX_PRIME_NUM; ++ quot = bits / RSA_MAX_PRIME_NUM; + rmd = bits % RSA_MAX_PRIME_NUM; + for (i = 0; i < RSA_MAX_PRIME_NUM; i++) +- bitsr[i] = (i < rmd) ? quo + 1 : quo; ++ bitsr[i] = (i < rmd) ? quot + 1 : quot; + + /* Generate p, q and other primes (if any) */ + for (i = 0; i < RSA_MAX_PRIME_NUM; i++) { +@@ -815,12 +817,12 @@ static int rsa_primes_gen(int bits, BIGNUM *e_pub, BIGNUM *p, + rsa_set_primes(i, param->rsa_p, param->rsa_q, ¶m->prime); + while (flag == 1) { + ret = get_rsa_prime_once(i, bitsr, &n, e_pub, param, +- ctx, cb); ++ bnctx, cb); + if (ret == -1) + goto free_param; + bitse += bitsr[i]; + ret = check_rsa_prime_sufficient(&i, bitsr, &bitse, &n, +- param, ctx, cb); ++ param, bnctx, cb); + if (ret == BN_ERR) + goto free_param; + else if (ret == BN_REDO) +@@ -836,8 +838,8 @@ static int rsa_primes_gen(int bits, BIGNUM *e_pub, BIGNUM *p, + free_param: + OPENSSL_free(param); + free_ctx: +- BN_CTX_end(ctx); +- BN_CTX_free(ctx); ++ BN_CTX_end(bnctx); ++ BN_CTX_free(bnctx); + return ret; + } + +@@ -847,7 +849,7 @@ static int add_rsa_pubenc_padding(int flen, const unsigned char *from, + int ret; + + if (!buf || !num) { +- fprintf(stderr, "buf or num is invalid\n"); ++ fprintf(stderr, "buf or num is invalid.\n"); + return UADK_E_FAIL; + } + +@@ -855,12 +857,12 @@ static int add_rsa_pubenc_padding(int flen, const unsigned char *from, + case RSA_PKCS1_PADDING: + ret = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + if (!ret) +- fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_PADDING err.\n"); + break; + case RSA_PKCS1_OAEP_PADDING: + ret = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + if (!ret) +- fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err.\n"); + break; + default: + ret = UADK_E_FAIL; +@@ -879,13 +881,13 @@ static int check_rsa_pridec_padding(unsigned char *to, int num, + case RSA_PKCS1_PADDING: + ret = RSA_padding_check_PKCS1_type_2(to, num, buf, flen, num); + if (ret == CHECK_PADDING_FAIL) +- fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_PADDING err.\n"); + break; + case RSA_PKCS1_OAEP_PADDING: + ret = RSA_padding_check_PKCS1_OAEP(to, num, buf, flen, num, + NULL, 0); + if (ret == CHECK_PADDING_FAIL) +- fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err.\n"); + break; + default: + ret = UADK_E_FAIL; +@@ -907,12 +909,12 @@ static int add_rsa_prienc_padding(int flen, const unsigned char *from, + case RSA_PKCS1_PADDING: + ret = RSA_padding_add_PKCS1_type_1(to_buf, tlen, from, flen); + if (!ret) +- fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_PADDING err.\n"); + break; + case RSA_X931_PADDING: + ret = RSA_padding_add_X931(to_buf, tlen, from, flen); + if (ret == -1) +- fprintf(stderr, "RSA_X931_PADDING err\n"); ++ fprintf(stderr, "RSA_X931_PADDING err.\n"); + break; + default: + ret = UADK_E_FAIL; +@@ -933,12 +935,12 @@ static int check_rsa_pubdec_padding(unsigned char *to, int num, + case RSA_PKCS1_PADDING: + ret = RSA_padding_check_PKCS1_type_1(to, num, buf, len, num); + if (ret == CHECK_PADDING_FAIL) +- fprintf(stderr, "RSA_PKCS1_PADDING err\n"); ++ fprintf(stderr, "RSA_PKCS1_PADDING err.\n"); + break; + case RSA_X931_PADDING: + ret = RSA_padding_check_X931(to, num, buf, len, num); + if (ret == CHECK_PADDING_FAIL) +- fprintf(stderr, "RSA_X931_PADDING err\n"); ++ fprintf(stderr, "RSA_X931_PADDING err.\n"); + break; + default: + ret = UADK_E_FAIL; +@@ -950,10 +952,15 @@ static int check_rsa_pubdec_padding(unsigned char *to, int num, + return ret; + } + ++static BN_ULONG *bn_get_words(const BIGNUM *a) ++{ ++ return a->d; ++} ++ + static int check_rsa_input_para(const int flen, const unsigned char *from, + unsigned char *to, RSA *rsa) + { +- if (!rsa || !from || !to || flen <= 0) { ++ if (!rsa || !to || !from || flen <= 0) { + fprintf(stderr, "input param invalid\n"); + return UADK_E_FAIL; + } +@@ -961,11 +968,6 @@ static int check_rsa_input_para(const int flen, const unsigned char *from, + return rsa_check_bit_useful(uadk_rsa_bits(rsa), flen); + } + +-static BN_ULONG *bn_get_words(const BIGNUM *a) +-{ +- return a->d; +-} +- + static int rsa_get_sign_res(int padding, BIGNUM *to_bn, const BIGNUM *n, + BIGNUM *ret_bn, BIGNUM **res) + { +@@ -1053,8 +1055,8 @@ static struct uadk_rsa_sess *rsa_new_eng_session(RSA *rsa) + + memset(rsa_sess, 0, sizeof(struct uadk_rsa_sess)); + rsa_sess->alg = rsa; +- rsa_sess->is_prikey_ready = UN_SET; + rsa_sess->is_pubkey_ready = UN_SET; ++ rsa_sess->is_prikey_ready = UN_SET; + + return rsa_sess; + } +@@ -1065,8 +1067,8 @@ static void rsa_free_eng_session(struct uadk_rsa_sess *rsa_sess) + return; + + rsa_sess->alg = NULL; +- rsa_sess->is_prikey_ready = UN_SET; + rsa_sess->is_pubkey_ready = UN_SET; ++ rsa_sess->is_prikey_ready = UN_SET; + + wd_rsa_free_sess(rsa_sess->sess); + OPENSSL_free(rsa_sess); +@@ -1079,7 +1081,7 @@ static struct uadk_rsa_sess *rsa_get_eng_session(RSA *rsa, unsigned int bits, + struct sched_params params = {0}; + struct uadk_rsa_sess *rsa_sess; + +- rsa_sess = rsa_new_eng_session(rsa); ++ rsa_sess = rsa_new_eng_session(rsa); + if (!rsa_sess) + return NULL; + +@@ -1105,8 +1107,8 @@ static int rsa_fill_pubkey(struct rsa_pubkey_param *pubkey_param, + unsigned char *in_buf, unsigned char *to) + { + struct wd_rsa_pubkey *pubkey = NULL; +- struct wd_dtb *wd_e = NULL; + struct wd_dtb *wd_n = NULL; ++ struct wd_dtb *wd_e = NULL; + + if (!rsa_sess->is_pubkey_ready) { + wd_rsa_get_pubkey(rsa_sess->sess, &pubkey); +@@ -1114,17 +1116,17 @@ static int rsa_fill_pubkey(struct rsa_pubkey_param *pubkey_param, + return UADK_E_FAIL; + + wd_rsa_get_pubkey_params(pubkey, &wd_e, &wd_n); +- if (!wd_e || !wd_n) ++ if (!wd_n || !wd_e) + return UADK_E_FAIL; + +- wd_e->dsize = BN_bn2bin(pubkey_param->e, +- (unsigned char *)wd_e->data); + wd_n->dsize = BN_bn2bin(pubkey_param->n, + (unsigned char *)wd_n->data); +- rsa_sess->is_pubkey_ready = IS_SET; ++ wd_e->dsize = BN_bn2bin(pubkey_param->e, ++ (unsigned char *)wd_e->data); + rsa_sess->req.src_bytes = rsa_sess->key_size; + rsa_sess->req.dst_bytes = rsa_sess->key_size; + rsa_sess->req.op_type = WD_RSA_VERIFY; ++ rsa_sess->is_pubkey_ready = IS_SET; + rsa_sess->req.src = in_buf; + rsa_sess->req.dst = to; + +@@ -1140,12 +1142,12 @@ static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess, + { + struct wd_rsa_prikey *prikey = NULL; + struct wd_dtb *wd_qinv = NULL; +- struct wd_dtb *wd_dq = NULL; + struct wd_dtb *wd_dp = NULL; +- struct wd_dtb *wd_q = NULL; ++ struct wd_dtb *wd_dq = NULL; + struct wd_dtb *wd_p = NULL; +- struct wd_dtb *wd_d = NULL; ++ struct wd_dtb *wd_q = NULL; + struct wd_dtb *wd_n = NULL; ++ struct wd_dtb *wd_d = NULL; + + if (!(rsa_sess->is_prikey_ready) && (pri->is_crt)) { + wd_rsa_get_prikey(rsa_sess->sess, &prikey); +@@ -1157,14 +1159,14 @@ static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess, + if (!wd_dq || !wd_dp || !wd_qinv || !wd_q || !wd_p) + return UADK_E_FAIL; + +- wd_dq->dsize = BN_bn2bin(pri->dmq1, +- (unsigned char *)wd_dq->data); + wd_dp->dsize = BN_bn2bin(pri->dmp1, + (unsigned char *)wd_dp->data); +- wd_q->dsize = BN_bn2bin(pri->q, +- (unsigned char *)wd_q->data); ++ wd_dq->dsize = BN_bn2bin(pri->dmq1, ++ (unsigned char *)wd_dq->data); + wd_p->dsize = BN_bn2bin(pri->p, + (unsigned char *)wd_p->data); ++ wd_q->dsize = BN_bn2bin(pri->q, ++ (unsigned char *)wd_q->data); + wd_qinv->dsize = BN_bn2bin(pri->iqmp, + (unsigned char *)wd_qinv->data); + } else if (!(rsa_sess->is_prikey_ready) && !(pri->is_crt)) { +@@ -1176,16 +1178,17 @@ static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess, + if (!wd_d || !wd_n) + return UADK_E_FAIL; + +- wd_d->dsize = BN_bn2bin(pri->d, +- (unsigned char *)wd_d->data); + wd_n->dsize = BN_bn2bin(pri->n, + (unsigned char *)wd_n->data); ++ wd_d->dsize = BN_bn2bin(pri->d, ++ (unsigned char *)wd_d->data); + } else { + return UADK_E_FAIL; + } ++ + rsa_sess->is_prikey_ready = IS_SET; +- rsa_sess->req.src_bytes = rsa_sess->key_size; + rsa_sess->req.op_type = WD_RSA_SIGN; ++ rsa_sess->req.src_bytes = rsa_sess->key_size; + rsa_sess->req.dst_bytes = rsa_sess->key_size; + rsa_sess->req.src = in_buf; + rsa_sess->req.dst = to; +@@ -1198,7 +1201,7 @@ static int rsa_get_keygen_param(struct wd_rsa_req *req, handle_t ctx, RSA *rsa, + { + struct wd_rsa_kg_out *out = (struct wd_rsa_kg_out *)req->dst; + struct wd_dtb wd_d, wd_n, wd_qinv, wd_dq, wd_dp; +- BIGNUM *dmp1, *dmq1, *iqmp, *n, *d; ++ BIGNUM *dmp1, *dmq1, *iqmp, *d, *n; + unsigned int key_bits, key_size; + BN_CTX *bn_ctx = *bn_ctx_in; + +@@ -1210,14 +1213,14 @@ static int rsa_get_keygen_param(struct wd_rsa_req *req, handle_t ctx, RSA *rsa, + wd_rsa_get_kg_out_params(out, &wd_d, &wd_n); + wd_rsa_get_kg_out_crt_params(out, &wd_qinv, &wd_dq, &wd_dp); + +- dmp1 = BN_CTX_get(bn_ctx); +- if (!dmp1) +- return UADK_E_FAIL; +- + dmq1 = BN_CTX_get(bn_ctx); + if (!dmq1) + return UADK_E_FAIL; + ++ dmp1 = BN_CTX_get(bn_ctx); ++ if (!dmp1) ++ return UADK_E_FAIL; ++ + iqmp = BN_CTX_get(bn_ctx); + if (!iqmp) + return UADK_E_FAIL; +@@ -1230,8 +1233,8 @@ static int rsa_get_keygen_param(struct wd_rsa_req *req, handle_t ctx, RSA *rsa, + if (!d) + return UADK_E_FAIL; + +- BN_bin2bn((unsigned char *)wd_d.data, key_size, d); + BN_bin2bn((unsigned char *)wd_n.data, key_size, n); ++ BN_bin2bn((unsigned char *)wd_d.data, key_size, d); + BN_bin2bn((unsigned char *)wd_qinv.data, wd_qinv.dsize, iqmp); + BN_bin2bn((unsigned char *)wd_dq.data, wd_dq.dsize, dmq1); + BN_bin2bn((unsigned char *)wd_dp.data, wd_dp.dsize, dmp1); +@@ -1246,15 +1249,15 @@ static int rsa_get_keygen_param(struct wd_rsa_req *req, handle_t ctx, RSA *rsa, + + static void uadk_e_rsa_cb(void *req_t) + { +- struct wd_rsa_req *req_new = (struct wd_rsa_req *)req_t; ++ struct wd_rsa_req *req = (struct wd_rsa_req *)req_t; + struct uadk_e_cb_info *cb_param; + struct wd_rsa_req *req_origin; + struct async_op *op; + +- if (!req_new) ++ if (!req) + return; + +- cb_param = req_new->cb_param; ++ cb_param = req->cb_param; + if (!cb_param) + return; + +@@ -1262,7 +1265,7 @@ static void uadk_e_rsa_cb(void *req_t) + if (!req_origin) + return; + +- req_origin->status = req_new->status; ++ req_origin->status = req->status; + + op = cb_param->op; + if (op && op->job && !op->done) { +@@ -1345,21 +1348,19 @@ static int rsa_fill_keygen_data(struct uadk_rsa_sess *rsa_sess, + + wd_rsa_get_crt_prikey_params(key_pair->prikey, NULL, NULL, NULL, + &keygen_param->wd_q, &keygen_param->wd_p); +- if (!keygen_param->wd_q || !keygen_param->wd_p) ++ if (!keygen_param->wd_p || !keygen_param->wd_q) + return UADK_E_FAIL; + +- keygen_param->wd_q->dsize = BN_bn2bin(bn_param->q, +- (unsigned char *)keygen_param->wd_q->data); + keygen_param->wd_p->dsize = BN_bn2bin(bn_param->p, + (unsigned char *)keygen_param->wd_p->data); ++ keygen_param->wd_q->dsize = BN_bn2bin(bn_param->q, ++ (unsigned char *)keygen_param->wd_q->data); + + rsa_sess->req.src_bytes = rsa_sess->key_size; + rsa_sess->req.dst_bytes = rsa_sess->key_size; + rsa_sess->req.op_type = WD_RSA_GENKEY; +- rsa_sess->req.src = wd_rsa_new_kg_in(rsa_sess->sess, +- keygen_param->wd_e, +- keygen_param->wd_p, +- keygen_param->wd_q); ++ rsa_sess->req.src = wd_rsa_new_kg_in(rsa_sess->sess, keygen_param->wd_e, ++ keygen_param->wd_p, keygen_param->wd_q); + if (!rsa_sess->req.src) + return UADK_E_FAIL; + +@@ -1377,8 +1378,8 @@ static void rsa_free_keygen_data(struct uadk_rsa_sess *rsa_sess) + if (!rsa_sess) + return; + +- wd_rsa_del_kg_in(rsa_sess->sess, rsa_sess->req.src); + wd_rsa_del_kg_out(rsa_sess->sess, rsa_sess->req.dst); ++ wd_rsa_del_kg_in(rsa_sess->sess, rsa_sess->req.src); + } + + static int rsa_keygen_param_alloc(struct rsa_keygen_param **keygen_param, +@@ -1389,7 +1390,7 @@ static int rsa_keygen_param_alloc(struct rsa_keygen_param **keygen_param, + + *keygen_param = OPENSSL_malloc(sizeof(struct rsa_keygen_param)); + if (!(*keygen_param)) +- goto err; ++ goto error; + + *keygen_bn_param = (struct rsa_keygen_param_bn *) + OPENSSL_malloc(sizeof(struct rsa_keygen_param_bn)); +@@ -1407,10 +1408,6 @@ static int rsa_keygen_param_alloc(struct rsa_keygen_param **keygen_param, + BN_CTX_start(bn_ctx); + *bn_ctx_in = bn_ctx; + +- (*keygen_bn_param)->e = BN_CTX_get(bn_ctx); +- if (!(*keygen_bn_param)->e) +- goto free_bn_ctx; +- + (*keygen_bn_param)->p = BN_CTX_get(bn_ctx); + if (!(*keygen_bn_param)->p) + goto free_bn_ctx; +@@ -1419,6 +1416,10 @@ static int rsa_keygen_param_alloc(struct rsa_keygen_param **keygen_param, + if (!(*keygen_bn_param)->q) + goto free_bn_ctx; + ++ (*keygen_bn_param)->e = BN_CTX_get(bn_ctx); ++ if (!(*keygen_bn_param)->e) ++ goto free_bn_ctx; ++ + return UADK_E_SUCCESS; + + free_bn_ctx: +@@ -1430,7 +1431,7 @@ free_keygen_bn_param: + OPENSSL_free(*keygen_bn_param); + free_keygen_param: + OPENSSL_free(*keygen_param); +-err: ++error: + return -ENOMEM; + } + +@@ -1440,9 +1441,9 @@ static void rsa_keygen_param_free(struct rsa_keygen_param **keygen_param, + int free_bn_ctx_tag) + { + /* +- * When an abnormal situation occurs, uadk engine needs +- * to switch to software keygen function, so we need to +- * free BN ctx we alloced before. But in normal situation, ++ * When an abnormal situation occurs, uadk engine needs to ++ * switch to software keygen function, so we need to free ++ * BN ctx we alloced before. But in normal situation, + * the BN ctx should be freed by OpenSSL tools or users. + * Therefore, we use a tag to distinguish these cases. + */ +@@ -1451,20 +1452,14 @@ static void rsa_keygen_param_free(struct rsa_keygen_param **keygen_param, + BN_CTX_free(*bn_ctx); + } + +- OPENSSL_free(*keygen_bn_param); +- OPENSSL_free(*keygen_param); + OPENSSL_free(*key_pair); ++ OPENSSL_free(*keygen_param); ++ OPENSSL_free(*keygen_bn_param); + } + + static int rsa_pkey_param_alloc(struct rsa_pubkey_param **pub, + struct rsa_prikey_param **pri) + { +- if (pub) { +- *pub = OPENSSL_malloc(sizeof(struct rsa_pubkey_param)); +- if (!(*pub)) +- return -ENOMEM; +- } +- + if (pri) { + *pri = OPENSSL_malloc(sizeof(struct rsa_prikey_param)); + if (!(*pri)) { +@@ -1474,23 +1469,29 @@ static int rsa_pkey_param_alloc(struct rsa_pubkey_param **pub, + } + } + ++ if (pub) { ++ *pub = OPENSSL_malloc(sizeof(struct rsa_pubkey_param)); ++ if (!(*pub)) ++ return -ENOMEM; ++ } ++ + return UADK_E_SUCCESS; + } + + static void rsa_pkey_param_free(struct rsa_pubkey_param **pub, + struct rsa_prikey_param **pri) + { +- if (pub) +- OPENSSL_free(*pub); + if (pri) + OPENSSL_free(*pri); ++ if (pub) ++ OPENSSL_free(*pub); + } + + static int rsa_create_pub_bn_ctx(RSA *rsa, struct rsa_pubkey_param *pub, + unsigned char **from_buf, int *num_bytes) + { + uadk_rsa_get0_key(rsa, &pub->n, &pub->e, NULL); +- if (!(pub->n) || !(pub->e)) ++ if (!(pub->e) || !(pub->n)) + return UADK_E_FAIL; + + *num_bytes = BN_num_bytes(pub->n); +@@ -1782,27 +1783,27 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + struct uadk_rsa_sess *rsa_sess = NULL; +- struct rsa_prikey_param *pri = NULL; ++ struct rsa_prikey_param *prik = NULL; + unsigned char *from_buf = NULL; +- int num_bytes, ret; ++ int ret, num_bytes; + + ret = check_rsa_input_para(flen, from, to, rsa); + if (ret != UADK_E_SUCCESS) + return ret; + +- ret = rsa_pkey_param_alloc(NULL, &pri); ++ ret = rsa_pkey_param_alloc(NULL, &prik); + if (ret == -ENOMEM) + return UADK_E_FAIL; + +- pri->is_crt = check_rsa_is_crt(rsa); ++ prik->is_crt = check_rsa_is_crt(rsa); + +- rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), pri->is_crt); ++ rsa_sess = rsa_get_eng_session(rsa, uadk_rsa_bits(rsa), prik->is_crt); + if (!rsa_sess) { + ret = UADK_DO_SOFT; + goto free_pkey; + } + +- ret = rsa_create_pri_bn_ctx(rsa, pri, &from_buf, &num_bytes); ++ ret = rsa_create_pri_bn_ctx(rsa, prik, &from_buf, &num_bytes); + if (ret <= 0 || flen > num_bytes) { + ret = UADK_E_FAIL; + goto free_sess; +@@ -1814,7 +1815,7 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, + goto free_buf; + } + +- ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); ++ ret = rsa_fill_prikey(rsa, rsa_sess, prik, from_buf, to); + if (!ret) { + ret = UADK_E_FAIL; + goto free_buf; +@@ -1826,14 +1827,14 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, + goto free_buf; + } + +- ret = sign_trans_bn(rsa_sess, from_buf, pri, padding, to, num_bytes); ++ ret = sign_trans_bn(rsa_sess, from_buf, prik, padding, to, num_bytes); + + free_buf: + rsa_free_pri_bn_ctx(&from_buf); + free_sess: + rsa_free_eng_session(rsa_sess); + free_pkey: +- rsa_pkey_param_free(NULL, &pri); ++ rsa_pkey_param_free(NULL, &prik); + return ret; + } + +@@ -1897,23 +1898,23 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, + ret = rsa_fill_pubkey(pub, rsa_sess, from_buf, to); + if (!ret) { + ret = UADK_E_FAIL; +- goto free_buf; ++ goto free_buff; + } + + memcpy(rsa_sess->req.src, from, rsa_sess->req.src_bytes); + ret = rsa_do_crypto(rsa_sess); + if (!ret || rsa_sess->req.status) { + ret = UADK_DO_SOFT; +- goto free_buf; ++ goto free_buff; + } + + ret = verify_trans_bn(rsa_sess, from_buf, num_bytes, pub, padding, &len); + if (!ret) +- goto free_buf; ++ goto free_buff; + + ret = check_rsa_pubdec_padding(to, num_bytes, from_buf, len, padding); + +-free_buf: ++free_buff: + rsa_free_pub_bn_ctx(&from_buf); + free_sess: + rsa_free_eng_session(rsa_sess); +@@ -1951,24 +1952,24 @@ static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, + static int uadk_rsa_init(void *vprsactx, void *vrsa, + const OSSL_PARAM params[], int operation) + { +- PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; ++ PROV_RSA_SIG_CTX *ctx = (PROV_RSA_SIG_CTX *)vprsactx; + +- if (priv == NULL || vrsa == NULL) ++ if (ctx == NULL || vrsa == NULL) + return UADK_E_FAIL; + +- priv->rsa = vrsa; +- priv->operation = operation; ++ ctx->rsa = vrsa; ++ ctx->operation = operation; + + /* Maximum for sign, auto for verify */ +- priv->saltlen = RSA_PSS_SALTLEN_AUTO; +- priv->min_saltlen = -1; ++ ctx->saltlen = RSA_PSS_SALTLEN_AUTO; ++ ctx->min_saltlen = -1; + +- switch (uadk_rsa_test_flags(priv->rsa, RSA_FLAG_TYPE_MASK)) { ++ switch (uadk_rsa_test_flags(ctx->rsa, RSA_FLAG_TYPE_MASK)) { + case RSA_FLAG_TYPE_RSA: +- priv->pad_mode = RSA_PKCS1_PADDING; ++ ctx->pad_mode = RSA_PKCS1_PADDING; + break; + case RSA_FLAG_TYPE_RSASSAPSS: +- priv->pad_mode = RSA_PKCS1_PSS_PADDING; ++ ctx->pad_mode = RSA_PKCS1_PSS_PADDING; + break; + default: + ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); +@@ -1976,7 +1977,7 @@ static int uadk_rsa_init(void *vprsactx, void *vrsa, + } + + if (uadk_prov_rsa_init()) +- priv->soft = 1; ++ ctx->soft = 1; + + return UADK_E_SUCCESS; + } +@@ -2430,7 +2431,6 @@ static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, + else + return UADK_E_FAIL; + } +- + *outlen = ret; + + return UADK_E_SUCCESS; +-- +2.25.1 + diff --git a/0009-uadk_prov_cipher-dec-and-enc-use-same-op.patch b/0009-uadk_prov_cipher-dec-and-enc-use-same-op.patch deleted file mode 100644 index e6d6fce6a9c0b49b8ede500bb37cfa8f1e7772a0..0000000000000000000000000000000000000000 --- a/0009-uadk_prov_cipher-dec-and-enc-use-same-op.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4d8e10590405e7ed30a241202624146b18635030 Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Fri, 29 Mar 2024 08:54:32 +0000 -Subject: [PATCH 09/15] uadk_prov_cipher: dec and enc use same op - -Cipher can use same op for dec and enc, so alloc 1 op. - -Otherwise, there maybe issue in env case, where -driver->op_type_num is used, -drv/hisi_sec.c:621: .op_type_num = 1, - -Signed-off-by: Zhangfei Gao ---- - src/uadk_prov_cipher.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c -index fc41104..91e60d8 100644 ---- a/src/uadk_prov_cipher.c -+++ b/src/uadk_prov_cipher.c -@@ -420,14 +420,13 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) - struct wd_ctx_nums *ctx_set_num; - struct wd_ctx_params cparams = {0}; - -- /* 0: enc, 1: dec */ -- ctx_set_num = calloc(2, sizeof(*ctx_set_num)); -+ ctx_set_num = calloc(1, sizeof(*ctx_set_num)); - if (!ctx_set_num) { - fprintf(stderr, "failed to alloc ctx_set_size!\n"); - return; - } - -- cparams.op_type_num = 2; -+ cparams.op_type_num = 1; - cparams.ctx_set_num = ctx_set_num; - cparams.bmp = numa_allocate_nodemask(); - if (!cparams.bmp) { -@@ -440,8 +439,6 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) - - ctx_set_num[0].sync_ctx_num = 2; - ctx_set_num[0].async_ctx_num = 2; -- ctx_set_num[1].sync_ctx_num = 2; -- ctx_set_num[1].async_ctx_num = 2; - - ret = wd_cipher_init2_(priv->alg_name, 0, 0, &cparams); - numa_free_nodemask(cparams.bmp); -@@ -458,7 +455,8 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) - } - pthread_mutex_unlock(&cipher_mutex); - -- params.type = priv->req.op_type; -+ /* dec and enc use the same op */ -+ params.type = 0; - /* Use the default numa parameters */ - params.numa_id = -1; - priv->setup.sched_param = ¶ms; --- -2.43.0 - diff --git a/0010-kmgmt-KEYMGMT-struct-is-different-in-3.2.patch b/0010-kmgmt-KEYMGMT-struct-is-different-in-3.2.patch deleted file mode 100644 index 7671033156be4fe40444833ae2dcef4bb3245915..0000000000000000000000000000000000000000 --- a/0010-kmgmt-KEYMGMT-struct-is-different-in-3.2.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 43304e09b57473e3925457612d37a321e61fc39c Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Mon, 6 May 2024 14:54:21 +0000 -Subject: [PATCH 10/15] kmgmt: KEYMGMT struct is different in 3.2 - -KEYMGMT struct is different in 3.2 causes Segmentation fault. -Fix it by adding version check. - -$ openssl speed -provider uadk provider rsa1024 -Segmentation fault(core dumped) - -$ openssl version -OpenssL 3.2.0-dev (Library: OpenssL 3.2.0-dev) - -Signed-off-by: Zhangfei Gao ---- - src/uadk_prov_dh.c | 2 ++ - src/uadk_prov_rsa.c | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c -index 5437c46..c0adc2b 100644 ---- a/src/uadk_prov_dh.c -+++ b/src/uadk_prov_dh.c -@@ -248,7 +248,9 @@ typedef struct { - OSSL_PROVIDER *prov; - - int refcnt; -+# if OPENSSL_VERSION_NUMBER < 0x30200000 - void *lock; -+# endif - - /* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new; -diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c -index b60de0c..7918b51 100644 ---- a/src/uadk_prov_rsa.c -+++ b/src/uadk_prov_rsa.c -@@ -299,7 +299,9 @@ typedef struct{ - OSSL_PROVIDER *prov; - - int refcnt; -+# if OPENSSL_VERSION_NUMBER < 0x30200000 - void *lock; -+# endif - - /* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new; --- -2.43.0 - diff --git a/0011-uadk_prov_cipher-do_soft-when-hw-failed.patch b/0011-uadk_prov_cipher-do_soft-when-hw-failed.patch deleted file mode 100644 index 49398102069616940848b8fbbb88a6f942c46c97..0000000000000000000000000000000000000000 --- a/0011-uadk_prov_cipher-do_soft-when-hw-failed.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 04e53b7daedf16c7d50237a54f7f9d5c5b1b044e Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Mon, 29 Apr 2024 15:14:26 +0000 -Subject: [PATCH 11/15] uadk_prov_cipher: do_soft when hw failed - -By default, do_soft is disabled. -To enable sw handling, need set enable_sw_offload = 1 via OPENSSL_CONF - -For example: uadk_provider.cnf - -openssl_conf = openssl_init - -[openssl_init] -providers = provider_sect - -[provider_sect] -uadk_provider = uadk_sect - -[uadk_sect] -activate = 1 -enable_sw_offload = 1 - -export OPENSSL_CONF=uadk_provider.cnf - -Signed-off-by: Zhangfei Gao ---- - src/uadk_prov_cipher.c | 83 +++++++++++++++++++++++++++--------------- - 1 file changed, 53 insertions(+), 30 deletions(-) - -diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c -index 91e60d8..fa79764 100644 ---- a/src/uadk_prov_cipher.c -+++ b/src/uadk_prov_cipher.c -@@ -286,6 +286,7 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, - - if (enable_sw_offload) - uadk_prov_cipher_sw_init(priv, key, iv); -+ - return 1; - } - -@@ -639,19 +640,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - (priv->switch_flag == UADK_DO_SOFT || - (priv->switch_flag != UADK_DO_HW && - inlen <= priv->switch_threshold))) { -- /* -- * Using soft only if enable_sw_offload, which is set in conf file, -- * then sw_cipher is initialzied -- * 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); -- if (ret) { -- *outl = outlint; -- return 1; -- } -- -- fprintf(stderr, "do soft ciphers failed.\n"); -+ goto do_soft; - } - - if (priv->bufsz != 0) -@@ -669,6 +658,8 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); - if (ret != 1) { - fprintf(stderr, "do hw ciphers failed.\n"); -+ if (priv->sw_cipher) -+ goto do_soft; - return ret; - } - -@@ -687,6 +678,8 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); - if (ret != 1) { - fprintf(stderr, "do hw ciphers failed.\n"); -+ if (priv->sw_cipher) -+ goto do_soft; - return ret; - } - -@@ -701,6 +694,22 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - - *outl = outlint; - return inlen == 0; -+ -+do_soft: -+ /* -+ * Using soft only if enable_sw_offload, which is set in conf file, -+ * then sw_cipher is initialzied -+ * 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); -+ if (ret) { -+ *outl = outlint; -+ return 1; -+ } -+ -+ fprintf(stderr, "do soft ciphers failed.\n"); -+ return 0; - } - - void uadk_prov_destroy_cipher(void) -@@ -756,12 +765,7 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - - if (priv->sw_cipher && - priv->switch_flag == UADK_DO_SOFT) { -- if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { -- fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); -- return 0; -- } -- *outl = sw_final_len; -- return 1; -+ goto do_soft; - } - - if (priv->enc) { -@@ -783,6 +787,8 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); - if (ret != 1) { - fprintf(stderr, "do hw ciphers failed.\n"); -+ if (priv->sw_cipher) -+ goto do_soft; - return ret; - } - *outl = blksz; -@@ -802,6 +808,8 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - ret = uadk_prov_hw_cipher(priv, priv->buf, outl, outsize, priv->buf, blksz); - if (ret != 1) { - fprintf(stderr, "do hw ciphers failed.\n"); -+ if (priv->sw_cipher) -+ goto do_soft; - return ret; - } - -@@ -820,6 +828,14 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - priv->bufsz = 0; - - return 1; -+ -+do_soft: -+ if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { -+ fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); -+ return 0; -+ } -+ *outl = sw_final_len; -+ return 1; - } - - static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, -@@ -867,24 +883,31 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, - (priv->switch_flag == UADK_DO_SOFT || - (priv->switch_flag != UADK_DO_HW && - inl <= priv->switch_threshold))) { -- int len = 0; -- -- /* have isseu if both using hw and soft partly */ -- ret = uadk_prov_cipher_soft_work(priv, out, &len, in, inl); -- if (ret) { -- *outl = len; -- return 1; -- } -- -- fprintf(stderr, "do soft ciphers failed.\n"); -+ goto do_soft; - } - - ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, inl); -- if (ret != 1) -+ if (ret != 1) { -+ if (priv->sw_cipher) -+ goto do_soft; - return ret; -+ } - - *outl = inl; - return 1; -+ -+do_soft: -+ int len = 0; -+ -+ /* have isseu if both using hw and soft partly */ -+ ret = uadk_prov_cipher_soft_work(priv, out, &len, in, inl); -+ if (ret) { -+ *outl = len; -+ return 1; -+ } -+ -+ fprintf(stderr, "do soft ciphers failed.\n"); -+ return 0; - } - - static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, --- -2.43.0 - diff --git a/0012-uadk_digest-solve-build-warning.patch b/0012-uadk_digest-solve-build-warning.patch deleted file mode 100644 index d50bdcc7db627d629179f980ed6071085d77ffa7..0000000000000000000000000000000000000000 --- a/0012-uadk_digest-solve-build-warning.patch +++ /dev/null @@ -1,32 +0,0 @@ -From da203ad894a33f1b06c01794947532d1cb36af7d Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Tue, 30 Apr 2024 04:14:18 +0000 -Subject: [PATCH 12/15] uadk_digest: solve build warning - -solve build warning since no {} - -Signed-off-by: Zhangfei Gao ---- - src/uadk_digest.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/uadk_digest.c b/src/uadk_digest.c -index 43bbf60..9a583b4 100644 ---- a/src/uadk_digest.c -+++ b/src/uadk_digest.c -@@ -202,10 +202,11 @@ static int digest_soft_init(struct digest_priv_ctx *md_ctx) - int app_datasize; - - /* Allocate a soft ctx for hardware engine */ -- if (md_ctx->soft_ctx == NULL) -+ if (md_ctx->soft_ctx == NULL) { - md_ctx->soft_ctx = EVP_MD_CTX_new(); - if (md_ctx->soft_ctx == NULL) - return 0; -+ } - - ctx = md_ctx->soft_ctx; - --- -2.43.0 - diff --git a/0013-cipher-remove-aead-in-v2-temporarily-for-nginx.patch b/0013-cipher-remove-aead-in-v2-temporarily-for-nginx.patch deleted file mode 100644 index a8177e8b36a2cc84d03091ef9d15feb1651df6a5..0000000000000000000000000000000000000000 --- a/0013-cipher-remove-aead-in-v2-temporarily-for-nginx.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2432c3f2c3014ffd3cab7ed2405e988a3a533387 Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Sat, 11 May 2024 08:10:51 +0000 -Subject: [PATCH 13/15] cipher: remove aead in v2 temporarily for nginx - -The aead has issues causing nginx failure. -log: -do aead update operation failed, ret: -22, state: 0! - -Temporarily, remove aead support to make nginx work. - -Signed-off-by: Zhangfei Gao ---- - src/uadk_cipher_adapter.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/src/uadk_cipher_adapter.c b/src/uadk_cipher_adapter.c -index caf8af3..b4a7a0e 100644 ---- a/src/uadk_cipher_adapter.c -+++ b/src/uadk_cipher_adapter.c -@@ -34,9 +34,6 @@ static int cipher_hw_v2_nids[] = { - NID_sm4_ecb, - NID_des_ede3_cbc, - NID_des_ede3_ecb, -- NID_aes_128_gcm, -- NID_aes_192_gcm, -- NID_aes_256_gcm - }; - - static int cipher_hw_v3_nids[] = { --- -2.43.0 - diff --git a/0014-sm2-fix-build-warning-in-openssl-3.0-of-incompatible.patch b/0014-sm2-fix-build-warning-in-openssl-3.0-of-incompatible.patch deleted file mode 100644 index e82730c11217ebc832e1046ff603fddffe9b328b..0000000000000000000000000000000000000000 --- a/0014-sm2-fix-build-warning-in-openssl-3.0-of-incompatible.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b840e2d5d9ff7b828b0e82047e06fa374aa6354c Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Sun, 26 May 2024 01:17:38 +0000 -Subject: [PATCH 14/15] sm2: fix build warning in openssl 3.0 of incompatible - pointer type - -openssl 3.0 introduce const, fixed by version check - -Signed-off-by: Zhangfei Gao ---- - src/uadk_sm2.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c -index c0a5303..b8548d1 100644 ---- a/src/uadk_sm2.c -+++ b/src/uadk_sm2.c -@@ -1605,7 +1605,11 @@ static int sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) - return EVP_DigestUpdate(mctx, z, (size_t)mdlen); - } - -+# if OPENSSL_VERSION_NUMBER < 0x30000000 - static int sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -+# else -+static int sm2_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) -+# endif - { - struct sm2_ctx *dctx, *sctx; - --- -2.43.0 - diff --git a/0015-aead-fix-build-warning-of-storing-address-of-local-v.patch b/0015-aead-fix-build-warning-of-storing-address-of-local-v.patch deleted file mode 100644 index ef65515dd23b2f908d1f550d641277bd4b6f7226..0000000000000000000000000000000000000000 --- a/0015-aead-fix-build-warning-of-storing-address-of-local-v.patch +++ /dev/null @@ -1,101 +0,0 @@ -From ee30a80cf45d0c165a3a993d29ffca94a3747111 Mon Sep 17 00:00:00 2001 -From: Zhangfei Gao -Date: Sun, 26 May 2024 01:59:06 +0000 -Subject: [PATCH 15/15] aead: fix build warning of storing address of local - variable - -uadk_aead.c:280:33: warning: storing the address of local variable \ - 'params' in '*priv.setup.sched_param' [-Wdangling-pointer=] - -The local variable will disappear when func returns, so its address -should not be stored. - -Signed-off-by: Zhangfei Gao ---- - src/uadk_aead.c | 33 +++++++++++++++++---------------- - 1 file changed, 17 insertions(+), 16 deletions(-) - -diff --git a/src/uadk_aead.c b/src/uadk_aead.c -index c7527ed..2a5c024 100644 ---- a/src/uadk_aead.c -+++ b/src/uadk_aead.c -@@ -46,7 +46,6 @@ - - struct aead_priv_ctx { - handle_t sess; -- struct wd_aead_sess_setup setup; - struct wd_aead_req req; - unsigned char *data; - unsigned char iv[AES_GCM_BLOCK_SIZE]; -@@ -262,24 +261,17 @@ static int uadk_e_init_aead_cipher(void) - return 1; - } - --static int uadk_e_ctx_init(struct aead_priv_ctx *priv, const unsigned char *ckey, int ckey_len) -+static int uadk_e_ctx_init(struct aead_priv_ctx *priv, const unsigned char *ckey, -+ int ckey_len, struct wd_aead_sess_setup *setup) - { -- struct sched_params params = {0}; - int ret; - - ret = uadk_e_init_aead_cipher(); - if (!ret) - return 0; - -- params.type = priv->req.op_type; -- ret = uadk_e_is_env_enabled("aead"); -- if (ret) -- params.type = 0; -- -- params.numa_id = g_aead_engine.numa_id; -- priv->setup.sched_param = ¶ms; - if (!priv->sess) { -- priv->sess = wd_aead_alloc_sess(&priv->setup); -+ priv->sess = wd_aead_alloc_sess(setup); - if (!priv->sess) { - fprintf(stderr, "uadk engine failed to alloc aead session!\n"); - return 0; -@@ -316,6 +308,8 @@ out: - static int uadk_e_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *ckey, - const unsigned char *iv, int enc) - { -+ struct wd_aead_sess_setup setup; -+ struct sched_params params = {0}; - struct aead_priv_ctx *priv; - int ret, ckey_len; - -@@ -331,10 +325,10 @@ static int uadk_e_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *ckey, - if (iv) - memcpy(priv->iv, iv, AES_GCM_IV_LEN); - -- priv->setup.calg = WD_CIPHER_AES; -- priv->setup.cmode = WD_CIPHER_GCM; -- priv->setup.dalg = 0; -- priv->setup.dmode = 0; -+ setup.calg = WD_CIPHER_AES; -+ setup.cmode = WD_CIPHER_GCM; -+ setup.dalg = 0; -+ setup.dmode = 0; - - priv->req.assoc_bytes = 0; - priv->req.out_bytes = 0; -@@ -354,8 +348,15 @@ static int uadk_e_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *ckey, - else - priv->req.op_type = WD_CIPHER_DECRYPTION_DIGEST; - -+ params.type = priv->req.op_type; -+ ret = uadk_e_is_env_enabled("aead"); -+ if (ret) -+ params.type = 0; -+ params.numa_id = g_aead_engine.numa_id; -+ setup.sched_param = ¶ms; -+ - ckey_len = EVP_CIPHER_CTX_key_length(ctx); -- ret = uadk_e_ctx_init(priv, ckey, ckey_len); -+ ret = uadk_e_ctx_init(priv, ckey, ckey_len, &setup); - if (!ret) - return 0; - --- -2.43.0 - diff --git a/openssl.tar.gz b/openssl.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5bd4f847710cc4df4268e83b76eb889aea3a038e Binary files /dev/null and b/openssl.tar.gz differ diff --git a/uadk_engine-1.3.0.tar.gz b/uadk_engine-1.3.0.tar.gz deleted file mode 100644 index 5875ec19b38eab044d586eb516cdcc2f18dffb79..0000000000000000000000000000000000000000 Binary files a/uadk_engine-1.3.0.tar.gz and /dev/null differ diff --git a/uadk_engine-1.5.0.tar.gz b/uadk_engine-1.5.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6455fbbf3279da5c2d061b106651c307c52c5c13 Binary files /dev/null and b/uadk_engine-1.5.0.tar.gz differ diff --git a/uadk_engine.spec b/uadk_engine.spec index 484ac91023627693810a0b982fe68500313262b3..3aed911dc0e73805cf7ee3a2bbd5e660cce6a793 100644 --- a/uadk_engine.spec +++ b/uadk_engine.spec @@ -1,7 +1,8 @@ +%define soversion 1 Name: uadk_engine Summary: UADK Accelerator Engine -Version: 1.3.0 -Release: 3 +Version: 1.5.0 +Release: 1 License: Apache-2.0 Source: %{name}-%{version}.tar.gz ExclusiveOS: linux @@ -10,74 +11,80 @@ Prefix: /usr/local/lib/engines-1.1 Conflicts: %{name} < %{version}-%{release} Provides: %{name} = %{version}-%{release} BuildRequires: libwd >= 2.6.0 -BuildRequires: compat-openssl11-devel sed autoconf automake libtool numactl-devel +BuildRequires: compat-openssl11-libs openssl-devel sed autoconf automake libtool numactl-devel ExclusiveArch: aarch64 -Patch0001: 0001-v1-dh-add-iova_map-and-iova_unmap-ops.patch -Patch0002: 0002-uadk_util-fix-clang-build-error.patch -Patch0003: 0003-uadk_engine-add-secure-compilation-option.patch -Patch0004: 0004-uadk_engine-cleanup-code-style-of-async-functions.patch -Patch0005: 0005-cipher-cleanup-repeated-function-invoking.patch -Patch0006: 0006-digest-add-ctx-allocation-check.patch -Patch0007: 0007-sm2-add-ctx-allocation-check.patch -Patch0008: 0008-uadk_prov_cipher-enable-padding-for-block-mode.patch -Patch0009: 0009-uadk_prov_cipher-dec-and-enc-use-same-op.patch -Patch0010: 0010-kmgmt-KEYMGMT-struct-is-different-in-3.2.patch -Patch0011: 0011-uadk_prov_cipher-do_soft-when-hw-failed.patch -Patch0012: 0012-uadk_digest-solve-build-warning.patch -Patch0013: 0013-cipher-remove-aead-in-v2-temporarily-for-nginx.patch -Patch0014: 0014-sm2-fix-build-warning-in-openssl-3.0-of-incompatible.patch -Patch0015: 0015-aead-fix-build-warning-of-storing-address-of-local-v.patch +Patch0001: 0001-uadk_provider-add-aead-alg-for-uadk_provider-in-open.patch +Patch0002: 0002-uadk_provider-move-functions-to-uadk_prov_pkey.patch +Patch0003: 0003-uadk_provider-add-query_operation_name-callback-for-.patch +Patch0004: 0004-uadk_provider-support-ec-keymgmt-hardware-accelerati.patch +Patch0005: 0005-uadk_provider-support-ecdh-keyexch-hardware-accelera.patch +Patch0006: 0006-uadk_provider-support-x448-alg.patch +Patch0007: 0007-uadk_engine-Clear-some-compilation-warnings-specific.patch +Patch0008: 0008-uadk_provider_rsa-cleanup-variable-definition-and-re.patch %description -This package contains the UADK Accelerator Engine +This package contains the UADK Accelerator Engine. +In this version, uadk_engine.rpm not only supports the engine 1 +function of openssl1.1, but also supports the provider function +of openssl3.0. %global debug_package %{nil} %prep -%autosetup -n %{name} -p1 +%autosetup -n %{name}-%{version} -p1 %build +tar -zxvf %{_sourcedir}/openssl.tar.gz +%define pkg_dir %{_builddir}/%{name}-%{version}/openssl%{_libdir}/pkgconfig +%define openssl_dir %{_builddir}/%{name}-%{version}/openssl/usr +echo "prefix=%{openssl_dir}" | cat - %{pkg_dir}/libcrypto.pc > tmp && mv tmp %{pkg_dir}/libcrypto.pc + +export PKG_CONFIG_PATH=%{pkg_dir} + autoreconf -i chmod +x configure ./configure --enable-kae make %install -mkdir -p ${RPM_BUILD_ROOT}/usr/local/lib/engines-1.1 -install -b -m755 src/.libs/uadk_engine.so.%{version} ${RPM_BUILD_ROOT}/usr/local/lib/engines-1.1 +mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/engines-1.1 +install -b -m755 src/.libs/uadk_engine.so.%{version} ${RPM_BUILD_ROOT}%{_libdir}/engines-1.1 +for lib in $RPM_BUILD_ROOT%{_libdir}/engines-1.1/*.so.%{version} ; do + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/engines-1.1/`basename ${lib} .%{version}` + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/engines-1.1/`basename ${lib} .%{version}`.%{soversion} +done + +make clean +unset PKG_CONFIG_PATH +autoreconf -i +./configure --libdir=/usr/lib64/ossl-modules/ +make + +mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/ossl-modules/ +install -b -m755 src/.libs/uadk_provider.so.%{version} ${RPM_BUILD_ROOT}%{_libdir}/ossl-modules/ +for lib in $RPM_BUILD_ROOT%{_libdir}/ossl-modules/*.so.%{version} ; do + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/ossl-modules/`basename ${lib} .%{version}` + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/ossl-modules/`basename ${lib} .%{version}`.%{soversion} +done %clean rm -rf ${RPM_BUILD_ROOT} %files %defattr(755,root,root) -/usr/local/lib/engines-1.1/uadk_engine.so.%{version} - -%pre -if [ "$1" = "2" ] ; then #2: update - rm -rf $RPM_INSTALL_PREFIX/uadk_engine.so > /dev/null 2>&1 || true - rm -rf $RPM_INSTALL_PREFIX/uadk_engine.so.0 > /dev/null 2>&1 || true -fi +%{_libdir}/engines-1.1/* +%{_libdir}/ossl-modules/* %post -if [[ "$1" = "1" || "$1" = "2" ]] ; then #1: install 2: update - ln -sf $RPM_INSTALL_PREFIX/uadk_engine.so.%{version} $RPM_INSTALL_PREFIX/uadk_engine.so - ln -sf $RPM_INSTALL_PREFIX/uadk_engine.so.%{version} $RPM_INSTALL_PREFIX/uadk_engine.so.0 -fi /sbin/ldconfig -%preun -if [ "$1" = "0" ] ; then #0: uninstall - rm -rf $RPM_INSTALL_PREFIX/uadk_engine.so > /dev/null 2>&1 || true - rm -rf $RPM_INSTALL_PREFIX/uadk_engine.so.0 > /dev/null 2>&1 || true - rm -f /var/log/uadk_engine.log > /dev/null 2>&1 || true - rm -f /var/log/uadk_engine.log.old > /dev/null 2>&1 || true -fi - %postun /sbin/ldconfig %changelog +* Wed Dec 11 2024 JiangShui Yang 1.5.0-1 + - uadk_engine: adding the uadk_provider library + * Fri Nov 22 2024 JiangShui Yang 1.3.0-3 - Backport uadk engine patch