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_RSA
18
19 #include "crypt_types.h"
20 #include "crypt_rsa.h"
21 #include "crypt_utils.h"
22 #include "bsl_err_internal.h"
23 #include "rsa_local.h"
24 #include "crypt_errno.h"
25 #include "securec.h"
26 #include "bsl_sal.h"
27 #include "crypt_params_key.h"
28
29 typedef struct {
30 BSL_Param *d; /**< RSA private key parameter marked as d. */
31 BSL_Param *n; /**< RSA private key parameter marked as n. */
32 BSL_Param *p; /**< RSA private key parameter marked as p. */
33 BSL_Param *q; /**< RSA private key parameter marked as q. */
34 BSL_Param *dP; /**< RSA private key parameter marked as dP. */
35 BSL_Param *dQ; /**< RSA private key parameter marked as dQ. */
36 BSL_Param *qInv; /**< RSA private key parameter marked as qInv. */
37 BSL_Param *e; /**< RSA public key parameter marked as e. */
38 } CRYPT_RsaPrvParam;
39
SetPrvPara(const CRYPT_RSA_PrvKey * prvKey,const CRYPT_RsaPrvParam * prv)40 static int32_t SetPrvPara(const CRYPT_RSA_PrvKey *prvKey, const CRYPT_RsaPrvParam *prv)
41 {
42 int32_t ret = BN_Bin2Bn(prvKey->n, prv->n->value, prv->n->valueLen);
43 if (ret != CRYPT_SUCCESS) {
44 BSL_ERR_PUSH_ERROR(ret);
45 return ret;
46 }
47 uint32_t bnBits = BN_Bits(prvKey->n);
48 if (bnBits > RSA_MAX_MODULUS_BITS || bnBits < RSA_MIN_MODULUS_BITS) {
49 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS);
50 return CRYPT_RSA_ERR_KEY_BITS;
51 }
52 ret = BN_Bin2Bn(prvKey->d, prv->d->value, prv->d->valueLen);
53 if (ret != CRYPT_SUCCESS) {
54 BSL_ERR_PUSH_ERROR(ret);
55 return ret;
56 }
57 // d cannot be 0 or 1. The mathematical logic of e and d is that
58 // d and e are reciprocal in mod((p-1) * (q-1)); When d is 1, e and d must be 1. When d is 0, e doesn't exist.
59 if (BN_IsZero(prvKey->d) || BN_IsOne(prvKey->d)) {
60 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE);
61 return CRYPT_RSA_ERR_INPUT_VALUE;
62 }
63 if (BN_Cmp(prvKey->n, prvKey->d) <= 0) {
64 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE);
65 return CRYPT_RSA_ERR_INPUT_VALUE;
66 }
67 if (!PARAMISNULL(prv->e)) {
68 ret = BN_Bin2Bn(prvKey->e, prv->e->value, prv->e->valueLen);
69 if (ret != CRYPT_SUCCESS) {
70 BSL_ERR_PUSH_ERROR(ret);
71 return ret;
72 }
73 if (BN_Cmp(prvKey->n, prvKey->e) <= 0) {
74 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE);
75 return CRYPT_RSA_ERR_INPUT_VALUE;
76 }
77 }
78 if (!PARAMISNULL(prv->p)) {
79 GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->p, prv->p->value, prv->p->valueLen), ret);
80 GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->q, prv->q->value, prv->q->valueLen), ret);
81 if (BN_IsZero(prvKey->p) == true || BN_IsZero(prvKey->q) == true) {
82 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_INPUT_VALUE);
83 return CRYPT_RSA_ERR_INPUT_VALUE;
84 }
85 if (!PARAMISNULL(prv->dP)) {
86 GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->dP, prv->dP->value, prv->dP->valueLen), ret);
87 GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->dQ, prv->dQ->value, prv->dQ->valueLen), ret);
88 GOTO_ERR_IF_EX(BN_Bin2Bn(prvKey->qInv, prv->qInv->value, prv->qInv->valueLen), ret);
89 }
90 }
91 ERR:
92 return ret;
93 }
94
GetAndCheckPrvKey(CRYPT_RSA_Ctx * ctx,BSL_Param * para,CRYPT_RsaPrvParam * prv)95 static int32_t GetAndCheckPrvKey(CRYPT_RSA_Ctx *ctx, BSL_Param *para, CRYPT_RsaPrvParam *prv)
96 {
97 if (ctx == NULL || para == NULL) {
98 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
99 return CRYPT_NULL_INPUT;
100 }
101 prv->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_N);
102 prv->d = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_D);
103 prv->e = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_E);
104 prv->p = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_P);
105 prv->q = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_Q);
106 prv->dP = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_DP);
107 prv->dQ = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_DQ);
108 prv->qInv = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_QINV);
109 if (PARAMISNULL(prv->n) || prv->n->valueLen == 0 || PARAMISNULL(prv->d)) {
110 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
111 return CRYPT_NULL_INPUT;
112 }
113 if (prv->n->valueLen > RSA_MAX_MODULUS_LEN) {
114 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS);
115 return CRYPT_RSA_ERR_KEY_BITS;
116 }
117 // prv->p\q and prv->dP\dQ\qInv must be both empty or not.
118 // If prv->p is empty, prv->dP must be empty.
119 if ((PARAMISNULL(prv->p) != PARAMISNULL(prv->q)) || (PARAMISNULL(prv->p) && !PARAMISNULL(prv->dP))) {
120 BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO);
121 return CRYPT_RSA_NO_KEY_INFO;
122 }
123 if ((PARAMISNULL(prv->dP) || PARAMISNULL(prv->dQ) || PARAMISNULL(prv->qInv)) &&
124 (!PARAMISNULL(prv->dP) || !PARAMISNULL(prv->dQ) || !PARAMISNULL(prv->qInv))) {
125 BSL_ERR_PUSH_ERROR(CRYPT_RSA_NO_KEY_INFO);
126 return CRYPT_RSA_NO_KEY_INFO;
127 }
128 return CRYPT_SUCCESS;
129 }
130
SetPrvBnLenCheck(const CRYPT_RsaPrvParam * prv)131 static int32_t SetPrvBnLenCheck(const CRYPT_RsaPrvParam *prv)
132 {
133 /* The length of n is used as the length of a BigNum. The lengths of d, p, and q are not greater than n. */
134 uint32_t bnBytes = prv->n->valueLen;
135 if (prv->d->valueLen > bnBytes || prv->p->valueLen > bnBytes || prv->q->valueLen > bnBytes) {
136 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS);
137 return CRYPT_RSA_ERR_KEY_BITS;
138 }
139 return CRYPT_SUCCESS;
140 }
141
CRYPT_RSA_SetPrvKey(CRYPT_RSA_Ctx * ctx,const BSL_Param * para)142 int32_t CRYPT_RSA_SetPrvKey(CRYPT_RSA_Ctx *ctx, const BSL_Param *para)
143 {
144 CRYPT_RsaPrvParam prv = {0};
145 int32_t ret = GetAndCheckPrvKey(ctx, (BSL_Param *)(uintptr_t)para, &prv);
146 if (ret != CRYPT_SUCCESS) {
147 return ret;
148 }
149 ret = SetPrvBnLenCheck(&prv);
150 if (ret != CRYPT_SUCCESS) {
151 return ret;
152 }
153 CRYPT_RSA_Ctx *newCtx = CRYPT_RSA_NewCtx();
154 if (newCtx == NULL) {
155 return CRYPT_MEM_ALLOC_FAIL;
156 }
157 newCtx->prvKey = RSA_NewPrvKey(prv.n->valueLen * 8); // Bit length is obtained by multiplying byte length by 8.
158 if (newCtx->prvKey == NULL) {
159 ret = CRYPT_MEM_ALLOC_FAIL;
160 BSL_ERR_PUSH_ERROR(ret);
161 goto ERR;
162 }
163
164 ret = SetPrvPara(newCtx->prvKey, &prv);
165 if (ret != CRYPT_SUCCESS) {
166 BSL_ERR_PUSH_ERROR(ret);
167 goto ERR;
168 }
169 if (!PARAMISNULL(prv.p) && PARAMISNULL(prv.dP)) {
170 BN_Optimizer *optimizer = BN_OptimizerCreate();
171 if (optimizer == NULL) {
172 ret = CRYPT_MEM_ALLOC_FAIL;
173 BSL_ERR_PUSH_ERROR(ret);
174 goto ERR;
175 }
176 ret = RSA_CalcPrvKey(newCtx->para, newCtx, optimizer);
177 BN_OptimizerDestroy(optimizer);
178 if (ret != CRYPT_SUCCESS) {
179 goto ERR;
180 }
181 }
182
183 RSA_FREE_PRV_KEY(ctx->prvKey);
184 #ifdef HITLS_CRYPTO_RSA_BLINDING
185 RSA_BlindFreeCtx(ctx->scBlind);
186 ctx->scBlind = newCtx->scBlind;
187 #endif
188
189 ctx->prvKey = newCtx->prvKey;
190 ctx->pad = newCtx->pad;
191
192 BSL_SAL_ReferencesFree(&(newCtx->references));
193 BSL_SAL_FREE(newCtx);
194 return ret;
195 ERR:
196 CRYPT_RSA_FreeCtx(newCtx);
197 return ret;
198 }
199
SetPubBasicCheckAndGet(const CRYPT_RSA_Ctx * ctx,const BSL_Param * para,const BSL_Param * n,const BSL_Param * e)200 static int32_t SetPubBasicCheckAndGet(const CRYPT_RSA_Ctx *ctx, const BSL_Param *para, const BSL_Param *n,
201 const BSL_Param *e)
202 {
203 if (ctx == NULL || para == NULL) {
204 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
205 return CRYPT_NULL_INPUT;
206 }
207 if (PARAMISNULL(n)) {
208 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
209 return CRYPT_NULL_INPUT;
210 }
211 if (PARAMISNULL(e)) {
212 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
213 return CRYPT_NULL_INPUT;
214 }
215 if (n->valueLen > RSA_MAX_MODULUS_LEN) {
216 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS);
217 return CRYPT_RSA_ERR_KEY_BITS;
218 }
219 /* The length of n is used as the length of a BigNum, and the length of e is not greater than n. */
220 if (e->valueLen > n->valueLen) {
221 BSL_ERR_PUSH_ERROR(CRYPT_RSA_ERR_KEY_BITS);
222 return CRYPT_RSA_ERR_KEY_BITS;
223 }
224 return CRYPT_SUCCESS;
225 }
226
CRYPT_RSA_SetPubKey(CRYPT_RSA_Ctx * ctx,const BSL_Param * para)227 int32_t CRYPT_RSA_SetPubKey(CRYPT_RSA_Ctx *ctx, const BSL_Param *para)
228 {
229 const BSL_Param *nParam = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_RSA_N);
230 const BSL_Param *eParam = BSL_PARAM_FindConstParam(para, CRYPT_PARAM_RSA_E);
231 int32_t ret = SetPubBasicCheckAndGet(ctx, para, nParam, eParam);
232 if (ret != CRYPT_SUCCESS) {
233 BSL_ERR_PUSH_ERROR(ret);
234 return ret;
235 }
236 uint32_t bnBits;
237 CRYPT_RSA_PubKey *newPub = NULL;
238 (void)memset_s(&(ctx->pad), sizeof(RSAPad), 0, sizeof(RSAPad));
239 /* Bit length is obtained by multiplying byte length by 8. */
240 newPub = RSA_NewPubKey(nParam->valueLen * 8);
241 if (newPub == NULL) {
242 return CRYPT_MEM_ALLOC_FAIL;
243 }
244 GOTO_ERR_IF(BN_Bin2Bn(newPub->n, nParam->value, nParam->valueLen), ret);
245 bnBits = BN_Bits(newPub->n);
246 if (bnBits > RSA_MAX_MODULUS_BITS || bnBits < RSA_MIN_MODULUS_BITS) {
247 ret = CRYPT_RSA_ERR_KEY_BITS;
248 BSL_ERR_PUSH_ERROR(ret);
249 goto ERR;
250 }
251 GOTO_ERR_IF(BN_Bin2Bn(newPub->e, eParam->value, eParam->valueLen), ret);
252 if (nParam->valueLen > RSA_SMALL_MODULUS_BYTES && BN_Bytes(newPub->e) > RSA_MAX_PUBEXP_BYTES) {
253 ret = CRYPT_RSA_ERR_KEY_BITS;
254 BSL_ERR_PUSH_ERROR(ret);
255 goto ERR;
256 }
257 /**
258 * n > e
259 * e cannot be 0 or 1; The mathematical logic of e and d is that
260 * d and e are reciprocal in mod((p - 1) * (q - 1));
261 * When e is 1, both e and d must be 1. When e is 0, d does not exist.
262 */
263 if (BN_Cmp(newPub->n, newPub->e) <= 0 || BN_IsZero(newPub->e) || BN_IsOne(newPub->e)) {
264 ret = CRYPT_RSA_ERR_INPUT_VALUE;
265 BSL_ERR_PUSH_ERROR(ret);
266 goto ERR;
267 }
268
269 newPub->mont = BN_MontCreate(newPub->n);
270 if (newPub->mont == NULL) {
271 ret = CRYPT_MEM_ALLOC_FAIL;
272 BSL_ERR_PUSH_ERROR(ret);
273 goto ERR;
274 }
275
276 RSA_FREE_PUB_KEY(ctx->pubKey);
277 ctx->pubKey = newPub;
278 return ret;
279 ERR:
280 RSA_FREE_PUB_KEY(newPub);
281 return ret;
282 }
283
GetPrvBasicCheck(const CRYPT_RSA_Ctx * ctx,BSL_Param * para,CRYPT_RsaPrvParam * prv)284 static int32_t GetPrvBasicCheck(const CRYPT_RSA_Ctx *ctx, BSL_Param *para, CRYPT_RsaPrvParam *prv)
285 {
286 if (ctx == NULL || ctx->prvKey == NULL || para == NULL) {
287 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
288 return CRYPT_NULL_INPUT;
289 }
290 prv->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_N);
291 prv->d = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_D);
292 prv->e = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_E);
293 prv->p = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_P);
294 prv->q = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_Q);
295 prv->dP = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_DP);
296 prv->dQ = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_DQ);
297 prv->qInv = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_QINV);
298 // ctx\ctx->prvKey\prv is not empty.
299 // prv->p\q and prv->dP\dQ\qInv are both null or non-null.
300 // If prv->p is empty, prv->dP is empty.
301 if ((PARAMISNULL(prv->p) != PARAMISNULL(prv->q)) ||
302 ((PARAMISNULL(prv->dP) || PARAMISNULL(prv->dQ) || PARAMISNULL(prv->qInv)) &&
303 (!PARAMISNULL(prv->dP) || !PARAMISNULL(prv->dQ) || !PARAMISNULL(prv->qInv))) ||
304 (PARAMISNULL(prv->p) && !PARAMISNULL(prv->dP))) {
305 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
306 return CRYPT_NULL_INPUT;
307 }
308 return CRYPT_SUCCESS;
309 }
310
CRYPT_RSA_GetPrvKey(const CRYPT_RSA_Ctx * ctx,BSL_Param * para)311 int32_t CRYPT_RSA_GetPrvKey(const CRYPT_RSA_Ctx *ctx, BSL_Param *para)
312 {
313 CRYPT_RsaPrvParam prv = {0};
314 int32_t ret = GetPrvBasicCheck(ctx, para, &prv);
315 if (ret != CRYPT_SUCCESS) {
316 return ret;
317 }
318
319 prv.n->useLen = prv.n->valueLen;
320 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->n, prv.n->value, &(prv.n->useLen)), ret);
321 prv.d->useLen = prv.d->valueLen;
322 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->d, prv.d->value, &(prv.d->useLen)), ret);
323 if (!PARAMISNULL(prv.e)) {
324 prv.e->useLen = prv.e->valueLen;
325 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->e, prv.e->value, &(prv.e->useLen)), ret);
326 }
327 if (!PARAMISNULL(prv.p)) {
328 prv.p->useLen = prv.p->valueLen;
329 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->p, prv.p->value, &(prv.p->useLen)), ret);
330 prv.q->useLen = prv.q->valueLen;
331 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->q, prv.q->value, &(prv.q->useLen)), ret);
332 }
333 if (!PARAMISNULL(prv.dQ)) {
334 prv.dQ->useLen = prv.dQ->valueLen;
335 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->dQ, prv.dQ->value, &(prv.dQ->useLen)), ret);
336 prv.dP->useLen = prv.dP->valueLen;
337 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->dP, prv.dP->value, &(prv.dP->useLen)), ret);
338 prv.qInv->useLen = prv.qInv->valueLen;
339 GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->qInv, prv.qInv->value, &(prv.qInv->useLen)), ret);
340 }
341 return CRYPT_SUCCESS;
342
343 ERR:
344 if (!PARAMISNULL(prv.d) && prv.d->useLen != 0) {
345 BSL_SAL_CleanseData(prv.d->value, prv.d->useLen);
346 prv.d->useLen = 0;
347 }
348 if (!PARAMISNULL(prv.p) && prv.p->useLen != 0) {
349 BSL_SAL_CleanseData(prv.p->value, prv.p->useLen);
350 prv.p->useLen = 0;
351 }
352 if (!PARAMISNULL(prv.q) && prv.q->useLen != 0) {
353 BSL_SAL_CleanseData(prv.q->value, prv.q->useLen);
354 prv.q->useLen = 0;
355 }
356 if (!PARAMISNULL(prv.dQ) && prv.dQ->useLen != 0) {
357 BSL_SAL_CleanseData(prv.dQ->value, prv.dQ->useLen);
358 prv.dQ->useLen = 0;
359 }
360 if (!PARAMISNULL(prv.dP) && prv.dP->useLen != 0) {
361 BSL_SAL_CleanseData(prv.dP->value, prv.dP->useLen);
362 prv.dP->useLen = 0;
363 }
364 if (!PARAMISNULL(prv.qInv) && prv.qInv->useLen != 0) {
365 BSL_SAL_CleanseData(prv.qInv->value, prv.qInv->useLen);
366 prv.qInv->useLen = 0;
367 }
368 return ret;
369 }
370
CRYPT_RSA_GetPubKey(const CRYPT_RSA_Ctx * ctx,BSL_Param * para)371 int32_t CRYPT_RSA_GetPubKey(const CRYPT_RSA_Ctx *ctx, BSL_Param *para)
372 {
373 if (ctx == NULL || ctx->pubKey == NULL || para == NULL) {
374 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
375 return CRYPT_NULL_INPUT;
376 }
377 BSL_Param *e = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_E);
378 if (e == NULL || e->value == NULL) {
379 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
380 return CRYPT_NULL_INPUT;
381 }
382 uint32_t eLen = e->valueLen;
383 int32_t ret = BN_Bn2Bin(ctx->pubKey->e, e->value, &eLen);
384 if (ret != CRYPT_SUCCESS) {
385 BSL_ERR_PUSH_ERROR(ret);
386 return ret;
387 }
388 BSL_Param *n = BSL_PARAM_FindParam(para, CRYPT_PARAM_RSA_N);
389 if (n == NULL || n->value == NULL) {
390 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
391 return CRYPT_NULL_INPUT;
392 }
393 uint32_t nLen = n->valueLen;
394 ret = BN_Bn2Bin(ctx->pubKey->n, n->value, &nLen);
395 if (ret != CRYPT_SUCCESS) {
396 BSL_ERR_PUSH_ERROR(ret);
397 return ret;
398 }
399 e->useLen = eLen;
400 n->useLen = nLen;
401 return CRYPT_SUCCESS;
402 }
403
CRYPT_RSA_Cmp(const CRYPT_RSA_Ctx * a,const CRYPT_RSA_Ctx * b)404 int32_t CRYPT_RSA_Cmp(const CRYPT_RSA_Ctx *a, const CRYPT_RSA_Ctx *b)
405 {
406 RETURN_RET_IF(a == NULL || b == NULL, CRYPT_NULL_INPUT);
407
408 RETURN_RET_IF(a->pubKey == NULL || b->pubKey == NULL, CRYPT_RSA_NO_KEY_INFO);
409
410 RETURN_RET_IF(BN_Cmp(a->pubKey->n, b->pubKey->n) != 0 ||
411 BN_Cmp(a->pubKey->e, b->pubKey->e) != 0,
412 CRYPT_RSA_PUBKEY_NOT_EQUAL);
413
414 return CRYPT_SUCCESS;
415 }
416
CRYPT_RSA_GetSecBits(const CRYPT_RSA_Ctx * ctx)417 int32_t CRYPT_RSA_GetSecBits(const CRYPT_RSA_Ctx *ctx)
418 {
419 if (ctx == NULL) {
420 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
421 return 0;
422 }
423 int32_t bits = (int32_t)CRYPT_RSA_GetBits(ctx);
424 return BN_SecBits(bits, -1);
425 }
426 #endif // HITLS_CRYPTO_RSA
427