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_ECC
18
19 #include <stdbool.h>
20 #include "crypt_errno.h"
21 #include "crypt_types.h"
22 #include "crypt_utils.h"
23 #include "securec.h"
24 #include "bsl_sal.h"
25 #include "bsl_err_internal.h"
26 #include "crypt_bn.h"
27 #include "crypt_ecc.h"
28 #include "ecc_local.h"
29 #include "crypt_ecc_pkey.h"
30 #include "crypt_params_key.h"
31
32 typedef struct {
33 const char *name; /* elliptic curve NIST name */
34 CRYPT_PKEY_ParaId id; /* elliptic curve ID */
35 } EC_NAME;
36
ECC_FreeCtx(ECC_Pkey * ctx)37 void ECC_FreeCtx(ECC_Pkey *ctx)
38 {
39 int ret = 0;
40 if (ctx == NULL) {
41 return;
42 }
43 BSL_SAL_AtomicDownReferences(&(ctx->references), &ret);
44 if (ret > 0) {
45 return;
46 }
47 BSL_SAL_ReferencesFree(&(ctx->references));
48 BN_Destroy(ctx->prvkey);
49 ECC_FreePoint(ctx->pubkey);
50 ECC_FreePara(ctx->para);
51 BSL_SAL_Free(ctx);
52 return;
53 }
54
ECC_DupCtx(ECC_Pkey * ctx)55 ECC_Pkey *ECC_DupCtx(ECC_Pkey *ctx)
56 {
57 if (ctx == NULL) {
58 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
59 return NULL;
60 }
61
62 ECC_Pkey *newCtx = BSL_SAL_Calloc(1u, sizeof(ECC_Pkey));
63 if (newCtx == NULL) {
64 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
65 return NULL;
66 }
67
68 newCtx->useCofactorMode = ctx->useCofactorMode;
69 newCtx->pointFormat = ctx->pointFormat;
70 BSL_SAL_ReferencesInit(&(newCtx->references));
71 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->prvkey, ctx->prvkey, BN_Dup(ctx->prvkey), CRYPT_MEM_ALLOC_FAIL);
72
73 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pubkey, ctx->pubkey, ECC_DupPoint(ctx->pubkey), CRYPT_MEM_ALLOC_FAIL);
74
75 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->para, ctx->para, ECC_DupPara(ctx->para), CRYPT_MEM_ALLOC_FAIL);
76 return newCtx;
77
78 ERR:
79 ECC_FreeCtx(newCtx);
80 return NULL;
81 }
82
83 // GetBits applies to both public and private keys.
84 // The public key requires the largest space. Therefore, the public key space prevails.
ECC_PkeyGetBits(const ECC_Pkey * ctx)85 uint32_t ECC_PkeyGetBits(const ECC_Pkey *ctx)
86 {
87 if ((ctx == NULL) || (ctx->para == NULL)) {
88 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
89 return 0;
90 }
91
92 // The length of ECC_ParaBits is internally specified and can ensure that the length is not 0. 1 byte = 8 bits.
93 uint32_t bytes = ((ECC_ParaBits(ctx->para) - 1) / 8) + 1;
94
95 // The public key contains 2 coordinates. The public key flag occupies is 1 byte. 1 byte = 8 bits.
96 return (bytes * 2 + 1) * 8;
97 }
98
ECC_PkeySetPrvKey(ECC_Pkey * ctx,const BSL_Param * para)99 int32_t ECC_PkeySetPrvKey(ECC_Pkey *ctx, const BSL_Param *para)
100 {
101 if (ctx == NULL || ctx->para == NULL || para == NULL) {
102 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
103 return CRYPT_NULL_INPUT;
104 }
105 const BSL_Param *prv = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_EC_PRVKEY);
106 if (prv == NULL || prv->value == NULL || prv->valueLen == 0) {
107 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
108 return CRYPT_NULL_INPUT;
109 }
110
111 int32_t ret;
112 BN_BigNum *paraN = ECC_GetParaN(ctx->para);
113 BN_BigNum *newPrvKey = BN_Create(ECC_ParaBits(ctx->para));
114 if ((paraN == NULL) || (newPrvKey == NULL)) {
115 ret = CRYPT_MEM_ALLOC_FAIL;
116 BSL_ERR_PUSH_ERROR(ret);
117 goto ERR;
118 }
119 if (ctx->para->id == CRYPT_ECC_SM2) {
120 (void)BN_SubLimb(paraN, paraN, 1);
121 }
122 ret = BN_Bin2Bn(newPrvKey, prv->value, prv->valueLen);
123 if (ret != CRYPT_SUCCESS) {
124 BSL_ERR_PUSH_ERROR(ret);
125 goto ERR;
126 }
127
128 if (BN_IsZero(newPrvKey) || (BN_Cmp(newPrvKey, paraN)) >= 0) {
129 ret = CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY;
130 BSL_ERR_PUSH_ERROR(ret);
131 goto ERR;
132 }
133
134 BN_Destroy(ctx->prvkey);
135 ctx->prvkey = newPrvKey;
136 BN_Destroy(paraN);
137 return CRYPT_SUCCESS;
138
139 ERR:
140 BN_Destroy(newPrvKey);
141 BN_Destroy(paraN);
142 return ret;
143 }
144
145 /**
146 * In NIST.SP.800-56 Ar3, the FFC Full Public-Key Validation Routine needs to check nQ = Ø.
147 * For performance considerations, we perform Partial public-key Validation (Section 5.6.2.3.4) when
148 * setting the Public Key.
149 */
ECC_PkeySetPubKey(ECC_Pkey * ctx,const BSL_Param * para)150 int32_t ECC_PkeySetPubKey(ECC_Pkey *ctx, const BSL_Param *para)
151 {
152 if (ctx == NULL || ctx->para == NULL || para == NULL) {
153 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
154 return CRYPT_NULL_INPUT;
155 }
156 // assume that the two scenarios will not coexist.
157 const BSL_Param *pub = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_EC_PUBKEY);
158 if (pub == NULL) {
159 pub = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
160 }
161 if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
162 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
163 return CRYPT_NULL_INPUT;
164 }
165 ECC_Point *newPubKey = ECC_NewPoint(ctx->para);
166 if (newPubKey == NULL) {
167 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
168 return CRYPT_MEM_ALLOC_FAIL;
169 }
170
171 int32_t ret = ECC_DecodePoint(ctx->para, newPubKey, pub->value, pub->valueLen);
172 if (ret == CRYPT_SUCCESS) {
173 ECC_FreePoint(ctx->pubkey);
174 ctx->pubkey = newPubKey;
175 return ret;
176 }
177 ECC_FreePoint(newPubKey);
178 return ret;
179 }
180
ECC_PkeyGetPrvKey(const ECC_Pkey * ctx,BSL_Param * para)181 int32_t ECC_PkeyGetPrvKey(const ECC_Pkey *ctx, BSL_Param *para)
182 {
183 if ((ctx == NULL) || (para == NULL)) {
184 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
185 return CRYPT_NULL_INPUT;
186 }
187 BSL_Param *prv = BSL_PARAM_FindParam(para, CRYPT_PARAM_EC_PRVKEY);
188 if (prv == NULL || prv->value == NULL || prv->valueLen == 0) {
189 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
190 return CRYPT_NULL_INPUT;
191 }
192 if (ctx->prvkey == NULL) {
193 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_EMPTY_KEY);
194 return CRYPT_ECC_PKEY_ERR_EMPTY_KEY;
195 }
196 uint32_t uesLen = prv->valueLen;
197 int32_t ret = BN_Bn2Bin(ctx->prvkey, prv->value, &uesLen);
198 if (ret != CRYPT_SUCCESS) {
199 BSL_ERR_PUSH_ERROR(ret);
200 return ret;
201 }
202 prv->useLen = uesLen;
203 return CRYPT_SUCCESS;
204 }
205
ECC_PkeyGetPubKey(const ECC_Pkey * ctx,BSL_Param * para)206 int32_t ECC_PkeyGetPubKey(const ECC_Pkey *ctx, BSL_Param *para)
207 {
208 if ((ctx == NULL) || (ctx->para == NULL) || (para == NULL)) {
209 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
210 return CRYPT_NULL_INPUT;
211 }
212 // assume that the two scenarios will not coexist.
213 BSL_Param *pub = BSL_PARAM_FindParam(para, CRYPT_PARAM_EC_PUBKEY);
214 if (pub == NULL) {
215 pub = BSL_PARAM_FindParam(para, CRYPT_PARAM_PKEY_ENCODE_PUBKEY);
216 }
217
218 if (pub == NULL || pub->value == NULL || pub->valueLen == 0) {
219 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
220 return CRYPT_NULL_INPUT;
221 }
222
223 if (ctx->pubkey == NULL) {
224 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_EMPTY_KEY);
225 return CRYPT_ECC_PKEY_ERR_EMPTY_KEY;
226 }
227 uint32_t useLen = pub->valueLen;
228 int32_t ret = ECC_EncodePoint(ctx->para, ctx->pubkey, pub->value, &useLen, ctx->pointFormat);
229 if (ret != CRYPT_SUCCESS) {
230 BSL_ERR_PUSH_ERROR(ret);
231 return ret;
232 }
233 pub->useLen = useLen;
234 return CRYPT_SUCCESS;
235 }
236
GenPrivateKey(ECC_Pkey * ctx)237 static int32_t GenPrivateKey(ECC_Pkey *ctx)
238 {
239 int32_t ret = CRYPT_SUCCESS;
240 uint32_t tryCount = 0;
241 uint32_t paraBits = ECC_ParaBits(ctx->para);
242 BN_BigNum *paraN = NULL;
243 if (ctx->para->id == CRYPT_ECC_SM2) {
244 paraN = BN_Create(paraBits);
245 if (paraN == NULL) {
246 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
247 return CRYPT_MEM_ALLOC_FAIL;
248 }
249 (void)BN_SubLimb(paraN, ctx->para->n, 1);
250 } else {
251 paraN = ctx->para->n;
252 }
253 if (ctx->prvkey == NULL) {
254 ctx->prvkey = BN_Create(paraBits);
255 if (ctx->prvkey == NULL) {
256 ret = CRYPT_MEM_ALLOC_FAIL;
257 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
258 goto EXIT;
259 }
260 }
261 do {
262 ret = BN_RandRangeEx(ctx->libCtx, ctx->prvkey, paraN);
263 if (ret != CRYPT_SUCCESS) {
264 BSL_ERR_PUSH_ERROR(ret);
265 goto EXIT;
266 }
267 tryCount += 1;
268 } while ((BN_IsZero(ctx->prvkey) == true) && (tryCount < CRYPT_ECC_TRY_MAX_CNT));
269
270 if (tryCount == CRYPT_ECC_TRY_MAX_CNT) {
271 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_TRY_CNT);
272 ret = CRYPT_ECC_PKEY_ERR_TRY_CNT;
273 }
274 EXIT:
275 if (paraN != ctx->para->n) {
276 BN_Destroy(paraN);
277 }
278 return ret;
279 }
280
ECC_GenPublicKey(ECC_Pkey * ctx)281 int32_t ECC_GenPublicKey(ECC_Pkey *ctx)
282 {
283 if (ctx->pubkey != NULL) {
284 return CRYPT_SUCCESS;
285 }
286 ctx->pubkey = ECC_NewPoint(ctx->para);
287 if (ctx->pubkey == NULL) {
288 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
289 return CRYPT_MEM_ALLOC_FAIL;
290 }
291 int32_t ret = ECC_PointMul(ctx->para, ctx->pubkey, ctx->prvkey, NULL);
292 if (ret != CRYPT_SUCCESS) {
293 ECC_FreePoint(ctx->pubkey);
294 ctx->pubkey = NULL;
295 }
296 return ret;
297 }
298
GenPublicKey(ECC_Pkey * ctx)299 static int32_t GenPublicKey(ECC_Pkey *ctx)
300 {
301 if (ctx->prvkey == NULL) {
302 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
303 return CRYPT_NULL_INPUT;
304 }
305
306 if (ctx->pubkey == NULL) {
307 ctx->pubkey = ECC_NewPoint(ctx->para);
308 if (ctx->pubkey == NULL) {
309 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
310 return CRYPT_MEM_ALLOC_FAIL;
311 }
312 }
313
314 return ECC_PointMul(ctx->para, ctx->pubkey, ctx->prvkey, NULL);
315 }
316
ECC_PkeyGen(ECC_Pkey * ctx)317 int32_t ECC_PkeyGen(ECC_Pkey *ctx)
318 {
319 if ((ctx == NULL) || (ctx->para == NULL)) {
320 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
321 return CRYPT_NULL_INPUT;
322 }
323
324 int32_t ret = GenPrivateKey(ctx);
325 if (ret != CRYPT_SUCCESS) {
326 goto ERR;
327 }
328
329 ret = GenPublicKey(ctx);
330 if (ret != CRYPT_SUCCESS) {
331 goto ERR;
332 }
333
334 return CRYPT_SUCCESS;
335 ERR:
336 BN_Zeroize(ctx->prvkey);
337 BN_Destroy(ctx->prvkey);
338 ctx->prvkey = NULL;
339 ECC_FreePoint(ctx->pubkey);
340 ctx->pubkey = NULL;
341 return ret;
342 }
343
EcCurveId2nist(CRYPT_PKEY_ParaId id)344 static const char *EcCurveId2nist(CRYPT_PKEY_ParaId id)
345 {
346 static EC_NAME nistCurves[] = {
347 {"P-224", CRYPT_ECC_NISTP224},
348 {"P-256", CRYPT_ECC_NISTP256},
349 {"P-384", CRYPT_ECC_NISTP384},
350 {"P-521", CRYPT_ECC_NISTP521}
351 };
352
353 for (uint32_t i = 0; i < sizeof(nistCurves) / sizeof(nistCurves[0]); i++) {
354 if (nistCurves[i].id == id) {
355 return nistCurves[i].name;
356 }
357 }
358 return NULL;
359 }
360
ECC_GetPubXYBnBin(ECC_Pkey * ctx,int32_t opt,void * val,uint32_t len)361 static int32_t ECC_GetPubXYBnBin(ECC_Pkey *ctx, int32_t opt, void *val, uint32_t len)
362 {
363 if (ctx->para == NULL || len != sizeof(CRYPT_Data) || val == NULL || ((CRYPT_Data *)val)->data == NULL) {
364 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
365 return CRYPT_INVALID_ARG;
366 }
367
368 int32_t ret;
369 uint32_t bits = BN_Bits(ctx->para->p);
370 BN_BigNum *x = BN_Create(bits);
371 BN_BigNum *y = BN_Create(bits);
372 do {
373 if (x == NULL || y == NULL) {
374 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
375 ret = CRYPT_MEM_ALLOC_FAIL;
376 break;
377 }
378 ret = ECC_GetPoint2Bn(ctx->para, ctx->pubkey, x, y);
379 if (ret != CRYPT_SUCCESS) {
380 break;
381 }
382 if (opt == CRYPT_CTRL_GET_ECC_PUB_X_BIN) {
383 ret = BN_Bn2Bin(x, ((CRYPT_Data *)val)->data, &((CRYPT_Data *)val)->len);
384 } else {
385 ret = BN_Bn2Bin(y, ((CRYPT_Data *)val)->data, &((CRYPT_Data *)val)->len);
386 }
387 } while (0);
388
389 BN_Destroy(x);
390 BN_Destroy(y);
391 return ret;
392 }
393
GetOrderBits(const ECC_Pkey * ctx)394 static uint32_t GetOrderBits(const ECC_Pkey *ctx)
395 {
396 if (ctx->para == NULL) {
397 BSL_ERR_PUSH_ERROR(CRYPT_ECC_ERR_PARA);
398 return 0;
399 }
400 return BN_Bits(ctx->para->n);
401 }
402
ECC_GetKeyLen(const ECC_Pkey * ctx)403 static uint32_t ECC_GetKeyLen(const ECC_Pkey *ctx)
404 {
405 if ((ctx == NULL) || (ctx->para == NULL)) {
406 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
407 return 0;
408 }
409 return BN_Bytes(ctx->para->p);
410 }
411
ECC_GetPubKeyLen(const ECC_Pkey * ctx)412 static uint32_t ECC_GetPubKeyLen(const ECC_Pkey *ctx)
413 {
414 uint32_t keylen = ECC_GetKeyLen(ctx);
415 if (keylen == 0) {
416 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
417 return 0;
418 }
419 if (ctx->pointFormat == CRYPT_POINT_COMPRESSED) {
420 return (keylen + 1);
421 }
422 return (keylen * 2 + 1);
423 }
424
GetEccName(ECC_Pkey * ctx,void * val,uint32_t len)425 static int32_t GetEccName(ECC_Pkey *ctx, void *val, uint32_t len)
426 {
427 if (ctx->para == NULL) {
428 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
429 return CRYPT_NULL_INPUT;
430 }
431 if (memcpy_s(val, len, EcCurveId2nist(ctx->para->id), strlen("P-521") + 1) != EOK) {
432 BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
433 return CRYPT_SECUREC_FAIL;
434 }
435 return CRYPT_SUCCESS;
436 }
437
SetEccPointFormat(ECC_Pkey * ctx,void * val,uint32_t len)438 static int32_t SetEccPointFormat(ECC_Pkey *ctx, void *val, uint32_t len)
439 {
440 if (len != sizeof(uint32_t)) {
441 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN);
442 return CRYPT_ECC_PKEY_ERR_CTRL_LEN;
443 }
444 uint32_t pointFormat = *(uint32_t *)val;
445 if (pointFormat >= CRYPT_POINT_MAX) {
446 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT);
447 return CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT;
448 }
449 ctx->pointFormat = pointFormat;
450 return CRYPT_SUCCESS;
451 }
452
SetEccUseCofactorMode(ECC_Pkey * ctx,void * val,uint32_t len)453 static int32_t SetEccUseCofactorMode(ECC_Pkey *ctx, void *val, uint32_t len)
454 {
455 if (len != sizeof(uint32_t)) {
456 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN);
457 return CRYPT_ECC_PKEY_ERR_CTRL_LEN;
458 }
459 ctx->useCofactorMode = *(uint32_t *)val;
460 return CRYPT_SUCCESS;
461 }
462
ECC_PkeyCtrl(ECC_Pkey * ctx,int32_t opt,void * val,uint32_t len)463 int32_t ECC_PkeyCtrl(ECC_Pkey *ctx, int32_t opt, void *val, uint32_t len)
464 {
465 if (ctx == NULL || (val == NULL && opt != CRYPT_CTRL_GEN_ECC_PUBLICKEY)) {
466 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
467 return CRYPT_NULL_INPUT;
468 }
469 switch (opt) {
470 case CRYPT_CTRL_GET_ECC_NAME:
471 return GetEccName(ctx, val, len);
472 case CRYPT_CTRL_GET_ECC_PUB_X_BIN:
473 case CRYPT_CTRL_GET_ECC_PUB_Y_BIN:
474 return ECC_GetPubXYBnBin(ctx, opt, val, len);
475 case CRYPT_CTRL_SET_ECC_POINT_FORMAT:
476 return SetEccPointFormat(ctx, val, len);
477 case CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE:
478 return SetEccUseCofactorMode(ctx, val, len);
479 case CRYPT_CTRL_GEN_ECC_PUBLICKEY:
480 return GenPublicKey(ctx);
481 case CRYPT_CTRL_GET_ECC_ORDER_BITS:
482 return GetUintCtrl(ctx, val, len, (GetUintCallBack)GetOrderBits);
483 case CRYPT_CTRL_GET_PUBKEY_LEN:
484 return GetUintCtrl(ctx, val, len, (GetUintCallBack)ECC_GetPubKeyLen);
485 case CRYPT_CTRL_GET_PRVKEY_LEN:
486 case CRYPT_CTRL_GET_SHARED_KEY_LEN:
487 return GetUintCtrl(ctx, val, len, (GetUintCallBack)ECC_GetKeyLen);
488 case CRYPT_CTRL_UP_REFERENCES:
489 if (len != (uint32_t)sizeof(int)) {
490 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN);
491 return CRYPT_ECC_PKEY_ERR_CTRL_LEN;
492 }
493 return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val);
494 default:
495 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION);
496 return CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION;
497 }
498 }
499
ECC_PkeyNewCtx(CRYPT_PKEY_ParaId id)500 ECC_Pkey *ECC_PkeyNewCtx(CRYPT_PKEY_ParaId id)
501 {
502 ECC_Para *para = ECC_NewPara(id);
503 if (para == NULL) {
504 return NULL;
505 }
506 ECC_Pkey *key = BSL_SAL_Calloc(1u, sizeof(ECC_Pkey));
507 if (key == NULL) {
508 ECC_FreePara(para);
509 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
510 return NULL;
511 }
512 key->para = para;
513 key->pointFormat = CRYPT_POINT_UNCOMPRESSED;
514 BSL_SAL_ReferencesInit(&(key->references));
515 return key;
516 }
517
ECC_PkeyCmp(const ECC_Pkey * a,const ECC_Pkey * b)518 int32_t ECC_PkeyCmp(const ECC_Pkey *a, const ECC_Pkey *b)
519 {
520 RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT);
521
522 // Compare public keys.
523 RETURN_RET_IF(ECC_PointCmp(a->para, a->pubkey, b->pubkey), CRYPT_ECC_KEY_PUBKEY_NOT_EQUAL);
524
525 // Compare parameters.
526 RETURN_RET_IF(b->para == NULL || a->para->id != b->para->id, CRYPT_ECC_POINT_ERR_CURVE_ID);
527
528 return CRYPT_SUCCESS;
529 }
530 #endif /* HITLS_CRYPTO_ECC */
531