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