
If there is no available instance, the sm2_init() will failed, the setting of sched_init() will failed, so sched_init() will be NULL. If the sm2_ctrl() function still call the sm2_update_sess() in this situation, and make wd_ecc_alloc_sess() to call sched_init(), there will be a segfault. The solution is to modify the status field of sm2_ctx, make the variable 'init_status' to indicate the status of init operation: 'CTX_UNINIT' indicates the init operation has not been performed, 'CTX_INIT_SUCC' indicates the init operation has been succeeded, 'CTX_INIT_FAIL' indicates the init operation has been failed. The sm2_update_sess() will only be called if the 'init_status' is 'CTX_INIT_SUCC'. Then there will be no segfault. And when there is no available instance, it should switch to openssl software method, so modify some return values to help finish this process. Signed-off-by: Zhiqi Song <songzhiqi1@huawei.com> --- src/uadk_sm2.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/uadk_sm2.c b/src/uadk_sm2.c index 1ef6032..3ecce6b 100644 --- a/src/uadk_sm2.c +++ b/src/uadk_sm2.c @@ -25,6 +25,12 @@ #include "uadk.h" #include "uadk_pkey.h" +enum { + CTX_INIT_FAIL = -1, + CTX_UNINIT, + CTX_INIT_SUCC +}; + typedef struct { /* Key and paramgen group */ EC_GROUP *gen_group; @@ -43,7 +49,7 @@ struct sm2_ctx { const BIGNUM *prikey; const EC_POINT *pubkey; BIGNUM *order; - bool is_init; + int init_status; }; typedef struct sm2_ciphertext { @@ -165,6 +171,7 @@ static int sm2_update_sess(struct sm2_ctx *smctx) memset(&setup, 0, sizeof(setup)); setup.alg = "sm2"; + if (smctx->ctx.md) { setup.hash.cb = compute_hash; setup.hash.usr = (void *)smctx->ctx.md; @@ -189,6 +196,7 @@ static int sm2_update_sess(struct sm2_ctx *smctx) if (smctx->sess) wd_ecc_free_sess(smctx->sess); + smctx->sess = sess; smctx->prikey = NULL; smctx->pubkey = NULL; @@ -636,7 +644,7 @@ static int sm2_sign_check(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, if (!smctx || !smctx->sess) { fprintf(stderr, "smctx or sess NULL\n"); - return -EINVAL; + return UADK_DO_SOFT; } if (sig_sz <= 0) { @@ -676,7 +684,7 @@ static int sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, if (ret) goto do_soft; - if (!smctx->is_init) { + if (smctx->init_status != CTX_INIT_SUCC) { ret = UADK_DO_SOFT; goto do_soft; } @@ -744,6 +752,13 @@ static int sm2_verify_check(EVP_PKEY_CTX *ctx, const unsigned char *tbs, size_t tbslen) { + struct sm2_ctx *smctx = EVP_PKEY_CTX_get_data(ctx); + + if (!smctx || !smctx->sess) { + fprintf(stderr, "smctx or sess NULL\n"); + return UADK_DO_SOFT; + } + if (tbslen > SM2_KEY_BYTES) return UADK_DO_SOFT; @@ -772,7 +787,7 @@ static int sm2_verify(EVP_PKEY_CTX *ctx, if (ret) goto do_soft; - if (!smctx->is_init) { + if (smctx->init_status != CTX_INIT_SUCC) { ret = UADK_DO_SOFT; goto do_soft; } @@ -853,7 +868,7 @@ static int sm2_encrypt_check(EVP_PKEY_CTX *ctx, if (!smctx || !smctx->sess) { fprintf(stderr, "smctx or sess NULL\n"); - return 0; + return UADK_DO_SOFT; } md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; @@ -897,7 +912,7 @@ static int sm2_encrypt(EVP_PKEY_CTX *ctx, if (ret) goto do_soft; - if (!smctx->is_init) { + if (smctx->init_status != CTX_INIT_SUCC) { ret = UADK_DO_SOFT; goto do_soft; } @@ -953,7 +968,7 @@ static int sm2_decrypt_check(EVP_PKEY_CTX *ctx, if (!smctx || !smctx->sess) { fprintf(stderr, "smctx or sess NULL\n"); - return -EINVAL; + return UADK_DO_SOFT; } md = (smctx->ctx.md == NULL) ? EVP_sm3() : smctx->ctx.md; @@ -1038,7 +1053,7 @@ static int sm2_decrypt(EVP_PKEY_CTX *ctx, if (ret) goto do_soft; - if (!smctx->is_init) { + if (smctx->init_status != CTX_INIT_SUCC) { ret = UADK_DO_SOFT; goto do_soft; } @@ -1124,18 +1139,18 @@ static int sm2_init(EVP_PKEY_CTX *ctx) ret = uadk_init_ecc(); if (ret) { fprintf(stderr, "failed to uadk_init_ecc, ret = %d\n", ret); - smctx->is_init = false; + smctx->init_status = CTX_INIT_FAIL; goto end; } ret = sm2_update_sess(smctx); if (ret) { fprintf(stderr, "failed to update sess\n"); - smctx->is_init = false; + smctx->init_status = CTX_INIT_FAIL; goto end; } - smctx->is_init = true; + smctx->init_status = CTX_INIT_SUCC; end: EVP_PKEY_CTX_set_data(ctx, smctx); EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0); @@ -1196,8 +1211,13 @@ static int sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_MD: smctx->ctx.md = p2; - if (sm2_update_sess(smctx)) + if (smctx->init_status != CTX_INIT_SUCC) + return 1; + + if (sm2_update_sess(smctx)) { + fprintf(stderr, "failed to set MD\n"); return 0; + } return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = smctx->ctx.md; -- 2.30.0