* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "hitls_build.h"
#ifdef HITLS_CRYPTO_ECDSA
#include <stdbool.h>
#include "crypt_errno.h"
#include "crypt_types.h"
#include "crypt_utils.h"
#include "crypt_util_ctrl.h"
#include "bsl_err_internal.h"
#include "crypt_bn.h"
#include "crypt_encode.h"
#include "crypt_ecc.h"
#include "bsl_sal.h"
#include "crypt_ecc_pkey.h"
#include "eal_pkey_local.h"
#include "eal_md_local.h"
#include "crypt_ecdsa.h"
#include "bsl_params.h"
#include "crypt_params_key.h"
CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtx(void)
{
CRYPT_ECDSA_Ctx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_ECDSA_Ctx));
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
return NULL;
}
ctx->pointFormat = CRYPT_POINT_UNCOMPRESSED;
BSL_SAL_ReferencesInit(&(ctx->references));
ctx->signMdId = CRYPT_MD_MAX;
return ctx;
}
CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtxEx(void *libCtx)
{
CRYPT_ECDSA_Ctx *ctx = CRYPT_ECDSA_NewCtx();
if (ctx == NULL) {
return NULL;
}
ctx->libCtx = libCtx;
return ctx;
}
CRYPT_EcdsaPara *CRYPT_ECDSA_NewPara(const CRYPT_EccPara *eccPara)
{
CRYPT_PKEY_ParaId id = GetCurveId(eccPara);
if (id == CRYPT_PKEY_PARAID_MAX) {
BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA);
return NULL;
}
return CRYPT_ECDSA_NewParaById(id);
}
CRYPT_PKEY_ParaId CRYPT_ECDSA_GetParaId(const CRYPT_ECDSA_Ctx *ctx)
{
if (ctx == NULL) {
return CRYPT_PKEY_PARAID_MAX;
}
return ECC_GetParaId(ctx->para);
}
int32_t CRYPT_ECDSA_SetPara(CRYPT_ECDSA_Ctx *ctx, const CRYPT_EccPara *para)
{
if (ctx == NULL || para == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
return ECC_SetPara(ctx, CRYPT_ECDSA_NewPara(para));
}
int32_t CRYPT_ECDSA_SetParaEx(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *para)
{
if (ctx == NULL || para == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
#ifdef HITLS_CRYPTO_PROVIDER
int32_t ret;
const BSL_Param *temp = NULL;
if ((temp = EAL_FindConstParam(para, CRYPT_PARAM_MD_ATTR)) != NULL) {
ret = CRYPT_PkeySetMdAttr((const char *)(temp->value), temp->valueLen, &(ctx->mdAttr));
if (ret != CRYPT_SUCCESS) {
return ret;
}
}
#endif
if (EAL_FindConstParam(para, CRYPT_PARAM_EC_P) == NULL) {
return CRYPT_SUCCESS;
}
CRYPT_EccPara eccPara = {0};
(void)GetConstParamValue(para, CRYPT_PARAM_EC_P, &(eccPara.p), &(eccPara.pLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_A, &(eccPara.a), &(eccPara.aLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_B, &(eccPara.b), &(eccPara.bLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_H, &(eccPara.h), &(eccPara.hLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_N, &(eccPara.n), &(eccPara.nLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_X, &(eccPara.x), &(eccPara.xLen));
(void)GetConstParamValue(para, CRYPT_PARAM_EC_Y, &(eccPara.y), &(eccPara.yLen));
return CRYPT_ECDSA_SetPara(ctx, &eccPara);
}
uint32_t CRYPT_ECDSA_GetSignLen(const CRYPT_ECDSA_Ctx *ctx)
{
if (ctx == NULL || ctx->para == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return 0;
}
* https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
* If the integer is positive but the high order bit is set to 1,
* a leading 0x00 is added to the content to indicate that the number is not negative
*/
uint32_t qLen = (ECC_ParaBits(ctx->para) + 7) / 8;
uint32_t maxSignLen = 0;
int32_t ret = CRYPT_EAL_GetSignEncodeLen(qLen, qLen, &maxSignLen);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return 0;
}
return maxSignLen;
}
static BN_BigNum *GetBnByData(const BN_BigNum *n, const uint8_t *data, uint32_t dataLen)
{
uint32_t nBits = BN_Bits(n);
BN_BigNum *d = BN_Create(nBits);
if (d == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
return NULL;
}
if (data == NULL) {
return d;
}
uint32_t dLen = dataLen;
if (8 * dLen > nBits) {
dLen = (nBits + 7) >> 3;
}
(void)BN_Bin2Bn(d, data, dLen);
if (8 * dLen > nBits) {
int32_t ret = BN_Rshift(d, d, (8 - (nBits & 7)));
if (ret != CRYPT_SUCCESS) {
BN_Destroy(d);
BSL_ERR_PUSH_ERROR(ret);
return NULL;
}
}
return d;
}
static int32_t EcdsaSignCore(const CRYPT_ECDSA_Ctx *ctx, const BN_BigNum *paraN, BN_BigNum *d,
BN_BigNum *r, BN_BigNum *s)
{
uint32_t keyBits = CRYPT_ECDSA_GetBits(ctx);
BN_BigNum *k = BN_Create(keyBits);
BN_BigNum *k2 = BN_Create(keyBits);
ECC_Point *pt = ECC_NewPoint(ctx->para);
BN_BigNum *ptX = BN_Create(keyBits);
BN_Optimizer *opt = BN_OptimizerCreate();
int32_t ret;
int32_t i;
if ((k == NULL) || (k2 == NULL) || (pt == NULL) || (opt == NULL) || (ptX == NULL)) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
ret = CRYPT_MEM_ALLOC_FAIL;
goto ERR;
}
for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) {
GOTO_ERR_IF(BN_RandRangeEx(ctx->libCtx, k, paraN), ret);
if (BN_IsZero(k)) {
continue;
}
GOTO_ERR_IF(ECC_PointMul(ctx->para, pt, k, NULL), ret);
GOTO_ERR_IF_EX(ECC_GetPointDataX(ctx->para, pt, ptX), ret);
GOTO_ERR_IF(BN_Mod(r, ptX, paraN, opt), ret);
if (BN_IsZero(r)) {
continue;
}
GOTO_ERR_IF(BN_ModMul(s, ctx->prvkey, r, paraN, opt), ret);
GOTO_ERR_IF(BN_ModAddQuick(s, d, s, paraN, opt), ret);
GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, k2, k), ret);
GOTO_ERR_IF(BN_ModMul(s, k2, s, paraN, opt), ret);
if (BN_IsZero(s) != true) {
break;
}
}
if (i >= CRYPT_ECC_TRY_MAX_CNT) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_TRY_CNT);
ret = CRYPT_ECDSA_ERR_TRY_CNT;
}
ERR:
BN_Destroy(k);
BN_Destroy(k2);
BN_Destroy(ptX);
ECC_FreePoint(pt);
BN_OptimizerDestroy(opt);
return ret;
}
static int32_t CryptEcdsaSign(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
BN_BigNum **r, BN_BigNum **s)
{
int32_t rc = CRYPT_SUCCESS;
BN_BigNum *signR = NULL;
BN_BigNum *signS = NULL;
BN_BigNum *d = NULL;
BN_BigNum *paraN = ECC_GetParaRawN(ctx->para);
uint32_t keyBits = ECC_PkeyGetBits(ctx);
signR = BN_Create(keyBits);
signS = BN_Create(keyBits);
if ((signR == NULL) || (signS == NULL)) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
rc = CRYPT_MEM_ALLOC_FAIL;
goto ERR;
}
d = GetBnByData(paraN, data, dataLen);
if (d == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
rc = CRYPT_MEM_ALLOC_FAIL;
goto ERR;
}
GOTO_ERR_IF_EX(EcdsaSignCore(ctx, paraN, d, signR, signS), rc);
*r = signR;
*s = signS;
goto OK;
ERR:
BN_Destroy(signR);
BN_Destroy(signS);
OK:
BN_Destroy(d);
return rc;
}
int32_t CRYPT_ECDSA_SignData(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
uint8_t *sign, uint32_t *signLen)
{
bool nullInput = (ctx == NULL) || (ctx->para == NULL) || (sign == NULL) || (signLen == NULL) ||
((data == NULL) && (dataLen != 0));
if (nullInput == true) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
if (ctx->signMdId != CRYPT_MD_MAX && CRYPT_GetMdSizeById(ctx->signMdId) != dataLen) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_PKEY_ERR_SIGN_DATA_LEN);
return CRYPT_ECDSA_PKEY_ERR_SIGN_DATA_LEN;
}
if (ctx->prvkey == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY);
return CRYPT_ECDSA_ERR_EMPTY_KEY;
}
if (*signLen < CRYPT_ECDSA_GetSignLen(ctx)) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH);
return CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH;
}
int32_t ret;
BN_BigNum *r = NULL;
BN_BigNum *s = NULL;
ret = CryptEcdsaSign(ctx, data, dataLen, &r, &s);
if (ret != CRYPT_SUCCESS) {
return ret;
}
ret = CRYPT_EAL_EncodeSign(r, s, sign, signLen);
BN_Destroy(r);
BN_Destroy(s);
return ret;
}
int32_t CRYPT_ECDSA_Sign(const CRYPT_ECDSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
uint8_t *sign, uint32_t *signLen)
{
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
uint8_t hash[64];
uint32_t hashDataLen = sizeof(hash) / sizeof(hash[0]);
int32_t ret = EAL_Md(algId, ctx->libCtx, ctx->mdAttr, data, dataLen, hash, &hashDataLen, true,
ctx->libCtx != NULL);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
return CRYPT_ECDSA_SignData(ctx, hash, hashDataLen, sign, signLen);
}
static int32_t VerifyCheckSign(const BN_BigNum *paraN, BN_BigNum *r, BN_BigNum *s)
{
if ((BN_Cmp(r, paraN) >= 0) || (BN_Cmp(s, paraN) >= 0)) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_VERIFY_FAIL);
return CRYPT_ECDSA_VERIFY_FAIL;
}
if (BN_IsZero(r) || BN_IsZero(s)) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_VERIFY_FAIL);
return CRYPT_ECDSA_VERIFY_FAIL;
}
return CRYPT_SUCCESS;
}
static int32_t EcdsaVerifyCore(const CRYPT_ECDSA_Ctx *ctx, const BN_BigNum *paraN, BN_BigNum *d, const BN_BigNum *r,
const BN_BigNum *s)
{
BN_Optimizer *opt = BN_OptimizerCreate();
if (opt == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
return CRYPT_MEM_ALLOC_FAIL;
}
(void)OptimizerStart(opt);
uint32_t room = BITS_TO_BN_UNIT(CRYPT_ECDSA_GetBits(ctx));
BN_BigNum *w;
BN_BigNum *u1;
BN_BigNum *u2;
BN_BigNum *v;
BN_BigNum *tptX;
BN_BigNum *bns[5];
ECC_Point *tpt = ECC_NewPoint(ctx->para);
int32_t ret = CRYPT_MEM_ALLOC_FAIL;
if (tpt == NULL || (ret = OptimizerGetXBn(opt, room, 5, bns)) != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
goto ERR;
}
w = bns[0];
u1 = bns[1];
u2 = bns[2];
v = bns[3];
tptX = bns[4];
GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, w, s), ret);
GOTO_ERR_IF(BN_ModMul(u1, d, w, paraN, opt), ret);
GOTO_ERR_IF(BN_ModMul(u2, r, w, paraN, opt), ret);
GOTO_ERR_IF(ECC_PointMulAdd(ctx->para, tpt, u1, u2, ctx->pubkey), ret);
GOTO_ERR_IF(ECC_GetPointDataX(ctx->para, tpt, tptX), ret);
GOTO_ERR_IF(BN_Mod(v, tptX, paraN, opt), ret);
if (BN_Cmp(v, r) != 0) {
BSL_ERR_PUSH_ERROR(ret);
ret = CRYPT_ECDSA_VERIFY_FAIL;
}
ERR:
ECC_FreePoint(tpt);
OptimizerEnd(opt);
BN_OptimizerDestroy(opt);
return ret;
}
int32_t CRYPT_ECDSA_VerifyData(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
const uint8_t *sign, uint32_t signLen)
{
bool nullInput = (ctx == NULL) || (ctx->para == NULL) || ((data == NULL) && (dataLen != 0)) ||
(sign == NULL) || (signLen == 0);
if (nullInput == true) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
if (ctx->pubkey == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY);
return CRYPT_ECDSA_ERR_EMPTY_KEY;
}
int32_t ret;
BN_BigNum *paraN = ECC_GetParaRawN(ctx->para);
uint32_t keyBits = ECC_PkeyGetBits(ctx);
BN_BigNum *r = BN_Create(keyBits);
BN_BigNum *s = BN_Create(keyBits);
BN_BigNum *d = GetBnByData(paraN, data, dataLen);
if (r == NULL || s == NULL || d == NULL) {
ret = CRYPT_MEM_ALLOC_FAIL;
goto ERR;
}
GOTO_ERR_IF(CRYPT_EAL_DecodeSign(sign, signLen, r, s), ret);
GOTO_ERR_IF(VerifyCheckSign(paraN, r, s), ret);
GOTO_ERR_IF(EcdsaVerifyCore(ctx, paraN, d, r, s), ret);
ERR:
BN_Destroy(r);
BN_Destroy(s);
BN_Destroy(d);
return ret;
}
int32_t CRYPT_ECDSA_Verify(const CRYPT_ECDSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
const uint8_t *sign, uint32_t signLen)
{
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
uint8_t hash[64];
uint32_t hashLen = sizeof(hash) / sizeof(hash[0]);
int32_t ret = EAL_Md(algId, ctx->libCtx, ctx->mdAttr, data, dataLen, hash, &hashLen, true, ctx->libCtx != NULL);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
return CRYPT_ECDSA_VerifyData(ctx, hash, hashLen, sign, signLen);
}
int32_t CRYPT_ECDSA_Ctrl(CRYPT_ECDSA_Ctx *ctx, int32_t opt, void *val, uint32_t len)
{
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
switch (opt) {
case CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE:
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION);
return CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION;
case CRYPT_CTRL_GET_PARAID:
return CRYPT_CTRL_GET_NUM32_EX(ECC_GetParaId, ctx->para, val, len);
case CRYPT_CTRL_GET_BITS:
return CRYPT_CTRL_GET_NUM32_EX(ECC_PkeyGetBits, ctx, val, len);
case CRYPT_CTRL_GET_SIGNLEN:
return CRYPT_CTRL_GET_NUM32_EX(CRYPT_ECDSA_GetSignLen, ctx, val, len);
case CRYPT_CTRL_GET_SECBITS:
return CRYPT_CTRL_GET_NUM32_EX(ECC_GetSecBits, ctx->para, val, len);
case CRYPT_CTRL_SET_PARA_BY_ID:
if (val == NULL || len != sizeof(int32_t)) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
return ECC_SetPara(ctx, CRYPT_ECDSA_NewParaById(*(int32_t *)val));
case CRYPT_CTRL_SET_SIGN_MD:
return CRYPT_SetSignMdCtrl(&ctx->signMdId, val, len, NULL);
default:
return ECC_PkeyCtrl(ctx, opt, val, len);
}
}
int32_t CRYPT_ECDSA_GetSecBits(const CRYPT_ECDSA_Ctx *ctx)
{
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return 0;
}
return ECC_GetSecBits(ctx->para);
}
#ifdef HITLS_CRYPTO_KEY_DECODE_CHAIN
static int32_t SetCurveInfo(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *curve)
{
if (curve->value == NULL || curve->valueType != BSL_PARAM_TYPE_INT32 ||
curve->valueLen != sizeof(int32_t)) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
CRYPT_PKEY_ParaId paraId = *(CRYPT_PKEY_ParaId *)curve->value;
int32_t ret = ECC_SetPara(ctx, CRYPT_ECDSA_NewParaById((int32_t)paraId));
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
}
return ret;
}
int32_t CRYPT_ECDSA_Import(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *params)
{
if (ctx == NULL || params == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
int32_t ret = CRYPT_SUCCESS;
const BSL_Param *prv = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PRVKEY);
const BSL_Param *pub = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PUBKEY);
const BSL_Param *curve = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_CURVE_ID);
if (curve != NULL) {
ret = SetCurveInfo(ctx, curve);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
}
if (prv != NULL) {
ret = CRYPT_ECDSA_SetPrvKeyEx(ctx, params);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
}
if (pub != NULL) {
ret = CRYPT_ECDSA_SetPubKeyEx(ctx, params);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
}
return ret;
}
int32_t CRYPT_ECDSA_Export(const CRYPT_ECDSA_Ctx *ctx, BSL_Param *params)
{
if (ctx == NULL || params == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
return CRYPT_NULL_INPUT;
}
CRYPT_PKEY_ParaId curveId = CRYPT_ECDSA_GetParaId(ctx);
if (curveId == CRYPT_PKEY_PARAID_MAX) {
BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA);
return CRYPT_ECC_ERR_PARA;
}
uint32_t keyBytes = (CRYPT_ECDSA_GetBits(ctx) + 7) / 8;
if (keyBytes == 0) {
BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
return CRYPT_INVALID_ARG;
}
int index = 1;
void *args = NULL;
CRYPT_EAL_ProcessFuncCb processCb = NULL;
BSL_Param ecdsaParams[4] = {
{CRYPT_PARAM_EC_CURVE_ID, BSL_PARAM_TYPE_INT32, (int32_t *)&curveId, sizeof(int32_t), 0},
{0}, {0}, BSL_PARAM_END
};
int32_t ret = CRYPT_GetPkeyProcessParams(params, &processCb, &args);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
uint8_t *tempBuffer = BSL_SAL_Calloc(1, keyBytes * 2);
if (tempBuffer == NULL) {
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
return CRYPT_MEM_ALLOC_FAIL;
}
if (ctx->pubkey != NULL) {
(void)BSL_PARAM_InitValue(&ecdsaParams[index], CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS,
tempBuffer, keyBytes);
ret = CRYPT_ECDSA_GetPubKeyEx(ctx, ecdsaParams);
if (ret != CRYPT_SUCCESS) {
BSL_SAL_Free(tempBuffer);
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
ecdsaParams[index].valueLen = ecdsaParams[index].useLen;
index++;
}
if (ctx->prvkey != NULL) {
(void)BSL_PARAM_InitValue(&ecdsaParams[index], CRYPT_PARAM_EC_PRVKEY, BSL_PARAM_TYPE_OCTETS,
tempBuffer + keyBytes, keyBytes);
ret = CRYPT_ECDSA_GetPrvKeyEx(ctx, ecdsaParams);
if (ret != CRYPT_SUCCESS) {
BSL_SAL_Free(tempBuffer);
BSL_ERR_PUSH_ERROR(ret);
return ret;
}
ecdsaParams[index].valueLen = ecdsaParams[index].useLen;
index++;
}
ret = processCb(ecdsaParams, args);
BSL_SAL_ClearFree(tempBuffer, keyBytes * 2);
if (ret != CRYPT_SUCCESS) {
BSL_ERR_PUSH_ERROR(ret);
}
return ret;
}
#endif
#ifdef HITLS_CRYPTO_ECDSA_CHECK
int32_t CRYPT_ECDSA_Check(uint32_t checkType, const CRYPT_ECDSA_Ctx *pkey1, const CRYPT_ECDSA_Ctx *pkey2)
{
int32_t ret = ECC_PkeyCheck(pkey1, pkey2, checkType);
if (ret == CRYPT_ECC_PAIRWISE_CHECK_FAIL) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_PAIRWISE_CHECK_FAIL);
return CRYPT_ECDSA_PAIRWISE_CHECK_FAIL;
}
if (ret == CRYPT_ECC_INVALID_PRVKEY) {
BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_INVALID_PRVKEY);
return CRYPT_ECDSA_INVALID_PRVKEY;
}
return ret;
}
#endif
#endif