• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_ECDSA
18 
19 #include <stdbool.h>
20 #include "securec.h"
21 #include "crypt_errno.h"
22 #include "crypt_types.h"
23 #include "crypt_utils.h"
24 #include "bsl_sal.h"
25 #include "bsl_err_internal.h"
26 #include "crypt_bn.h"
27 #include "crypt_encode_internal.h"
28 #include "crypt_ecc.h"
29 #include "crypt_ecc_pkey.h"
30 #include "eal_pkey_local.h"
31 #include "eal_md_local.h"
32 #include "crypt_ecdsa.h"
33 
CRYPT_ECDSA_NewCtx(void)34 CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtx(void)
35 {
36     CRYPT_ECDSA_Ctx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_ECDSA_Ctx));
37     if (ctx == NULL) {
38         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
39         return NULL;
40     }
41     ctx->pointFormat = CRYPT_POINT_UNCOMPRESSED;    // point format is uncompressed by default.
42     BSL_SAL_ReferencesInit(&(ctx->references));
43     return ctx;
44 }
45 
CRYPT_ECDSA_NewCtxEx(void * libCtx)46 CRYPT_ECDSA_Ctx *CRYPT_ECDSA_NewCtxEx(void *libCtx)
47 {
48     CRYPT_ECDSA_Ctx *ctx = CRYPT_ECDSA_NewCtx();
49     if (ctx == NULL) {
50         return NULL;
51     }
52     ctx->libCtx = libCtx;
53     return ctx;
54 }
55 
CRYPT_ECDSA_DupCtx(CRYPT_ECDSA_Ctx * ctx)56 CRYPT_ECDSA_Ctx *CRYPT_ECDSA_DupCtx(CRYPT_ECDSA_Ctx *ctx)
57 {
58     return ECC_DupCtx(ctx);
59 }
60 
CRYPT_ECDSA_FreeCtx(CRYPT_ECDSA_Ctx * ctx)61 void CRYPT_ECDSA_FreeCtx(CRYPT_ECDSA_Ctx *ctx)
62 {
63     if (ctx == NULL) {
64         return;
65     }
66     ECC_FreeCtx(ctx);
67 }
68 
CRYPT_ECDSA_NewParaById(int32_t id)69 CRYPT_EcdsaPara *CRYPT_ECDSA_NewParaById(int32_t id)
70 {
71     return ECC_NewPara(id);
72 }
73 
CRYPT_ECDSA_NewPara(const BSL_Param * eccPara)74 CRYPT_EcdsaPara *CRYPT_ECDSA_NewPara(const BSL_Param *eccPara)
75 {
76     if (eccPara == NULL) {
77         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
78         return NULL;
79     }
80     CRYPT_PKEY_ParaId id = ECC_GetCurveId(eccPara);
81     if (id == CRYPT_PKEY_PARAID_MAX) {
82         BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA);
83         return NULL;
84     }
85     return CRYPT_ECDSA_NewParaById(id);
86 }
87 
CRYPT_ECDSA_GetParaId(const CRYPT_ECDSA_Ctx * ctx)88 CRYPT_PKEY_ParaId CRYPT_ECDSA_GetParaId(const CRYPT_ECDSA_Ctx *ctx)
89 {
90     if (ctx == NULL) {
91         return CRYPT_PKEY_PARAID_MAX;
92     }
93     return ECC_GetParaId(ctx->para);
94 }
95 
CRYPT_ECDSA_FreePara(CRYPT_EcdsaPara * para)96 void CRYPT_ECDSA_FreePara(CRYPT_EcdsaPara *para)
97 {
98     ECC_FreePara(para);
99 }
100 
CRYPT_ECDSA_GetPara(const CRYPT_ECDSA_Ctx * ctx,BSL_Param * param)101 int32_t CRYPT_ECDSA_GetPara(const CRYPT_ECDSA_Ctx *ctx, BSL_Param *param)
102 {
103     return ECC_GetPara(ctx, param);
104 }
105 
CRYPT_ECDSA_SetParaEx(CRYPT_ECDSA_Ctx * ctx,CRYPT_EcdsaPara * para)106 int32_t CRYPT_ECDSA_SetParaEx(CRYPT_ECDSA_Ctx *ctx, CRYPT_EcdsaPara *para)
107 {
108     return ECC_SetPara(ctx, para);
109 }
110 
CRYPT_ECDSA_SetPara(CRYPT_ECDSA_Ctx * ctx,const BSL_Param * para)111 int32_t CRYPT_ECDSA_SetPara(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *para)
112 {
113     if (ctx == NULL) {
114         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
115         return CRYPT_NULL_INPUT;
116     }
117     CRYPT_EcdsaPara *ecdsaPara = CRYPT_ECDSA_NewPara(para);
118     if (ecdsaPara == NULL) {
119         BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_NEW_PARA_FAIL);
120         return CRYPT_EAL_ERR_NEW_PARA_FAIL;
121     }
122 
123     // Refresh the public and private keys.
124     BN_Destroy(ctx->prvkey);
125     ctx->prvkey = NULL;
126     ECC_FreePoint(ctx->pubkey);
127     ctx->pubkey = NULL;
128 
129     ECC_FreePara(ctx->para);
130     ctx->para = ecdsaPara;
131     ECC_SetLibCtx(ctx->libCtx, ctx->para);
132     return CRYPT_SUCCESS;
133 }
134 
CRYPT_ECDSA_GetBits(const CRYPT_ECDSA_Ctx * ctx)135 uint32_t CRYPT_ECDSA_GetBits(const CRYPT_ECDSA_Ctx *ctx)
136 {
137     return ECC_PkeyGetBits(ctx);
138 }
139 
CRYPT_ECDSA_SetPrvKey(CRYPT_ECDSA_Ctx * ctx,const BSL_Param * para)140 int32_t CRYPT_ECDSA_SetPrvKey(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *para)
141 {
142     return ECC_PkeySetPrvKey(ctx, para);
143 }
144 
CRYPT_ECDSA_SetPubKey(CRYPT_ECDSA_Ctx * ctx,const BSL_Param * para)145 int32_t CRYPT_ECDSA_SetPubKey(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *para)
146 {
147     return ECC_PkeySetPubKey(ctx, para);
148 }
149 
CRYPT_ECDSA_GetPrvKey(const CRYPT_ECDSA_Ctx * ctx,BSL_Param * para)150 int32_t CRYPT_ECDSA_GetPrvKey(const CRYPT_ECDSA_Ctx *ctx, BSL_Param *para)
151 {
152     return ECC_PkeyGetPrvKey(ctx, para);
153 }
154 
CRYPT_ECDSA_GetPubKey(const CRYPT_ECDSA_Ctx * ctx,BSL_Param * para)155 int32_t CRYPT_ECDSA_GetPubKey(const CRYPT_ECDSA_Ctx *ctx, BSL_Param *para)
156 {
157     return ECC_PkeyGetPubKey(ctx, para);
158 }
159 
CRYPT_ECDSA_Gen(CRYPT_ECDSA_Ctx * ctx)160 int32_t CRYPT_ECDSA_Gen(CRYPT_ECDSA_Ctx *ctx)
161 {
162     return ECC_PkeyGen(ctx);
163 }
164 
CRYPT_ECDSA_GetSignLen(const CRYPT_ECDSA_Ctx * ctx)165 uint32_t CRYPT_ECDSA_GetSignLen(const CRYPT_ECDSA_Ctx *ctx)
166 {
167     if (ctx == NULL) {
168         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
169         return 0;
170     }
171 
172     /**
173      * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
174      * If the integer is positive but the high order bit is set to 1,
175      * a leading 0x00 is added to the content to indicate that the number is not negative
176      */
177     // When the number of bits is a multiple of 8 and the most significant bit is 1, 0x00 needs to be added.
178     // If the number of bits is not a multiple of 8,
179     // an extra byte needs to be added to store the data with less than 8 bits.
180     uint32_t qLen = (ECC_ParaBits(ctx->para) / 8) + 1;    // divided by 8 to converted to bytes
181     uint32_t maxSignLen = 0;
182     int32_t ret = CRYPT_EAL_GetSignEncodeLen(qLen, qLen, &maxSignLen);
183     if (ret != CRYPT_SUCCESS) {
184         BSL_ERR_PUSH_ERROR(ret);
185         return 0;
186     }
187     return maxSignLen;
188 }
189 
190 // Obtain the input hash data. For details, see RFC6979-2.4.1 and RFC6979-2.3.2
GetBnByData(const BN_BigNum * n,const uint8_t * data,uint32_t dataLen)191 static BN_BigNum *GetBnByData(const BN_BigNum *n, const uint8_t *data, uint32_t dataLen)
192 {
193     uint32_t nBits = BN_Bits(n);
194     BN_BigNum *d = BN_Create(nBits); // each byte has 8bits
195     if (d == NULL) {
196         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
197         return NULL;
198     }
199 
200     if (data == NULL) {
201         return d;
202     }
203 
204     uint32_t dLen = dataLen;
205     if (8 * dLen > nBits) {         // bytes * 8 = bits
206         dLen = (nBits + 7) >> 3;    // Add 7 and shift rightward by 3 (equal to /8) to achieve the effect of bits2bytes.
207     }
208     // The input parameters of the function have been verified, and no failure case exists.
209     (void)BN_Bin2Bn(d, data, dLen);
210     if (8 * dLen > nBits) {         // bytes * 8 = bits
211         // Subtracted by 8 and &7 to be accurate to bits.
212         int32_t ret = BN_Rshift(d, d, (8 - (nBits & 7)));
213         if (ret != CRYPT_SUCCESS) {
214             BN_Destroy(d);
215             BSL_ERR_PUSH_ERROR(ret);
216             return NULL;
217         }
218     }
219 
220     return d;
221 }
222 
EcdsaSignCore(const CRYPT_ECDSA_Ctx * ctx,const BN_BigNum * paraN,BN_BigNum * d,BN_BigNum * r,BN_BigNum * s)223 static int32_t EcdsaSignCore(const CRYPT_ECDSA_Ctx *ctx, const BN_BigNum *paraN, BN_BigNum *d,
224                              BN_BigNum *r, BN_BigNum *s)
225 {
226     uint32_t keyBits = CRYPT_ECDSA_GetBits(ctx);    // input parameter has been checked externally.
227     BN_BigNum *k = BN_Create(keyBits);
228     BN_BigNum *k2 = BN_Create(keyBits);
229     ECC_Point *pt = ECC_NewPoint(ctx->para);
230     BN_BigNum *ptX = BN_Create(keyBits);
231     BN_Optimizer *opt = BN_OptimizerCreate();
232     int32_t ret;
233     int32_t i;
234 
235     if ((k == NULL) || (k2 == NULL) || (pt == NULL) || (opt == NULL) || (ptX == NULL)) {
236         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
237         ret = CRYPT_MEM_ALLOC_FAIL;
238         goto ERR;
239     }
240 
241     for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) {
242         GOTO_ERR_IF(BN_RandRangeEx(ctx->libCtx, k, paraN), ret);
243         if (BN_IsZero(k)) {
244             continue;
245         }
246 
247         // pt = k * G
248         GOTO_ERR_IF(ECC_PointMul(ctx->para, pt, k, NULL), ret);
249 
250         // r = pt->x mod n
251         GOTO_ERR_IF_EX(ECC_GetPointDataX(ctx->para, pt, ptX), ret);
252         GOTO_ERR_IF(BN_Mod(r, ptX, paraN, opt), ret);
253 
254         // if r == 0, then restart
255         if (BN_IsZero(r)) {
256             continue;
257         }
258 
259         // prvkey * r mod n
260         GOTO_ERR_IF(BN_ModMul(s, ctx->prvkey, r, paraN, opt), ret);
261 
262         // hash + prvkey * r mod n
263         GOTO_ERR_IF(BN_ModAddQuick(s, d, s, paraN, opt), ret);
264 
265         // 1/k mod n
266         GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, k2, k), ret);
267 
268         // s = (1/k) * (hash + prvkey * r) mod n
269         GOTO_ERR_IF(BN_ModMul(s, k2, s, paraN, opt), ret);
270 
271         // if s == 0, then restart
272         if (BN_IsZero(s) != true) {
273             break;
274         }
275     }
276 
277     if (i >= CRYPT_ECC_TRY_MAX_CNT) {
278         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_TRY_CNT);
279         ret = CRYPT_ECDSA_ERR_TRY_CNT;
280     }
281 
282 ERR:
283     BN_Destroy(k);
284     BN_Destroy(k2);
285     BN_Destroy(ptX);
286     ECC_FreePoint(pt);
287     BN_OptimizerDestroy(opt);
288     return ret;
289 }
290 
CryptEcdsaSign(const CRYPT_ECDSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,BN_BigNum ** r,BN_BigNum ** s)291 static int32_t CryptEcdsaSign(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
292                               BN_BigNum **r, BN_BigNum **s)
293 {
294     int32_t rc = CRYPT_SUCCESS;
295     BN_BigNum *signR = NULL;
296     BN_BigNum *signS = NULL;
297     BN_BigNum *d = NULL;
298     BN_BigNum *paraN = ECC_GetParaN(ctx->para);
299     if (paraN == NULL) {
300         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
301         return CRYPT_MEM_ALLOC_FAIL;
302     }
303     uint32_t keyBits = ECC_PkeyGetBits(ctx);
304     signR = BN_Create(keyBits);
305     signS = BN_Create(keyBits);
306     if ((signR == NULL) || (signS == NULL)) {
307         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
308         rc = CRYPT_MEM_ALLOC_FAIL;
309         goto ERR;
310     }
311 
312     d = GetBnByData(paraN, data, dataLen);
313     if (d == NULL) {
314         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
315         rc = CRYPT_MEM_ALLOC_FAIL;
316         goto ERR;
317     }
318     GOTO_ERR_IF_EX(EcdsaSignCore(ctx, paraN, d, signR, signS), rc);
319 
320     *r = signR;
321     *s = signS;
322     goto OK;
323 ERR:
324     BN_Destroy(signR);
325     BN_Destroy(signS);
326 OK:
327     BN_Destroy(paraN);
328     BN_Destroy(d);
329     return rc;
330 }
331 
332 // Data with a value of 0 can also be signed.
CRYPT_ECDSA_SignData(const CRYPT_ECDSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)333 int32_t CRYPT_ECDSA_SignData(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
334     uint8_t *sign, uint32_t *signLen)
335 {
336     if ((ctx == NULL) || (ctx->para == NULL) || (sign == NULL) || (signLen == NULL) ||
337         ((data == NULL) && (dataLen != 0))) {
338         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
339         return CRYPT_NULL_INPUT;
340     }
341 
342     if (ctx->prvkey == NULL) {
343         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY);
344         return CRYPT_ECDSA_ERR_EMPTY_KEY;
345     }
346 
347     if (*signLen < CRYPT_ECDSA_GetSignLen(ctx)) {
348         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH);
349         return CRYPT_ECDSA_BUFF_LEN_NOT_ENOUGH;
350     }
351 
352     int32_t ret;
353     BN_BigNum *r = NULL;
354     BN_BigNum *s = NULL;
355     ret = CryptEcdsaSign(ctx, data, dataLen, &r, &s);
356     if (ret != CRYPT_SUCCESS) {
357         return ret;
358     }
359     ret = CRYPT_EAL_EncodeSign(r, s, sign, signLen);
360     BN_Destroy(r);
361     BN_Destroy(s);
362     return ret;
363 }
364 
CRYPT_ECDSA_Sign(const CRYPT_ECDSA_Ctx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)365 int32_t CRYPT_ECDSA_Sign(const CRYPT_ECDSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
366     uint8_t *sign, uint32_t *signLen)
367 {
368     uint8_t hash[64]; // 64 is max hash len
369     uint32_t hashLen = sizeof(hash) / sizeof(hash[0]);
370     int32_t ret = EAL_Md(algId, data, dataLen, hash, &hashLen);
371     if (ret != CRYPT_SUCCESS) {
372         BSL_ERR_PUSH_ERROR(ret);
373         return ret;
374     }
375     return CRYPT_ECDSA_SignData(ctx, hash, hashLen, sign, signLen);
376 }
377 
VerifyCheckSign(const BN_BigNum * paraN,BN_BigNum * r,BN_BigNum * s)378 static int32_t VerifyCheckSign(const BN_BigNum *paraN, BN_BigNum *r, BN_BigNum *s)
379 {
380     if ((BN_Cmp(r, paraN) >= 0) || (BN_Cmp(s, paraN) >= 0)) {
381         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_VERIFY_FAIL);
382         return CRYPT_ECDSA_VERIFY_FAIL;
383     }
384     if (BN_IsZero(r) || BN_IsZero(s)) {
385         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_VERIFY_FAIL);
386         return CRYPT_ECDSA_VERIFY_FAIL;
387     }
388 
389     return CRYPT_SUCCESS;
390 }
391 
EcdsaVerifyCore(const CRYPT_ECDSA_Ctx * ctx,const BN_BigNum * paraN,BN_BigNum * d,const BN_BigNum * r,const BN_BigNum * s)392 static int32_t EcdsaVerifyCore(const CRYPT_ECDSA_Ctx *ctx, const BN_BigNum *paraN, BN_BigNum *d, const BN_BigNum *r,
393     const BN_BigNum *s)
394 {
395     BN_Optimizer *opt = BN_OptimizerCreate();
396     if (opt == NULL) {
397         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
398         return CRYPT_MEM_ALLOC_FAIL;
399     }
400     (void)OptimizerStart(opt);
401     ECC_Point *tpt = ECC_NewPoint(ctx->para);
402     uint32_t keyBits = CRYPT_ECDSA_GetBits(ctx);
403     uint32_t room = BITS_TO_BN_UNIT(keyBits);
404     BN_BigNum *w = OptimizerGetBn(opt, room);
405     BN_BigNum *u1 = OptimizerGetBn(opt, room);
406     BN_BigNum *u2 = OptimizerGetBn(opt, room);
407     BN_BigNum *v = OptimizerGetBn(opt, room);
408     BN_BigNum *tptX = OptimizerGetBn(opt, room);
409     int32_t ret;
410     if (tpt == NULL) {
411         ret = CRYPT_MEM_ALLOC_FAIL;
412         BSL_ERR_PUSH_ERROR(ret);
413         goto ERR;
414     }
415     if ((w == NULL) || (u1 == NULL) || (u2 == NULL) || (v == NULL) || (tptX == NULL)) {
416         ret = CRYPT_BN_OPTIMIZER_GET_FAIL;
417         BSL_ERR_PUSH_ERROR(ret);
418         goto ERR;
419     }
420 
421     // w = 1/s mod n
422     GOTO_ERR_IF(ECC_ModOrderInv(ctx->para, w, s), ret);
423 
424     // u1 = msg*(1/s) mod n
425     GOTO_ERR_IF(BN_ModMul(u1, d, w, paraN, opt), ret);
426 
427     // u2 = r*(1/s) mod n
428     GOTO_ERR_IF(BN_ModMul(u2, r, w, paraN, opt), ret);
429 
430     // tpt : u1*G + u2*pubkey
431     GOTO_ERR_IF(ECC_PointMulAdd(ctx->para, tpt, u1, u2, ctx->pubkey), ret);
432 
433     GOTO_ERR_IF(ECC_GetPointDataX(ctx->para, tpt, tptX), ret);
434     GOTO_ERR_IF(BN_Mod(v, tptX, paraN, opt), ret);
435 
436     if (BN_Cmp(v, r) != 0) {
437         BSL_ERR_PUSH_ERROR(ret);
438         ret = CRYPT_ECDSA_VERIFY_FAIL;
439     }
440 
441 ERR:
442     ECC_FreePoint(tpt);
443     OptimizerEnd(opt);
444     BN_OptimizerDestroy(opt);
445     return ret;
446 }
447 
CRYPT_ECDSA_VerifyData(const CRYPT_ECDSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)448 int32_t CRYPT_ECDSA_VerifyData(const CRYPT_ECDSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
449     const uint8_t *sign, uint32_t signLen)
450 {
451     if ((ctx == NULL) || (ctx->para == NULL) || ((data == NULL) && (dataLen != 0)) ||
452         (sign == NULL) || (signLen == 0)) {
453         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
454         return CRYPT_NULL_INPUT;
455     }
456 
457     if (ctx->pubkey == NULL) {
458         BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_EMPTY_KEY);
459         return CRYPT_ECDSA_ERR_EMPTY_KEY;
460     }
461 
462     int32_t ret;
463     BN_BigNum *paraN = ECC_GetParaN(ctx->para);
464     if (paraN == NULL) {
465         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
466         return CRYPT_MEM_ALLOC_FAIL;
467     }
468     uint32_t keyBits = ECC_PkeyGetBits(ctx);
469     BN_BigNum *r = BN_Create(keyBits);
470     BN_BigNum *s = BN_Create(keyBits);
471     BN_BigNum *d = GetBnByData(paraN, data, dataLen);
472     if (r == NULL || s == NULL || d == NULL) {
473         ret = CRYPT_MEM_ALLOC_FAIL;
474         goto ERR;
475     }
476 
477     GOTO_ERR_IF(CRYPT_EAL_DecodeSign(sign, signLen, r, s), ret);
478 
479     GOTO_ERR_IF(VerifyCheckSign(paraN, r, s), ret);
480 
481     GOTO_ERR_IF(EcdsaVerifyCore(ctx, paraN, d, r, s), ret);
482 ERR:
483     BN_Destroy(paraN);
484     BN_Destroy(r);
485     BN_Destroy(s);
486     BN_Destroy(d);
487     return ret;
488 }
489 
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)490 int32_t CRYPT_ECDSA_Verify(const CRYPT_ECDSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
491     const uint8_t *sign, uint32_t signLen)
492 {
493     uint8_t hash[64]; // 64 is max hash len
494     uint32_t hashLen = sizeof(hash) / sizeof(hash[0]);
495     int32_t ret = EAL_Md(algId, data, dataLen, hash, &hashLen);
496     if (ret != CRYPT_SUCCESS) {
497         BSL_ERR_PUSH_ERROR(ret);
498         return ret;
499     }
500     return CRYPT_ECDSA_VerifyData(ctx, hash, hashLen, sign, signLen);
501 }
502 
CRYPT_ECDSA_GetLen(const CRYPT_ECDSA_Ctx * ctx,GetLenFunc func,void * val,uint32_t len)503 static int32_t CRYPT_ECDSA_GetLen(const CRYPT_ECDSA_Ctx *ctx, GetLenFunc func, void *val, uint32_t len)
504 {
505     if (val == NULL || len != sizeof(int32_t)) {
506         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
507         return CRYPT_NULL_INPUT;
508     }
509 
510     *(int32_t *)val = func(ctx);
511     return CRYPT_SUCCESS;
512 }
513 
CRYPT_ECDSA_Ctrl(CRYPT_ECDSA_Ctx * ctx,int32_t opt,void * val,uint32_t len)514 int32_t CRYPT_ECDSA_Ctrl(CRYPT_ECDSA_Ctx *ctx, int32_t opt, void *val, uint32_t len)
515 {
516     if (ctx == NULL) {
517         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
518         return CRYPT_NULL_INPUT;
519     }
520     switch (opt) {
521         case CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE:
522             BSL_ERR_PUSH_ERROR(CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION);
523             return CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION;
524         case CRYPT_CTRL_GET_PARAID:
525             return CRYPT_ECDSA_GetLen(ctx, (GetLenFunc)CRYPT_ECDSA_GetParaId, val, len);
526         case CRYPT_CTRL_GET_BITS:
527             return CRYPT_ECDSA_GetLen(ctx, (GetLenFunc)CRYPT_ECDSA_GetBits, val, len);
528         case CRYPT_CTRL_GET_SIGNLEN:
529             return CRYPT_ECDSA_GetLen(ctx, (GetLenFunc)CRYPT_ECDSA_GetSignLen, val, len);
530         case CRYPT_CTRL_GET_SECBITS:
531             return CRYPT_ECDSA_GetLen(ctx, (GetLenFunc)CRYPT_ECDSA_GetSecBits, val, len);
532         case CRYPT_CTRL_SET_PARA_BY_ID:
533             return CRYPT_ECDSA_SetParaEx(ctx, CRYPT_ECDSA_NewParaById(*(CRYPT_PKEY_ParaId *)val));
534         default:
535             break;
536     }
537 
538     return ECC_PkeyCtrl(ctx, opt, val, len);
539 }
540 
CRYPT_ECDSA_Cmp(const CRYPT_ECDSA_Ctx * a,const CRYPT_ECDSA_Ctx * b)541 int32_t CRYPT_ECDSA_Cmp(const CRYPT_ECDSA_Ctx *a, const CRYPT_ECDSA_Ctx *b)
542 {
543     return ECC_PkeyCmp(a, b);
544 }
545 
CRYPT_ECDSA_GetSecBits(const CRYPT_ECDSA_Ctx * ctx)546 int32_t CRYPT_ECDSA_GetSecBits(const CRYPT_ECDSA_Ctx *ctx)
547 {
548     if (ctx == NULL) {
549         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
550         return 0;
551     }
552     return ECC_GetSecBits(ctx->para);
553 }
554 
555 #ifdef HITLS_CRYPTO_PROVIDER
556 
SetCurveInfo(CRYPT_ECDSA_Ctx * ctx,const BSL_Param * curve)557 static int32_t SetCurveInfo(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *curve)
558 {
559     if (curve->value == NULL || curve->valueType != BSL_PARAM_TYPE_INT32 ||
560         curve->valueLen != sizeof(int32_t)) {
561         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
562         return CRYPT_NULL_INPUT;
563     }
564     CRYPT_PKEY_ParaId paraId = *(CRYPT_PKEY_ParaId *)curve->value;
565     int32_t ret = CRYPT_ECDSA_SetParaEx(ctx, CRYPT_ECDSA_NewParaById((int32_t)paraId));
566     if (ret != CRYPT_SUCCESS) {
567         BSL_ERR_PUSH_ERROR(ret);
568     }
569     return ret;
570 }
571 
CRYPT_ECDSA_Import(CRYPT_ECDSA_Ctx * ctx,const BSL_Param * params)572 int32_t CRYPT_ECDSA_Import(CRYPT_ECDSA_Ctx *ctx, const BSL_Param *params)
573 {
574     if (ctx == NULL || params == NULL) {
575         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
576         return CRYPT_NULL_INPUT;
577     }
578     int32_t ret = CRYPT_SUCCESS;
579     const BSL_Param *prv = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PRVKEY);
580     const BSL_Param *pub = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PUBKEY);
581     const BSL_Param *curve = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_CURVE_ID);
582     if (curve != NULL) {
583         ret = SetCurveInfo(ctx, curve);
584         if (ret != CRYPT_SUCCESS) {
585             BSL_ERR_PUSH_ERROR(ret);
586             return ret;
587         }
588     }
589     if (prv != NULL) {
590         ret = CRYPT_ECDSA_SetPrvKey(ctx, params);
591         if (ret != CRYPT_SUCCESS) {
592             BSL_ERR_PUSH_ERROR(ret);
593             return ret;
594         }
595     }
596     if (pub != NULL) {
597         ret = CRYPT_ECDSA_SetPubKey(ctx, params);
598         if (ret != CRYPT_SUCCESS) {
599             BSL_ERR_PUSH_ERROR(ret);
600             return ret;
601         }
602     }
603     return ret;
604 }
605 
CRYPT_ECDSA_Export(const CRYPT_ECDSA_Ctx * ctx,BSL_Param * params)606 int32_t CRYPT_ECDSA_Export(const CRYPT_ECDSA_Ctx *ctx, BSL_Param *params)
607 {
608     if (ctx == NULL || params == NULL) {
609         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
610         return CRYPT_NULL_INPUT;
611     }
612     CRYPT_PKEY_ParaId curveId = CRYPT_ECDSA_GetParaId(ctx);
613     if (curveId == CRYPT_PKEY_PARAID_MAX) {
614         BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA);
615         return CRYPT_ECC_ERR_PARA;
616     }
617     uint32_t keyBytes = (CRYPT_ECDSA_GetBits(ctx) + 7) / 8;
618     if (keyBytes == 0) {
619         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
620         return CRYPT_INVALID_ARG;
621     }
622     int32_t ret;
623     int index = 1;
624     void *args = NULL;
625     CRYPT_EAL_ProcessFuncCb processCb = NULL;
626     BSL_Param ecdsaParams[4] = {
627         {CRYPT_PARAM_EC_CURVE_ID, BSL_PARAM_TYPE_INT32, (int32_t *)&curveId, sizeof(int32_t), 0},
628         {0},
629         {0},
630         BSL_PARAM_END
631     };
632     ret = CRYPT_GetPkeyProcessParams(params, &processCb, &args);
633     if (ret != CRYPT_SUCCESS) {
634         BSL_ERR_PUSH_ERROR(ret);
635         return ret;
636     }
637     uint8_t *buffer = BSL_SAL_Calloc(1, keyBytes * 2); // 2 denote private + public key
638     if (buffer == NULL) {
639         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
640         return CRYPT_MEM_ALLOC_FAIL;
641     }
642     if (ctx->pubkey != NULL) {
643         (void)BSL_PARAM_InitValue(&ecdsaParams[index], CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS,
644             buffer, keyBytes);
645         ret = CRYPT_ECDSA_GetPubKey(ctx, ecdsaParams);
646         if (ret != CRYPT_SUCCESS) {
647             BSL_SAL_Free(buffer);
648             BSL_ERR_PUSH_ERROR(ret);
649             return ret;
650         }
651         ecdsaParams[index].valueLen = ecdsaParams[index].useLen;
652         index++;
653     }
654     if (ctx->prvkey != NULL) {
655         (void)BSL_PARAM_InitValue(&ecdsaParams[index], CRYPT_PARAM_EC_PRVKEY, BSL_PARAM_TYPE_OCTETS,
656             buffer + keyBytes, keyBytes);
657         ret = CRYPT_ECDSA_GetPrvKey(ctx, ecdsaParams);
658         if (ret != CRYPT_SUCCESS) {
659             BSL_SAL_Free(buffer);
660             BSL_ERR_PUSH_ERROR(ret);
661             return ret;
662         }
663         ecdsaParams[index].valueLen = ecdsaParams[index].useLen;
664         index++;
665     }
666     ret = processCb(ecdsaParams, args);
667     BSL_SAL_Free(buffer);
668     if (ret != CRYPT_SUCCESS) {
669         BSL_ERR_PUSH_ERROR(ret);
670     }
671     return ret;
672 }
673 #endif // HITLS_CRYPTO_PROVIDER
674 
675 #endif /* HITLS_CRYPTO_ECDSA */
676