This patch set contains some tiny bugfix and cleanup of ecc/rsa/cipher.
Wenkai Lin (1): cipher: code clean for update iv and check length
Zhiqi Song (4): rsa: fix wrong input parameters cipher: fix unused input parameter uadk_engine: bugfix null dereference in abnormal conditions ecc: bugfix potential null dereference problems
Fix the problem that when the third input parameter of BN_GENCB_call() is a pointer, for example '*n' , and the value of the pointer need to be increased after using it, '(*n)++' should be used, rather than '*n++'.
As the value of the pointer will be changed, the type of this pointer should not be 'const int *', so change its type to 'int * const'. And the parameter of functions should not be used as working variable, so increase the value of the pointer out of the BN_GENCB_call().
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_rsa.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c index e7ab9ff..229306e 100644 --- a/src/uadk_rsa.c +++ b/src/uadk_rsa.c @@ -187,7 +187,7 @@ static int rsa_prime_mul_res(int num, struct rsa_prime_param *param, }
static int check_rsa_prime_sufficient(int *num, const int *bitsr, - int *bitse, const int *n, + int *bitse, int * const n, struct rsa_prime_param *param, BN_CTX *ctx, BN_GENCB *cb) { @@ -230,7 +230,8 @@ static int check_rsa_prime_sufficient(int *num, const int *bitsr, else return -1;
- ret = BN_GENCB_call(cb, GENCB_NEXT, *n++); + ret = BN_GENCB_call(cb, GENCB_NEXT, *n); + (*n)++; if (!ret) return -1;
@@ -287,13 +288,14 @@ static int check_rsa_prime_equal(int num, BIGNUM *rsa_p, BIGNUM *rsa_q, return UADK_E_SUCCESS; }
-static int check_rsa_prime_useful(const int *n, struct rsa_prime_param *param, +static int check_rsa_prime_useful(int * const n, struct rsa_prime_param *param, BIGNUM *e_pub, BN_CTX *ctx, BN_GENCB *cb) { unsigned long err; + int ret;
/* - * BN_sub(r,a,b) substracts b from a and place the result in r, + * BN_sub(r, a, b) substracts b from a and place the result in r, * r = a-b. * BN_value_one() returns a BIGNUM constant of value 1. * r2 = prime - 1. @@ -303,16 +305,15 @@ static int check_rsa_prime_useful(const int *n, struct rsa_prime_param *param, ERR_set_mark(); BN_set_flags(param->r2, BN_FLG_CONSTTIME); /* - * BN_mod_inverse(r,a,n,ctx) used to compute inverse modulo n. + * BN_mod_inverse(r, a, n, ctx) used to compute inverse modulo n. * Precisely, it computes the inverse of "a" modulo "n", and places - * the result in "r", which means (a * r) % n==1. + * the result in "r", which means (a * r) % n == 1. * If r == NULL, error. If r != NULL, success. - * The expected result: (r2 * r1) % e_pub ==1, + * The expected result: (r2 * r1) % e_pub == 1, * the inverse of r2 exist, that is r1. */ if (BN_mod_inverse(param->r1, param->r2, e_pub, ctx)) return UADK_E_SUCCESS; - err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_INVERSE) @@ -320,13 +321,15 @@ static int check_rsa_prime_useful(const int *n, struct rsa_prime_param *param, else return BN_ERR;
- if (!BN_GENCB_call(cb, GENCB_NEXT, *n++)) + ret = BN_GENCB_call(cb, GENCB_NEXT, *n); + (*n)++; + if (!ret) return BN_ERR;
return GET_ERR_FINISH; }
-static int get_rsa_prime_once(int num, const int *bitsr, const int *n, +static int get_rsa_prime_once(int num, const int *bitsr, int * const n, BIGNUM *e_pub, struct rsa_prime_param *param, BN_CTX *ctx, BN_GENCB *cb) {
Use input parameter 'alg_name' to indicate the device, rather than a fixed string.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_cipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c index c71e54c..ee9363e 100644 --- a/src/uadk_cipher.c +++ b/src/uadk_cipher.c @@ -337,7 +337,7 @@ static int uadk_get_accel_platform(char *alg_name) { struct uacce_dev *dev;
- dev = wd_get_accel_dev("cipher"); + dev = wd_get_accel_dev(alg_name); if (dev == NULL) return 0;
From: Wenkai Lin linwenkai6@hisilicon.com
Reduces some counting and branching judgments.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com --- src/uadk_cipher.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c index ee9363e..5242428 100644 --- a/src/uadk_cipher.c +++ b/src/uadk_cipher.c @@ -63,7 +63,7 @@ struct cipher_priv_ctx { void *sw_ctx_data; /* Crypto small packet offload threshold */ size_t switch_threshold; - int update_iv; + bool update_iv; };
struct cipher_info { @@ -316,12 +316,6 @@ static int uadk_e_cipher_soft_work(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; }
-static int sec_ciphers_is_check_valid(struct cipher_priv_ctx *priv) -{ - return priv->req.in_bytes <= priv->switch_threshold ? - 0 : 1; -} - static void uadk_e_cipher_sw_cleanup(EVP_CIPHER_CTX *ctx) { struct cipher_priv_ctx *priv = @@ -770,13 +764,12 @@ static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) int i;
switch (priv->setup.mode) { + case WD_CIPHER_CFB: case WD_CIPHER_CBC: if (priv->req.op_type == WD_CIPHER_ENCRYPTION) - memcpy(priv->iv, priv->req.dst + priv->req.in_bytes - iv_bytes, - iv_bytes); + memcpy(priv->iv, priv->req.dst + offset, iv_bytes); else - memcpy(priv->iv, priv->req.src + priv->req.in_bytes - iv_bytes, - iv_bytes); + memcpy(priv->iv, priv->req.src + offset, iv_bytes);
break; case WD_CIPHER_OFB: @@ -785,15 +778,6 @@ static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) *((unsigned char *)priv->req.dst + offset + i); } memcpy(priv->iv, K, iv_bytes); - break; - case WD_CIPHER_CFB: - if (priv->req.op_type == WD_CIPHER_ENCRYPTION) - memcpy(priv->iv, priv->req.dst + priv->req.in_bytes - iv_bytes, - iv_bytes); - else - memcpy(priv->iv, priv->req.src + priv->req.in_bytes - iv_bytes, - iv_bytes); - break; case WD_CIPHER_CTR: ctr_iv_inc(priv->iv, priv->req.in_bytes >> CTR_MODE_LEN_SHIFT); @@ -810,8 +794,7 @@ static int do_cipher_sync(struct cipher_priv_ctx *priv) if (unlikely(priv->switch_flag == UADK_DO_SOFT)) return 0;
- ret = sec_ciphers_is_check_valid(priv); - if (!ret) + if (priv->switch_threshold >= priv->req.in_bytes) return 0;
ret = wd_do_cipher_sync(priv->sess, &priv->req);
Add judgment to prevent null dereference in abnormal conditions.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_ec.c | 13 +++++++++++++ src/uadk_rsa.c | 18 ++++++++++++++++++ src/uadk_sm2.c | 15 +++++++++++++++ 3 files changed, 46 insertions(+)
diff --git a/src/uadk_ec.c b/src/uadk_ec.c index e341f5b..0a8bae0 100644 --- a/src/uadk_ec.c +++ b/src/uadk_ec.c @@ -453,6 +453,11 @@ static ECDSA_SIG *create_ecdsa_sig(struct wd_ecc_req *req) }
wd_ecdsa_get_sign_out_params(req->dst, &r, &s); + if (!r || !s) { + fprintf(stderr, "failed to get r or s\n"); + goto err; + } + if (!BN_bin2bn((void *)r->data, r->dsize, br) || !BN_bin2bn((void *)s->data, s->dsize, bs)) { fprintf(stderr, "failed to BN_bin2bn r or s\n"); @@ -1069,6 +1074,10 @@ static int ecdh_set_key_to_ec_key(EC_KEY *ecdh, struct wd_ecc_req *req) int ret = 0;
wd_ecxdh_get_out_params(req->dst, &pubkey); + if (!pubkey) { + fprintf(stderr, "failed to get pubkey\n"); + return ret; + }
group = EC_KEY_get0_group(ecdh); point = EC_POINT_new(group); @@ -1134,6 +1143,10 @@ static int ecdh_get_shared_key(const EC_KEY *ecdh, struct wd_ecc_point *shared_key = NULL;
wd_ecxdh_get_out_params(req->dst, &shared_key); + if (!shared_key) { + fprintf(stderr, "failed to get shared key\n"); + return 0; + }
*outlen = shared_key->x.dsize;
diff --git a/src/uadk_rsa.c b/src/uadk_rsa.c index 229306e..857fd79 100644 --- a/src/uadk_rsa.c +++ b/src/uadk_rsa.c @@ -912,7 +912,13 @@ static int rsa_fill_pubkey(struct rsa_pubkey_param *pubkey_param,
if (!rsa_sess->is_pubkey_ready) { wd_rsa_get_pubkey(rsa_sess->sess, &pubkey); + if (!pubkey) + return UADK_E_FAIL; + wd_rsa_get_pubkey_params(pubkey, &wd_e, &wd_n); + if (!wd_e || !wd_n) + return UADK_E_FAIL; + wd_e->dsize = BN_bn2bin(pubkey_param->e, (unsigned char *)wd_e->data); wd_n->dsize = BN_bn2bin(pubkey_param->n, @@ -945,8 +951,14 @@ static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess,
if (!(rsa_sess->is_prikey_ready) && (pri->is_crt)) { wd_rsa_get_prikey(rsa_sess->sess, &prikey); + if (!prikey) + return UADK_E_FAIL; + wd_rsa_get_crt_prikey_params(prikey, &wd_dq, &wd_dp, &wd_qinv, &wd_q, &wd_p); + if (!wd_dq || !wd_dp || !wd_qinv || !wd_q || !wd_p) + return UADK_E_FAIL; + wd_dq->dsize = BN_bn2bin(pri->dmq1, (unsigned char *)wd_dq->data); wd_dp->dsize = BN_bn2bin(pri->dmp1, @@ -959,7 +971,13 @@ static int rsa_fill_prikey(RSA *rsa, struct uadk_rsa_sess *rsa_sess, (unsigned char *)wd_qinv->data); } else if (!(rsa_sess->is_prikey_ready) && !(pri->is_crt)) { wd_rsa_get_prikey(rsa_sess->sess, &prikey); + if (!prikey) + return UADK_E_FAIL; + wd_rsa_get_prikey_params(prikey, &wd_d, &wd_n); + if (!wd_d || !wd_n) + return UADK_E_FAIL; + wd_d->dsize = BN_bn2bin(pri->d, (unsigned char *)wd_d->data); wd_n->dsize = BN_bn2bin(pri->n, diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c index af26690..0173a43 100644 --- a/src/uadk_sm2.c +++ b/src/uadk_sm2.c @@ -710,6 +710,11 @@ static int sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, }
wd_sm2_get_sign_out_params(req.dst, &r, &s); + if (!r || !s) { + ret = UADK_DO_SOFT; + goto uninit_iot; + } + ret = sign_bin_to_ber(NULL, r, s, sig, siglen); if (ret) goto uninit_iot; @@ -939,6 +944,11 @@ static int sm2_encrypt(EVP_PKEY_CTX *ctx,
md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; wd_sm2_get_enc_out_params(req.dst, &c1, &c2, &c3); + if (!c1 || !c2 || !c3) { + ret = UADK_DO_SOFT; + goto uninit_iot; + } + ret = cipher_bin_to_ber(md, c1, c2, c3, out, outlen); if (ret) goto uninit_iot; @@ -1029,6 +1039,11 @@ static int sm2_get_plaintext(struct wd_ecc_req *req, struct wd_dtb *ptext = NULL;
wd_sm2_get_dec_out_params(req->dst, &ptext); + if (!ptext) { + fprintf(stderr, "failed to get ptext\n"); + return -EINVAL; + } + if (*outlen < ptext->dsize) { fprintf(stderr, "outlen(%lu) < (%u)\n", *outlen, ptext->dsize); return -EINVAL;
Add judgment to prevent null dereference in abnormal conditions.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_ec.c | 4 ++++ src/uadk_ecx.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/uadk_ec.c b/src/uadk_ec.c index 0a8bae0..9e99195 100644 --- a/src/uadk_ec.c +++ b/src/uadk_ec.c @@ -760,6 +760,10 @@ static int set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) int ret;
wd_sm2_get_kg_out_params(req->dst, &privkey, &pubkey); + if (!privkey || !pubkey) { + fprintf(stderr, "failed to get privkey or pubkey\n"); + return -EINVAL; + }
tmp = BN_bin2bn((unsigned char *)privkey->data, privkey->dsize, NULL); ret = EC_KEY_set_private_key(ec, tmp); diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c index e6edbc3..e365fd2 100644 --- a/src/uadk_ecx.c +++ b/src/uadk_ecx.c @@ -287,12 +287,17 @@ static int ecx_keygen_set_pkey(EVP_PKEY *pkey, struct ecx_ctx *ecx_ctx, int key_size = ecx_ctx->key_size; int ret;
- wd_ecxdh_get_out_params(req->dst, &pubkey); if (key_size > ECX_MAX_KEYLEN) { fprintf(stderr, "invalid key size, key_size = %d\n", key_size); return UADK_E_FAIL; }
+ wd_ecxdh_get_out_params(req->dst, &pubkey); + if (!pubkey) { + fprintf(stderr, "failed to get pubkey\n"); + return UADK_E_FAIL; + } + memcpy(ecx_key->pubkey, (const unsigned char *)pubkey->x.data, key_size); /* Trans public key from big-endian to little-endian */