The private key that allocated in dh_prepare_data() should be released in error handling branch. Fixed this problem and cleanup the related functions.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_dh.c | 82 ++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 43 deletions(-)
diff --git a/src/uadk_dh.c b/src/uadk_dh.c index c5ef813..fc91609 100644 --- a/src/uadk_dh.c +++ b/src/uadk_dh.c @@ -51,6 +51,7 @@ #define UADK_E_POLL_FAIL (-1) #define UADK_E_INIT_SUCCESS 0 #define ENV_ENABLED 1 +#define KEY_GEN_BY_ENGINE 1
static DH_METHOD *uadk_dh_method;
@@ -68,6 +69,8 @@ struct uadk_dh_sess { struct wd_dh_req req; DH *alg; __u16 key_size; + /* key_flag: 0 - key is defined by user, 1 - key is generated by engine */ + int key_flag; };
struct dh_res { @@ -162,30 +165,24 @@ static int dh_generate_new_priv_key(const DH *dh, BIGNUM *new_priv_key) return UADK_E_SUCCESS; }
-static int dh_try_get_priv_key(const DH *dh, BIGNUM **priv_key) +static int dh_try_get_priv_key(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **priv_key) { - int generate_new_key = 0; - BIGNUM *new_priv_key; - *priv_key = (BIGNUM *)DH_get0_priv_key(dh); if (!(*priv_key)) { - new_priv_key = BN_secure_new(); - if (!new_priv_key) - goto err; - generate_new_key = 1; - } + *priv_key = BN_secure_new(); + if (!(*priv_key)) + return UADK_E_FAIL;
- if (generate_new_key) { - if (!dh_generate_new_priv_key(dh, new_priv_key)) + if (!dh_generate_new_priv_key(dh, *priv_key)) goto err; - else - *priv_key = new_priv_key; + + dh_sess->key_flag = KEY_GEN_BY_ENGINE; }
return UADK_E_SUCCESS;
err: - BN_free(new_priv_key); + BN_free(*priv_key); return UADK_E_FAIL; }
@@ -526,13 +523,19 @@ static int check_dh_bit_useful(const __u16 bits) return UADK_E_FAIL; }
-static int dh_prepare_data(const __u16 bits, const BIGNUM *g, DH *dh, +static int dh_prepare_data(const BIGNUM *g, DH *dh, struct uadk_dh_sess **dh_sess, BIGNUM **priv_key) { bool is_g2 = BN_is_word(g, DH_GENERATOR_2); + __u16 bits; int ret;
+ /* + * The max module bits of DH is + * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. + */ + bits = (__u16)DH_bits(dh); ret = check_dh_bit_useful(bits); if (!ret) { fprintf(stderr, "op size is not supported by uadk engine\n"); @@ -545,8 +548,8 @@ static int dh_prepare_data(const __u16 bits, const BIGNUM *g, DH *dh, return UADK_E_FAIL; }
- ret = dh_try_get_priv_key(dh, priv_key); - if (!ret || !(*priv_key)) { + ret = dh_try_get_priv_key(*dh_sess, dh, priv_key); + if (!ret) { dh_free_eng_session(*dh_sess); return UADK_E_FAIL; } @@ -764,7 +767,6 @@ static int uadk_e_dh_generate_key(DH *dh) const BIGNUM *p = NULL; const BIGNUM *g = NULL; const BIGNUM *q = NULL; - __u16 bits; int ret;
if (!dh) @@ -778,14 +780,8 @@ static int uadk_e_dh_generate_key(DH *dh) if (!p || !g || q) goto exe_soft;
- /* - * The max module bits of DH is - * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. - */ - bits = (__u16)DH_bits(dh); - /* Get session and prepare private key */ - ret = dh_prepare_data(bits, g, dh, &dh_sess, &priv_key); + ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); if (!ret) { fprintf(stderr, "prepare dh data failed\n"); goto exe_soft; @@ -794,30 +790,30 @@ static int uadk_e_dh_generate_key(DH *dh) ret = dh_fill_genkey_req(g, p, priv_key, dh_sess); if (!ret) { fprintf(stderr, "failed to fill req\n"); - ret = UADK_DO_SOFT; - goto free_sess; + goto free_data; }
ret = dh_do_crypto(dh_sess); if (!ret) { fprintf(stderr, "failed to generate DH key\n"); - ret = UADK_DO_SOFT; - goto free_sess; + goto free_data; }
ret = dh_get_pubkey(dh_sess, &pub_key); if (!ret) { fprintf(stderr, "failed to get public key\n"); - ret = UADK_DO_SOFT; - goto free_sess; + goto free_data; }
ret = dh_soft_set_pkey(dh, pub_key, priv_key); + dh_free_eng_session(dh_sess);
-free_sess: + return ret; + +free_data: + if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) + BN_free(priv_key); dh_free_eng_session(dh_sess); - if (ret != UADK_DO_SOFT) - return ret; exe_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); return uadk_e_dh_soft_generate_key(dh); @@ -827,7 +823,6 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { struct uadk_dh_sess *dh_sess = NULL; - __u16 bits = (__u16)DH_bits(dh); BIGNUM *priv_key = NULL; const BIGNUM *p = NULL; const BIGNUM *g = NULL; @@ -845,7 +840,7 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, if (!p || !g) goto exe_soft;
- ret = dh_prepare_data(bits, g, dh, &dh_sess, &priv_key); + ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); if (!ret) { fprintf(stderr, "failed to prepare dh data\n"); goto exe_soft; @@ -854,24 +849,25 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, ret = dh_fill_compkey_req(g, p, priv_key, pub_key, dh_sess); if (!ret) { fprintf(stderr, "failed to fill req\n"); - ret = UADK_DO_SOFT; - goto free_sess; + goto free_data; }
ret = dh_do_crypto(dh_sess); if (!ret) { fprintf(stderr, "failed to generate DH shared key\n"); - ret = UADK_DO_SOFT; - goto free_sess; + goto free_data; }
memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); ret = dh_sess->req.pri_bytes; + dh_free_eng_session(dh_sess);
-free_sess: + return ret; + +free_data: + if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) + BN_free(priv_key); dh_free_eng_session(dh_sess); - if (ret != UADK_DO_SOFT) - return ret; exe_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); return uadk_e_dh_soft_compute_key(key, pub_key, dh);