• 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_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