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