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_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_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_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); } diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index d442d3d..2606c2f 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -488,11 +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; - - if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { - UADK_ERR("async cipher init failed.\n"); - return UADK_P_FAIL; - } + int cnt = 0; cb_param.op = op; cb_param.priv = &priv->req; @@ -506,18 +502,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) @@ -756,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_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..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; @@ -625,8 +620,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 +632,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) @@ -657,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; @@ -676,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; @@ -703,8 +696,8 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest 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_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_hmac.c b/src/uadk_prov_hmac.c index 0c53d12..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; @@ -596,16 +591,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) @@ -747,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; @@ -767,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); @@ -798,8 +789,8 @@ static int uadk_hmac_final(struct hmac_priv_ctx *priv, unsigned char *digest) ret = UADK_P_FAIL; UADK_ERR("do sec digest final failed.\n"); } -clear: async_clear_async_event_notification(); + return ret; } 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..386f7b5 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; + } + + if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { + UADK_ERR("do rsa async operation timeout\n"); + goto free_poll_task; } - } while (ret == -EBUSY); + } 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; @@ -391,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: @@ -413,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) { @@ -421,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 1286ae5..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; @@ -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 } }; 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_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); diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c index 318f8ed..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) @@ -1162,12 +1199,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; @@ -1459,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) @@ -1535,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; @@ -1568,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; @@ -1623,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; @@ -1738,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; @@ -1805,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; @@ -1827,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;