diff --git a/kae_engine/src/e_uadk.c b/kae_engine/src/e_uadk.c new file mode 100644 index 0000000000000000000000000000000000000000..0a9e3e65961e635db7c0f6d1bf839144a230f1d6 --- /dev/null +++ b/kae_engine/src/e_uadk.c @@ -0,0 +1,421 @@ +/* + * Copyright 2020-2022 Huawei Technologies Co.,Ltd. All rights reserved. + * Copyright 2020-2022 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. + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "uadk.h" +#include "uadk_async.h" +#ifdef KAE +#include "v1/uadk_v1.h" +#endif + +#define UADK_CMD_ENABLE_CIPHER_ENV ENGINE_CMD_BASE +#define UADK_CMD_ENABLE_DIGEST_ENV (ENGINE_CMD_BASE + 1) +#define UADK_CMD_ENABLE_RSA_ENV (ENGINE_CMD_BASE + 2) +#define UADK_CMD_ENABLE_DH_ENV (ENGINE_CMD_BASE + 3) +#define UADK_CMD_ENABLE_ECC_ENV (ENGINE_CMD_BASE + 4) + +/* Constants used when creating the ENGINE */ +const char *engine_uadk_id = "uadk_engine"; +static const char *engine_uadk_name = "uadk hardware engine support"; + +static int uadk_cipher; +static int uadk_digest; +static int uadk_rsa; +static int uadk_dh; +static int uadk_ecc; +static int uadk_inited; +static pthread_mutex_t uadk_engine_mutex = PTHREAD_MUTEX_INITIALIZER; + +#ifdef KAE +static int uadk_cipher_nosva; +static int uadk_digest_nosva; +static int uadk_rsa_nosva; +static int uadk_dh_nosva; +#endif + +static const ENGINE_CMD_DEFN g_uadk_cmd_defns[] = { + { + UADK_CMD_ENABLE_CIPHER_ENV, + "UADK_CMD_ENABLE_CIPHER_ENV", + "Enable or Disable cipher engine environment variable.", + ENGINE_CMD_FLAG_NUMERIC + }, + { + UADK_CMD_ENABLE_DIGEST_ENV, + "UADK_CMD_ENABLE_DIGEST_ENV", + "Enable or Disable digest engine environment variable.", + ENGINE_CMD_FLAG_NUMERIC + }, + { + UADK_CMD_ENABLE_RSA_ENV, + "UADK_CMD_ENABLE_RSA_ENV", + "Enable or Disable rsa engine environment variable.", + ENGINE_CMD_FLAG_NUMERIC + }, + { + UADK_CMD_ENABLE_DH_ENV, + "UADK_CMD_ENABLE_DH_ENV", + "Enable or Disable dh engine environment variable.", + ENGINE_CMD_FLAG_NUMERIC + }, + { + UADK_CMD_ENABLE_ECC_ENV, + "UADK_CMD_ENABLE_ECC_ENV", + "Enable or Disable ecc engine environment variable.", + ENGINE_CMD_FLAG_NUMERIC + }, + { + 0, NULL, NULL, 0 + } +}; + +static void __attribute__((constructor)) uadk_constructor(void) +{ +} + +static void __attribute__((destructor)) uadk_destructor(void) +{ +} + +struct uadk_alg_env_enabled { + const char *alg_name; + __u8 env_enabled; +}; + +static struct uadk_alg_env_enabled uadk_env_enabled[] = { + { "cipher", 0 }, + { "digest", 0 }, + { "rsa", 0 }, + { "dh", 0 }, + { "ecc", 0 } +}; + +int uadk_e_is_env_enabled(const char *alg_name) +{ + int len = ARRAY_SIZE(uadk_env_enabled); + int i = 0; + + while (i < len) { + if (!strcmp(uadk_env_enabled[i].alg_name, alg_name)) + return uadk_env_enabled[i].env_enabled; + i++; + } + + return 0; +} + +static void uadk_e_set_env_enabled(const char *alg_name, __u8 value) +{ + int len = ARRAY_SIZE(uadk_env_enabled); + int i = 0; + + while (i < len) { + if (!strcmp(uadk_env_enabled[i].alg_name, alg_name)) { + uadk_env_enabled[i].env_enabled = value; + return; + } + + i++; + } +} + +int uadk_e_set_env(const char *var_name, int numa_id) +{ + char env_string[ENV_STRING_LEN] = {0}; + const char *var_s; + int ret; + + var_s = secure_getenv(var_name); + if (!var_s || !strlen(var_s)) { + /* uadk will request ctxs from device on specified numa node */ + ret = snprintf(env_string, ENV_STRING_LEN, "%s%d%s%d", + "sync:2@", numa_id, + ",async:2@", numa_id); + if (ret < 0) + return ret; + + ret = setenv(var_name, env_string, 1); + if (ret < 0) + return ret; + } + return 0; +} + +static int uadk_engine_ctrl(ENGINE *e, int cmd, long i, + void *p, void (*f) (void)) +{ + (void)p; + (void)f; + + if (!e) { + fprintf(stderr, "Null Engine\n"); + return 0; + } + + switch (cmd) { + case UADK_CMD_ENABLE_CIPHER_ENV: + uadk_e_set_env_enabled("cipher", i); + break; + case UADK_CMD_ENABLE_DIGEST_ENV: + uadk_e_set_env_enabled("digest", i); + break; + case UADK_CMD_ENABLE_RSA_ENV: + uadk_e_set_env_enabled("rsa", i); + break; + case UADK_CMD_ENABLE_DH_ENV: + uadk_e_set_env_enabled("dh", i); + break; + case UADK_CMD_ENABLE_ECC_ENV: + uadk_e_set_env_enabled("ecc", i); + break; + default: + return 0; + } + + return 1; +} + +static int uadk_destroy(ENGINE *e) +{ +#ifdef KAE + if (uadk_cipher_nosva) + sec_ciphers_free_ciphers(); + if (uadk_digest_nosva) + sec_digests_free_methods(); + if (uadk_rsa_nosva) + hpre_destroy(); + if (uadk_dh_nosva) + hpre_dh_destroy(); + kae_debug_close_log(); +#endif + + if (uadk_cipher) + uadk_e_destroy_cipher(); + if (uadk_digest) + uadk_e_destroy_digest(); + if (uadk_rsa) + uadk_e_destroy_rsa(); + if (uadk_ecc) + uadk_e_destroy_ecc(); + if (uadk_dh) + uadk_e_destroy_dh(); + + pthread_mutex_lock(&uadk_engine_mutex); + uadk_inited = 0; + pthread_mutex_unlock(&uadk_engine_mutex); + + return 1; +} + +static int uadk_init(ENGINE *e) +{ + int ret; + + pthread_mutex_lock(&uadk_engine_mutex); + if (uadk_inited) { + pthread_mutex_unlock(&uadk_engine_mutex); + return 1; + } + + if (uadk_cipher || uadk_digest || uadk_rsa || uadk_dh || uadk_ecc) { + ret = async_module_init(); + if (!ret) { + pthread_mutex_unlock(&uadk_engine_mutex); + fprintf(stderr, "failed to init async module!\n"); + return 0; + } + } + + if (uadk_digest) + uadk_e_digest_lock_init(); + if (uadk_cipher) + uadk_e_cipher_lock_init(); + if (uadk_rsa) + uadk_e_rsa_lock_init(); + if (uadk_dh) + uadk_e_dh_lock_init(); + if (uadk_ecc) + uadk_e_ecc_lock_init(); + + uadk_inited = 1; + pthread_mutex_unlock(&uadk_engine_mutex); + + return 1; +} + +static int uadk_finish(ENGINE *e) +{ + return 1; +} + +static void engine_init_child_at_fork_handler(void) +{ + int ret; + + ret = async_module_init(); + if (!ret) + fprintf(stderr, "failed to init child async module!\n"); +} + +#ifdef KAE +static void bind_fn_kae_alg(ENGINE *e) +{ + int dev_num; + + dev_num = wd_get_nosva_dev_num("cipher"); + if (dev_num > 0) { + cipher_module_init(); + if (!ENGINE_set_ciphers(e, sec_engine_ciphers)) + fprintf(stderr, "uadk bind cipher failed\n"); + else + uadk_cipher_nosva = 1; + } + + dev_num = wd_get_nosva_dev_num("digest"); + if (dev_num > 0) { + digest_module_init(); + if (!ENGINE_set_digests(e, sec_engine_digests)) + fprintf(stderr, "uadk bind digest failed\n"); + else + uadk_digest_nosva = 1; + } + + dev_num = wd_get_nosva_dev_num("rsa"); + if (dev_num > 0) { + hpre_module_init(); + if (!ENGINE_set_RSA(e, hpre_get_rsa_methods())) + fprintf(stderr, "uadk bind rsa failed\n"); + else + uadk_rsa_nosva = 1; + } + + dev_num = wd_get_nosva_dev_num("dh"); + if (dev_num > 0) { + hpre_module_dh_init(); + if (!ENGINE_set_DH(e, hpre_get_dh_methods())) + fprintf(stderr, "uadk bind dh failed\n"); + else + uadk_dh_nosva = 1; + } +} +#endif + +static void bind_fn_uadk_alg(ENGINE *e) +{ + struct uacce_dev *dev; + + dev = wd_get_accel_dev("cipher"); + if (dev) { + if (!uadk_e_bind_cipher(e)) + fprintf(stderr, "uadk bind cipher failed\n"); + else + uadk_cipher = 1; + free(dev); + } + + dev = wd_get_accel_dev("digest"); + if (dev) { + if (!uadk_e_bind_digest(e)) + fprintf(stderr, "uadk bind digest failed\n"); + else + uadk_digest = 1; + free(dev); + } + + dev = wd_get_accel_dev("rsa"); + if (dev) { + if (!uadk_e_bind_rsa(e)) + fprintf(stderr, "uadk bind rsa failed\n"); + else + uadk_rsa = 1; + free(dev); + } + + dev = wd_get_accel_dev("dh"); + if (dev) { + if (!uadk_e_bind_dh(e)) + fprintf(stderr, "uadk bind dh failed\n"); + else + uadk_dh = 1; + free(dev); + } + + /* find an ecc device, no difference for sm2/ecdsa/ecdh/x25519/x448 */ + dev = wd_get_accel_dev("ecdsa"); + if (dev) { + if (!uadk_e_bind_ecc(e)) + fprintf(stderr, "uadk bind ecc failed\n"); + else + uadk_ecc = 1; + free(dev); + } +} + +/* + * Connect uadk_engine to OpenSSL engine library. + */ +static int bind_fn(ENGINE *e, const char *id) +{ + int ret; + + if (!ENGINE_set_id(e, engine_uadk_id) || + !ENGINE_set_destroy_function(e, uadk_destroy) || + !ENGINE_set_init_function(e, uadk_init) || + !ENGINE_set_finish_function(e, uadk_finish) || + !ENGINE_set_name(e, engine_uadk_name)) { + fprintf(stderr, "bind failed\n"); + return 0; + } + +#ifdef KAE + kae_debug_init_log(); + bind_fn_kae_alg(e); + + if (uadk_cipher_nosva || uadk_digest_nosva || uadk_rsa_nosva || + uadk_dh_nosva) { + async_module_init_v1(); + pthread_atfork(NULL, NULL, engine_init_child_at_fork_handler_v1); + } +#endif + bind_fn_uadk_alg(e); + + if (uadk_cipher || uadk_digest || uadk_rsa || uadk_dh || uadk_ecc) + pthread_atfork(NULL, NULL, engine_init_child_at_fork_handler); + + ret = ENGINE_set_ctrl_function(e, uadk_engine_ctrl); + if (ret != 1) { + fprintf(stderr, "failed to set ctrl function\n"); + return 0; + } + + ret = ENGINE_set_cmd_defns(e, g_uadk_cmd_defns); + if (ret != 1) { + fprintf(stderr, "failed to set defns\n"); + return 0; + } + + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) diff --git a/kae_engine/src/uadk.h b/kae_engine/src/uadk.h new file mode 100644 index 0000000000000000000000000000000000000000..30c099fefa81ca8fe9e204fc23ca36816b2dae4b --- /dev/null +++ b/kae_engine/src/uadk.h @@ -0,0 +1,49 @@ +/* + * Copyright 2020-2022 Huawei Technologies Co.,Ltd. All rights reserved. + * Copyright 2020-2022 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. + * + */ +#ifndef UADK_H +#define UADK_H +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ENV_STRING_LEN 256 +#define ENGINE_RECV_MAX_CNT 60000000 + +enum { + HW_V2, + HW_V3, +}; + +extern const char *engine_uadk_id; +int uadk_e_bind_cipher(ENGINE *e); +void uadk_e_destroy_cipher(void); +int uadk_e_bind_digest(ENGINE *e); +void uadk_e_destroy_digest(void); +int uadk_e_bind_rsa(ENGINE *e); +void uadk_e_destroy_rsa(void); +int uadk_e_bind_dh(ENGINE *e); +void uadk_e_destroy_dh(void); +int uadk_e_bind_ecc(ENGINE *e); +void uadk_e_destroy_ecc(void); +int uadk_e_is_env_enabled(const char *alg_name); +int uadk_e_set_env(const char *var_name, int numa_id); +void uadk_e_ecc_lock_init(void); +void uadk_e_rsa_lock_init(void); +void uadk_e_dh_lock_init(void); +void uadk_e_cipher_lock_init(void); +void uadk_e_digest_lock_init(void); +#endif diff --git a/kae_engine/src/uadk_async.c b/kae_engine/src/uadk_async.c new file mode 100644 index 0000000000000000000000000000000000000000..2edd6ea7daecf13d99afc5aa4821a2cb0b006ba8 --- /dev/null +++ b/kae_engine/src/uadk_async.c @@ -0,0 +1,377 @@ +/* + * Copyright 2020-2022 Huawei Technologies Co.,Ltd. All rights reserved. + * Copyright 2020-2022 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 "uadk.h" +#include "uadk_async.h" + +static struct async_poll_queue poll_queue; + +static async_recv_t async_recv_func[ASYNC_TASK_MAX]; + +static void async_fd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD readfd, void *custom) +{ + close(readfd); +} + +int async_setup_async_event_notification(struct async_op *op) +{ + ASYNC_WAIT_CTX *waitctx; + 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; + + waitctx = ASYNC_get_wait_ctx(op->job); + if (waitctx == NULL) + return 0; + + if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_uadk_id, + &efd, &custom) == 0) { + efd = eventfd(0, EFD_NONBLOCK); + if (efd == -1) + return 0; + + if (ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_uadk_id, efd, + custom, async_fd_cleanup) == 0) { + async_fd_cleanup(waitctx, engine_uadk_id, efd, NULL); + return 0; + } + } + + return 1; +} + +int async_clear_async_event_notification(void) +{ + ASYNC_JOB *job; + ASYNC_WAIT_CTX *waitctx; + OSSL_ASYNC_FD efd; + size_t num_add_fds; + size_t num_del_fds; + void *custom = NULL; + + job = ASYNC_get_current_job(); + if (job == NULL) + return 0; + + waitctx = ASYNC_get_wait_ctx(job); + if (waitctx == NULL) + return 0; + + if (ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &num_add_fds, + NULL, &num_del_fds) == 0) + return 0; + + if (num_add_fds > 0) { + if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_uadk_id, + &efd, &custom) == 0) + return 0; + + async_fd_cleanup(waitctx, engine_uadk_id, efd, NULL); + + if (ASYNC_WAIT_CTX_clear_fd(waitctx, engine_uadk_id) == 0) + return 0; + } + + return 1; +} + +static void async_poll_task_free(void) +{ + int error; + struct async_poll_task *task; + + error = pthread_mutex_lock(&poll_queue.async_task_mutex); + if (error != 0) + return; + + task = poll_queue.head; + if (task != NULL) + OPENSSL_free(task); + + poll_queue.head = NULL; + pthread_mutex_unlock(&poll_queue.async_task_mutex); + sem_destroy(&poll_queue.empty_sem); + sem_destroy(&poll_queue.full_sem); + pthread_mutex_destroy(&poll_queue.async_task_mutex); +} + +static int async_get_poll_task(int *id) +{ + int idx = poll_queue.rid; + int cnt = 0; + + while (!poll_queue.status[idx]) { + idx = (idx + 1) % ASYNC_QUEUE_TASK_NUM; + if (cnt++ == ASYNC_QUEUE_TASK_NUM) + return 0; + } + + *id = idx; + poll_queue.rid = (idx + 1) % ASYNC_QUEUE_TASK_NUM; + + return 1; +} + +static struct async_poll_task *async_get_queue_task(void) +{ + struct async_poll_task *cur_task = NULL; + struct async_poll_task *task_queue; + int idx, ret; + + if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) + return NULL; + + ret = async_get_poll_task(&idx); + if (!ret) + goto err; + + task_queue = poll_queue.head; + cur_task = &task_queue[idx]; + poll_queue.is_recv = 0; + +err: + if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) + return NULL; + + if (cur_task && cur_task->op == NULL) + return NULL; + + return cur_task; +} + +void async_free_poll_task(int id, bool is_cb) +{ + if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) + return; + + poll_queue.status[id] = 0; + + if (is_cb) + poll_queue.is_recv = 1; + + if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) + return; + + (void)sem_post(&poll_queue.empty_sem); +} + +int async_get_free_task(int *id) +{ + struct async_poll_task *task_queue; + struct async_poll_task *task; + int idx, ret; + int cnt = 0; + + if (sem_wait(&poll_queue.empty_sem) != 0) + return 0; + + if (pthread_mutex_lock(&poll_queue.async_task_mutex) != 0) + return 0; + + idx = poll_queue.sid; + while (poll_queue.status[idx]) { + idx = (idx + 1) % ASYNC_QUEUE_TASK_NUM; + if (cnt++ == ASYNC_QUEUE_TASK_NUM) { + ret = 0; + goto out; + } + } + + *id = idx; + poll_queue.sid = (idx + 1) % ASYNC_QUEUE_TASK_NUM; + poll_queue.status[idx] = 1; + task_queue = poll_queue.head; + task = &task_queue[idx]; + task->op = NULL; + ret = 1; + +out: + if (pthread_mutex_unlock(&poll_queue.async_task_mutex) != 0) + return 0; + + return ret; +} + +static int async_add_poll_task(void *ctx, struct async_op *op, enum task_type type, int id) +{ + struct async_poll_task *task_queue; + struct async_poll_task *task; + int ret; + + task_queue = poll_queue.head; + task = &task_queue[id]; + task->ctx = ctx; + task->type = type; + task->op = op; + + ret = sem_post(&poll_queue.full_sem); + if (ret) + return 0; + + return 1; +} + +int async_pause_job(void *ctx, struct async_op *op, enum task_type type, int id) +{ + ASYNC_WAIT_CTX *waitctx; + OSSL_ASYNC_FD efd; + void *custom; + uint64_t buf; + int ret; + + ret = async_add_poll_task(ctx, op, type, id); + if (ret == 0) + return ret; + + waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)op->job); + if (waitctx == NULL) + return 0; + + do { + if (ASYNC_pause_job() == 0) + return 0; + + ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_uadk_id, &efd, &custom); + if (ret <= 0) + continue; + + if (read(efd, &buf, sizeof(uint64_t)) == -1) { + if (errno != EAGAIN) + fprintf(stderr, "failed to read from fd: %d - error: %d\n", + efd, errno); + /* Not resumed by the expected async_wake_job() */ + } + } while (!op->done); + + return ret; +} + +int async_wake_job(ASYNC_JOB *job) +{ + ASYNC_WAIT_CTX *waitctx; + OSSL_ASYNC_FD efd; + void *custom; + uint64_t buf = 1; + int ret; + + waitctx = ASYNC_get_wait_ctx(job); + if (waitctx == NULL) + return 0; + + ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_uadk_id, &efd, &custom); + if (ret > 0) { + if (write(efd, &buf, sizeof(uint64_t)) == -1) + fprintf(stderr, "failed to write to fd: %d - error: %d\n", efd, errno); + } + + return ret; +} + +void async_register_poll_fn(int type, async_recv_t func) +{ + if (type < 0 || type >= ASYNC_TASK_MAX) { + fprintf(stderr, "alg type is error, type= %d.\n", type); + return; + } + + async_recv_func[type] = func; +} + +static void *async_poll_process_func(void *args) +{ + struct async_poll_task *task; + struct async_op *op; + int ret, idx; + + while (1) { + if (sem_wait(&poll_queue.full_sem) != 0) { + if (errno == EINTR) { + /* sem_wait is interrupted by interrupt, continue */ + continue; + } + } + + task = async_get_queue_task(); + if (task == NULL) { + (void)sem_post(&poll_queue.full_sem); + usleep(1); + continue; + } + + op = task->op; + idx = op->idx; + ret = async_recv_func[task->type](task->ctx); + if (!poll_queue.is_recv && op->job) { + op->done = 1; + op->ret = ret; + async_wake_job(op->job); + async_free_poll_task(idx, 0); + } + } + + return NULL; +} + +int async_module_init(void) +{ + pthread_t thread_id; + pthread_attr_t thread_attr; + + memset(&poll_queue, 0, sizeof(struct async_poll_queue)); + + if (pthread_mutex_init(&(poll_queue.async_task_mutex), NULL) < 0) + return 0; + + poll_queue.head = malloc(sizeof(struct async_poll_task) * ASYNC_QUEUE_TASK_NUM); + if (poll_queue.head == NULL) + return 0; + + memset(poll_queue.head, 0, + sizeof(struct async_poll_task) * ASYNC_QUEUE_TASK_NUM); + + if (sem_init(&poll_queue.empty_sem, 0, + ASYNC_QUEUE_TASK_NUM) != 0) + goto err; + + if (sem_init(&poll_queue.full_sem, 0, 0) != 0) + goto err; + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + if (pthread_create(&thread_id, &thread_attr, async_poll_process_func, NULL)) + goto err; + + poll_queue.thread_id = thread_id; + OPENSSL_atexit(async_poll_task_free); + + return 1; + +err: + async_poll_task_free(); + return 0; +} diff --git a/kae_engine/src/uadk_async.h b/kae_engine/src/uadk_async.h new file mode 100644 index 0000000000000000000000000000000000000000..8a4822eac5fd96501df2696928d1a123092caf41 --- /dev/null +++ b/kae_engine/src/uadk_async.h @@ -0,0 +1,76 @@ +/* + * Copyright 2020-2022 Huawei Technologies Co.,Ltd. All rights reserved. + * Copyright 2020-2022 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. + * + */ +#ifndef UADK_ASYNC_H +#define UADK_ASYNC_H + +#include +#include +#include + +#define ASYNC_QUEUE_TASK_NUM 1024 + +struct async_op { + ASYNC_JOB *job; + int done; + int idx; + int ret; +}; + +struct uadk_e_cb_info { + void *priv; + struct async_op *op; +}; + +typedef int (*async_recv_t)(void *ctx); + +enum task_type { + ASYNC_TASK_CIPHER, + ASYNC_TASK_DIGEST, + ASYNC_TASK_RSA, + ASYNC_TASK_DH, + ASYNC_TASK_ECC, + ASYNC_TASK_MAX +}; + +struct async_poll_task { + enum task_type type; + void *ctx; + struct async_op *op; +}; + +struct async_poll_queue { + struct async_poll_task *head; + int status[ASYNC_QUEUE_TASK_NUM]; + int sid; + int rid; + bool is_recv; + sem_t empty_sem; + sem_t full_sem; + pthread_mutex_t async_task_mutex; + pthread_t thread_id; +}; + +int async_setup_async_event_notification(struct async_op *op); +int async_clear_async_event_notification(void); +int async_pause_job(void *ctx, struct async_op *op, enum task_type type, int id); +void async_register_poll_fn(int type, async_recv_t func); +int async_module_init(void); +int async_wake_job(ASYNC_JOB *job); +void async_free_poll_task(int id, bool is_cb); +int async_get_free_task(int *id); +#endif