1124 lines
27 KiB
Diff
1124 lines
27 KiB
Diff
From ea76570d9ba3547dc1b3cc8c9b68d4bdf8ea9106 Mon Sep 17 00:00:00 2001
|
|
From: Weili Qian <qianweili@huawei.com>
|
|
Date: Sat, 25 Nov 2023 16:13:19 +0800
|
|
Subject: [PATCH 68/82] uadk_engine: add device initialization status
|
|
|
|
The process needs to initialize the device only once. The process pid is
|
|
used to intercept repeated initialization, but the getpid() takes a
|
|
long time. Therefore, the device status is added, and the system does
|
|
not attempt to initialize the device after the device initialization
|
|
fails. When the device is reset, update status to UADK_DEVICE_ERROR,
|
|
and tasks are not sent to the hardware.
|
|
|
|
Signed-off-by: Weili Qian <qianweili@huawei.com>
|
|
---
|
|
src/uadk.h | 4 ++
|
|
src/uadk_dh.c | 139 +++++++++++++++++++++++--------------
|
|
src/uadk_ec.c | 60 ++++++++--------
|
|
src/uadk_ecx.c | 8 +--
|
|
src/uadk_pkey.c | 100 ++++++++++++++++----------
|
|
src/uadk_rsa.c | 181 +++++++++++++++++++++++++++++-------------------
|
|
src/uadk_sm2.c | 3 +-
|
|
7 files changed, 300 insertions(+), 195 deletions(-)
|
|
|
|
diff --git a/src/uadk.h b/src/uadk.h
|
|
index 3dbaba1..c5ebf32 100644
|
|
--- a/src/uadk.h
|
|
+++ b/src/uadk.h
|
|
@@ -22,6 +22,10 @@
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
#define ENV_STRING_LEN 256
|
|
#define ENGINE_RECV_MAX_CNT 60000000
|
|
+#define UADK_UNINIT 0
|
|
+#define UADK_INIT_SUCCESS 1
|
|
+#define UADK_INIT_FAIL 2
|
|
+#define UADK_DEVICE_ERROR 3
|
|
|
|
enum {
|
|
HW_V2,
|
|
diff --git a/src/uadk_dh.c b/src/uadk_dh.c
|
|
index 418747e..62c75fe 100644
|
|
--- a/src/uadk_dh.c
|
|
+++ b/src/uadk_dh.c
|
|
@@ -75,8 +75,8 @@ struct uadk_dh_sess {
|
|
|
|
struct dh_res {
|
|
struct wd_ctx_config *ctx_res;
|
|
- int pid;
|
|
int numa_id;
|
|
+ int status;
|
|
pthread_spinlock_t lock;
|
|
} g_dh_res;
|
|
|
|
@@ -200,6 +200,13 @@ static __u32 dh_pick_next_ctx(handle_t sched_ctx,
|
|
return CTX_SYNC;
|
|
}
|
|
|
|
+static void uadk_e_dh_set_status(void)
|
|
+{
|
|
+ pthread_spin_lock(&g_dh_res.lock);
|
|
+ g_dh_res.status = UADK_DEVICE_ERROR;
|
|
+ pthread_spin_unlock(&g_dh_res.lock);
|
|
+}
|
|
+
|
|
static int uadk_e_dh_poll(void *ctx)
|
|
{
|
|
__u64 rx_cnt = 0;
|
|
@@ -210,12 +217,15 @@ static int uadk_e_dh_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_dh_poll_ctx(idx, expt, &recv);
|
|
- if (!ret && recv == expt)
|
|
+ if (!ret && recv == expt) {
|
|
return UADK_E_POLL_SUCCESS;
|
|
- else if (ret == -EAGAIN)
|
|
+ } else if (ret == -EAGAIN) {
|
|
rx_cnt++;
|
|
- else
|
|
+ } else {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_dh_set_status();
|
|
return UADK_E_POLL_FAIL;
|
|
+ }
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
fprintf(stderr, "failed to recv msg: timeout!\n");
|
|
@@ -281,8 +291,11 @@ static int uadk_e_dh_env_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_dh_poll(expt, &recv);
|
|
- if (ret < 0 || recv == expt)
|
|
+ if (ret < 0 || recv == expt) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_dh_set_status();
|
|
return ret;
|
|
+ }
|
|
rx_cnt++;
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
@@ -363,41 +376,42 @@ free_cfg:
|
|
|
|
static int uadk_e_dh_init(void)
|
|
{
|
|
- struct uacce_dev *dev;
|
|
+ struct uacce_dev *dev = NULL;
|
|
int ret;
|
|
|
|
- if (g_dh_res.pid != getpid()) {
|
|
- pthread_spin_lock(&g_dh_res.lock);
|
|
- if (g_dh_res.pid == getpid()) {
|
|
- pthread_spin_unlock(&g_dh_res.lock);
|
|
- return UADK_E_INIT_SUCCESS;
|
|
- }
|
|
-
|
|
- dev = wd_get_accel_dev("dh");
|
|
- if (!dev) {
|
|
- pthread_spin_unlock(&g_dh_res.lock);
|
|
- fprintf(stderr, "failed to get device for dh\n");
|
|
- return -ENOMEM;
|
|
- }
|
|
+ if (g_dh_res.status != UADK_UNINIT)
|
|
+ return g_dh_res.status;
|
|
|
|
- ret = uadk_e_wd_dh_init(&dh_res_config, dev);
|
|
- if (ret)
|
|
- goto err_unlock;
|
|
+ pthread_spin_lock(&g_dh_res.lock);
|
|
+ if (g_dh_res.status != UADK_UNINIT)
|
|
+ goto unlock;
|
|
|
|
- g_dh_res.numa_id = dev->numa_id;
|
|
- g_dh_res.pid = getpid();
|
|
- pthread_spin_unlock(&g_dh_res.lock);
|
|
- free(dev);
|
|
+ dev = wd_get_accel_dev("dh");
|
|
+ if (!dev) {
|
|
+ fprintf(stderr, "no device available, switch to software!\n");
|
|
+ goto err_init;
|
|
}
|
|
|
|
- return UADK_E_INIT_SUCCESS;
|
|
+ ret = uadk_e_wd_dh_init(&dh_res_config, dev);
|
|
+ if (ret) {
|
|
+ fprintf(stderr, "device unavailable(%d), switch to software!\n", ret);
|
|
+ goto err_init;
|
|
+ }
|
|
|
|
-err_unlock:
|
|
+ g_dh_res.numa_id = dev->numa_id;
|
|
+ g_dh_res.status = UADK_INIT_SUCCESS;
|
|
pthread_spin_unlock(&g_dh_res.lock);
|
|
free(dev);
|
|
- fprintf(stderr, "failed to init dh(%d)\n", ret);
|
|
|
|
- return ret;
|
|
+ return g_dh_res.status;
|
|
+
|
|
+err_init:
|
|
+ g_dh_res.status = UADK_INIT_FAIL;
|
|
+unlock:
|
|
+ pthread_spin_unlock(&g_dh_res.lock);
|
|
+ if (dev)
|
|
+ free(dev);
|
|
+ return g_dh_res.status;
|
|
}
|
|
|
|
static void uadk_e_wd_dh_uninit(void)
|
|
@@ -406,20 +420,26 @@ static void uadk_e_wd_dh_uninit(void)
|
|
__u32 i;
|
|
int ret;
|
|
|
|
- if (g_dh_res.pid == getpid()) {
|
|
- ret = uadk_e_is_env_enabled("dh");
|
|
- if (ret == ENV_ENABLED) {
|
|
- wd_dh_env_uninit();
|
|
- } else {
|
|
- wd_dh_uninit();
|
|
- for (i = 0; i < ctx_cfg->ctx_num; i++)
|
|
- wd_release_ctx(ctx_cfg->ctxs[i].ctx);
|
|
+ if (g_dh_res.status == UADK_UNINIT)
|
|
+ return;
|
|
|
|
- free(ctx_cfg->ctxs);
|
|
- free(ctx_cfg);
|
|
- }
|
|
- g_dh_res.pid = 0;
|
|
+ if (g_dh_res.status == UADK_INIT_FAIL)
|
|
+ goto clear_status;
|
|
+
|
|
+ ret = uadk_e_is_env_enabled("dh");
|
|
+ if (ret == ENV_ENABLED) {
|
|
+ wd_dh_env_uninit();
|
|
+ } else {
|
|
+ wd_dh_uninit();
|
|
+ for (i = 0; i < ctx_cfg->ctx_num; i++)
|
|
+ wd_release_ctx(ctx_cfg->ctxs[i].ctx);
|
|
+
|
|
+ free(ctx_cfg->ctxs);
|
|
+ free(ctx_cfg);
|
|
}
|
|
+
|
|
+clear_status:
|
|
+ g_dh_res.status = UADK_UNINIT;
|
|
}
|
|
|
|
static struct uadk_dh_sess *dh_new_eng_session(DH *dh_alg)
|
|
@@ -706,8 +726,11 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess)
|
|
|
|
if (!op.job) {
|
|
ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req);
|
|
- if (ret)
|
|
+ if (ret) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_dh_set_status();
|
|
return UADK_E_FAIL;
|
|
+ }
|
|
} else {
|
|
cb_param.op = &op;
|
|
cb_param.priv = &dh_sess->req;
|
|
@@ -723,6 +746,8 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess)
|
|
do {
|
|
ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req);
|
|
if (ret < 0 && ret != -EBUSY) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_dh_set_status();
|
|
async_free_poll_task(op.idx, 0);
|
|
goto err;
|
|
}
|
|
@@ -770,21 +795,21 @@ static int uadk_e_dh_generate_key(DH *dh)
|
|
int ret;
|
|
|
|
if (!dh)
|
|
- goto exe_soft;
|
|
+ return UADK_E_FAIL;
|
|
|
|
ret = uadk_e_dh_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
DH_get0_pqg(dh, &p, &q, &g);
|
|
if (!p || !g || q)
|
|
- goto exe_soft;
|
|
+ return UADK_E_FAIL;
|
|
|
|
/* Get session and prepare private key */
|
|
ret = dh_prepare_data(g, dh, &dh_sess, &priv_key);
|
|
if (!ret) {
|
|
fprintf(stderr, "prepare dh data failed\n");
|
|
- goto exe_soft;
|
|
+ goto soft_log;
|
|
}
|
|
|
|
ret = dh_fill_genkey_req(g, p, priv_key, dh_sess);
|
|
@@ -814,8 +839,9 @@ free_data:
|
|
if (dh_sess->key_flag == KEY_GEN_BY_ENGINE)
|
|
BN_free(priv_key);
|
|
dh_free_eng_session(dh_sess);
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return uadk_e_dh_soft_generate_key(dh);
|
|
}
|
|
|
|
@@ -830,20 +856,20 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key,
|
|
int ret;
|
|
|
|
if (!dh || !key || !pub_key || !DH_get0_priv_key(dh))
|
|
- goto exe_soft;
|
|
+ return UADK_E_FAIL;
|
|
|
|
ret = uadk_e_dh_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
DH_get0_pqg(dh, &p, &q, &g);
|
|
if (!p || !g)
|
|
- goto exe_soft;
|
|
+ return UADK_E_FAIL;
|
|
|
|
ret = dh_prepare_data(g, dh, &dh_sess, &priv_key);
|
|
if (!ret) {
|
|
fprintf(stderr, "failed to prepare dh data\n");
|
|
- goto exe_soft;
|
|
+ goto soft_log;
|
|
}
|
|
|
|
ret = dh_fill_compkey_req(g, p, priv_key, pub_key, dh_sess);
|
|
@@ -868,8 +894,9 @@ free_data:
|
|
if (dh_sess->key_flag == KEY_GEN_BY_ENGINE)
|
|
BN_free(priv_key);
|
|
dh_free_eng_session(dh_sess);
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return uadk_e_dh_soft_compute_key(key, pub_key, dh);
|
|
}
|
|
|
|
@@ -919,7 +946,13 @@ void uadk_e_destroy_dh(void)
|
|
uadk_e_wd_dh_uninit();
|
|
}
|
|
|
|
+static void uadk_e_dh_clear_status(void)
|
|
+{
|
|
+ g_dh_res.status = UADK_UNINIT;
|
|
+}
|
|
+
|
|
void uadk_e_dh_lock_init(void)
|
|
{
|
|
+ pthread_atfork(NULL, NULL, uadk_e_dh_clear_status);
|
|
pthread_spin_init(&g_dh_res.lock, PTHREAD_PROCESS_PRIVATE);
|
|
}
|
|
diff --git a/src/uadk_ec.c b/src/uadk_ec.c
|
|
index 5852d04..78c403f 100644
|
|
--- a/src/uadk_ec.c
|
|
+++ b/src/uadk_ec.c
|
|
@@ -479,19 +479,19 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
|
|
|
|
ret = ecdsa_do_sign_check(eckey, dgst, dlen, in_kinv, in_r);
|
|
if (ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_ecc_get_support_state(ECDSA_SUPPORT);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto do_soft;
|
|
|
|
sess = ecc_alloc_sess(eckey, "ecdsa");
|
|
if (!sess)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
tdgst.data = (void *)dgst;
|
|
@@ -521,8 +521,9 @@ uninit_iot:
|
|
wd_ecc_del_out(sess, req.dst);
|
|
free_sess:
|
|
wd_ecc_free_sess(sess);
|
|
-do_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+do_soft:
|
|
return openssl_do_sign(dgst, dlen, in_kinv, in_r, eckey);
|
|
}
|
|
|
|
@@ -677,19 +678,19 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dlen,
|
|
|
|
ret = ecdsa_do_verify_check(eckey, dgst, dlen, sig);
|
|
if (ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_ecc_get_support_state(ECDSA_SUPPORT);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto do_soft;
|
|
|
|
sess = ecc_alloc_sess(eckey, "ecdsa");
|
|
if (!sess)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
tdgst.data = (void *)dgst;
|
|
@@ -717,8 +718,9 @@ uninit_iot:
|
|
wd_ecc_del_in(sess, req.src);
|
|
free_sess:
|
|
wd_ecc_free_sess(sess);
|
|
-do_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+do_soft:
|
|
return openssl_do_verify(dgst, dlen, sig, eckey);
|
|
}
|
|
|
|
@@ -970,23 +972,23 @@ static int sm2_generate_key(EC_KEY *eckey)
|
|
|
|
ret = ecc_genkey_check(eckey);
|
|
if (ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = eckey_create_key(eckey);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_ecc_get_support_state(SM2_SUPPORT);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto do_soft;
|
|
|
|
sess = ecc_alloc_sess(eckey, "sm2");
|
|
if (!sess)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
ret = sm2_keygen_init_iot(sess, &req);
|
|
@@ -1010,8 +1012,9 @@ uninit_iot:
|
|
wd_ecc_del_out(sess, req.dst);
|
|
free_sess:
|
|
wd_ecc_free_sess(sess);
|
|
-do_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+do_soft:
|
|
return openssl_do_generate(eckey);
|
|
}
|
|
|
|
@@ -1031,7 +1034,6 @@ static int ecdh_keygen_init_iot(handle_t sess, struct wd_ecc_req *req,
|
|
return 1;
|
|
}
|
|
|
|
-
|
|
static int ecdh_compkey_init_iot(handle_t sess, struct wd_ecc_req *req,
|
|
const EC_POINT *pubkey, const EC_KEY *ecdh)
|
|
{
|
|
@@ -1201,23 +1203,23 @@ static int ecdh_generate_key(EC_KEY *ecdh)
|
|
|
|
ret = ecc_genkey_check(ecdh);
|
|
if (ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = ecdh_create_key(ecdh);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_ecc_get_support_state(ECDH_SUPPORT);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto do_soft;
|
|
|
|
sess = ecc_alloc_sess(ecdh, "ecdh");
|
|
if (!sess)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
ret = ecdh_keygen_init_iot(sess, &req, ecdh);
|
|
@@ -1245,8 +1247,9 @@ uninit_iot:
|
|
wd_ecc_del_out(sess, req.dst);
|
|
free_sess:
|
|
wd_ecc_free_sess(sess);
|
|
-do_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+do_soft:
|
|
return openssl_do_generate(ecdh);
|
|
}
|
|
|
|
@@ -1319,19 +1322,19 @@ static int ecdh_compute_key(unsigned char **out, size_t *outlen,
|
|
|
|
ret = ecc_compkey_check(out, outlen, pub_key, ecdh);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_ecc_get_support_state(ECDH_SUPPORT);
|
|
if (!ret)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto do_soft;
|
|
|
|
sess = ecc_alloc_sess(ecdh, "ecdh");
|
|
if (!sess)
|
|
- goto do_soft;
|
|
+ goto soft_log;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
ret = ecdh_compkey_init_iot(sess, &req, pub_key, ecdh);
|
|
@@ -1365,8 +1368,9 @@ uninit_iot:
|
|
wd_ecc_del_out(sess, req.dst);
|
|
free_sess:
|
|
wd_ecc_free_sess(sess);
|
|
-do_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+do_soft:
|
|
return openssl_do_compute(out, outlen, pub_key, ecdh);
|
|
}
|
|
|
|
diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c
|
|
index 3eafdfb..c8d7205 100644
|
|
--- a/src/uadk_ecx.c
|
|
+++ b/src/uadk_ecx.c
|
|
@@ -85,10 +85,8 @@ static int x25519_init(EVP_PKEY_CTX *ctx)
|
|
}
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret) {
|
|
- fprintf(stderr, "failed to uadk_init_ecc, ret = %d\n", ret);
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
return UADK_E_FAIL;
|
|
- }
|
|
|
|
x25519_ctx = calloc(1, sizeof(struct ecx_ctx));
|
|
if (!x25519_ctx) {
|
|
@@ -141,10 +139,8 @@ static int x448_init(EVP_PKEY_CTX *ctx)
|
|
}
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret) {
|
|
- fprintf(stderr, "failed to do uadk_init_ecc, ret = %d\n", ret);
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
return UADK_E_FAIL;
|
|
- }
|
|
|
|
x448_ctx = calloc(1, sizeof(struct ecx_ctx));
|
|
if (!x448_ctx) {
|
|
diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c
|
|
index b071d8b..a950f6d 100644
|
|
--- a/src/uadk_pkey.c
|
|
+++ b/src/uadk_pkey.c
|
|
@@ -50,7 +50,7 @@ struct ecc_res_config {
|
|
/* ECC global hardware resource is saved here */
|
|
struct ecc_res {
|
|
struct wd_ctx_config *ctx_res;
|
|
- int pid;
|
|
+ int status;
|
|
int numa_id;
|
|
pthread_spinlock_t lock;
|
|
} ecc_res;
|
|
@@ -105,6 +105,13 @@ void uadk_e_ecc_cb(void *req_t)
|
|
}
|
|
}
|
|
|
|
+static void uadk_e_ecc_set_status(void)
|
|
+{
|
|
+ pthread_spin_lock(&ecc_res.lock);
|
|
+ ecc_res.status = UADK_DEVICE_ERROR;
|
|
+ pthread_spin_unlock(&ecc_res.lock);
|
|
+}
|
|
+
|
|
static int uadk_ecc_poll(void *ctx)
|
|
{
|
|
unsigned int recv = 0;
|
|
@@ -114,12 +121,15 @@ static int uadk_ecc_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_ecc_poll_ctx(CTX_ASYNC, expt, &recv);
|
|
- if (!ret && recv == expt)
|
|
+ if (!ret && recv == expt) {
|
|
return 0;
|
|
- else if (ret == -EAGAIN)
|
|
+ } else if (ret == -EAGAIN) {
|
|
rx_cnt++;
|
|
- else
|
|
+ } else {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_ecc_set_status();
|
|
return -1;
|
|
+ }
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
fprintf(stderr, "failed to recv msg: timeout!\n");
|
|
@@ -166,8 +176,11 @@ static int uadk_e_ecc_env_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_ecc_poll(expt, &recv);
|
|
- if (ret < 0 || recv == expt)
|
|
+ if (ret < 0 || recv == expt) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_ecc_set_status();
|
|
return ret;
|
|
+ }
|
|
rx_cnt++;
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
@@ -262,9 +275,12 @@ static void uadk_wd_ecc_uninit(void)
|
|
__u32 i;
|
|
int ret;
|
|
|
|
- if (ecc_res.pid != getpid())
|
|
+ if (ecc_res.status == UADK_UNINIT)
|
|
return;
|
|
|
|
+ if (ecc_res.status == UADK_INIT_FAIL)
|
|
+ goto clear_status;
|
|
+
|
|
ret = uadk_e_is_env_enabled("ecc");
|
|
if (ret == ENV_ENABLED) {
|
|
wd_ecc_env_uninit();
|
|
@@ -276,8 +292,10 @@ static void uadk_wd_ecc_uninit(void)
|
|
free(ctx_cfg);
|
|
ecc_res.ctx_res = NULL;
|
|
}
|
|
- ecc_res.pid = 0;
|
|
ecc_res.numa_id = 0;
|
|
+
|
|
+clear_status:
|
|
+ ecc_res.status = UADK_UNINIT;
|
|
}
|
|
|
|
int uadk_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr)
|
|
@@ -307,6 +325,8 @@ int uadk_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr)
|
|
do {
|
|
ret = wd_do_ecc_async(sess, req);
|
|
if (ret < 0 && ret != -EBUSY) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_ecc_set_status();
|
|
async_free_poll_task(op.idx, 0);
|
|
goto err;
|
|
}
|
|
@@ -319,8 +339,11 @@ int uadk_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr)
|
|
return 0;
|
|
} else {
|
|
ret = wd_do_ecc_sync(sess, req);
|
|
- if (ret < 0)
|
|
+ if (ret < 0) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_ecc_set_status();
|
|
return 0;
|
|
+ }
|
|
}
|
|
return 1;
|
|
err:
|
|
@@ -513,42 +536,43 @@ bool uadk_support_algorithm(const char *alg)
|
|
|
|
int uadk_init_ecc(void)
|
|
{
|
|
- struct uacce_dev *dev;
|
|
+ struct uacce_dev *dev = NULL;
|
|
int ret;
|
|
|
|
- if (ecc_res.pid != getpid()) {
|
|
- pthread_spin_lock(&ecc_res.lock);
|
|
- if (ecc_res.pid == getpid()) {
|
|
- pthread_spin_unlock(&ecc_res.lock);
|
|
- return 0;
|
|
- }
|
|
+ if (ecc_res.status != UADK_UNINIT)
|
|
+ return ecc_res.status;
|
|
|
|
- /* Find an ecc device, no difference for sm2/ecdsa/ecdh/x25519/x448 */
|
|
- dev = wd_get_accel_dev("ecdsa");
|
|
- if (!dev) {
|
|
- pthread_spin_unlock(&ecc_res.lock);
|
|
- fprintf(stderr, "failed to get device for ecc\n");
|
|
- return -ENOMEM;
|
|
- }
|
|
+ pthread_spin_lock(&ecc_res.lock);
|
|
+ if (ecc_res.status != UADK_UNINIT)
|
|
+ goto unlock;
|
|
|
|
- ret = uadk_wd_ecc_init(&ecc_res_config, dev);
|
|
- if (ret) {
|
|
- fprintf(stderr, "failed to init ec(%d).\n", ret);
|
|
- goto err_unlock;
|
|
- }
|
|
-
|
|
- ecc_res.numa_id = dev->numa_id;
|
|
- ecc_res.pid = getpid();
|
|
- pthread_spin_unlock(&ecc_res.lock);
|
|
- free(dev);
|
|
+ /* Find an ecc device, no difference for sm2/ecdsa/ecdh/x25519/x448 */
|
|
+ dev = wd_get_accel_dev("ecdsa");
|
|
+ if (!dev) {
|
|
+ fprintf(stderr, "no device available, switch to software!\n");
|
|
+ goto err_init;
|
|
}
|
|
|
|
- return 0;
|
|
+ ret = uadk_wd_ecc_init(&ecc_res_config, dev);
|
|
+ if (ret) {
|
|
+ fprintf(stderr, "device unavailable(%d), switch to software!\n", ret);
|
|
+ goto err_init;
|
|
+ }
|
|
|
|
-err_unlock:
|
|
+ ecc_res.numa_id = dev->numa_id;
|
|
+ ecc_res.status = UADK_INIT_SUCCESS;
|
|
pthread_spin_unlock(&ecc_res.lock);
|
|
free(dev);
|
|
- return ret;
|
|
+
|
|
+ return ecc_res.status;
|
|
+
|
|
+err_init:
|
|
+ ecc_res.status = UADK_INIT_FAIL;
|
|
+unlock:
|
|
+ pthread_spin_unlock(&ecc_res.lock);
|
|
+ if (dev)
|
|
+ free(dev);
|
|
+ return ecc_res.status;
|
|
}
|
|
|
|
static void uadk_uninit_ecc(void)
|
|
@@ -630,8 +654,14 @@ static int uadk_ecc_bind_pmeth(ENGINE *e)
|
|
return ENGINE_set_pkey_meths(e, get_pkey_meths);
|
|
}
|
|
|
|
+static void uadk_e_ecc_clear_status(void)
|
|
+{
|
|
+ ecc_res.status = UADK_UNINIT;
|
|
+}
|
|
+
|
|
void uadk_e_ecc_lock_init(void)
|
|
{
|
|
+ pthread_atfork(NULL, NULL, uadk_e_ecc_clear_status);
|
|
pthread_spin_init(&ecc_res.lock, PTHREAD_PROCESS_PRIVATE);
|
|
}
|
|
|
|
diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c
|
|
index ca05ef7..fa4d354 100644
|
|
--- a/src/uadk_rsa.c
|
|
+++ b/src/uadk_rsa.c
|
|
@@ -132,8 +132,8 @@ struct rsa_res_config {
|
|
/* Save rsa global hardware resource */
|
|
struct rsa_res {
|
|
struct wd_ctx_config *ctx_res;
|
|
- int pid;
|
|
int numa_id;
|
|
+ int status;
|
|
pthread_spinlock_t lock;
|
|
} g_rsa_res;
|
|
|
|
@@ -659,6 +659,13 @@ static int rsa_poll_policy(handle_t h_sched_ctx, __u32 expect, __u32 *count)
|
|
return UADK_E_POLL_SUCCESS;
|
|
}
|
|
|
|
+static void uadk_e_rsa_set_status(void)
|
|
+{
|
|
+ pthread_spin_lock(&g_rsa_res.lock);
|
|
+ g_rsa_res.status = UADK_DEVICE_ERROR;
|
|
+ pthread_spin_unlock(&g_rsa_res.lock);
|
|
+}
|
|
+
|
|
static int uadk_e_rsa_poll(void *ctx)
|
|
{
|
|
__u64 rx_cnt = 0;
|
|
@@ -668,12 +675,15 @@ static int uadk_e_rsa_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_rsa_poll_ctx(CTX_ASYNC, expt, &recv);
|
|
- if (!ret && recv == expt)
|
|
+ if (!ret && recv == expt) {
|
|
return UADK_E_POLL_SUCCESS;
|
|
- else if (ret == -EAGAIN)
|
|
+ } else if (ret == -EAGAIN) {
|
|
rx_cnt++;
|
|
- else
|
|
+ } else {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_rsa_set_status();
|
|
return UADK_E_POLL_FAIL;
|
|
+ }
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
fprintf(stderr, "failed to recv msg: timeout!\n");
|
|
@@ -704,8 +714,11 @@ static int uadk_e_rsa_env_poll(void *ctx)
|
|
|
|
do {
|
|
ret = wd_rsa_poll(expt, &recv);
|
|
- if (ret < 0 || recv == expt)
|
|
+ if (ret < 0 || recv == expt) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_rsa_set_status();
|
|
return ret;
|
|
+ }
|
|
rx_cnt++;
|
|
} while (rx_cnt < ENGINE_RECV_MAX_CNT);
|
|
|
|
@@ -788,42 +801,42 @@ free_cfg:
|
|
|
|
static int uadk_e_rsa_init(void)
|
|
{
|
|
- struct uacce_dev *dev;
|
|
+ struct uacce_dev *dev = NULL;
|
|
int ret;
|
|
|
|
- if (g_rsa_res.pid != getpid()) {
|
|
- pthread_spin_lock(&g_rsa_res.lock);
|
|
- if (g_rsa_res.pid == getpid()) {
|
|
- pthread_spin_unlock(&g_rsa_res.lock);
|
|
- return UADK_E_INIT_SUCCESS;
|
|
- }
|
|
+ if (g_rsa_res.status != UADK_UNINIT)
|
|
+ return g_rsa_res.status;
|
|
|
|
- dev = wd_get_accel_dev("rsa");
|
|
- if (!dev) {
|
|
- pthread_spin_unlock(&g_rsa_res.lock);
|
|
- fprintf(stderr, "failed to get device for rsa\n");
|
|
- return -ENOMEM;
|
|
- }
|
|
-
|
|
- ret = uadk_e_wd_rsa_init(&rsa_res_config, dev);
|
|
- if (ret)
|
|
- goto err_unlock;
|
|
+ pthread_spin_lock(&g_rsa_res.lock);
|
|
+ if (g_rsa_res.status != UADK_UNINIT)
|
|
+ goto unlock;
|
|
|
|
- g_rsa_res.numa_id = dev->numa_id;
|
|
- g_rsa_res.pid = getpid();
|
|
- pthread_spin_unlock(&g_rsa_res.lock);
|
|
- free(dev);
|
|
+ dev = wd_get_accel_dev("rsa");
|
|
+ if (!dev) {
|
|
+ fprintf(stderr, "no device available, switch to software!\n");
|
|
+ goto err_init;
|
|
}
|
|
|
|
- return UADK_E_INIT_SUCCESS;
|
|
+ ret = uadk_e_wd_rsa_init(&rsa_res_config, dev);
|
|
+ if (ret) {
|
|
+ fprintf(stderr, "device unavailable(%d), switch to software!\n", ret);
|
|
+ goto err_init;
|
|
+ }
|
|
|
|
-err_unlock:
|
|
- g_rsa_res.ctx_res = NULL;
|
|
+ g_rsa_res.numa_id = dev->numa_id;
|
|
+ g_rsa_res.status = UADK_INIT_SUCCESS;
|
|
pthread_spin_unlock(&g_rsa_res.lock);
|
|
free(dev);
|
|
- (void)fprintf(stderr, "failed to init rsa(%d)\n", ret);
|
|
|
|
- return ret;
|
|
+ return g_rsa_res.status;
|
|
+
|
|
+err_init:
|
|
+ g_rsa_res.status = UADK_INIT_FAIL;
|
|
+unlock:
|
|
+ pthread_spin_unlock(&g_rsa_res.lock);
|
|
+ if (dev)
|
|
+ free(dev);
|
|
+ return g_rsa_res.status;
|
|
}
|
|
|
|
static void uadk_e_rsa_uninit(void)
|
|
@@ -832,23 +845,25 @@ static void uadk_e_rsa_uninit(void)
|
|
__u32 i;
|
|
int ret;
|
|
|
|
- if (!ctx_cfg)
|
|
+ if (g_rsa_res.status == UADK_UNINIT)
|
|
return;
|
|
|
|
- if (g_rsa_res.pid == getpid()) {
|
|
- ret = uadk_e_is_env_enabled("rsa");
|
|
- if (ret == ENV_ENABLED) {
|
|
- wd_rsa_env_uninit();
|
|
- } else {
|
|
- wd_rsa_uninit();
|
|
- for (i = 0; i < ctx_cfg->ctx_num; i++)
|
|
- wd_release_ctx(ctx_cfg->ctxs[i].ctx);
|
|
- free(ctx_cfg->ctxs);
|
|
- free(ctx_cfg);
|
|
- }
|
|
+ if (g_rsa_res.status == UADK_INIT_FAIL)
|
|
+ goto clear_status;
|
|
|
|
- g_rsa_res.pid = 0;
|
|
+ ret = uadk_e_is_env_enabled("rsa");
|
|
+ if (ret == ENV_ENABLED) {
|
|
+ wd_rsa_env_uninit();
|
|
+ } else {
|
|
+ wd_rsa_uninit();
|
|
+ for (i = 0; i < ctx_cfg->ctx_num; i++)
|
|
+ wd_release_ctx(ctx_cfg->ctxs[i].ctx);
|
|
+ free(ctx_cfg->ctxs);
|
|
+ free(ctx_cfg);
|
|
}
|
|
+
|
|
+clear_status:
|
|
+ g_rsa_res.status = UADK_UNINIT;
|
|
}
|
|
|
|
static struct uadk_rsa_sess *rsa_new_eng_session(RSA *rsa)
|
|
@@ -1094,10 +1109,13 @@ static int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess)
|
|
|
|
if (!op.job) {
|
|
ret = wd_do_rsa_sync(rsa_sess->sess, &(rsa_sess->req));
|
|
- if (!ret)
|
|
- return UADK_E_SUCCESS;
|
|
- else
|
|
+ if (ret) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_rsa_set_status();
|
|
goto err;
|
|
+ } else {
|
|
+ return UADK_E_SUCCESS;
|
|
+ }
|
|
}
|
|
cb_param.op = &op;
|
|
cb_param.priv = &(rsa_sess->req);
|
|
@@ -1113,6 +1131,8 @@ static int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess)
|
|
do {
|
|
ret = wd_do_rsa_async(rsa_sess->sess, &(rsa_sess->req));
|
|
if (ret < 0 && ret != -EBUSY) {
|
|
+ if (ret == -WD_HW_EACCESS)
|
|
+ uadk_e_rsa_set_status();
|
|
async_free_poll_task(op.idx, 0);
|
|
goto err;
|
|
}
|
|
@@ -1379,16 +1399,18 @@ static int uadk_e_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
|
|
int ret;
|
|
|
|
ret = rsa_check_bit_useful(bits, 0);
|
|
- if (!ret || ret == SOFT)
|
|
- goto exe_soft;
|
|
+ if (!ret)
|
|
+ return UADK_E_FAIL;
|
|
+ else if (ret == SOFT)
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_rsa_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
ret = rsa_keygen_param_alloc(&keygen_param, &bn_param, &key_pair, &bn_ctx);
|
|
if (ret == -ENOMEM)
|
|
- goto exe_soft;
|
|
+ return ret;
|
|
|
|
rsa_sess = rsa_get_eng_session(rsa, bits, is_crt);
|
|
if (!rsa_sess) {
|
|
@@ -1431,8 +1453,9 @@ free_keygen:
|
|
rsa_keygen_param_free(&keygen_param, &bn_param, &key_pair, &bn_ctx, ret);
|
|
if (ret != UADK_DO_SOFT)
|
|
return ret;
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return uadk_e_soft_rsa_keygen(rsa, bits, e, cb);
|
|
}
|
|
|
|
@@ -1446,16 +1469,18 @@ static int uadk_e_rsa_public_encrypt(int flen, const unsigned char *from,
|
|
BIGNUM *enc_bn = NULL;
|
|
|
|
ret = check_rsa_input_para(flen, from, to, rsa);
|
|
- if (!ret || ret == SOFT)
|
|
- goto exe_soft;
|
|
+ if (!ret)
|
|
+ return UADK_E_FAIL;
|
|
+ else if (ret == SOFT)
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_rsa_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
ret = rsa_pkey_param_alloc(&pub_enc, NULL);
|
|
if (ret == -ENOMEM)
|
|
- goto exe_soft;
|
|
+ return ret;
|
|
|
|
is_crt = check_rsa_is_crt(rsa);
|
|
|
|
@@ -1510,8 +1535,9 @@ free_pkey:
|
|
rsa_pkey_param_free(&pub_enc, NULL);
|
|
if (ret != UADK_DO_SOFT)
|
|
return ret;
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())
|
|
(flen, from, to, rsa, padding);
|
|
}
|
|
@@ -1526,16 +1552,18 @@ static int uadk_e_rsa_private_decrypt(int flen, const unsigned char *from,
|
|
BIGNUM *dec_bn = NULL;
|
|
|
|
ret = check_rsa_input_para(flen, from, to, rsa);
|
|
- if (!ret || ret == SOFT)
|
|
- goto exe_soft;
|
|
+ if (!ret)
|
|
+ return UADK_E_FAIL;
|
|
+ else if (ret == SOFT)
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_rsa_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
ret = rsa_pkey_param_alloc(NULL, &pri);
|
|
if (ret == -ENOMEM)
|
|
- goto exe_soft;
|
|
+ return ret;
|
|
|
|
pri->is_crt = check_rsa_is_crt(rsa);
|
|
|
|
@@ -1592,8 +1620,9 @@ free_pkey:
|
|
rsa_pkey_param_free(NULL, &pri);
|
|
if (ret != UADK_DO_SOFT)
|
|
return ret;
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())
|
|
(flen, from, to, rsa, padding);
|
|
}
|
|
@@ -1610,16 +1639,18 @@ static int uadk_e_rsa_private_sign(int flen, const unsigned char *from,
|
|
int num_bytes, ret;
|
|
|
|
ret = check_rsa_input_para(flen, from, to, rsa);
|
|
- if (!ret || ret == SOFT)
|
|
- goto exe_soft;
|
|
+ if (!ret)
|
|
+ return UADK_E_FAIL;
|
|
+ else if (ret == SOFT)
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_rsa_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
ret = rsa_pkey_param_alloc(NULL, &pri);
|
|
if (ret == -ENOMEM)
|
|
- goto exe_soft;
|
|
+ return ret;
|
|
|
|
pri->is_crt = check_rsa_is_crt(rsa);
|
|
|
|
@@ -1686,8 +1717,9 @@ free_pkey:
|
|
rsa_pkey_param_free(NULL, &pri);
|
|
if (ret != UADK_DO_SOFT)
|
|
return ret;
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())
|
|
(flen, from, to, rsa, padding);
|
|
}
|
|
@@ -1705,15 +1737,15 @@ static int uadk_e_rsa_public_verify(int flen, const unsigned char *from,
|
|
if (!ret)
|
|
return UADK_E_FAIL;
|
|
else if (ret == SOFT)
|
|
- goto exe_soft;
|
|
+ goto soft_log;
|
|
|
|
ret = uadk_e_rsa_init();
|
|
- if (ret)
|
|
+ if (ret != UADK_INIT_SUCCESS)
|
|
goto exe_soft;
|
|
|
|
ret = rsa_pkey_param_alloc(&pub, NULL);
|
|
if (ret == -ENOMEM)
|
|
- goto exe_soft;
|
|
+ return ret;
|
|
|
|
is_crt = check_rsa_is_crt(rsa);
|
|
|
|
@@ -1775,8 +1807,9 @@ free_pkey:
|
|
rsa_pkey_param_free(&pub, NULL);
|
|
if (ret != UADK_DO_SOFT)
|
|
return ret;
|
|
-exe_soft:
|
|
+soft_log:
|
|
fprintf(stderr, "switch to execute openssl software calculation.\n");
|
|
+exe_soft:
|
|
return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())
|
|
(flen, from, to, rsa, padding);
|
|
}
|
|
@@ -1834,7 +1867,13 @@ void uadk_e_destroy_rsa(void)
|
|
uadk_e_rsa_uninit();
|
|
}
|
|
|
|
+static void uadk_e_rsa_clear_status(void)
|
|
+{
|
|
+ g_rsa_res.status = UADK_UNINIT;
|
|
+}
|
|
+
|
|
void uadk_e_rsa_lock_init(void)
|
|
{
|
|
+ pthread_atfork(NULL, NULL, uadk_e_rsa_clear_status);
|
|
pthread_spin_init(&g_rsa_res.lock, PTHREAD_PROCESS_PRIVATE);
|
|
}
|
|
diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c
|
|
index df760fe..1db6e3a 100644
|
|
--- a/src/uadk_sm2.c
|
|
+++ b/src/uadk_sm2.c
|
|
@@ -1204,8 +1204,7 @@ static int sm2_init(EVP_PKEY_CTX *ctx)
|
|
}
|
|
|
|
ret = uadk_init_ecc();
|
|
- if (ret) {
|
|
- fprintf(stderr, "failed to uadk_init_ecc, ret = %d\n", ret);
|
|
+ if (ret != UADK_INIT_SUCCESS) {
|
|
smctx->init_status = CTX_INIT_FAIL;
|
|
goto end;
|
|
}
|
|
--
|
|
2.25.1
|
|
|