[PATCH 0/7] uadk_provider: asynchronous SEC switching to software computing is supported
From: parm64 <parm64@huawei.com> Weili Qian (3): uadk_provider/sm2: fix compilation warning uadk_engine: add asynchronous request sending return value check uadk_provider: modify the return value check for asynchronous request sending Zhushuai Yin (2): uadk_provider: asynchronous SEC switching to software computing is supported uadk_provider: asynchronous aead switching to software computing is supported lizhi (2): uadk_provider/ecdh: ensure proper ECDH key length and add RSA-PSS query function uadk_provider/rsa: add input length validation and initialization parameter checks src/uadk_dh.c | 11 +++-- src/uadk_ec.c | 15 ++++++- src/uadk_pkey.c | 11 +++-- src/uadk_prov_aead.c | 15 +------ src/uadk_prov_cipher.c | 43 ++++++++++--------- src/uadk_prov_dh.c | 7 ++- src/uadk_prov_digest.c | 47 +++++++++------------ src/uadk_prov_ecdh_exch.c | 6 ++- src/uadk_prov_hmac.c | 49 +++++++++------------ src/uadk_prov_pkey.c | 7 ++- src/uadk_prov_rsa.c | 66 +++++++++++++++++++++++++---- src/uadk_prov_rsa.h | 4 +- src/uadk_prov_rsa_enc.c | 25 ++++++----- src/uadk_prov_rsa_kmgmt.c | 12 +++++- src/uadk_prov_rsa_sign.c | 14 +++++- src/uadk_prov_sm2_kmgmt.c | 2 +- src/uadk_rsa.c | 89 ++++++++++++++++++++++++++++++++------- 17 files changed, 278 insertions(+), 145 deletions(-) -- 2.43.0
From: Weili Qian <qianweili@huawei.com> warning: suggest parentheses around operand of '!' or change '&' to '&&' or '!' to '~' [-Wparentheses]. Signed-off-by: Weili Qian <qianweili@huawei.com> --- src/uadk_prov_sm2_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uadk_prov_sm2_kmgmt.c b/src/uadk_prov_sm2_kmgmt.c index 22871e6..1791cdd 100644 --- a/src/uadk_prov_sm2_kmgmt.c +++ b/src/uadk_prov_sm2_kmgmt.c @@ -471,7 +471,7 @@ static void *uadk_keymgmt_sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba } /* If there is no need to generate the private and public keys, return directly. */ - if (!gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) + if (!(gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR)) return ec; ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_SM2); -- 2.43.0
From: Weili Qian <qianweili@huawei.com> After calling the asynchronous interface to send a request, if the return value is not 0, -WD_HW_EACCESS, or -EBUSY, it is considered that the request was sent successfully. In this case, the request receiving operation continues, which may cause a request receiving timeout. Therefore, add checks for other return values. Signed-off-by: Weili Qian <qianweili@huawei.com> --- src/uadk_dh.c | 11 +++++++---- src/uadk_pkey.c | 11 +++++++---- src/uadk_rsa.c | 11 +++++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/uadk_dh.c b/src/uadk_dh.c index e49250b..ce00953 100644 --- a/src/uadk_dh.c +++ b/src/uadk_dh.c @@ -755,12 +755,15 @@ static int dh_do_async(struct uadk_dh_sess *dh_sess, struct async_op *op) do { ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); if (unlikely(ret < 0)) { - if (unlikely(ret == -WD_HW_EACCESS)) - uadk_e_dh_set_status(); - else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) + if (unlikely(ret != -EBUSY)) { + fprintf(stderr, "do dh async operation failed.\n"); + if (unlikely(ret == -WD_HW_EACCESS)) + uadk_e_dh_set_status(); + } else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) { fprintf(stderr, "do dh async operation timeout.\n"); - else + } else { continue; + } async_free_poll_task(op->idx, 0); ret = UADK_E_FAIL; diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c index c5f711b..5878be7 100644 --- a/src/uadk_pkey.c +++ b/src/uadk_pkey.c @@ -342,12 +342,15 @@ static int uadk_ecc_do_async(handle_t sess, struct wd_ecc_req *req, do { ret = wd_do_ecc_async(sess, req); if (unlikely(ret < 0)) { - if (unlikely(ret == -WD_HW_EACCESS)) - uadk_e_ecc_set_status(); - else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) + if (unlikely(ret != -EBUSY)) { + fprintf(stderr, "do ecc async operation failed.\n"); + if (unlikely(ret == -WD_HW_EACCESS)) + uadk_e_ecc_set_status(); + } else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) { fprintf(stderr, "do ecc async operation timeout.\n"); - else + } else { continue; + } async_free_poll_task(op->idx, 0); ret = 0; diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c index 318f8ed..11663d8 100644 --- a/src/uadk_rsa.c +++ b/src/uadk_rsa.c @@ -1162,12 +1162,15 @@ static int rsa_do_async(struct uadk_rsa_sess *rsa_sess, struct async_op *op) do { ret = wd_do_rsa_async(rsa_sess->sess, &rsa_sess->req); if (unlikely(ret < 0)) { - if (unlikely(ret == -WD_HW_EACCESS)) - uadk_e_rsa_set_status(); - else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) + if (unlikely(ret != -EBUSY)) { + fprintf(stderr, "do rsa async operation failed.\n"); + if (unlikely(ret == -WD_HW_EACCESS)) + uadk_e_rsa_set_status(); + } else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) { fprintf(stderr, "do rsa async operation timeout.\n"); - else + } else { continue; + } async_free_poll_task(op->idx, 0); ret = UADK_E_FAIL; -- 2.43.0
From: Weili Qian <qianweili@huawei.com> When the request is sent successfully but cnt is greater than PROV_SEND_MAX_CNT, it will be considered timeout. Modify this to first check if the operation was successful, and if it was, exit the loop and wait for the request reception to complete. Signed-off-by: Weili Qian <qianweili@huawei.com> --- src/uadk_prov_cipher.c | 22 +++++++++++++++++----- src/uadk_prov_dh.c | 7 +++++-- src/uadk_prov_digest.c | 9 ++++++--- src/uadk_prov_hmac.c | 11 +++++++---- src/uadk_prov_pkey.c | 7 +++++-- src/uadk_prov_rsa.c | 20 +++++++++++++++----- 6 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index d442d3d..0c3023e 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -488,6 +488,7 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o { struct uadk_e_cb_info cb_param; int idx, ret; + int cnt = 0; if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { UADK_ERR("async cipher init failed.\n"); @@ -506,18 +507,29 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o op->idx = idx; do { ret = wd_do_cipher_async(priv->sess, &priv->req); - if (ret < 0 && ret != -EBUSY) { - UADK_ERR("do sec cipher failed, switch to soft cipher.\n"); - async_free_poll_task(op->idx, 0); - return UADK_P_FAIL; + if (likely(!ret)) + break; + + if (ret != -EBUSY) { + UADK_ERR("failed to do cipher async\n"); + goto free_poll_task; + } + + if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { + UADK_ERR("do cipher async operation timeout\n"); + goto free_poll_task; } - } while (ret == -EBUSY); + } while (true); ret = async_pause_job(priv, op, ASYNC_TASK_CIPHER); if (!ret || priv->req.state) return UADK_P_FAIL; return UADK_P_SUCCESS; + +free_poll_task: + async_free_poll_task(op->idx, 0); + return UADK_P_FAIL; } static void uadk_cipher_mutex_infork(void) diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c index 2d96a1d..cf31971 100644 --- a/src/uadk_prov_dh.c +++ b/src/uadk_prov_dh.c @@ -925,7 +925,10 @@ static int uadk_prov_dh_do_crypto(struct uadk_dh_sess *dh_sess) cnt = 0; do { ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); - if (ret < 0 && ret != -EBUSY) { + if (likely(!ret)) + break; + + if (ret != -EBUSY) { UADK_ERR("failed to do dh async\n"); goto free_poll_task; } @@ -934,7 +937,7 @@ static int uadk_prov_dh_do_crypto(struct uadk_dh_sess *dh_sess) UADK_ERR("do dh async operation timeout\n"); goto free_poll_task; } - } while (ret == -EBUSY); + } while (true); ret = async_pause_job(dh_sess, &op, ASYNC_TASK_DH); if (!ret) diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index c5d1db4..aaf3061 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -625,8 +625,11 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o do { ret = wd_do_digest_async(priv->sess, &priv->req); - if (ret < 0 && ret != -EBUSY) { - UADK_ERR("do sec digest async failed.\n"); + if (likely(!ret)) + break; + + if (ret != -EBUSY) { + UADK_ERR("do digest async failed.\n"); goto free_poll_task; } @@ -634,7 +637,7 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o UADK_ERR("do digest async operation timeout.\n"); goto free_poll_task; } - } while (ret == -EBUSY); + } while (true); ret = async_pause_job(priv, op, ASYNC_TASK_DIGEST); if (!ret || priv->req.state) diff --git a/src/uadk_prov_hmac.c b/src/uadk_prov_hmac.c index 0c53d12..96da4eb 100644 --- a/src/uadk_prov_hmac.c +++ b/src/uadk_prov_hmac.c @@ -596,16 +596,19 @@ static int uadk_do_hmac_async(struct hmac_priv_ctx *priv, struct async_op *op) op->idx = idx; do { ret = wd_do_digest_async(priv->sess, &priv->req); - if (ret < 0 && ret != -EBUSY) { - UADK_ERR("do sec digest async failed.\n"); + if (likely(!ret)) + break; + + if (ret != -EBUSY) { + UADK_ERR("do hmac async failed.\n"); goto free_poll_task; } if (unlikely(++cnt > ENGINE_SEND_MAX_CNT)) { - UADK_ERR("do digest async operation timeout.\n"); + UADK_ERR("do hmac async operation timeout.\n"); goto free_poll_task; } - } while (ret == -EBUSY); + } while (true); ret = async_pause_job(priv, op, ASYNC_TASK_HMAC); if (!ret || priv->req.state) diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c index 994ea07..2e2ca0b 100644 --- a/src/uadk_prov_pkey.c +++ b/src/uadk_prov_pkey.c @@ -407,7 +407,10 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) cnt = 0; do { ret = wd_do_ecc_async(sess, req); - if (ret < 0 && ret != -EBUSY) { + if (likely(!ret)) + break; + + if (ret != -EBUSY) { UADK_ERR("failed to do ecc async\n"); goto free_poll_task; } @@ -416,7 +419,7 @@ int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr) UADK_ERR("do ecc async operation timeout\n"); goto free_poll_task; } - } while (ret == -EBUSY); + } while (true); ret = async_pause_job(usr, &op, ASYNC_TASK_ECC); if (ret == 0) diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c index f77f718..4fe415f 100644 --- a/src/uadk_prov_rsa.c +++ b/src/uadk_prov_rsa.c @@ -335,6 +335,7 @@ int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) struct uadk_e_cb_info cb_param; struct async_op op; int idx, ret; + int cnt = 0; ret = async_setup_async_event_notification(&op); if (!ret) { @@ -361,11 +362,19 @@ int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) op.idx = idx; do { ret = wd_do_rsa_async(rsa_sess->sess, &(rsa_sess->req)); - if (ret < 0 && ret != -EBUSY) { - async_free_poll_task(op.idx, 0); - goto err; + if (likely(!ret)) + break; + + if (ret != -EBUSY) { + UADK_ERR("failed to do rsa async\n"); + goto free_poll_task; } - } while (ret == -EBUSY); + + if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { + UADK_ERR("do rsa async operation timeout\n"); + goto free_poll_task; + } + } while (true); ret = async_pause_job(rsa_sess, &op, ASYNC_TASK_RSA); if (!ret) @@ -375,7 +384,8 @@ int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess) return UADK_P_FAIL; 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; -- 2.43.0
From: lizhi <lizhi206@huawei.com> 1. Replace BN_bn2bin with BN_bn2binpad in ECDH exchange to prevent zero value of x. 2. Implement dedicated query_operation_name for RSA-PSS mode instead of reusing RSA's. Signed-off-by: lizhi <lizhi206@huawei.com> --- src/uadk_ec.c | 15 +++++++++++++-- src/uadk_prov_ecdh_exch.c | 6 ++++-- src/uadk_prov_rsa_kmgmt.c | 10 +++++++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/uadk_ec.c b/src/uadk_ec.c index 0fbbf46..08ff7a3 100644 --- a/src/uadk_ec.c +++ b/src/uadk_ec.c @@ -1015,6 +1015,15 @@ static int ecdh_keygen_init_iot(handle_t sess, struct wd_ecc_req *req, return 1; } +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_compkey_init_iot(handle_t sess, struct wd_ecc_req *req, const EC_POINT *pubkey, const EC_KEY *ecdh) { @@ -1025,6 +1034,7 @@ static int ecdh_compkey_init_iot(handle_t sess, struct wd_ecc_req *req, struct wd_ecc_in *ecdh_in; BIGNUM *pkey_x, *pkey_y; const EC_GROUP *group; + size_t ec_size; BN_CTX *ctx; int ret = 0; @@ -1045,11 +1055,12 @@ static int ecdh_compkey_init_iot(handle_t sess, struct wd_ecc_req *req, if (!group) goto free_ctx; + ec_size = ecdh_get_ec_size(group); uadk_get_affine_coordinates(group, pubkey, 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); + in_pkey.x.dsize = BN_bn2binpad(pkey_x, (unsigned char *)in_pkey.x.data, ec_size); + in_pkey.y.dsize = BN_bn2binpad(pkey_y, (unsigned char *)in_pkey.y.data, ec_size); /* Set public key */ ecdh_in = wd_ecxdh_new_in(sess, &in_pkey); diff --git a/src/uadk_prov_ecdh_exch.c b/src/uadk_prov_ecdh_exch.c index 3ee7e5e..f2d09fb 100644 --- a/src/uadk_prov_ecdh_exch.c +++ b/src/uadk_prov_ecdh_exch.c @@ -216,6 +216,7 @@ static int ecdh_init_req(struct ecdh_sess_ctx *sess_ctx, struct wd_ecc_in *ecdh_in; BIGNUM *pkey_x, *pkey_y; int ret = UADK_P_FAIL; + size_t ec_size; BN_CTX *ctx; ctx = BN_CTX_new(); @@ -231,11 +232,12 @@ static int ecdh_init_req(struct ecdh_sess_ctx *sess_ctx, if (!pkey_y) goto free_ctx; + ec_size = ecdh_get_ec_size(sess_ctx->group); 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); + in_pkey.x.dsize = BN_bn2binpad(pkey_x, (unsigned char *)in_pkey.x.data, ec_size); + in_pkey.y.dsize = BN_bn2binpad(pkey_y, (unsigned char *)in_pkey.y.data, ec_size); /* Set public key */ ecdh_in = wd_ecxdh_new_in(sess, &in_pkey); diff --git a/src/uadk_prov_rsa_kmgmt.c b/src/uadk_prov_rsa_kmgmt.c index 1286ae5..fe87493 100644 --- a/src/uadk_prov_rsa_kmgmt.c +++ b/src/uadk_prov_rsa_kmgmt.c @@ -790,6 +790,14 @@ static const char *uadk_keymgmt_rsa_query_operation_name(int operation_id) return get_default_rsa_keymgmt().query_operation_name(operation_id); } +static const char *uadk_keymgmt_rsapss_query_operation_name(int operation_id) +{ + if (!get_default_rsapss_keymgmt().query_operation_name) + return NULL; + + return get_default_rsapss_keymgmt().query_operation_name(operation_id); +} + static void *uadk_keymgmt_rsa_new(void *provctx) { if (!get_default_rsa_keymgmt().new_fun) @@ -1071,6 +1079,6 @@ const OSSL_DISPATCH uadk_rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))uadk_keymgmt_rsa_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))uadk_keymgmt_rsa_dup }, { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, - (void (*)(void))uadk_keymgmt_rsa_query_operation_name }, + (void (*)(void))uadk_keymgmt_rsapss_query_operation_name }, { 0, NULL } }; -- 2.43.0
From: Zhushuai Yin <yinzhushuai@huawei.com> Currently, when an SEC device fails to be initialized, the asynchronous test case fails to be executed. This issue is resolved so that the asynchronous scenario can now switch from the hardware calculation to the software calculation after the hardware calculation fails. Signed-off-by: Zhushuai Yin <yinzhushuai@huawei.com> --- src/uadk_prov_cipher.c | 21 +++++---------------- src/uadk_prov_digest.c | 38 ++++++++++++++------------------------ src/uadk_prov_hmac.c | 38 +++++++++++++------------------------- 3 files changed, 32 insertions(+), 65 deletions(-) diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 0c3023e..2606c2f 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -490,11 +490,6 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o int idx, ret; int cnt = 0; - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - UADK_ERR("async cipher init failed.\n"); - return UADK_P_FAIL; - } - cb_param.op = op; cb_param.priv = &priv->req; priv->req.cb = (void *)async_cb; @@ -768,19 +763,13 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, return UADK_P_FAIL; } - if (op.job == NULL) { - /* Synchronous, only the synchronous mode supports soft computing */ + if (op.job == NULL) ret = uadk_do_cipher_sync(priv); - if (!ret) { - async_clear_async_event_notification(); - return UADK_P_FAIL; - } - } else { + else ret = uadk_do_cipher_async(priv, &op); - if (!ret) { - async_clear_async_event_notification(); - return UADK_P_FAIL; - } + if (!ret) { + async_clear_async_event_notification(); + return UADK_P_FAIL; } return UADK_P_SUCCESS; diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index aaf3061..0f4cb87 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -606,11 +606,6 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o int idx, ret; int cnt = 0; - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - UADK_ERR("digest soft switching is not supported in asynchronous mode.\n"); - return UADK_DIGEST_FAIL; - } - cb_param.op = op; cb_param.priv = &priv->req; priv->req.cb = (void *)uadk_async_cb; @@ -660,12 +655,16 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest return UADK_DIGEST_FAIL; } - if (unlikely(priv->switch_flag != UADK_DO_SOFT)) { - ret = uadk_digest_ctx_init(priv); - if (ret != UADK_DIGEST_SUCCESS) - return UADK_DIGEST_FAIL; + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { + ret = uadk_digest_soft_final(priv, digest); + digest_soft_cleanup(priv); + return ret; } + ret = uadk_digest_ctx_init(priv); + if (ret != UADK_DIGEST_SUCCESS) + return UADK_DIGEST_FAIL; + priv->req.in = priv->data; priv->req.out = priv->out; priv->req.in_bytes = priv->last_update_bufflen; @@ -679,22 +678,13 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest return UADK_DIGEST_FAIL; } - if (op.job == NULL) { - /* Synchronous, only the synchronous mode supports soft computing */ - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - ret = uadk_digest_soft_final(priv, digest); - digest_soft_cleanup(priv); - goto clear; - } - + if (op.job == NULL) ret = uadk_do_digest_sync(priv); - if (!ret) - goto sync_err; - } else { + else ret = uadk_do_digest_async(priv, &op); - if (!ret) - goto clear; - } + + if (!ret) + goto sync_err; memcpy(digest, priv->req.out, priv->req.out_bytes); return UADK_DIGEST_SUCCESS; @@ -706,8 +696,8 @@ sync_err: ret = UADK_DIGEST_FAIL; UADK_ERR("do sec digest final failed.\n"); } -clear: async_clear_async_event_notification(); + return ret; } diff --git a/src/uadk_prov_hmac.c b/src/uadk_prov_hmac.c index 96da4eb..5a88fe4 100644 --- a/src/uadk_prov_hmac.c +++ b/src/uadk_prov_hmac.c @@ -578,11 +578,6 @@ static int uadk_do_hmac_async(struct hmac_priv_ctx *priv, struct async_op *op) int idx, ret; int cnt = 0; - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - UADK_ERR("soft switching is not supported in asynchronous mode.\n"); - return UADK_P_FAIL; - } - cb_param.op = op; cb_param.priv = &priv->req; priv->req.cb = (void *)uadk_hmac_async_cb; @@ -750,13 +745,16 @@ static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) return UADK_P_FAIL; } - /* It dose not need to be initialized again if the software calculation is applied. */ - if (priv->switch_flag != UADK_DO_SOFT) { - ret = uadk_hmac_ctx_init(priv); - if (!ret) - return UADK_P_FAIL; + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { + ret = uadk_hmac_soft_final(priv, digest); + hmac_soft_cleanup(priv); + return ret; } + ret = uadk_hmac_ctx_init(priv); + if (!ret) + return UADK_P_FAIL; + priv->req.in = priv->data; priv->req.out = priv->state == SEC_DIGEST_INIT ? digest : priv->out; priv->req.in_bytes = priv->last_update_bufflen; @@ -770,23 +768,13 @@ static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) return UADK_P_FAIL; } - if (!op.job) { - /* Synchronous, only the synchronous mode supports soft computing */ - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - ret = uadk_hmac_soft_final(priv, digest); - hmac_soft_cleanup(priv); - goto clear; - } - + if (!op.job) ret = uadk_do_hmac_sync(priv); - if (!ret) - goto do_hmac_err; - } else { + else ret = uadk_do_hmac_async(priv, &op); - if (!ret) - goto clear; - } + if (!ret) + goto do_hmac_err; if (priv->state != SEC_DIGEST_INIT) memcpy(digest, priv->req.out, priv->req.out_bytes); @@ -801,8 +789,8 @@ do_hmac_err: ret = UADK_P_FAIL; UADK_ERR("do sec digest final failed.\n"); } -clear: async_clear_async_event_notification(); + return ret; } -- 2.43.0
From: Zhushuai Yin <yinzhushuai@huawei.com> Currently, when the input size of the AEAD algorithm is 0 or greater than 65535, the software algorithm is used only in synchronous mode. In asynchronous mode, the algorithm fails to be switched to the software algorithm. This modification supports asynchronous switching to the software algorithm. Signed-off-by: Zhushuai Yin <yinzhushuai@huawei.com> --- src/uadk_prov_aead.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c index efaf447..26eeb66 100644 --- a/src/uadk_prov_aead.c +++ b/src/uadk_prov_aead.c @@ -574,13 +574,8 @@ static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char { int ret; - if (inlen > MAX_AAD_LEN) { - if (priv->mode != ASYNC_MODE) - goto soft; - - UADK_ERR("the aad len is out of range, aad len = %zu.\n", inlen); - return UADK_AEAD_FAIL; - } + if (inlen > MAX_AAD_LEN || !inlen) + goto soft; priv->req.assoc_bytes = inlen; @@ -590,9 +585,6 @@ static int uadk_prov_do_aes_gcm_first(struct aead_priv_ctx *priv, unsigned char return UADK_AEAD_SUCCESS; } - if (!priv->req.assoc_bytes) - goto soft; - ret = uadk_do_aead_sync_inner(priv, out, in, inlen, AEAD_MSG_FIRST); if (unlikely(ret < 0)) goto soft; @@ -858,9 +850,6 @@ static int uadk_prov_aead_init(struct aead_priv_ctx *priv, const unsigned char * ret = uadk_prov_aead_dev_init(priv); if (unlikely(ret < 0)) { - if (ASYNC_get_current_job()) - return UADK_OSSL_FAIL; - UADK_ERR("aead switch to soft init.!\n"); return uadk_prov_aead_soft_init(priv, key, iv, params); } -- 2.43.0
From: lizhi <lizhi206@huawei.com> Add RSA input length validation to ensure input data size is less than modulus. Remove unsupported RSA-PSS padding mode in encryption/decryption scenarios. Signed-off-by: lizhi <lizhi206@huawei.com> --- src/uadk_prov_rsa.c | 46 +++++++++++++++++++++-- src/uadk_prov_rsa.h | 4 +- src/uadk_prov_rsa_enc.c | 25 ++++++++----- src/uadk_prov_rsa_kmgmt.c | 2 +- src/uadk_prov_rsa_sign.c | 14 ++++++- src/uadk_rsa.c | 78 +++++++++++++++++++++++++++++++++------ 6 files changed, 141 insertions(+), 28 deletions(-) diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c index 4fe415f..386f7b5 100644 --- a/src/uadk_prov_rsa.c +++ b/src/uadk_prov_rsa.c @@ -401,12 +401,10 @@ int uadk_rsa_size(const RSA *r) return BN_num_bytes(r->n); } -int rsa_check_bit_useful(const int bits, int flen) +int rsa_check_bit_useful(const int bits) { if (bits < RSA_MIN_MODULUS_BITS) return UADK_P_FAIL; - if (flen > (bits >> BIT_BYTES_SHIFT)) - return UADK_DO_SOFT; switch (bits) { case RSA1024BITS: @@ -423,6 +421,46 @@ int rsa_check_bit_useful(const int bits, int flen) } } +int is_valid_rsa_pub_key(const RSA *rsa) +{ + const BIGNUM *n; + const BIGNUM *e; + + RSA_get0_key(rsa, &n, &e, NULL); + if (BN_ucmp(n, e) <= 0) { + UADK_ERR("invalid: e is a bad value\n"); + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; +} + +int is_valid_rsa_input(const unsigned char *in, int inlen, const RSA *rsa) +{ + int ret = UADK_P_SUCCESS; + const BIGNUM *n; + BIGNUM *f; + int n_len; + + RSA_get0_key(rsa, &n, NULL, NULL); + n_len = BN_num_bytes(n); + if (inlen < n_len) + return UADK_P_SUCCESS; + if (inlen > n_len) { + UADK_ERR("data too large for rsa modulus\n"); + return UADK_P_FAIL; + } + + f = BN_bin2bn(in, inlen, NULL); + if (f == NULL || BN_ucmp(f, n) >= 0) { + UADK_ERR("data too large for rsa modulus\n"); + ret = UADK_P_FAIL; + } + + BN_free(f); + return ret; +} + int check_rsa_input_para(const int flen, const unsigned char *from, unsigned char *to, RSA *rsa) { @@ -431,7 +469,7 @@ int check_rsa_input_para(const int flen, const unsigned char *from, return UADK_P_FAIL; } - return rsa_check_bit_useful(uadk_rsa_bits(rsa), flen); + return rsa_check_bit_useful(uadk_rsa_bits(rsa)); } int rsa_pkey_param_alloc(struct rsa_pubkey_param **pub, diff --git a/src/uadk_prov_rsa.h b/src/uadk_prov_rsa.h index 279f64a..4d2b00a 100644 --- a/src/uadk_prov_rsa.h +++ b/src/uadk_prov_rsa.h @@ -162,7 +162,9 @@ struct uadk_rsa_sess *rsa_get_eng_session(RSA *rsa, unsigned int bits, int rsa_do_crypto(struct uadk_rsa_sess *rsa_sess); int uadk_rsa_bits(const RSA *r); int uadk_rsa_size(const RSA *r); -int rsa_check_bit_useful(const int bits, int flen); +int rsa_check_bit_useful(const int bits); +int is_valid_rsa_input(const unsigned char *in, int inlen, const RSA *rsa); +int is_valid_rsa_pub_key(const RSA *rsa); int check_rsa_input_para(const int flen, const unsigned char *from, unsigned char *to, RSA *rsa); int rsa_pkey_param_alloc(struct rsa_pubkey_param **pub, diff --git a/src/uadk_prov_rsa_enc.c b/src/uadk_prov_rsa_enc.c index aa36420..c0da4c9 100644 --- a/src/uadk_prov_rsa_enc.c +++ b/src/uadk_prov_rsa_enc.c @@ -220,6 +220,10 @@ static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, if (ret != UADK_P_SUCCESS) return ret; + ret = is_valid_rsa_pub_key(rsa); + if (!ret) + return UADK_P_FAIL; + ret = rsa_pkey_param_alloc(&pub_enc, NULL); if (ret == -ENOMEM) return UADK_P_FAIL; @@ -239,16 +243,16 @@ static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, } ret = add_rsa_pubenc_padding(flen, from, from_buf, num_bytes, padding); - if (!ret) { - ret = UADK_P_FAIL; + if (!ret) + goto free_buf; + + ret = is_valid_rsa_input(from_buf, num_bytes, rsa); + if (!ret) goto free_buf; - } ret = rsa_fill_pubkey(pub_enc, rsa_sess, from_buf, to); - if (!ret) { - ret = UADK_P_FAIL; + if (!ret) goto free_buf; - } ret = rsa_do_crypto(rsa_sess); if (!ret || rsa_sess->req.status) { @@ -279,6 +283,10 @@ static int uadk_prov_rsa_private_decrypt(int flen, const unsigned char *from, if (ret != UADK_P_SUCCESS) return ret; + ret = is_valid_rsa_input(from, flen, rsa); + if (!ret) + return UADK_P_FAIL; + ret = rsa_pkey_param_alloc(NULL, &pri); if (ret == -ENOMEM) return UADK_P_FAIL; @@ -350,9 +358,6 @@ static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, case RSA_FLAG_TYPE_RSA: priv->pad_mode = RSA_PKCS1_PADDING; break; - case RSA_FLAG_TYPE_RSASSAPSS: - priv->pad_mode = RSA_PKCS1_PSS_PADDING; - break; default: UADK_ERR("rsa asym operation not supported this keytype!\n"); return UADK_P_FAIL; @@ -361,7 +366,7 @@ static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, if (uadk_prov_rsa_init()) priv->soft = 1; - return UADK_P_SUCCESS; + return uadk_asym_cipher_rsa_set_ctx_params(vprsactx, params); } static void *uadk_asym_cipher_rsa_newctx(void *provctx) diff --git a/src/uadk_prov_rsa_kmgmt.c b/src/uadk_prov_rsa_kmgmt.c index fe87493..3e5b0bf 100644 --- a/src/uadk_prov_rsa_kmgmt.c +++ b/src/uadk_prov_rsa_kmgmt.c @@ -732,7 +732,7 @@ static int uadk_prov_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) int is_crt = 1; int ret; - ret = rsa_check_bit_useful(bits, 0); + ret = rsa_check_bit_useful(bits); if (ret != UADK_P_SUCCESS) return ret; diff --git a/src/uadk_prov_rsa_sign.c b/src/uadk_prov_rsa_sign.c index 8278610..e2b7073 100644 --- a/src/uadk_prov_rsa_sign.c +++ b/src/uadk_prov_rsa_sign.c @@ -293,6 +293,10 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, goto free_buf; } + ret = is_valid_rsa_input(from_buf, num_bytes, rsa); + if (!ret) + return UADK_P_FAIL; + ret = rsa_fill_prikey(rsa, rsa_sess, prik, from_buf, to); if (!ret) { ret = UADK_P_FAIL; @@ -353,6 +357,14 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, if (ret != UADK_P_SUCCESS) return ret; + ret = is_valid_rsa_pub_key(rsa); + if (!ret) + return UADK_P_FAIL; + + ret = is_valid_rsa_input(from, flen, rsa); + if (!ret) + return UADK_P_FAIL; + ret = rsa_pkey_param_alloc(&pub, NULL); if (ret == -ENOMEM) return UADK_P_FAIL; @@ -366,7 +378,7 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, } ret = rsa_create_pub_bn_ctx(rsa, pub, &from_buf, &num_bytes); - if (ret <= 0 || flen > num_bytes) { + if (ret <= 0) { ret = UADK_P_FAIL; goto free_sess; } diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c index 11663d8..8aa4757 100644 --- a/src/uadk_rsa.c +++ b/src/uadk_rsa.c @@ -151,11 +151,8 @@ enum { static int uadk_e_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); -static int rsa_check_bit_useful(const int bits, int flen) +static int rsa_check_bit_useful(const int bits) { - if (flen > bits) - return SOFT; - if (bits < RSA_MIN_MODULUS_BITS) return UADK_E_FAIL; @@ -174,6 +171,46 @@ static int rsa_check_bit_useful(const int bits, int flen) } } +static int is_valid_rsa_pub_key(const RSA *rsa) +{ + const BIGNUM *n; + const BIGNUM *e; + + RSA_get0_key(rsa, &n, &e, NULL); + if (BN_ucmp(n, e) <= 0) { + fprintf(stderr, "invalid: e is a bad value\n"); + return UADK_E_FAIL; + } + + return UADK_E_SUCCESS; +} + +static int is_valid_rsa_input(const unsigned char *in, int inlen, const RSA *rsa) +{ + int ret = UADK_E_SUCCESS; + const BIGNUM *n; + BIGNUM *f; + int n_len; + + RSA_get0_key(rsa, &n, NULL, NULL); + n_len = BN_num_bytes(n); + if (inlen < n_len) + return UADK_E_SUCCESS; + if (inlen > n_len) { + fprintf(stderr, "data too large for rsa modulus\n"); + return UADK_E_FAIL; + } + + f = BN_bin2bn(in, inlen, NULL); + if (f == NULL || BN_ucmp(f, n) >= 0) { + fprintf(stderr, "data too large for rsa modulus\n"); + ret = UADK_E_FAIL; + } + + BN_free(f); + return ret; +} + static int rsa_prime_mul_res(int num, struct rsa_prime_param *param, BN_CTX *ctx, BN_GENCB *cb) { @@ -629,7 +666,7 @@ static int check_rsa_input_para(const int flen, const unsigned char *from, return UADK_E_FAIL; } - return rsa_check_bit_useful(RSA_bits(rsa), flen); + return rsa_check_bit_useful(RSA_bits(rsa)); } static BN_ULONG *bn_get_words(const BIGNUM *a) @@ -1462,7 +1499,7 @@ static int uadk_e_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) int is_crt = 1; int ret; - ret = rsa_check_bit_useful(bits, 0); + ret = rsa_check_bit_useful(bits); if (!ret) return UADK_E_FAIL; else if (ret == SOFT) @@ -1538,6 +1575,10 @@ static int uadk_e_rsa_public_encrypt(int flen, const unsigned char *from, else if (ret == SOFT) goto soft_log; + ret = is_valid_rsa_pub_key(rsa); + if (!ret) + return UADK_E_FAIL; + ret = uadk_e_rsa_init(); if (ret != UADK_INIT_SUCCESS) goto exe_soft; @@ -1571,6 +1612,10 @@ static int uadk_e_rsa_public_encrypt(int flen, const unsigned char *from, goto free_buf; } + ret = is_valid_rsa_input(from_buf, num_bytes, rsa); + if (!ret) + goto free_buf; + ret = rsa_fill_pubkey(pub_enc, rsa_sess, from_buf, to); if (!ret) { ret = UADK_DO_SOFT; @@ -1626,6 +1671,10 @@ static int uadk_e_rsa_private_decrypt(int flen, const unsigned char *from, else if (ret == SOFT) goto soft_log; + ret = is_valid_rsa_input(from, flen, rsa); + if (!ret) + return UADK_E_FAIL; + ret = uadk_e_rsa_init(); if (ret != UADK_INIT_SUCCESS) goto exe_soft; @@ -1741,6 +1790,10 @@ static int uadk_e_rsa_private_sign(int flen, const unsigned char *from, goto free_buf; } + ret = is_valid_rsa_input(from_buf, num_bytes, rsa); + if (!ret) + goto free_buf; + ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); if (!ret) { ret = UADK_DO_SOFT; @@ -1808,6 +1861,14 @@ static int uadk_e_rsa_public_verify(int flen, const unsigned char *from, else if (ret == SOFT) goto soft_log; + ret = is_valid_rsa_pub_key(rsa); + if (!ret) + return UADK_E_FAIL; + + ret = is_valid_rsa_input(from, flen, rsa); + if (!ret) + return UADK_E_FAIL; + ret = uadk_e_rsa_init(); if (ret != UADK_INIT_SUCCESS) goto exe_soft; @@ -1830,11 +1891,6 @@ static int uadk_e_rsa_public_verify(int flen, const unsigned char *from, goto free_sess; } - if (flen > num_bytes) { - ret = UADK_DO_SOFT; - goto free_buf; - } - ret = rsa_fill_pubkey(pub, rsa_sess, from_buf, to); if (!ret) { ret = UADK_DO_SOFT; -- 2.43.0
participants (1)
-
ZongYu Wu