Release the engine DH/ECDH and provider DH/SM2 private keys with BN_clear_free instead of BN_free, and allocate the engine ECDH private key with BN_secure_new so the secret material is wiped. Also fix a memory leak in sm2_update_sess where the SM2 curve order was re-allocated on every call; reuse smctx->order across calls instead. Remove the erroneous BN_free on the DH-internal private key in the compute_key error path. Signed-off-by: Weili Qian <qianweili@huawei.com> --- src/uadk_dh.c | 4 +--- src/uadk_ec.c | 6 +++--- src/uadk_prov_dh.c | 4 ++-- src/uadk_prov_sm2_kmgmt.c | 2 +- src/uadk_sm2.c | 16 +++++++++++----- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/uadk_dh.c b/src/uadk_dh.c index fbb6dc9..be3b41c 100644 --- a/src/uadk_dh.c +++ b/src/uadk_dh.c @@ -183,7 +183,7 @@ static int dh_try_get_priv_key(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNU return UADK_E_SUCCESS; err: - BN_free(*priv_key); + BN_clear_free(*priv_key); return UADK_E_FAIL; } @@ -934,8 +934,6 @@ static int uadk_e_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, return ret; free_data: - if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) - BN_free(priv_key); dh_free_eng_session(dh_sess); soft_log: fprintf(stderr, "switch to execute openssl software calculation.\n"); diff --git a/src/uadk_ec.c b/src/uadk_ec.c index c7d50ac..d241e79 100644 --- a/src/uadk_ec.c +++ b/src/uadk_ec.c @@ -800,7 +800,7 @@ static int sm2_set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) return -EINVAL; } ret = EC_KEY_set_private_key(ec, tmp); - BN_free(tmp); + BN_clear_free(tmp); if (!ret) { fprintf(stderr, "failed to EC KEY set private key\n"); return -EINVAL; @@ -899,7 +899,7 @@ static int ecdh_set_private_key(EC_KEY *eckey, BIGNUM *order) BIGNUM *priv_key; int ret; - priv_key = BN_new(); + priv_key = BN_secure_new(); if (!priv_key) { fprintf(stderr, "failed to BN_new priv_key\n"); return 0; @@ -918,7 +918,7 @@ static int ecdh_set_private_key(EC_KEY *eckey, BIGNUM *order) fprintf(stderr, "failed to set private key\n"); free_priv_key: - BN_free(priv_key); + BN_clear_free(priv_key); return ret; } diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c index 3f49a6f..004b60e 100644 --- a/src/uadk_prov_dh.c +++ b/src/uadk_prov_dh.c @@ -581,7 +581,7 @@ static int uadk_prov_dh_prepare_prikey(struct uadk_dh_sess *dh_sess, const DH *d free_prikey: /* Free the prikey generated by uadk provider */ - BN_free(*prikey); + BN_clear_free(*prikey); *prikey = NULL; return UADK_P_FAIL; @@ -594,7 +594,7 @@ static void uadk_prov_dh_free_prikey(struct uadk_dh_sess *dh_sess, BIGNUM *prike /* User generated key will be freed by user, not uadk provider */ if (prikey && dh_sess->key_flag == KEY_GEN_BY_PROV) - BN_free(prikey); + BN_clear_free(prikey); } static void uadk_prov_dh_cb(void *req_t) diff --git a/src/uadk_prov_sm2_kmgmt.c b/src/uadk_prov_sm2_kmgmt.c index 8f36dfa..0085251 100644 --- a/src/uadk_prov_sm2_kmgmt.c +++ b/src/uadk_prov_sm2_kmgmt.c @@ -342,7 +342,7 @@ static int uadk_prov_sm2_set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) return UADK_P_FAIL; } ret = EC_KEY_set_private_key(ec, bn_key); - BN_free(bn_key); + BN_clear_free(bn_key); if (ret == 0) { UADK_ERR("failed to EC KEY set private key\n"); return UADK_P_FAIL; diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c index 9eb9f7b..6472abc 100644 --- a/src/uadk_sm2.c +++ b/src/uadk_sm2.c @@ -183,7 +183,6 @@ static int sm2_update_sess(struct sm2_ctx *smctx) }; struct wd_ecc_sess_setup setup; handle_t sess; - BIGNUM *order; int type; memset(&setup, 0, sizeof(setup)); @@ -202,13 +201,21 @@ static int sm2_update_sess(struct sm2_ctx *smctx) setup.hash.type = type; } - order = BN_bin2bn((void *)sm2_order, sizeof(sm2_order), NULL); + /* order free in sm2_cleanup() */ + if (!smctx->order) { + smctx->order = BN_bin2bn((void *)sm2_order, sizeof(sm2_order), NULL); + if (!smctx->order) { + fprintf(stderr, "failed to alloc order\n"); + smctx->init_status = CTX_INIT_FAIL; + return -ENOMEM; + } + } + setup.rand.cb = uadk_ecc_get_rand; - setup.rand.usr = (void *)order; + setup.rand.usr = (void *)smctx->order; sess = wd_ecc_alloc_sess(&setup); if (!sess) { fprintf(stderr, "failed to alloc sess\n"); - BN_free(order); smctx->init_status = CTX_INIT_FAIL; return -EINVAL; } @@ -220,7 +227,6 @@ static int sm2_update_sess(struct sm2_ctx *smctx) smctx->prikey = NULL; smctx->pubkey = NULL; - smctx->order = order; return 0; } -- 2.53.0.windows.2