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