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_SM2
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_encode_internal.h"
28 #include "crypt_ecc.h"
29 #include "crypt_ecc_pkey.h"
30 #include "crypt_local_types.h"
31 #include "crypt_sm2.h"
32 #include "sm2_local.h"
33 #include "eal_md_local.h"
34 #include "crypt_params_key.h"
35
Sm2SetUserId(CRYPT_SM2_Ctx * ctx,const uint8_t * val,uint32_t len)36 static int32_t Sm2SetUserId(CRYPT_SM2_Ctx *ctx, const uint8_t *val, uint32_t len)
37 {
38 ctx->userId = BSL_SAL_Calloc(len, 1u);
39 if (ctx->userId == NULL) {
40 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
41 return CRYPT_MEM_ALLOC_FAIL;
42 }
43 (void) memcpy_s(ctx->userId, len, val, len);
44 ctx->userIdLen = len;
45 return CRYPT_SUCCESS;
46 }
47
CRYPT_SM2_NewCtx(void)48 CRYPT_SM2_Ctx *CRYPT_SM2_NewCtx(void)
49 {
50 CRYPT_SM2_Ctx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_SM2_Ctx));
51 if (ctx == NULL) {
52 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
53 return NULL;
54 }
55 ctx->pkey = ECC_PkeyNewCtx(CRYPT_ECC_SM2);
56 if (ctx->pkey == NULL) {
57 CRYPT_SM2_FreeCtx(ctx);
58 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
59 return NULL;
60 }
61
62 const EAL_MdMethod *mdMethod = EAL_MdFindMethod(CRYPT_MD_SM3);
63 if (mdMethod == NULL) {
64 CRYPT_SM2_FreeCtx(ctx);
65 BSL_ERR_PUSH_ERROR(CRYPT_EVENT_ERR);
66 return NULL;
67 }
68 ctx->hashMethod = (const EAL_MdMethod *)mdMethod;
69 ctx->server = 1; // Indicates the initiator by default.
70 ctx->isSumValid = 0; // checksum is invalid by default.
71 BSL_SAL_ReferencesInit(&(ctx->references));
72 return ctx;
73 }
74
CRYPT_SM2_NewCtxEx(void * libCtx)75 CRYPT_SM2_Ctx *CRYPT_SM2_NewCtxEx(void *libCtx)
76 {
77 CRYPT_SM2_Ctx *ctx = CRYPT_SM2_NewCtx();
78 if (ctx == NULL) {
79 return NULL;
80 }
81 ctx->pkey->libCtx = libCtx;
82 ECC_SetLibCtx(ctx->pkey->libCtx, ctx->pkey->para);
83 return ctx;
84 }
85
CRYPT_SM2_DupCtx(CRYPT_SM2_Ctx * ctx)86 CRYPT_SM2_Ctx *CRYPT_SM2_DupCtx(CRYPT_SM2_Ctx *ctx)
87 {
88 if (ctx == NULL) {
89 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
90 return NULL;
91 }
92
93 CRYPT_SM2_Ctx *newCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_SM2_Ctx));
94 if (newCtx == NULL) {
95 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
96 return NULL;
97 }
98
99 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pkey, ctx->pkey, ECC_DupCtx(ctx->pkey), CRYPT_MEM_ALLOC_FAIL);
100 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pointR, ctx->pointR, ECC_DupPoint(ctx->pointR), CRYPT_MEM_ALLOC_FAIL);
101 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->r, ctx->r, BN_Dup(ctx->r), CRYPT_MEM_ALLOC_FAIL);
102 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->userId, ctx->userId, BSL_SAL_Dump(ctx->userId, ctx->userIdLen),
103 CRYPT_MEM_ALLOC_FAIL);
104 newCtx->userIdLen = ctx->userIdLen;
105
106 newCtx->pkgImpl = ctx->pkgImpl;
107 newCtx->hashMethod = ctx->hashMethod;
108 newCtx->server = ctx->server;
109 newCtx->isSumValid = ctx->isSumValid;
110 BSL_SAL_ReferencesInit(&(newCtx->references));
111 (void)memcpy_s(newCtx->sumCheck, SM3_MD_SIZE, ctx->sumCheck, SM3_MD_SIZE);
112 (void)memcpy_s(newCtx->sumSend, SM3_MD_SIZE, ctx->sumSend, SM3_MD_SIZE);
113
114 return newCtx;
115 ERR:
116 CRYPT_SM2_FreeCtx(newCtx);
117 return NULL;
118 }
119
CRYPT_SM2_FreeCtx(CRYPT_SM2_Ctx * ctx)120 void CRYPT_SM2_FreeCtx(CRYPT_SM2_Ctx *ctx)
121 {
122 int val = 0;
123 if (ctx == NULL) {
124 return;
125 }
126 BSL_SAL_AtomicDownReferences(&(ctx->references), &val);
127 if (val > 0) {
128 return;
129 }
130 BSL_SAL_ReferencesFree(&(ctx->references));
131 ECC_FreeCtx(ctx->pkey);
132
133 BSL_SAL_FREE(ctx->userId);
134 BN_Destroy(ctx->r);
135 ECC_FreePoint(ctx->pointR);
136 BSL_SAL_FREE(ctx);
137 return;
138 }
139
Sm2ComputeZDigest(const CRYPT_SM2_Ctx * ctx,uint8_t * out,uint32_t * outLen)140 int32_t Sm2ComputeZDigest(const CRYPT_SM2_Ctx *ctx, uint8_t *out, uint32_t *outLen)
141 {
142 int32_t ret;
143 if (ctx->userIdLen >= (UINT16_MAX / 8)) {
144 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ID_TOO_LARGE);
145 return CRYPT_SM2_ID_TOO_LARGE;
146 }
147 /* 2-byte id length in bits */
148 uint16_t entl = (uint16_t)(8 * ctx->userIdLen);
149 uint8_t eByte = (uint8_t)(entl >> 8);
150 uint8_t maxPubData[SM2_MAX_PUBKEY_DATA_LENGTH] = {0};
151 CRYPT_Sm2Pub pub = {maxPubData, SM2_MAX_PUBKEY_DATA_LENGTH};
152 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
153 BN_BigNum *a = ECC_GetParaA(ctx->pkey->para);
154 BN_BigNum *b = ECC_GetParaB(ctx->pkey->para);
155 BN_BigNum *xG = ECC_GetParaX(ctx->pkey->para);
156 BN_BigNum *yG = ECC_GetParaY(ctx->pkey->para);
157 void *mdCtx = ctx->hashMethod->newCtx();
158 uint8_t *buf = BSL_SAL_Calloc(1u, keyBits);
159 if (a == NULL || b == NULL || xG == NULL || yG == NULL || buf == NULL || mdCtx == NULL) {
160 ret = CRYPT_MEM_ALLOC_FAIL;
161 BSL_ERR_PUSH_ERROR(ret);
162 goto ERR;
163 }
164 BSL_Param tmpPara[2] = {{CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS, maxPubData,
165 SM2_MAX_PUBKEY_DATA_LENGTH, 0}, BSL_PARAM_END};
166 GOTO_ERR_IF(CRYPT_SM2_GetPubKey(ctx, tmpPara), ret);
167 pub.len = tmpPara[0].useLen;
168 GOTO_ERR_IF(ctx->hashMethod->init(mdCtx, NULL), ret);
169 // User A has a distinguishable identifier IDA with a length of entlenA bits,
170 // and ENTLA is two bytes converted from an integer entlenA
171 // H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
172 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, &eByte, 1), ret); // ENTLA
173 eByte = entl & 0xFF;
174 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, &eByte, 1), ret); // ENTLA
175 if (ctx->userIdLen > 0) {
176 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, ctx->userId, ctx->userIdLen), ret); // IDA
177 }
178 GOTO_ERR_IF_EX(BN_Bn2Bin(a, buf, &keyBits), ret);
179 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // a
180 GOTO_ERR_IF_EX(BN_Bn2Bin(b, buf, &keyBits), ret);
181 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // b
182 GOTO_ERR_IF_EX(BN_Bn2Bin(xG, buf, &keyBits), ret);
183 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // xG
184 keyBits = CRYPT_SM2_GetBits(ctx);
185 GOTO_ERR_IF_EX(BN_Bn2Bin(yG, buf, &keyBits), ret);
186 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, buf, keyBits), ret); // yG
187 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, pub.data + 1, pub.len - 1), ret); // xA and yA
188 GOTO_ERR_IF(ctx->hashMethod->final(mdCtx, out, outLen), ret);
189 ERR:
190 ctx->hashMethod->freeCtx(mdCtx);
191 BN_Destroy(a);
192 BN_Destroy(b);
193 BN_Destroy(xG);
194 BN_Destroy(yG);
195 BSL_SAL_FREE(buf);
196 return ret;
197 }
198
199 #ifdef HITLS_CRYPTO_SM2_SIGN
Sm2ComputeMsgHash(const CRYPT_SM2_Ctx * ctx,const uint8_t * msg,uint32_t msgLen,BN_BigNum * e)200 static int32_t Sm2ComputeMsgHash(const CRYPT_SM2_Ctx *ctx, const uint8_t *msg, uint32_t msgLen, BN_BigNum *e)
201 {
202 int ret;
203 uint8_t out[SM3_MD_SIZE];
204 uint32_t outLen = sizeof(out);
205 void *mdCtx = ctx->hashMethod->newCtx();
206 if (mdCtx == NULL) {
207 ret = CRYPT_MEM_ALLOC_FAIL;
208 BSL_ERR_PUSH_ERROR(ret);
209 goto ERR;
210 }
211 GOTO_ERR_IF_EX(Sm2ComputeZDigest(ctx, out, &outLen), ret);
212 GOTO_ERR_IF(ctx->hashMethod->init(mdCtx, NULL), ret);
213 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, out, outLen), ret);
214 GOTO_ERR_IF(ctx->hashMethod->update(mdCtx, msg, msgLen), ret);
215 GOTO_ERR_IF(ctx->hashMethod->final(mdCtx, out, &outLen), ret);
216 GOTO_ERR_IF_EX(BN_Bin2Bn(e, out, outLen), ret);
217 ERR:
218 ctx->hashMethod->freeCtx(mdCtx);
219 return ret;
220 }
221 #endif
222
CRYPT_SM2_GetBits(const CRYPT_SM2_Ctx * ctx)223 uint32_t CRYPT_SM2_GetBits(const CRYPT_SM2_Ctx *ctx)
224 {
225 if (ctx == NULL) {
226 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
227 return 0;
228 }
229 return ECC_PkeyGetBits(ctx->pkey);
230 }
231
CRYPT_SM2_SetPrvKey(CRYPT_SM2_Ctx * ctx,const BSL_Param * para)232 int32_t CRYPT_SM2_SetPrvKey(CRYPT_SM2_Ctx *ctx, const BSL_Param *para)
233 {
234 if (ctx == NULL) {
235 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
236 return CRYPT_NULL_INPUT;
237 }
238 return ECC_PkeySetPrvKey(ctx->pkey, para);
239 }
240
CRYPT_SM2_SetPubKey(CRYPT_SM2_Ctx * ctx,const BSL_Param * para)241 int32_t CRYPT_SM2_SetPubKey(CRYPT_SM2_Ctx *ctx, const BSL_Param *para)
242 {
243 if (ctx == NULL) {
244 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
245 return CRYPT_NULL_INPUT;
246 }
247 return ECC_PkeySetPubKey(ctx->pkey, para);
248 }
249
CRYPT_SM2_GetPrvKey(const CRYPT_SM2_Ctx * ctx,BSL_Param * para)250 int32_t CRYPT_SM2_GetPrvKey(const CRYPT_SM2_Ctx *ctx, BSL_Param *para)
251 {
252 if (ctx == NULL) {
253 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
254 return CRYPT_NULL_INPUT;
255 }
256
257 return ECC_PkeyGetPrvKey(ctx->pkey, para);
258 }
259
CRYPT_SM2_GetPubKey(const CRYPT_SM2_Ctx * ctx,BSL_Param * para)260 int32_t CRYPT_SM2_GetPubKey(const CRYPT_SM2_Ctx *ctx, BSL_Param *para)
261 {
262 if (ctx == NULL) {
263 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
264 return CRYPT_NULL_INPUT;
265 }
266
267 return ECC_PkeyGetPubKey(ctx->pkey, para);
268 }
269
CRYPT_SM2_Gen(CRYPT_SM2_Ctx * ctx)270 int32_t CRYPT_SM2_Gen(CRYPT_SM2_Ctx *ctx)
271 {
272 if (ctx == NULL) {
273 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
274 return CRYPT_NULL_INPUT;
275 }
276
277 return ECC_PkeyGen(ctx->pkey);
278 }
279
280 #ifdef HITLS_CRYPTO_PROVIDER
CRYPT_SM2_Import(CRYPT_SM2_Ctx * ctx,const BSL_Param * params)281 int32_t CRYPT_SM2_Import(CRYPT_SM2_Ctx *ctx, const BSL_Param *params)
282 {
283 if (ctx == NULL || params == NULL) {
284 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
285 return CRYPT_NULL_INPUT;
286 }
287 int32_t ret;
288 const BSL_Param *prv = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PRVKEY);
289 const BSL_Param *pub = BSL_PARAM_FindConstParam(params, CRYPT_PARAM_EC_PUBKEY);
290 if (prv != NULL) {
291 ret = CRYPT_SM2_SetPrvKey(ctx, prv);
292 if (ret != CRYPT_SUCCESS) {
293 BSL_ERR_PUSH_ERROR(ret);
294 return ret;
295 }
296 }
297 if (pub != NULL) {
298 ret = CRYPT_SM2_SetPubKey(ctx, pub);
299 if (ret != CRYPT_SUCCESS) {
300 BSL_ERR_PUSH_ERROR(ret);
301 return ret;
302 }
303 }
304
305 return CRYPT_SUCCESS;
306 }
307
CRYPT_SM2_Export(const CRYPT_SM2_Ctx * ctx,BSL_Param * params)308 int32_t CRYPT_SM2_Export(const CRYPT_SM2_Ctx *ctx, BSL_Param *params)
309 {
310 if (ctx == NULL || params == NULL) {
311 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
312 return CRYPT_NULL_INPUT;
313 }
314 uint32_t index = 0;
315 uint32_t keyBytes = (CRYPT_SM2_GetBits(ctx) + 7) / 8;
316 CRYPT_EAL_ProcessFuncCb processCb = NULL;
317 void *args = NULL;
318 BSL_Param sm2Params[3] = {0};
319 int32_t ret = CRYPT_GetPkeyProcessParams(params, &processCb, &args);
320 if (ret != CRYPT_SUCCESS) {
321 BSL_ERR_PUSH_ERROR(ret);
322 return ret;
323 }
324 uint8_t *buffer = BSL_SAL_Calloc(1, keyBytes * 2);
325 if (buffer == NULL) {
326 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
327 return CRYPT_MEM_ALLOC_FAIL;
328 }
329 if (ctx->pkey->prvkey != NULL) {
330 (void)BSL_PARAM_InitValue(&sm2Params[index], CRYPT_PARAM_EC_PRVKEY, BSL_PARAM_TYPE_OCTETS, buffer, keyBytes);
331 ret = CRYPT_SM2_GetPrvKey(ctx, sm2Params);
332 if (ret != CRYPT_SUCCESS) {
333 BSL_SAL_Free(buffer);
334 BSL_ERR_PUSH_ERROR(ret);
335 return ret;
336 }
337 sm2Params[index].valueLen = sm2Params[index].useLen;
338 index++;
339 }
340 if (ctx->pkey->pubkey != NULL) {
341 (void)BSL_PARAM_InitValue(&sm2Params[index], CRYPT_PARAM_EC_PUBKEY, BSL_PARAM_TYPE_OCTETS,
342 buffer, keyBytes);
343 ret = CRYPT_SM2_GetPubKey(ctx, sm2Params);
344 if (ret != CRYPT_SUCCESS) {
345 BSL_SAL_Free(buffer);
346 BSL_ERR_PUSH_ERROR(ret);
347 return ret;
348 }
349 sm2Params[index].valueLen = sm2Params[index].useLen;
350 index++;
351 }
352 ret = processCb(sm2Params, args);
353 BSL_SAL_Free(buffer);
354 if (ret != CRYPT_SUCCESS) {
355 BSL_ERR_PUSH_ERROR(ret);
356 }
357 return ret;
358 }
359 #endif
360 #ifdef HITLS_CRYPTO_SM2_SIGN
CRYPT_SM2_GetSignLen(const CRYPT_SM2_Ctx * ctx)361 uint32_t CRYPT_SM2_GetSignLen(const CRYPT_SM2_Ctx *ctx)
362 {
363 if (ctx == NULL || ctx->pkey == NULL) {
364 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
365 return 0;
366 }
367 uint32_t qLen = (ECC_ParaBits(ctx->pkey->para) / 8) + 1;
368 uint32_t maxSignLen = 0;
369 int32_t ret = CRYPT_EAL_GetSignEncodeLen(qLen, qLen, &maxSignLen);
370 if (ret != CRYPT_SUCCESS) {
371 BSL_ERR_PUSH_ERROR(ret);
372 return 0;
373 }
374 return maxSignLen;
375 }
376
Sm2SignCore(const CRYPT_SM2_Ctx * ctx,BN_BigNum * e,BN_BigNum * r,BN_BigNum * s)377 static int32_t Sm2SignCore(const CRYPT_SM2_Ctx *ctx, BN_BigNum *e, BN_BigNum *r, BN_BigNum *s)
378 {
379 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
380 BN_BigNum *k = BN_Create(keyBits);
381 BN_BigNum *tmp = BN_Create(keyBits);
382 // An extra bit is allocated to prevent the number of bits in the result of adding BNs from exceeding the keybits.
383 BN_BigNum *t = BN_Create(keyBits + 1);
384 BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para);
385 ECC_Point *pt = ECC_NewPoint(ctx->pkey->para);
386 BN_Optimizer *opt = BN_OptimizerCreate();
387 int32_t ret, i;
388
389 if ((k == NULL) || (tmp == NULL) || (t == NULL) || (pt == NULL) || (paraN == NULL) || (opt == NULL)) {
390 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
391 ret = CRYPT_MEM_ALLOC_FAIL;
392 goto ERR;
393 }
394 for (i = 0; i < CRYPT_ECC_TRY_MAX_CNT; i++) {
395 GOTO_ERR_IF(BN_RandRangeEx(ctx->pkey->libCtx, k, paraN), ret);
396 if (BN_IsZero(k)) {
397 continue;
398 }
399 // pt = k * G
400 GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, pt, k, NULL), ret);
401 // r = (e + pt->x) mod n
402 GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, pt, tmp), ret);
403 GOTO_ERR_IF(BN_ModAdd(r, e, tmp, paraN, opt), ret);
404 // if r == 0 || r + k == n, then restart
405 GOTO_ERR_IF(BN_Add(t, r, k), ret);
406 if (BN_IsZero(r) || BN_Cmp(t, paraN) == 0) {
407 continue;
408 }
409 // prvkey * r mod n == (r * dA) mod n
410 GOTO_ERR_IF(BN_ModMul(s, ctx->pkey->prvkey, r, paraN, opt), ret);
411 // k - prvkey * r mod n
412 GOTO_ERR_IF(BN_ModSub(s, k, s, paraN, opt), ret);
413 // 1/(1 + d) mod n, tmp stores 1/(1 + d)
414 GOTO_ERR_IF(BN_AddLimb(t, ctx->pkey->prvkey, 1), ret);
415 GOTO_ERR_IF(ECC_ModOrderInv(ctx->pkey->para, tmp, t), ret);
416 // s = (1/(1+d)) * (k - prvkey * r) mod n
417 GOTO_ERR_IF(BN_ModMul(s, tmp, s, paraN, opt), ret);
418 // if s == 0, then restart
419 if (BN_IsZero(s) != true) {
420 break;
421 }
422 }
423
424 if (i >= CRYPT_ECC_TRY_MAX_CNT) {
425 ret = CRYPT_SM2_ERR_TRY_CNT;
426 BSL_ERR_PUSH_ERROR(ret);
427 }
428
429 ERR:
430 BN_Destroy(k);
431 BN_Destroy(tmp);
432 BN_Destroy(t);
433 BN_Destroy(paraN);
434 ECC_FreePoint(pt);
435 BN_OptimizerDestroy(opt);
436 return ret;
437 }
438
KeyCheckAndPubGen(const CRYPT_SM2_Ctx * ctx)439 int32_t KeyCheckAndPubGen(const CRYPT_SM2_Ctx *ctx)
440 {
441 int32_t ret;
442 if (ctx->pkey == NULL) {
443 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_EMPTY_KEY);
444 return CRYPT_SM2_ERR_EMPTY_KEY;
445 }
446
447 if (ctx->pkey->prvkey == NULL) {
448 BSL_ERR_PUSH_ERROR(CRYPT_SM2_NO_PRVKEY);
449 return CRYPT_SM2_NO_PRVKEY;
450 }
451 if (ctx->pkey->pubkey != NULL) {
452 return CRYPT_SUCCESS;
453 }
454 ret = ECC_GenPublicKey(ctx->pkey);
455 if (ret != CRYPT_SUCCESS) {
456 BSL_ERR_PUSH_ERROR(ret);
457 }
458 return ret;
459 }
460
CRYPT_SM2_Sign(const CRYPT_SM2_Ctx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)461 int32_t CRYPT_SM2_Sign(const CRYPT_SM2_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
462 uint8_t *sign, uint32_t *signLen)
463 {
464 int32_t ret;
465 if (algId != CRYPT_MD_SM3) {
466 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
467 return CRYPT_EAL_ERR_ALGID;
468 }
469
470 if ((ctx == NULL) || (sign == NULL) || (signLen == NULL) || ((data == NULL) && (dataLen != 0))) {
471 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
472 return CRYPT_NULL_INPUT;
473 }
474 ret = KeyCheckAndPubGen(ctx);
475 if (ret != CRYPT_SUCCESS) {
476 return ret;
477 }
478
479 if (ctx->hashMethod == NULL) {
480 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD);
481 return CRYPT_SM2_ERR_NO_HASH_METHOD;
482 }
483 if (*signLen < CRYPT_SM2_GetSignLen(ctx)) {
484 BSL_ERR_PUSH_ERROR(CRYPT_SM2_BUFF_LEN_NOT_ENOUGH);
485 return CRYPT_SM2_BUFF_LEN_NOT_ENOUGH;
486 }
487
488 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
489 BN_BigNum *r = BN_Create(keyBits);
490 BN_BigNum *s = BN_Create(keyBits);
491 BN_BigNum *d = BN_Create(keyBits);
492 if (r == NULL || s == NULL || d == NULL) {
493 ret = CRYPT_MEM_ALLOC_FAIL;
494 BSL_ERR_PUSH_ERROR(ret);
495 goto ERR;
496 }
497
498 GOTO_ERR_IF_EX(Sm2ComputeMsgHash(ctx, data, dataLen, d), ret);
499 GOTO_ERR_IF_EX(Sm2SignCore(ctx, d, r, s), ret);
500 ret = CRYPT_EAL_EncodeSign(r, s, sign, signLen);
501 if (ret != CRYPT_SUCCESS) {
502 BSL_ERR_PUSH_ERROR(ret);
503 }
504 ERR:
505 BN_Destroy(r);
506 BN_Destroy(s);
507 BN_Destroy(d);
508 return ret;
509 }
510
VerifyCheckSign(const CRYPT_SM2_Ctx * ctx,BN_BigNum * r,BN_BigNum * s)511 static int32_t VerifyCheckSign(const CRYPT_SM2_Ctx *ctx, BN_BigNum *r, BN_BigNum *s)
512 {
513 if (ctx->pkey->para == NULL) {
514 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
515 return CRYPT_NULL_INPUT;
516 }
517 BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para);
518 if (paraN == NULL) {
519 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
520 return CRYPT_MEM_ALLOC_FAIL;
521 }
522
523 if ((BN_Cmp(r, paraN) >= 0) || (BN_Cmp(s, paraN) >= 0)) {
524 BN_Destroy(paraN);
525 BSL_ERR_PUSH_ERROR(CRYPT_SM2_VERIFY_FAIL);
526 return CRYPT_SM2_VERIFY_FAIL;
527 }
528 BN_Destroy(paraN);
529 if (BN_IsZero(r) || BN_IsZero(s)) {
530 BSL_ERR_PUSH_ERROR(CRYPT_SM2_VERIFY_FAIL);
531 return CRYPT_SM2_VERIFY_FAIL;
532 }
533
534 return CRYPT_SUCCESS;
535 }
536
Sm2VerifyCore(const CRYPT_SM2_Ctx * ctx,BN_BigNum * e,const BN_BigNum * r,const BN_BigNum * s)537 static int32_t Sm2VerifyCore(const CRYPT_SM2_Ctx *ctx, BN_BigNum *e, const BN_BigNum *r, const BN_BigNum *s)
538 {
539 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
540 BN_BigNum *t = BN_Create(keyBits);
541 ECC_Point *tpt = ECC_NewPoint(ctx->pkey->para);
542 BN_BigNum *tptX = BN_Create(keyBits);
543 BN_Optimizer *opt = BN_OptimizerCreate();
544 BN_BigNum *paraN = ECC_GetParaN(ctx->pkey->para);
545 int32_t ret;
546
547 if ((t == NULL) || (tpt == NULL) || (tptX == NULL) || (paraN == NULL) || (opt == NULL)) {
548 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
549 ret = CRYPT_MEM_ALLOC_FAIL;
550 goto ERR;
551 }
552 // B5: calculate t = (r' + s') modn, verification failed if t=0
553 GOTO_ERR_IF_EX(BN_ModAddQuick(t, r, s, paraN, opt), ret);
554 if (BN_IsZero(t)) {
555 ret = CRYPT_SM2_VERIFY_FAIL;
556 BSL_ERR_PUSH_ERROR(ret);
557 }
558 // calculate the point (x1', y1')=[s']G + [t]PA
559 GOTO_ERR_IF(ECC_PointMulAdd(ctx->pkey->para, tpt, s, t, ctx->pkey->pubkey), ret);
560 GOTO_ERR_IF_EX(ECC_GetPointDataX(ctx->pkey->para, tpt, tptX), ret);
561 // calculate R=(e'+x1') modn, verification pass if yes, otherwise failed
562 GOTO_ERR_IF_EX(BN_ModAdd(t, e, tptX, paraN, opt), ret);
563 if (BN_Cmp(r, t) != 0) {
564 ret = CRYPT_SM2_VERIFY_FAIL;
565 BSL_ERR_PUSH_ERROR(ret);
566 }
567
568 ERR:
569 BN_Destroy(t);
570 BN_Destroy(paraN);
571 ECC_FreePoint(tpt);
572 BN_Destroy(tptX);
573 BN_OptimizerDestroy(opt);
574 return ret;
575 }
576
IsParaVaild(const CRYPT_SM2_Ctx * ctx)577 static int32_t IsParaVaild(const CRYPT_SM2_Ctx *ctx)
578 {
579 if (ctx->pkey == NULL) {
580 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_EMPTY_KEY);
581 return CRYPT_SM2_ERR_EMPTY_KEY;
582 }
583
584 if (ctx->pkey->pubkey == NULL) {
585 BSL_ERR_PUSH_ERROR(CRYPT_SM2_NO_PUBKEY);
586 return CRYPT_SM2_NO_PUBKEY;
587 }
588
589 if (ctx->hashMethod == NULL) {
590 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_NO_HASH_METHOD);
591 return CRYPT_SM2_ERR_NO_HASH_METHOD;
592 }
593
594 return CRYPT_SUCCESS;
595 }
596
CRYPT_SM2_Verify(const CRYPT_SM2_Ctx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)597 int32_t CRYPT_SM2_Verify(const CRYPT_SM2_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
598 const uint8_t *sign, uint32_t signLen)
599 {
600 if (algId != CRYPT_MD_SM3) {
601 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
602 return CRYPT_EAL_ERR_ALGID;
603 }
604 if ((ctx == NULL) || ((data == NULL) && (dataLen != 0)) || (sign == NULL) || (signLen == 0)) {
605 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
606 return CRYPT_NULL_INPUT;
607 }
608 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
609 int32_t ret = IsParaVaild(ctx);
610 if (ret != CRYPT_SUCCESS) {
611 return ret;
612 }
613 BN_BigNum *r = BN_Create(keyBits);
614 BN_BigNum *s = BN_Create(keyBits);
615 BN_BigNum *e = BN_Create(keyBits);
616 if (r == NULL || s == NULL || e == NULL) {
617 ret = CRYPT_MEM_ALLOC_FAIL;
618 BSL_ERR_PUSH_ERROR(ret);
619 goto ERR;
620 }
621 GOTO_ERR_IF_EX(Sm2ComputeMsgHash(ctx, data, dataLen, e), ret);
622 GOTO_ERR_IF(CRYPT_EAL_DecodeSign(sign, signLen, r, s), ret);
623 // Verify that r->s and s->s are within the range of 1~n-1.
624 GOTO_ERR_IF_EX(VerifyCheckSign(ctx, r, s), ret);
625 GOTO_ERR_IF_EX(Sm2VerifyCore(ctx, e, r, s), ret);
626 ERR:
627 BN_Destroy(r);
628 BN_Destroy(s);
629 BN_Destroy(e);
630 return ret;
631 }
632 #endif
633
Sm2Clean(CRYPT_SM2_Ctx * ctx)634 static void Sm2Clean(CRYPT_SM2_Ctx *ctx)
635 {
636 BN_Destroy(ctx->r);
637 ctx->r = NULL;
638 ECC_FreePoint(ctx->pointR);
639 ctx->pointR = NULL;
640 ctx->isSumValid = 0;
641 return;
642 }
643
Sm2GenerateR(CRYPT_SM2_Ctx * ctx,void * val,uint32_t len)644 static int32_t Sm2GenerateR(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len)
645 {
646 if (val == NULL) {
647 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
648 return CRYPT_NULL_INPUT;
649 }
650 int32_t ret;
651 Sm2Clean(ctx);
652 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
653 int32_t tryNum = 0;
654 BN_BigNum *order = ECC_GetParaN(ctx->pkey->para);
655 ctx->r = BN_Create(keyBits);
656 ctx->pointR = ECC_NewPoint(ctx->pkey->para);
657 BN_BigNum *tmp = BN_Create(keyBits);
658 if (order == NULL || ctx->r == NULL || ctx->pointR == NULL || tmp == NULL) {
659 ret = CRYPT_MEM_ALLOC_FAIL;
660 BSL_ERR_PUSH_ERROR(ret);
661 goto ERR;
662 }
663 for (; tryNum < CRYPT_ECC_TRY_MAX_CNT; tryNum++) {
664 GOTO_ERR_IF_EX(BN_RandRangeEx(ctx->pkey->libCtx, ctx->r, order), ret);
665 if (!BN_IsZero(ctx->r)) {
666 break;
667 }
668 }
669
670 if (tryNum >= CRYPT_ECC_TRY_MAX_CNT) {
671 ret = CRYPT_SM2_ERR_TRY_CNT;
672 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_TRY_CNT);
673 goto ERR;
674 }
675
676 GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, ctx->pointR, ctx->r, NULL), ret);
677 GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, ctx->pointR, tmp), ret);
678 GOTO_ERR_IF(ECC_EncodePoint(ctx->pkey->para, ctx->pointR, (uint8_t *)val, &len, CRYPT_POINT_UNCOMPRESSED), ret);
679 BN_Destroy(tmp);
680 BN_Destroy(order);
681 return ret;
682 ERR:
683 BN_Destroy(tmp);
684 BN_Destroy(order);
685 Sm2Clean(ctx);
686 return ret;
687 }
688
Sm2SetR(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)689 static int32_t Sm2SetR(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
690 {
691 if (val == NULL) {
692 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
693 return CRYPT_NULL_INPUT;
694 }
695 int32_t ret;
696 Sm2Clean(ctx);
697 ECC_Point *rs = ECC_NewPoint(ctx->pkey->para);
698 if (rs == NULL) {
699 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
700 return CRYPT_MEM_ALLOC_FAIL;
701 }
702 ret = ECC_DecodePoint(ctx->pkey->para, rs, (const uint8_t *)val, len);
703 if (ret != CRYPT_SUCCESS) {
704 ECC_FreePoint(rs);
705 BSL_ERR_PUSH_ERROR(ret);
706 return ret;
707 }
708 ctx->pointR = rs;
709 return ret;
710 }
711
Sm2SetRandom(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)712 static int32_t Sm2SetRandom(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
713 {
714 int32_t ret;
715 uint32_t keyBits = CRYPT_SM2_GetBits(ctx);
716 BN_BigNum *order = ECC_GetParaN(ctx->pkey->para);
717 ctx->r = BN_Create(keyBits);
718 ctx->pointR = ECC_NewPoint(ctx->pkey->para);
719 BN_BigNum *tmp = BN_Create(keyBits);
720 if (order == NULL || ctx->r == NULL || ctx->pointR == NULL || tmp == NULL) {
721 ret = CRYPT_MEM_ALLOC_FAIL;
722 BSL_ERR_PUSH_ERROR(ret);
723 goto ERR;
724 }
725
726 ret = BN_Bin2Bn(ctx->r, (const uint8_t *)val, len);
727 if (ret != CRYPT_SUCCESS) {
728 BSL_ERR_PUSH_ERROR(ret);
729 goto ERR;
730 }
731
732 GOTO_ERR_IF(ECC_PointMul(ctx->pkey->para, ctx->pointR, ctx->r, NULL), ret);
733 GOTO_ERR_IF(ECC_GetPointDataX(ctx->pkey->para, ctx->pointR, tmp), ret);
734 BN_Destroy(order);
735 BN_Destroy(tmp);
736 return ret;
737 ERR:
738 BN_Destroy(order);
739 BN_Destroy(tmp);
740 Sm2Clean(ctx);
741 return ret;
742 }
743
Sm2GetSumSend(CRYPT_SM2_Ctx * ctx,void * val,uint32_t len)744 static int32_t Sm2GetSumSend(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len)
745 {
746 if (val == NULL) {
747 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
748 return CRYPT_NULL_INPUT;
749 }
750 int32_t ret;
751 if (ctx->isSumValid != 1) {
752 ret = CRYPT_SM2_ERR_S_NOT_SET;
753 BSL_ERR_PUSH_ERROR(ret);
754 return ret;
755 }
756 if (len != SM3_MD_SIZE) {
757 ret = CRYPT_SM2_BUFF_LEN_NOT_ENOUGH;
758 BSL_ERR_PUSH_ERROR(ret);
759 return ret;
760 }
761 ret = memcpy_s((uint8_t *)val, len, ctx->sumSend, SM3_MD_SIZE);
762 if (ret != EOK) {
763 ret = CRYPT_SM2_ERR_GET_S;
764 BSL_ERR_PUSH_ERROR(ret);
765 return ret;
766 }
767
768 return CRYPT_SUCCESS;
769 }
770
771 /* consttime memcmp function */
IsDataEqual(const uint8_t * data1,const uint8_t * data2,uint32_t len)772 static int32_t IsDataEqual(const uint8_t *data1, const uint8_t *data2, uint32_t len)
773 {
774 uint8_t check = 0;
775 for (uint32_t i = 0; i < len; i++) {
776 check |= data1[i] ^ data2[i];
777 }
778 if (check != 0) {
779 BSL_ERR_PUSH_ERROR(CRYPT_SM2_EXCH_VERIFY_FAIL);
780 return CRYPT_SM2_EXCH_VERIFY_FAIL;
781 }
782 return CRYPT_SUCCESS;
783 }
784
Sm2DoCheck(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)785 static int32_t Sm2DoCheck(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
786 {
787 if (val == NULL) {
788 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
789 return CRYPT_NULL_INPUT;
790 }
791 int32_t ret;
792 if (ctx->isSumValid != 1) {
793 ret = CRYPT_SM2_ERR_S_NOT_SET;
794 BSL_ERR_PUSH_ERROR(ret);
795 return ret;
796 }
797 if (len != SM3_MD_SIZE) {
798 ret = CRYPT_SM2_ERR_DATA_LEN;
799 BSL_ERR_PUSH_ERROR(ret);
800 return ret;
801 }
802 ret = IsDataEqual(ctx->sumCheck, val, len);
803 if (ret != CRYPT_SUCCESS) {
804 ctx->isSumValid = 0;
805 }
806 return ret;
807 }
808
CtrlServerSet(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)809 static int32_t CtrlServerSet(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
810 {
811 if (val == NULL) {
812 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
813 return CRYPT_NULL_INPUT;
814 }
815 if (len != sizeof(uint32_t)) {
816 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_CTRL_LEN);
817 return CRYPT_SM2_ERR_CTRL_LEN;
818 }
819 const int32_t t = *(const int32_t *)val;
820 if (t != 0 && t != 1) {
821 BSL_ERR_PUSH_ERROR(CRYPT_SM2_INVALID_SERVER_TYPE);
822 return CRYPT_SM2_INVALID_SERVER_TYPE;
823 }
824 ctx->server = t;
825 return CRYPT_SUCCESS;
826 }
827
CtrlUserId(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)828 static int32_t CtrlUserId(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
829 {
830 if (val == NULL) {
831 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
832 return CRYPT_NULL_INPUT;
833 }
834 if (len == 0 || len > SM2_MAX_ID_LENGTH) {
835 BSL_ERR_PUSH_ERROR(CRYPT_ECC_PKEY_ERR_CTRL_LEN);
836 return CRYPT_ECC_PKEY_ERR_CTRL_LEN;
837 }
838 BSL_SAL_FREE(ctx->userId);
839 return Sm2SetUserId(ctx, val, len);
840 }
841
Sm2SetPKG(CRYPT_SM2_Ctx * ctx,const void * val,uint32_t len)842 static int32_t Sm2SetPKG(CRYPT_SM2_Ctx *ctx, const void *val, uint32_t len)
843 {
844 if (val == NULL) {
845 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
846 return CRYPT_NULL_INPUT;
847 }
848 if (len != sizeof(uint32_t)) {
849 BSL_ERR_PUSH_ERROR(CRYPT_SM2_ERR_CTRL_LEN);
850 return CRYPT_SM2_ERR_CTRL_LEN;
851 }
852 if (*(const uint32_t *)val != 0 && *(const uint32_t *)val != 1) {
853 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
854 return CRYPT_INVALID_ARG;
855 }
856 ctx->pkgImpl = *(const uint32_t *)val;
857 return CRYPT_SUCCESS;
858 }
859
SM2UpReferences(CRYPT_SM2_Ctx * ctx,void * val,uint32_t len)860 static int32_t SM2UpReferences(CRYPT_SM2_Ctx *ctx, void *val, uint32_t len)
861 {
862 if (val == NULL || len != (uint32_t)sizeof(int)) {
863 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
864 return CRYPT_NULL_INPUT;
865 }
866 return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val);
867 }
868
CRYPT_SM2_GetLen(const CRYPT_SM2_Ctx * ctx,GetLenFunc func,void * val,uint32_t len)869 static int32_t CRYPT_SM2_GetLen(const CRYPT_SM2_Ctx *ctx, GetLenFunc func, void *val, uint32_t len)
870 {
871 if (val == NULL || len != sizeof(int32_t)) {
872 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
873 return CRYPT_NULL_INPUT;
874 }
875
876 *(int32_t *)val = func(ctx);
877 return CRYPT_SUCCESS;
878 }
879
CRYPT_SM2_Ctrl(CRYPT_SM2_Ctx * ctx,int32_t opt,void * val,uint32_t len)880 int32_t CRYPT_SM2_Ctrl(CRYPT_SM2_Ctx *ctx, int32_t opt, void *val, uint32_t len)
881 {
882 if (ctx == NULL) {
883 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
884 return CRYPT_NULL_INPUT;
885 }
886 int32_t ret = CRYPT_SM2_ERR_UNSUPPORTED_CTRL_OPTION;
887 switch (opt) {
888 case CRYPT_CTRL_GET_BITS:
889 return CRYPT_SM2_GetLen(ctx, (GetLenFunc)CRYPT_SM2_GetBits, val, len);
890 #ifdef HITLS_CRYPTO_SM2_SIGN
891 case CRYPT_CTRL_GET_SIGNLEN:
892 return CRYPT_SM2_GetLen(ctx, (GetLenFunc)CRYPT_SM2_GetSignLen, val, len);
893 #endif
894 case CRYPT_CTRL_GET_SECBITS:
895 return CRYPT_SM2_GetLen(ctx, (GetLenFunc)CRYPT_SM2_GetSecBits, val, len);
896 case CRYPT_CTRL_SET_SM2_SERVER:
897 ret = CtrlServerSet(ctx, val, len);
898 break;
899 case CRYPT_CTRL_SET_SM2_USER_ID:
900 ret = CtrlUserId(ctx, val, len);
901 break;
902 case CRYPT_CTRL_GENE_SM2_R:
903 ret = Sm2GenerateR(ctx, val, len);
904 break;
905 case CRYPT_CTRL_SET_SM2_R:
906 ret = Sm2SetR(ctx, val, len);
907 break;
908 case CRYPT_CTRL_SET_SM2_RANDOM:
909 ret = Sm2SetRandom(ctx, val, len);
910 break;
911 case CRYPT_CTRL_GET_SM2_SEND_CHECK:
912 ret = Sm2GetSumSend(ctx, val, len);
913 break;
914 case CRYPT_CTRL_SM2_DO_CHECK:
915 ret = Sm2DoCheck(ctx, val, len);
916 break;
917 case CRYPT_CTRL_SET_SM2_PKG:
918 ret = Sm2SetPKG(ctx, val, len);
919 break;
920 case CRYPT_CTRL_UP_REFERENCES:
921 ret = SM2UpReferences(ctx, val, len);
922 break;
923 default:
924 ret = ECC_PkeyCtrl(ctx->pkey, opt, val, len);
925 break;
926 }
927 if (ret != CRYPT_SUCCESS) {
928 BSL_ERR_PUSH_ERROR(ret);
929 }
930 return ret;
931 }
932
CRYPT_SM2_Cmp(const CRYPT_SM2_Ctx * a,const CRYPT_SM2_Ctx * b)933 int32_t CRYPT_SM2_Cmp(const CRYPT_SM2_Ctx *a, const CRYPT_SM2_Ctx *b)
934 {
935 if (a == NULL || b == NULL) {
936 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
937 return CRYPT_NULL_INPUT;
938 }
939 return ECC_PkeyCmp(a->pkey, b->pkey);
940 }
941
CRYPT_SM2_GetSecBits(const CRYPT_SM2_Ctx * ctx)942 int32_t CRYPT_SM2_GetSecBits(const CRYPT_SM2_Ctx *ctx)
943 {
944 if (ctx == NULL || ctx->pkey == NULL) {
945 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
946 return 0;
947 }
948 return ECC_GetSecBits(ctx->pkey->para);
949 }
950
951 #endif // HITLS_CRYPTO_SM2_SIGN
952