The data size of the sm2 pubkey may less than or equal to the buffer size of it. So use the size offset to eliminate the difference when the data size is less than buffer size. This can avoid getting wrong pubkey value.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_ec.c | 20 +++++++++++++++----- src/uadk_pkey.h | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/uadk_ec.c b/src/uadk_ec.c index 33ffc26..69ad4e8 100644 --- a/src/uadk_ec.c +++ b/src/uadk_ec.c @@ -747,15 +747,15 @@ err: return ret; }
-static int set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) +static int sm2_set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) { - unsigned char buff[ECC_POINT_SIZE(SM2_KEY_BYTES) + 1] = {UADK_OCTET_STRING}; + unsigned char buff[ECC_POINT_SIZE(SM2_KEY_BYTES) + 1] = {0}; struct wd_ecc_point *pubkey = NULL; struct wd_dtb *privkey = NULL; + int x_offset, y_offset, ret; const EC_GROUP *group; EC_POINT *point, *ptr; BIGNUM *tmp; - int ret;
wd_sm2_get_kg_out_params(req->dst, &privkey, &pubkey); if (!privkey || !pubkey) { @@ -763,6 +763,11 @@ static int set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) return -EINVAL; }
+ if (pubkey->x.dsize > SM2_KEY_BYTES || pubkey->y.dsize > SM2_KEY_BYTES) { + fprintf(stderr, "invalid pubkey size: %u, %u\n", pubkey->x.dsize, pubkey->y.dsize); + return -EINVAL; + } + tmp = BN_bin2bn((unsigned char *)privkey->data, privkey->dsize, NULL); ret = EC_KEY_set_private_key(ec, tmp); BN_free(tmp); @@ -778,7 +783,12 @@ static int set_key_to_ec_key(EC_KEY *ec, struct wd_ecc_req *req) return -ENOMEM; }
- memcpy(buff + 1, pubkey->x.data, ECC_POINT_SIZE(SM2_KEY_BYTES)); + buff[0] = UADK_OCTET_STRING; + /* The component of sm2 pubkey need a SM2_KEY_BYTES align */ + x_offset = 1 + SM2_KEY_BYTES - pubkey->x.dsize; + y_offset = 1 + ECC_POINT_SIZE(SM2_KEY_BYTES) - pubkey->y.dsize; + memcpy(buff + x_offset, pubkey->x.data, pubkey->x.dsize); + memcpy(buff + y_offset, pubkey->y.data, pubkey->y.dsize); tmp = BN_bin2bn(buff, ECC_POINT_SIZE(SM2_KEY_BYTES) + 1, NULL); ptr = EC_POINT_bn2point(group, tmp, point, NULL); BN_free(tmp); @@ -972,7 +982,7 @@ static int sm2_generate_key(EC_KEY *eckey) if (!ret) goto uninit_iot;
- ret = set_key_to_ec_key(eckey, &req); + ret = sm2_set_key_to_ec_key(eckey, &req); if (ret) goto uninit_iot;
diff --git a/src/uadk_pkey.h b/src/uadk_pkey.h index d35bb37..b80e425 100644 --- a/src/uadk_pkey.h +++ b/src/uadk_pkey.h @@ -27,7 +27,7 @@ #define UADK_ECC_MAX_KEY_BYTES 66 #define UADK_ECC_CV_PARAM_NUM 6 #define SM2_KEY_BYTES 32 -#define UADK_OCTET_STRING 4 +#define UADK_OCTET_STRING 0x04 #define UADK_ECC_PUBKEY_PARAM_NUM 2 #define UADK_ECC_PADDING 7 #define UADK_ECDH_CV_NUM 8