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_DSA
18
19 #include "crypt_errno.h"
20 #include "securec.h"
21 #include "bsl_sal.h"
22 #include "bsl_err_internal.h"
23 #include "crypt_utils.h"
24 #include "crypt_encode_internal.h"
25 #include "dsa_local.h"
26 #include "crypt_dsa.h"
27 #include "eal_md_local.h"
28 #include "crypt_params_key.h"
29
CRYPT_DSA_NewCtx(void)30 CRYPT_DSA_Ctx *CRYPT_DSA_NewCtx(void)
31 {
32 CRYPT_DSA_Ctx *ctx = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Ctx));
33 if (ctx == NULL) {
34 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
35 return NULL;
36 }
37 (void)memset_s(ctx, sizeof(CRYPT_DSA_Ctx), 0, sizeof(CRYPT_DSA_Ctx));
38 BSL_SAL_ReferencesInit(&(ctx->references));
39 return ctx;
40 }
41
CRYPT_DSA_NewCtxEx(void * libCtx)42 CRYPT_DSA_Ctx *CRYPT_DSA_NewCtxEx(void *libCtx)
43 {
44 CRYPT_DSA_Ctx *ctx = CRYPT_DSA_NewCtx();
45 if (ctx == NULL) {
46 return NULL;
47 }
48 ctx->libCtx = libCtx;
49 return ctx;
50 }
51
InputBufferCheck(const uint8_t * buffer,uint32_t bufferLen)52 static bool InputBufferCheck(const uint8_t *buffer, uint32_t bufferLen)
53 {
54 if (buffer == NULL || bufferLen == 0) {
55 return true;
56 }
57 return false;
58 }
59
ParaMemGet(uint32_t bits)60 static CRYPT_DSA_Para *ParaMemGet(uint32_t bits)
61 {
62 CRYPT_DSA_Para *para = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Para));
63 if (para == NULL) {
64 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
65 return NULL;
66 }
67 para->p = BN_Create(bits);
68 para->q = BN_Create(bits);
69 para->g = BN_Create(bits);
70 if (para->p == NULL || para->q == NULL || para->g == NULL) {
71 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
72 CRYPT_DSA_FreePara(para);
73 return NULL;
74 }
75 return para;
76 }
77
GetDsaParamValue(const BSL_Param * params,int32_t paramId,uint32_t maxLen,const uint8_t ** value,uint32_t * valueLen)78 static int32_t GetDsaParamValue(const BSL_Param *params, int32_t paramId, uint32_t maxLen,
79 const uint8_t **value, uint32_t *valueLen)
80 {
81 const BSL_Param *param = BSL_PARAM_FindConstParam(params, paramId);
82 if (param == NULL || param->value == NULL || param->valueLen > maxLen || param->valueLen == 0) {
83 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
84 return CRYPT_DSA_ERR_KEY_PARA;
85 }
86 *value = param->value;
87 *valueLen = param->valueLen;
88 return CRYPT_SUCCESS;
89 }
90
GetAllDsaParams(const BSL_Param * params,const uint8_t ** p,uint32_t * pLen,const uint8_t ** q,uint32_t * qLen,const uint8_t ** g,uint32_t * gLen)91 static int32_t GetAllDsaParams(const BSL_Param *params,
92 const uint8_t **p, uint32_t *pLen,
93 const uint8_t **q, uint32_t *qLen,
94 const uint8_t **g, uint32_t *gLen)
95 {
96 int32_t ret = GetDsaParamValue(params, CRYPT_PARAM_DSA_P, BN_BITS_TO_BYTES(DSA_MAX_PBITS), p, pLen);
97 if (ret != CRYPT_SUCCESS) {
98 return ret;
99 }
100 ret = GetDsaParamValue(params, CRYPT_PARAM_DSA_Q, *pLen, q, qLen);
101 if (ret != CRYPT_SUCCESS) {
102 return ret;
103 }
104 return GetDsaParamValue(params, CRYPT_PARAM_DSA_G, *pLen, g, gLen);
105 }
106
InitDsaParaValues(CRYPT_DSA_Para * para,const uint8_t * p,uint32_t pLen,const uint8_t * q,uint32_t qLen,const uint8_t * g,uint32_t gLen)107 static int32_t InitDsaParaValues(CRYPT_DSA_Para *para,
108 const uint8_t *p, uint32_t pLen,
109 const uint8_t *q, uint32_t qLen,
110 const uint8_t *g, uint32_t gLen)
111 {
112 int32_t ret = BN_Bin2Bn(para->p, p, pLen);
113 if (ret != CRYPT_SUCCESS) {
114 BSL_ERR_PUSH_ERROR(ret);
115 return ret;
116 }
117 ret = BN_Bin2Bn(para->q, q, qLen);
118 if (ret != CRYPT_SUCCESS) {
119 BSL_ERR_PUSH_ERROR(ret);
120 return ret;
121 }
122 ret = BN_Bin2Bn(para->g, g, gLen);
123 if (ret != CRYPT_SUCCESS) {
124 BSL_ERR_PUSH_ERROR(ret);
125 }
126 return ret;
127 }
128
CRYPT_DSA_NewPara(const BSL_Param * params)129 CRYPT_DSA_Para *CRYPT_DSA_NewPara(const BSL_Param *params)
130 {
131 if (params == NULL) {
132 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
133 return NULL;
134 }
135 const uint8_t *p = NULL, *q = NULL, *g = NULL;
136 uint32_t pLen = 0, qLen = 0, gLen = 0;
137 int32_t ret = GetAllDsaParams(params, &p, &pLen, &q, &qLen, &g, &gLen);
138 if (ret != CRYPT_SUCCESS) {
139 return NULL;
140 }
141 CRYPT_DSA_Para *para = ParaMemGet(pLen * 8);
142 if (para == NULL) {
143 return NULL;
144 }
145 ret = InitDsaParaValues(para, p, pLen, q, qLen, g, gLen);
146 if (ret != CRYPT_SUCCESS) {
147 CRYPT_DSA_FreePara(para);
148 return NULL;
149 }
150 return para;
151 }
152
CRYPT_DSA_FreePara(CRYPT_DSA_Para * para)153 void CRYPT_DSA_FreePara(CRYPT_DSA_Para *para)
154 {
155 if (para == NULL) {
156 return;
157 }
158 BN_Destroy(para->p);
159 BN_Destroy(para->q);
160 BN_Destroy(para->g);
161 BSL_SAL_FREE(para);
162 }
163
CRYPT_DSA_FreeCtx(CRYPT_DSA_Ctx * ctx)164 void CRYPT_DSA_FreeCtx(CRYPT_DSA_Ctx *ctx)
165 {
166 if (ctx == NULL) {
167 return;
168 }
169 int ref = 0;
170 BSL_SAL_AtomicDownReferences(&(ctx->references), &ref);
171 if (ref > 0) {
172 return;
173 }
174 BSL_SAL_ReferencesFree(&(ctx->references));
175 CRYPT_DSA_FreePara(ctx->para);
176 BN_Destroy(ctx->x);
177 BN_Destroy(ctx->y);
178 BSL_SAL_FREE(ctx);
179 }
180
ParaPQGCheck(const BN_BigNum * p,const BN_BigNum * q,const BN_BigNum * g)181 static int32_t ParaPQGCheck(const BN_BigNum *p, const BN_BigNum *q, const BN_BigNum *g)
182 {
183 uint32_t pBits = BN_Bits(p);
184 BN_BigNum *r = BN_Create(pBits + 1);
185 BN_Optimizer *opt = BN_OptimizerCreate();
186 int32_t ret;
187 if (r == NULL || opt == NULL) {
188 ret = CRYPT_MEM_ALLOC_FAIL;
189 BSL_ERR_PUSH_ERROR(ret);
190 goto EXIT;
191 }
192 // judgment of numeric values
193 // r = p - 1
194 ret = BN_SubLimb(r, p, 1);
195 if (ret != CRYPT_SUCCESS) {
196 BSL_ERR_PUSH_ERROR(ret);
197 goto EXIT;
198 }
199 // q < p - 1
200 if (BN_Cmp(q, r) >= 0) {
201 ret = CRYPT_DSA_ERR_KEY_PARA;
202 BSL_ERR_PUSH_ERROR(ret);
203 goto EXIT;
204 }
205 // g < p - 1
206 if (BN_Cmp(g, r) >= 0) {
207 ret = CRYPT_DSA_ERR_KEY_PARA;
208 BSL_ERR_PUSH_ERROR(ret);
209 goto EXIT;
210 }
211 // judgment of multiple relationship about p & q
212 ret = BN_Div(NULL, r, r, q, opt);
213 if (ret != CRYPT_SUCCESS) {
214 BSL_ERR_PUSH_ERROR(ret);
215 goto EXIT;
216 }
217 // (p - 1) % q == 0
218 if (!BN_IsZero(r)) {
219 ret = CRYPT_DSA_ERR_KEY_PARA;
220 BSL_ERR_PUSH_ERROR(ret);
221 }
222 EXIT:
223 BN_Destroy(r);
224 BN_OptimizerDestroy(opt);
225 return ret;
226 }
227
ParaDataCheck(const CRYPT_DSA_Para * para)228 static int32_t ParaDataCheck(const CRYPT_DSA_Para *para)
229 {
230 const BN_BigNum *p = para->p;
231 const BN_BigNum *q = para->q;
232 const BN_BigNum *g = para->g;
233 // 1. judge validity of length
234 uint32_t pBits = BN_Bits(p);
235 if (pBits < DSA_MIN_PBITS || pBits > DSA_MAX_PBITS) {
236 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
237 return CRYPT_DSA_ERR_KEY_PARA;
238 }
239 if (BN_Bits(q) < DSA_MIN_QBITS) {
240 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
241 return CRYPT_DSA_ERR_KEY_PARA;
242 }
243 // 2. parity judgment of p & q and value judgment of g
244 // p is an odd number && q is an odd number
245 if (BN_GetBit(p, 0) == 0 || BN_GetBit(q, 0) == 0) {
246 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
247 return CRYPT_DSA_ERR_KEY_PARA;
248 }
249 // g != 1 && g != 0
250 if (BN_IsOne(g) || BN_IsZero(g)) {
251 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
252 return CRYPT_DSA_ERR_KEY_PARA;
253 }
254 // This interface is invoked only here, and pushErr is performed internally.
255 // If this interface fails, pushErr does not need to be invoked.
256 return ParaPQGCheck(p, q, g);
257 }
258
ParaDup(const CRYPT_DSA_Para * para)259 static CRYPT_DSA_Para *ParaDup(const CRYPT_DSA_Para *para)
260 {
261 CRYPT_DSA_Para *ret = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Para));
262 if (ret == NULL) {
263 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
264 return NULL;
265 }
266 ret->p = BN_Dup(para->p);
267 ret->q = BN_Dup(para->q);
268 ret->g = BN_Dup(para->g);
269 if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
270 CRYPT_DSA_FreePara(ret);
271 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
272 return NULL;
273 }
274 return ret;
275 }
276
CRYPT_DSA_SetPara(CRYPT_DSA_Ctx * ctx,const BSL_Param * para)277 int32_t CRYPT_DSA_SetPara(CRYPT_DSA_Ctx *ctx, const BSL_Param *para)
278 {
279 if (ctx == NULL) {
280 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
281 return CRYPT_NULL_INPUT;
282 }
283 CRYPT_DSA_Para *dsaPara = CRYPT_DSA_NewPara(para);
284 if (dsaPara == NULL) {
285 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_NEW_PARA_FAIL);
286 return CRYPT_EAL_ERR_NEW_PARA_FAIL;
287 }
288 int32_t ret = ParaDataCheck(dsaPara);
289 if (ret != CRYPT_SUCCESS) {
290 CRYPT_DSA_FreePara(dsaPara);
291 return ret;
292 }
293
294 BN_Destroy(ctx->x);
295 BN_Destroy(ctx->y);
296 CRYPT_DSA_FreePara(ctx->para);
297 ctx->x = NULL;
298 ctx->y = NULL;
299 ctx->para = dsaPara;
300 return CRYPT_SUCCESS;
301 }
302
GetDsaParam(const BN_BigNum * x,BSL_Param * param,int32_t key)303 static int32_t GetDsaParam(const BN_BigNum *x, BSL_Param *param, int32_t key)
304 {
305 BSL_Param *temp = BSL_PARAM_FindParam(param, key);
306 if (temp == NULL) {
307 BSL_ERR_PUSH_ERROR(CRYPT_DSA_PARA_ERROR);
308 return CRYPT_DSA_PARA_ERROR;
309 }
310
311 temp->useLen = temp->valueLen;
312 int32_t ret = BN_Bn2Bin(x, temp->value, &temp->useLen);
313 if (ret != CRYPT_SUCCESS) {
314 BSL_ERR_PUSH_ERROR(ret);
315 }
316 return ret;
317 }
318
CRYPT_DSA_GetPara(const CRYPT_DSA_Ctx * ctx,BSL_Param * param)319 int32_t CRYPT_DSA_GetPara(const CRYPT_DSA_Ctx *ctx, BSL_Param *param)
320 {
321 int32_t ret;
322 if (ctx == NULL || param == NULL) {
323 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
324 return CRYPT_NULL_INPUT;
325 }
326 if (ctx->para == NULL) {
327 BSL_ERR_PUSH_ERROR(CRYPT_DSA_PARA_ERROR);
328 return CRYPT_DSA_PARA_ERROR;
329 }
330
331 ret = GetDsaParam(ctx->para->p, param, CRYPT_PARAM_DSA_P);
332 if (ret != CRYPT_SUCCESS) {
333 BSL_ERR_PUSH_ERROR(ret);
334 return ret;
335 }
336 ret = GetDsaParam(ctx->para->q, param, CRYPT_PARAM_DSA_Q);
337 if (ret != CRYPT_SUCCESS) {
338 BSL_ERR_PUSH_ERROR(ret);
339 return ret;
340 }
341 ret = GetDsaParam(ctx->para->g, param, CRYPT_PARAM_DSA_G);
342 if (ret != CRYPT_SUCCESS) {
343 BSL_ERR_PUSH_ERROR(ret);
344 }
345 return ret;
346 }
347
CRYPT_DSA_DupCtx(CRYPT_DSA_Ctx * dsaCtx)348 CRYPT_DSA_Ctx *CRYPT_DSA_DupCtx(CRYPT_DSA_Ctx *dsaCtx)
349 {
350 if (dsaCtx == NULL) {
351 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
352 return NULL;
353 }
354
355 CRYPT_DSA_Ctx *dsaNewCtx = BSL_SAL_Malloc(sizeof(CRYPT_DSA_Ctx));
356 if (dsaNewCtx == NULL) {
357 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
358 return NULL;
359 }
360
361 (void)memset_s(dsaNewCtx, sizeof(CRYPT_DSA_Ctx), 0, sizeof(CRYPT_DSA_Ctx));
362
363 GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->x, dsaCtx->x, BN_Dup(dsaCtx->x), CRYPT_MEM_ALLOC_FAIL);
364 GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->y, dsaCtx->y, BN_Dup(dsaCtx->y), CRYPT_MEM_ALLOC_FAIL);
365 GOTO_ERR_IF_SRC_NOT_NULL(dsaNewCtx->para, dsaCtx->para, ParaDup(dsaCtx->para), CRYPT_MEM_ALLOC_FAIL);
366 BSL_SAL_ReferencesInit(&(dsaNewCtx->references));
367 return dsaNewCtx;
368
369 ERR:
370 CRYPT_DSA_FreeCtx(dsaNewCtx);
371 return NULL;
372 }
373
CRYPT_DSA_GetBits(const CRYPT_DSA_Ctx * ctx)374 uint32_t CRYPT_DSA_GetBits(const CRYPT_DSA_Ctx *ctx)
375 {
376 if (ctx == NULL) {
377 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
378 return 0;
379 }
380 if (ctx->para == NULL) {
381 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
382 return 0;
383 }
384 return BN_Bits(ctx->para->p);
385 }
386
CRYPT_DSA_GetSignLen(const CRYPT_DSA_Ctx * ctx)387 uint32_t CRYPT_DSA_GetSignLen(const CRYPT_DSA_Ctx *ctx)
388 {
389 if (ctx == NULL || ctx->para == NULL) {
390 return 0;
391 }
392 uint32_t qLen = BN_Bytes(ctx->para->q);
393 uint32_t maxSignLen = 0;
394 int32_t ret = CRYPT_EAL_GetSignEncodeLen(qLen, qLen, &maxSignLen);
395 if (ret != CRYPT_SUCCESS) {
396 BSL_ERR_PUSH_ERROR(ret);
397 return 0;
398 }
399 return maxSignLen;
400 }
401
402 /* x != 0 && x < q */
CRYPT_DSA_SetPrvKey(CRYPT_DSA_Ctx * ctx,const BSL_Param * para)403 int32_t CRYPT_DSA_SetPrvKey(CRYPT_DSA_Ctx *ctx, const BSL_Param *para)
404 {
405 if (ctx == NULL || para == NULL) {
406 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
407 return CRYPT_NULL_INPUT;
408 }
409 const BSL_Param *prv = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_DSA_PRVKEY);
410 if (prv == NULL || prv->value == NULL) {
411 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
412 return CRYPT_NULL_INPUT;
413 }
414 if (InputBufferCheck(prv->value, prv->valueLen)) {
415 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
416 return CRYPT_NULL_INPUT;
417 }
418 if (ctx->para == NULL) {
419 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
420 return CRYPT_DSA_ERR_KEY_PARA;
421 }
422 if (BN_Bytes(ctx->para->q) < prv->valueLen) {
423 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
424 return CRYPT_DSA_ERR_KEY_INFO;
425 }
426 BN_BigNum *bnX = BN_Create(prv->valueLen * 8);
427 if (bnX == NULL) {
428 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
429 return CRYPT_MEM_ALLOC_FAIL;
430 }
431 int32_t ret = BN_Bin2Bn(bnX, prv->value, prv->valueLen);
432 if (ret != CRYPT_SUCCESS) {
433 BSL_ERR_PUSH_ERROR(ret);
434 goto ERR;
435 }
436 // x < q
437 if (BN_Cmp(bnX, ctx->para->q) >= 0) {
438 ret = CRYPT_DSA_ERR_KEY_INFO;
439 BSL_ERR_PUSH_ERROR(ret);
440 goto ERR;
441 }
442 // x != 0
443 if (BN_IsZero(bnX)) {
444 ret = CRYPT_DSA_ERR_KEY_INFO;
445 BSL_ERR_PUSH_ERROR(ret);
446 goto ERR;
447 }
448 BN_Destroy(ctx->x);
449 ctx->x = bnX;
450 return ret;
451 ERR:
452 BN_Destroy(bnX);
453 return ret;
454 }
455
456 /* y != 0 && y != 1 && y < p */
CRYPT_DSA_SetPubKey(CRYPT_DSA_Ctx * ctx,const BSL_Param * para)457 int32_t CRYPT_DSA_SetPubKey(CRYPT_DSA_Ctx *ctx, const BSL_Param *para)
458 {
459 if (ctx == NULL || para == NULL) {
460 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
461 return CRYPT_NULL_INPUT;
462 }
463 const BSL_Param *pub = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_DSA_PUBKEY);
464 if (pub == NULL || pub->value == NULL) {
465 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
466 return CRYPT_NULL_INPUT;
467 }
468
469 if (InputBufferCheck(pub->value, pub->valueLen)) {
470 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
471 return CRYPT_NULL_INPUT;
472 }
473 if (ctx->para == NULL) {
474 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
475 return CRYPT_DSA_ERR_KEY_PARA;
476 }
477 if (BN_Bytes(ctx->para->p) < pub->valueLen) {
478 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
479 return CRYPT_DSA_ERR_KEY_INFO;
480 }
481 BN_BigNum *bnY = BN_Create(pub->valueLen * 8);
482 if (bnY == NULL) {
483 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
484 return CRYPT_MEM_ALLOC_FAIL;
485 }
486 int32_t ret = BN_Bin2Bn(bnY, pub->value, pub->valueLen);
487 if (ret != CRYPT_SUCCESS) {
488 BSL_ERR_PUSH_ERROR(ret);
489 goto ERR;
490 }
491 // y < p
492 if (BN_Cmp(bnY, ctx->para->p) >= 0) {
493 ret = CRYPT_DSA_ERR_KEY_INFO;
494 BSL_ERR_PUSH_ERROR(ret);
495 goto ERR;
496 }
497 // y != 0 && y != 1
498 if (BN_IsZero(bnY) || BN_IsOne(bnY)) {
499 ret = CRYPT_DSA_ERR_KEY_INFO;
500 BSL_ERR_PUSH_ERROR(ret);
501 goto ERR;
502 }
503 BN_Destroy(ctx->y);
504 ctx->y = bnY;
505 return CRYPT_SUCCESS;
506 ERR:
507 BN_Destroy(bnY);
508 return ret;
509 }
510
CRYPT_DSA_GetPrvKey(const CRYPT_DSA_Ctx * ctx,BSL_Param * para)511 int32_t CRYPT_DSA_GetPrvKey(const CRYPT_DSA_Ctx *ctx, BSL_Param *para)
512 {
513 if (ctx == NULL || para == NULL) {
514 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
515 return CRYPT_NULL_INPUT;
516 }
517 BSL_Param *prv = BSL_PARAM_FindParam(para, CRYPT_PARAM_DSA_PRVKEY);
518 if (prv == NULL || prv->value == NULL) {
519 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
520 return CRYPT_NULL_INPUT;
521 }
522
523 if (ctx->para == NULL) {
524 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
525 return CRYPT_DSA_ERR_KEY_PARA;
526 }
527 if (ctx->x == NULL) {
528 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
529 return CRYPT_DSA_ERR_KEY_INFO;
530 }
531 if (BN_Bytes(ctx->para->q) > prv->valueLen) {
532 BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH);
533 return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH;
534 }
535 uint32_t useLen = prv->valueLen;
536 int32_t ret = BN_Bn2Bin(ctx->x, prv->value, &useLen);
537 if (ret != CRYPT_SUCCESS) {
538 BSL_ERR_PUSH_ERROR(ret);
539 return ret;
540 }
541 prv->useLen = useLen;
542 return CRYPT_SUCCESS;
543 }
544
CRYPT_DSA_GetPubKey(const CRYPT_DSA_Ctx * ctx,BSL_Param * para)545 int32_t CRYPT_DSA_GetPubKey(const CRYPT_DSA_Ctx *ctx, BSL_Param *para)
546 {
547 if (ctx == NULL || para == NULL) {
548 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
549 return CRYPT_NULL_INPUT;
550 }
551 BSL_Param *pub = BSL_PARAM_FindParam(para, CRYPT_PARAM_DSA_PUBKEY);
552 if (pub == NULL || pub->value == NULL) {
553 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
554 return CRYPT_NULL_INPUT;
555 }
556
557 if (ctx->y == NULL) {
558 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
559 return CRYPT_DSA_ERR_KEY_INFO;
560 }
561 if (ctx->para == NULL) {
562 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
563 return CRYPT_DSA_ERR_KEY_PARA;
564 }
565 if (BN_Bytes(ctx->para->p) > pub->valueLen) {
566 BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH);
567 return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH;
568 }
569 uint32_t useLen = pub->valueLen;
570 int32_t ret = BN_Bn2Bin(ctx->y, pub->value, &useLen);
571 if (ret != CRYPT_SUCCESS) {
572 BSL_ERR_PUSH_ERROR(ret);
573 return ret;
574 }
575 pub->useLen = useLen;
576 return CRYPT_SUCCESS;
577 }
578
RandRangeQ(void * libCtx,BN_BigNum * r,const BN_BigNum * q)579 static int32_t RandRangeQ(void *libCtx, BN_BigNum *r, const BN_BigNum *q)
580 {
581 int32_t cnt = 0;
582 for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) {
583 int32_t ret = BN_RandRangeEx(libCtx, r, q);
584 if (ret != CRYPT_SUCCESS) {
585 BSL_ERR_PUSH_ERROR(ret);
586 return ret;
587 }
588 if (BN_IsZero(r)) {
589 continue;
590 }
591 return CRYPT_SUCCESS; // if succeed then exit
592 }
593 /* If the key fails to be generated after try CRYPT_DSA_TRI_MAX_CNT times, then failed and exit. */
594 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_TRY_CNT);
595 return CRYPT_DSA_ERR_TRY_CNT;
596 }
597
RefreshCtx(CRYPT_DSA_Ctx * ctx,BN_BigNum * x,BN_BigNum * y,int32_t ret)598 static void RefreshCtx(CRYPT_DSA_Ctx *ctx, BN_BigNum *x, BN_BigNum *y, int32_t ret)
599 {
600 if (ret == CRYPT_SUCCESS) {
601 BN_Destroy(ctx->x);
602 BN_Destroy(ctx->y);
603 ctx->x = x;
604 ctx->y = y;
605 } else {
606 BN_Destroy(x);
607 BN_Destroy(y);
608 }
609 }
610
CRYPT_DSA_Gen(CRYPT_DSA_Ctx * ctx)611 int32_t CRYPT_DSA_Gen(CRYPT_DSA_Ctx *ctx)
612 {
613 if (ctx == NULL) {
614 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
615 return CRYPT_NULL_INPUT;
616 }
617 if (ctx->para == NULL) {
618 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
619 return CRYPT_DSA_ERR_KEY_PARA;
620 }
621 int32_t ret = CRYPT_SUCCESS;
622 int32_t cnt;
623 BN_BigNum *x = BN_Create(BN_Bits(ctx->para->q));
624 BN_BigNum *y = BN_Create(BN_Bits(ctx->para->p));
625 BN_Mont *mont = BN_MontCreate(ctx->para->p);
626 BN_Optimizer *opt = BN_OptimizerCreate();
627 if (x == NULL || y == NULL || opt == NULL || mont == NULL) {
628 ret = CRYPT_MEM_ALLOC_FAIL;
629 BSL_ERR_PUSH_ERROR(ret);
630 goto ERR;
631 }
632 for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) {
633 /* Generate the private key x of [1, q-1], see RFC6979-2.2. */
634 ret = RandRangeQ(ctx->libCtx, x, ctx->para->q);
635 if (ret != CRYPT_SUCCESS) {
636 // Internal API, the BSL_ERR_PUSH_ERROR info is already exists when failed.
637 goto ERR;
638 }
639 /* Calculate the public key y. */
640 ret = BN_MontExpConsttime(y, ctx->para->g, x, mont, opt);
641 if (ret != CRYPT_SUCCESS) {
642 BSL_ERR_PUSH_ERROR(ret);
643 goto ERR;
644 }
645 /* y != 0 && y != 1 */
646 if (BN_IsZero(y) || BN_IsOne(y)) {
647 continue;
648 }
649 goto ERR; // If succeed then exit.
650 }
651 /* If the key fails to be generated after try CRYPT_DSA_TRY_MAX_CNT times, then failed and exit. */
652 ret = CRYPT_DSA_ERR_TRY_CNT;
653 BSL_ERR_PUSH_ERROR(ret);
654 ERR:
655 RefreshCtx(ctx, x, y, ret);
656 BN_MontDestroy(mont);
657 BN_OptimizerDestroy(opt);
658 return ret;
659 }
660
661 // Get the input hash data, see RFC6979-2.4.1 and RFC6979-2.3.2
DSA_Bits2Int(BN_BigNum * q,const uint8_t * data,uint32_t dataLen)662 static BN_BigNum *DSA_Bits2Int(BN_BigNum *q, const uint8_t *data, uint32_t dataLen)
663 {
664 BN_BigNum *d = BN_Create(BN_Bits(q)); // 1 byte = 8 bits
665 if (d == NULL) {
666 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
667 return NULL;
668 }
669 if (data != NULL) {
670 uint32_t qLen = BN_Bytes(q);
671 uint32_t dLen = (dataLen < qLen) ? dataLen : qLen;
672 // The input parameters of the function have been verified, and no failure exists.
673 (void)BN_Bin2Bn(d, data, dLen);
674 }
675 return d;
676 }
677
678 // s = (h+x*sign->r)/k mod q
CalcSValue(const CRYPT_DSA_Ctx * ctx,BN_BigNum * r,BN_BigNum * s,BN_BigNum * k,BN_BigNum * d,BN_Optimizer * opt)679 static int32_t CalcSValue(const CRYPT_DSA_Ctx *ctx, BN_BigNum *r, BN_BigNum *s, BN_BigNum *k,
680 BN_BigNum *d, BN_Optimizer *opt)
681 {
682 int32_t ret = BN_ModMul(s, ctx->x, r, ctx->para->q, opt);
683 if (ret != CRYPT_SUCCESS) {
684 BSL_ERR_PUSH_ERROR(ret);
685 return ret;
686 }
687 ret = BN_ModAdd(s, d, s, ctx->para->q, opt);
688 if (ret != CRYPT_SUCCESS) {
689 BSL_ERR_PUSH_ERROR(ret);
690 return ret;
691 }
692 ret = BN_ModInv(k, k, ctx->para->q, opt);
693 if (ret != CRYPT_SUCCESS) {
694 BSL_ERR_PUSH_ERROR(ret);
695 return ret;
696 }
697 return BN_ModMul(s, s, k, ctx->para->q, opt);
698 }
699
SignCore(const CRYPT_DSA_Ctx * ctx,BN_BigNum * d,BN_BigNum * r,BN_BigNum * s)700 static int32_t SignCore(const CRYPT_DSA_Ctx *ctx, BN_BigNum *d, BN_BigNum *r,
701 BN_BigNum *s)
702 {
703 int32_t cnt = 0;
704 int32_t ret = CRYPT_SUCCESS;
705 BN_BigNum *k = BN_Create(BN_Bits(ctx->para->q));
706 BN_Mont *montP = BN_MontCreate(ctx->para->p);
707 BN_Optimizer *opt = BN_OptimizerCreate();
708 if (k == NULL || montP == NULL || opt == NULL) {
709 ret = CRYPT_MEM_ALLOC_FAIL;
710 BSL_ERR_PUSH_ERROR(ret);
711 goto EXIT;
712 }
713 for (cnt = 0; cnt < CRYPT_DSA_TRY_MAX_CNT; cnt++) {
714 // Generate random number k of [1, q-1], see RFC6979-2.4.2 */
715 ret = RandRangeQ(ctx->libCtx, k, ctx->para->q);
716 if (ret != CRYPT_SUCCESS) {
717 // Internal function. The BSL_ERR_PUSH_ERROR information exists when the failure occurs.
718 goto EXIT;
719 }
720 // Compute r = g^k mod p mod q, see RFC6979-2.4.3 */
721 ret = BN_MontExpConsttime(r, ctx->para->g, k, montP, opt);
722 if (ret != CRYPT_SUCCESS) {
723 BSL_ERR_PUSH_ERROR(ret);
724 goto EXIT;
725 }
726 ret = BN_Mod(r, r, ctx->para->q, opt);
727 if (ret != CRYPT_SUCCESS) {
728 BSL_ERR_PUSH_ERROR(ret);
729 goto EXIT;
730 }
731 if (BN_IsZero(r)) {
732 continue;
733 }
734 // Compute s = (h+x*sign->r)/k mod q, see RFC6979-2.4.4 */
735 ret = CalcSValue(ctx, r, s, k, d, opt);
736 if (ret != CRYPT_SUCCESS) {
737 goto EXIT;
738 }
739 if (BN_IsZero(s)) {
740 continue;
741 }
742 goto EXIT; // The signature generation meets the requirements and exits successfully.
743 }
744 ret = CRYPT_DSA_ERR_TRY_CNT;
745 BSL_ERR_PUSH_ERROR(ret);
746 EXIT:
747 BN_Destroy(k);
748 BN_MontDestroy(montP);
749 BN_OptimizerDestroy(opt);
750 return ret;
751 }
752
CryptDsaSign(const CRYPT_DSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,BN_BigNum ** r,BN_BigNum ** s)753 static int32_t CryptDsaSign(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen, BN_BigNum **r,
754 BN_BigNum **s)
755 {
756 int32_t ret;
757 BN_BigNum *signR = NULL;
758 BN_BigNum *signS = NULL;
759 BN_BigNum *d = DSA_Bits2Int(ctx->para->q, data, dataLen);
760 if (d == NULL) {
761 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
762 return CRYPT_MEM_ALLOC_FAIL;
763 }
764 signR = BN_Create(BN_Bits(ctx->para->p));
765 signS = BN_Create(BN_Bits(ctx->para->q));
766 if ((signR == NULL) || (signS == NULL)) {
767 BN_Destroy(d);
768 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
769 ret = CRYPT_MEM_ALLOC_FAIL;
770 goto ERR;
771 }
772 ret = SignCore(ctx, d, signR, signS);
773 BN_Destroy(d);
774 if (ret != CRYPT_SUCCESS) {
775 goto ERR;
776 }
777 *r = signR;
778 *s = signS;
779 return ret;
780 ERR:
781 BN_Destroy(signR);
782 BN_Destroy(signS);
783 return ret;
784 }
785
786 // Data with a value of 0 can also be signed.
CRYPT_DSA_SignData(const CRYPT_DSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)787 int32_t CRYPT_DSA_SignData(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
788 uint8_t *sign, uint32_t *signLen)
789 {
790 if (ctx == NULL || sign == NULL || signLen == NULL || (data == NULL && dataLen != 0)) {
791 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
792 return CRYPT_NULL_INPUT;
793 }
794 if (ctx->para == NULL) {
795 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_PARA);
796 return CRYPT_DSA_ERR_KEY_PARA;
797 }
798 if (ctx->x == NULL) {
799 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
800 return CRYPT_DSA_ERR_KEY_INFO;
801 }
802 if (*signLen < CRYPT_DSA_GetSignLen(ctx)) {
803 BSL_ERR_PUSH_ERROR(CRYPT_DSA_BUFF_LEN_NOT_ENOUGH);
804 return CRYPT_DSA_BUFF_LEN_NOT_ENOUGH;
805 }
806 int32_t ret;
807 BN_BigNum *r = NULL;
808 BN_BigNum *s = NULL;
809 ret = CryptDsaSign(ctx, data, dataLen, &r, &s);
810 if (ret != CRYPT_SUCCESS) {
811 return ret;
812 }
813 ret = CRYPT_EAL_EncodeSign(r, s, sign, signLen);
814 BN_Destroy(r);
815 BN_Destroy(s);
816 return ret;
817 }
818
CRYPT_DSA_Sign(const CRYPT_DSA_Ctx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)819 int32_t CRYPT_DSA_Sign(const CRYPT_DSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
820 uint8_t *sign, uint32_t *signLen)
821 {
822 uint8_t hash[64]; // 64 is max hash len
823 uint32_t hashLen = sizeof(hash) / sizeof(hash[0]);
824 int32_t ret = EAL_Md(algId, data, dataLen, hash, &hashLen);
825 if (ret != CRYPT_SUCCESS) {
826 BSL_ERR_PUSH_ERROR(ret);
827 return ret;
828 }
829 return CRYPT_DSA_SignData(ctx, hash, hashLen, sign, signLen);
830 }
831
VerifyCore(const CRYPT_DSA_Ctx * ctx,BN_BigNum * d,BN_BigNum * r,BN_BigNum * s)832 static int32_t VerifyCore(const CRYPT_DSA_Ctx *ctx, BN_BigNum *d, BN_BigNum *r, BN_BigNum *s)
833 {
834 int32_t ret = CRYPT_MEM_ALLOC_FAIL;
835 BN_BigNum *u1 = BN_Create(BN_Bits(ctx->para->p));
836 BN_BigNum *u2 = BN_Create(BN_Bits(ctx->para->p));
837 BN_BigNum *w = BN_Create(BN_Bits(ctx->para->q));
838 BN_Mont *montP = BN_MontCreate(ctx->para->p);
839 BN_Optimizer *opt = BN_OptimizerCreate();
840 if (u1 == NULL || u2 == NULL || w == NULL || montP == NULL || opt == NULL) {
841 BSL_ERR_PUSH_ERROR(ret);
842 goto EXIT;
843 }
844 /* Calculate w = 1/s mod q
845 * u1 = (d * w) mod q
846 * u2 = (r * w) mod q
847 * u1 = (g ^ u1) mod p
848 * u2 = (y ^ u2) mod p
849 * v = (u1 * u2) mod p
850 * v = v mod q
851 * If v == r, sign verification is succeeded.
852 */
853 ret = BN_ModInv(w, s, ctx->para->q, opt);
854 if (ret != CRYPT_SUCCESS) {
855 BSL_ERR_PUSH_ERROR(ret);
856 goto EXIT;
857 }
858 ret = BN_ModMul(u1, d, w, ctx->para->q, opt);
859 if (ret != CRYPT_SUCCESS) {
860 BSL_ERR_PUSH_ERROR(ret);
861 goto EXIT;
862 }
863 ret = BN_ModMul(u2, r, w, ctx->para->q, opt);
864 if (ret != CRYPT_SUCCESS) {
865 BSL_ERR_PUSH_ERROR(ret);
866 goto EXIT;
867 }
868 ret = BN_MontExpMul(u1, ctx->para->g, u1, ctx->y, u2, montP, opt);
869 if (ret != CRYPT_SUCCESS) {
870 BSL_ERR_PUSH_ERROR(ret);
871 goto EXIT;
872 }
873 ret = BN_Mod(u1, u1, ctx->para->q, opt);
874 if (ret != CRYPT_SUCCESS) {
875 BSL_ERR_PUSH_ERROR(ret);
876 goto EXIT;
877 }
878 ret = BN_Cmp(u1, r);
879 if (ret != 0) {
880 BSL_ERR_PUSH_ERROR(ret);
881 ret = CRYPT_DSA_VERIFY_FAIL;
882 }
883 EXIT:
884 BN_Destroy(u1);
885 BN_Destroy(u2);
886 BN_Destroy(w);
887 BN_MontDestroy(montP);
888 BN_OptimizerDestroy(opt);
889 return ret;
890 }
891
CRYPT_DSA_VerifyData(const CRYPT_DSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)892 int32_t CRYPT_DSA_VerifyData(const CRYPT_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
893 const uint8_t *sign, uint32_t signLen)
894 {
895 if (ctx == NULL || sign == NULL || signLen == 0 || (data == NULL && dataLen != 0)) {
896 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
897 return CRYPT_NULL_INPUT;
898 }
899 if (ctx->para == NULL || ctx->y == NULL) {
900 BSL_ERR_PUSH_ERROR(CRYPT_DSA_ERR_KEY_INFO);
901 return CRYPT_DSA_ERR_KEY_INFO;
902 }
903
904 int32_t ret;
905 BN_BigNum *r = BN_Create(BN_Bits(ctx->para->p));
906 BN_BigNum *s = BN_Create(BN_Bits(ctx->para->q));
907 BN_BigNum *d = DSA_Bits2Int(ctx->para->q, data, dataLen);
908 if (r == NULL || s == NULL || d == NULL) {
909 ret = CRYPT_MEM_ALLOC_FAIL;
910 goto EXIT;
911 }
912
913 ret = CRYPT_EAL_DecodeSign(sign, signLen, r, s);
914 if (ret != CRYPT_SUCCESS) {
915 goto EXIT;
916 }
917 ret = VerifyCore(ctx, d, r, s);
918 EXIT:
919 BN_Destroy(r);
920 BN_Destroy(s);
921 BN_Destroy(d);
922 return ret;
923 }
924
CRYPT_DSA_Verify(const CRYPT_DSA_Ctx * ctx,int32_t algId,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)925 int32_t CRYPT_DSA_Verify(const CRYPT_DSA_Ctx *ctx, int32_t algId, const uint8_t *data, uint32_t dataLen,
926 const uint8_t *sign, uint32_t signLen)
927 {
928 uint8_t hash[64]; // 64 is max hash len
929 uint32_t hashLen = sizeof(hash) / sizeof(hash[0]);
930 int32_t ret = EAL_Md(algId, data, dataLen, hash, &hashLen);
931 if (ret != CRYPT_SUCCESS) {
932 BSL_ERR_PUSH_ERROR(ret);
933 return ret;
934 }
935 return CRYPT_DSA_VerifyData(ctx, hash, hashLen, sign, signLen);
936 }
937
CRYPT_DSA_Cmp(const CRYPT_DSA_Ctx * a,const CRYPT_DSA_Ctx * b)938 int32_t CRYPT_DSA_Cmp(const CRYPT_DSA_Ctx *a, const CRYPT_DSA_Ctx *b)
939 {
940 RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT);
941
942 RETURN_RET_IF(a->y == NULL || b->y == NULL, CRYPT_DSA_ERR_KEY_INFO);
943 RETURN_RET_IF(BN_Cmp(a->y, b->y) != 0, CRYPT_DSA_PUBKEY_NOT_EQUAL);
944
945 // para must be both NULL and non-NULL.
946 RETURN_RET_IF((a->para == NULL) != (b->para == NULL), CRYPT_DSA_PARA_ERROR);
947 if (a->para != NULL) {
948 RETURN_RET_IF(BN_Cmp(a->para->p, b->para->p) != 0 ||
949 BN_Cmp(a->para->q, b->para->q) != 0 ||
950 BN_Cmp(a->para->g, b->para->g) != 0,
951 CRYPT_DSA_PARA_NOT_EQUAL);
952 }
953 return CRYPT_SUCCESS;
954 }
955
CRYPT_DSA_GetPrvKeyLen(const CRYPT_DSA_Ctx * ctx)956 static uint32_t CRYPT_DSA_GetPrvKeyLen(const CRYPT_DSA_Ctx *ctx)
957 {
958 return BN_Bytes(ctx->x);
959 }
960
CRYPT_DSA_GetPubKeyLen(const CRYPT_DSA_Ctx * ctx)961 static uint32_t CRYPT_DSA_GetPubKeyLen(const CRYPT_DSA_Ctx *ctx)
962 {
963 if (ctx->para != NULL) {
964 return BN_Bytes(ctx->para->p);
965 }
966 if (ctx->y != NULL) {
967 return BN_Bytes(ctx->y);
968 }
969 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
970 return 0;
971 }
972
CRYPT_DSA_Ctrl(CRYPT_DSA_Ctx * ctx,int32_t opt,void * val,uint32_t len)973 int32_t CRYPT_DSA_Ctrl(CRYPT_DSA_Ctx *ctx, int32_t opt, void *val, uint32_t len)
974 {
975 if (ctx == NULL) {
976 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
977 return CRYPT_NULL_INPUT;
978 }
979 switch (opt) {
980 case CRYPT_CTRL_GET_BITS:
981 return GetUintCtrl(ctx, val, len, (GetUintCallBack)CRYPT_DSA_GetBits);
982 case CRYPT_CTRL_GET_SIGNLEN:
983 return GetUintCtrl(ctx, val, len, (GetUintCallBack)CRYPT_DSA_GetSignLen);
984 case CRYPT_CTRL_GET_SECBITS:
985 return GetUintCtrl(ctx, val, len, (GetUintCallBack)CRYPT_DSA_GetSecBits);
986 case CRYPT_CTRL_GET_PUBKEY_LEN:
987 return GetUintCtrl(ctx, val, len, (GetUintCallBack)CRYPT_DSA_GetPubKeyLen);
988 case CRYPT_CTRL_GET_PRVKEY_LEN:
989 return GetUintCtrl(ctx, val, len, (GetUintCallBack)CRYPT_DSA_GetPrvKeyLen);
990 case CRYPT_CTRL_UP_REFERENCES:
991 if (val == NULL || len != (uint32_t)sizeof(int)) {
992 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
993 return CRYPT_INVALID_ARG;
994 }
995 return BSL_SAL_AtomicUpReferences(&(ctx->references), (int *)val);
996 default:
997 break;
998 }
999 BSL_ERR_PUSH_ERROR(CRYPT_DSA_UNSUPPORTED_CTRL_OPTION);
1000 return CRYPT_DSA_UNSUPPORTED_CTRL_OPTION;
1001 }
1002
CRYPT_DSA_GetSecBits(const CRYPT_DSA_Ctx * ctx)1003 int32_t CRYPT_DSA_GetSecBits(const CRYPT_DSA_Ctx *ctx)
1004 {
1005 if (ctx == NULL || ctx->para == NULL || ctx->para->p == NULL || ctx->para->q == NULL) {
1006 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
1007 return 0;
1008 }
1009 return BN_SecBits(BN_Bits(ctx->para->p), BN_Bits(ctx->para->q));
1010 }
1011 #endif /* HITLS_CRYPTO_DSA */
1012