From: Weili Qian qianweili@huawei.com
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 | 102 +++++++++++++++++---------- src/uadk_rsa.c | 181 +++++++++++++++++++++++++++++------------------- src/uadk_sm2.c | 3 +- 7 files changed, 301 insertions(+), 196 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..3497e77 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) - return 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; - } - - /* 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; - } + if (ecc_res.status != UADK_UNINIT) + return ecc_res.status;
- ret = uadk_wd_ecc_init(&ecc_res_config, dev); - if (ret) { - fprintf(stderr, "failed to init ec(%d).\n", ret); - goto err_unlock; - } + pthread_spin_lock(&ecc_res.lock); + if (ecc_res.status != UADK_UNINIT) + goto 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; }