• 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_BN
18 
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_err_internal.h"
22 #include "crypt_errno.h"
23 #include "bn_bincal.h"
24 #include "bn_basic.h"
25 
BN_Create(uint32_t bits)26 BN_BigNum *BN_Create(uint32_t bits)
27 {
28     if (bits > BN_MAX_BITS) {
29         BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_INVALID);
30         return NULL;
31     }
32     uint32_t room = BITS_TO_BN_UNIT(bits);
33     BN_BigNum *r = (BN_BigNum *)BSL_SAL_Calloc(1u, sizeof(BN_BigNum));
34     if (r == NULL) {
35         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
36         return NULL;
37     }
38     if (room != 0) {
39         r->room = room;
40         r->data = (BN_UINT *)BSL_SAL_Calloc(1u, room * sizeof(BN_UINT));
41         if (r->data == NULL) {
42             BSL_SAL_FREE(r);
43             return NULL;
44         }
45     }
46 
47     return r;
48 }
49 
BN_Destroy(BN_BigNum * a)50 void BN_Destroy(BN_BigNum *a)
51 {
52     if (a == NULL) {
53         return;
54     }
55     // clear sensitive information
56     BSL_SAL_CleanseData((void *)(a->data), a->size * sizeof(BN_UINT));
57     if (a->flag == CRYPT_BN_FLAG_STATIC) {
58         return;
59     }
60     BSL_SAL_FREE(a->data);
61     if (!BN_IsFlag(a, CRYPT_BN_FLAG_OPTIMIZER)) {
62         BSL_SAL_FREE(a);
63     }
64 }
65 
BN_Init(BN_BigNum * bn,BN_UINT * data,uint32_t room,int32_t number)66 inline void BN_Init(BN_BigNum *bn, BN_UINT *data, uint32_t room, int32_t number)
67 {
68     for (uint32_t i = 0; i < (uint32_t)number; i++) {
69         bn[i].data = &data[room * i];
70         bn[i].room = room;
71         bn[i].flag = CRYPT_BN_FLAG_STATIC;
72     }
73 }
74 #ifdef HITLS_CRYPTO_EAL_BN
BnVaild(const BN_BigNum * a)75 bool BnVaild(const BN_BigNum *a)
76 {
77     if (a == NULL) {
78         return false;
79     }
80     if (a->size == 0) {
81         return !a->sign;
82     }
83     if (a->data == NULL || a->size > a->room) {
84         return false;
85     }
86     if ((a->size <= a->room) && (a->data[a->size - 1] != 0)) {
87         return true;
88     }
89     return false;
90 }
91 #endif
92 
93 #ifdef HITLS_CRYPTO_BN_CB
BN_CbCtxCreate(void)94 BN_CbCtx *BN_CbCtxCreate(void)
95 {
96     BN_CbCtx *r = (BN_CbCtx *)BSL_SAL_Calloc(1u, sizeof(BN_CbCtx));
97     if (r == NULL) {
98         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
99         return NULL;
100     }
101     return r;
102 }
103 
BN_CbCtxSet(BN_CbCtx * gencb,BN_CallBack callBack,void * arg)104 void BN_CbCtxSet(BN_CbCtx *gencb, BN_CallBack callBack, void *arg)
105 {
106     if (gencb == NULL) {
107         return;
108     }
109     BN_CbCtx *tmpCb = gencb;
110     tmpCb->arg = arg;
111     tmpCb->cb = callBack;
112 }
113 
BN_CbCtxGetArg(BN_CbCtx * callBack)114 void *BN_CbCtxGetArg(BN_CbCtx *callBack)
115 {
116     if (callBack == NULL) {
117         return NULL;
118     }
119     return callBack->arg;
120 }
121 
BN_CbCtxCall(BN_CbCtx * callBack,int32_t process,int32_t target)122 int32_t BN_CbCtxCall(BN_CbCtx *callBack, int32_t process, int32_t target)
123 {
124     if (callBack == NULL || callBack->cb == NULL) {
125         return CRYPT_SUCCESS;
126     }
127     int32_t ret = callBack->cb(callBack, process, target);
128     if (ret != CRYPT_SUCCESS) {
129         BSL_ERR_PUSH_ERROR(ret);
130     }
131     return ret;
132 }
133 
BN_CbCtxDestroy(BN_CbCtx * cb)134 void BN_CbCtxDestroy(BN_CbCtx *cb)
135 {
136     if (cb == NULL) {
137         return;
138     }
139     BSL_SAL_FREE(cb);
140 }
141 #endif
142 
BN_SetSign(BN_BigNum * a,bool sign)143 int32_t BN_SetSign(BN_BigNum *a, bool sign)
144 {
145     if (a == NULL) {
146         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
147         return CRYPT_NULL_INPUT;
148     }
149     /* 0 must be a positive number symbol */
150     if (BN_IsZero(a) == true && sign == true) {
151         BSL_ERR_PUSH_ERROR(CRYPT_BN_NO_NEGATIVE_ZERO);
152         return CRYPT_BN_NO_NEGATIVE_ZERO;
153     }
154     a->sign = sign;
155     return CRYPT_SUCCESS;
156 }
157 
IsLegalFlag(uint32_t flag)158 static bool IsLegalFlag(uint32_t flag)
159 {
160     switch (flag) {
161         case CRYPT_BN_FLAG_CONSTTIME:
162         case CRYPT_BN_FLAG_OPTIMIZER:
163         case CRYPT_BN_FLAG_STATIC:
164             return true;
165         default:
166             return false;
167     }
168 }
169 
BN_SetFlag(BN_BigNum * a,uint32_t flag)170 int32_t BN_SetFlag(BN_BigNum *a, uint32_t flag)
171 {
172     if (a == NULL) {
173         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
174         return CRYPT_NULL_INPUT;
175     }
176     if (!IsLegalFlag(flag)) {
177         BSL_ERR_PUSH_ERROR(CRYPT_BN_FLAG_INVALID);
178         return CRYPT_BN_FLAG_INVALID;
179     }
180     a->flag |= flag;
181     return CRYPT_SUCCESS;
182 }
183 
BN_Copy(BN_BigNum * r,const BN_BigNum * a)184 int32_t BN_Copy(BN_BigNum *r, const BN_BigNum *a)
185 {
186     if (r == NULL || a == NULL) {
187         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
188         return CRYPT_NULL_INPUT;
189     }
190     if (r != a) {
191         int32_t ret = BnExtend(r, a->size);
192         if (ret != CRYPT_SUCCESS) {
193             return ret;
194         }
195         r->sign = a->sign;
196         BN_COPY_BYTES(r->data, r->size, a->data, a->size);
197         r->size = a->size;
198     }
199     return CRYPT_SUCCESS;
200 }
201 
BN_Dup(const BN_BigNum * a)202 BN_BigNum *BN_Dup(const BN_BigNum *a)
203 {
204     if (a == NULL) {
205         return NULL;
206     }
207     BN_BigNum *r = BN_Create(a->room * BN_UINT_BITS);
208     if (r != NULL) {
209         r->sign = a->sign;
210         (void)memcpy_s(r->data, a->size * sizeof(BN_UINT), a->data, a->size * sizeof(BN_UINT));
211         r->size = a->size;
212     }
213     return r;
214 }
215 
BN_IsZero(const BN_BigNum * a)216 bool BN_IsZero(const BN_BigNum *a)
217 {
218     if (a == NULL) {
219         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
220         return true;
221     }
222     return (a->size == 0);
223 }
224 
BN_IsOne(const BN_BigNum * a)225 bool BN_IsOne(const BN_BigNum *a)
226 {
227     if (a == NULL) {
228         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
229         return false;
230     }
231     return (a->size == 1 && a->data[0] == 1 && a->sign == false);
232 }
233 
BN_IsNegative(const BN_BigNum * a)234 bool BN_IsNegative(const BN_BigNum *a)
235 {
236     if (a == NULL) {
237         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
238         return false;
239     }
240     return a->sign;
241 }
242 
BN_IsOdd(const BN_BigNum * a)243 bool BN_IsOdd(const BN_BigNum *a)
244 {
245     if (a == NULL) {
246         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
247         return false;
248     }
249     return (a->size > 0) && (a->data[0] & 1) != 0;
250 }
251 
BN_IsFlag(const BN_BigNum * a,uint32_t flag)252 bool BN_IsFlag(const BN_BigNum *a, uint32_t flag)
253 {
254     if (a == NULL) {
255         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
256         return false;
257     }
258     return a->flag & flag;
259 }
260 
BN_Zeroize(BN_BigNum * a)261 int32_t BN_Zeroize(BN_BigNum *a)
262 {
263     if (a == NULL) {
264         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
265         return CRYPT_NULL_INPUT;
266     }
267     // clear sensitive information
268     BSL_SAL_CleanseData(a->data, a->size * sizeof(BN_UINT));
269     a->sign = false;
270     a->size = 0;
271     return CRYPT_SUCCESS;
272 }
273 
BN_IsLimb(const BN_BigNum * a,const BN_UINT w)274 bool BN_IsLimb(const BN_BigNum *a, const BN_UINT w)
275 {
276     if (a == NULL) {
277         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
278         return (w == 0);
279     }
280     return !a->sign && (((a->size == 1) && (a->data[0] == w)) || ((w == 0) && (a->size == 0)));
281 }
282 
BN_SetLimb(BN_BigNum * r,BN_UINT w)283 int32_t BN_SetLimb(BN_BigNum *r, BN_UINT w)
284 {
285     if (r == NULL) {
286         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
287         return CRYPT_NULL_INPUT;
288     }
289     int32_t ret = BnExtend(r, 1);
290     if (ret != CRYPT_SUCCESS) {
291         return ret;
292     }
293     BN_Zeroize(r);
294     if (w != 0) {
295         r->data[r->size] = w;
296         r->size++;
297     }
298     return CRYPT_SUCCESS;
299 }
300 
BN_GetLimb(const BN_BigNum * a)301 BN_UINT BN_GetLimb(const BN_BigNum *a)
302 {
303     if (a == NULL) {
304         return 0;
305     }
306     if (a->size > 1) {
307         return BN_MASK;
308     } else if (a->size == 1) {
309         return a->data[0];
310     }
311     return 0;
312 }
313 
BN_GetBit(const BN_BigNum * a,uint32_t n)314 bool BN_GetBit(const BN_BigNum *a, uint32_t n)
315 {
316     if (a == NULL) {
317         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
318         return false;
319     }
320     uint32_t nw = n / BN_UINT_BITS;
321     uint32_t nb = n % BN_UINT_BITS;
322     if (nw >= a->size) {
323         return false;
324     }
325     return (uint32_t)(((a->data[nw]) >> nb) & ((BN_UINT)1));
326 }
327 
BN_SetBit(BN_BigNum * a,uint32_t n)328 int32_t BN_SetBit(BN_BigNum *a, uint32_t n)
329 {
330     if (a == NULL) {
331         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
332         return CRYPT_NULL_INPUT;
333     }
334     uint32_t nw = n / BN_UINT_BITS;
335     uint32_t nb = n % BN_UINT_BITS;
336     if (nw >= a->room) {
337         BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
338         return CRYPT_BN_SPACE_NOT_ENOUGH;
339     }
340     a->data[nw] |= (((BN_UINT)1) << nb);
341     if (a->size < nw + 1) {
342         a->size = nw + 1;
343     }
344     return CRYPT_SUCCESS;
345 }
346 
BN_ClrBit(BN_BigNum * a,uint32_t n)347 int32_t BN_ClrBit(BN_BigNum *a, uint32_t n)
348 {
349     if (a == NULL) {
350         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
351         return CRYPT_NULL_INPUT;
352     }
353     uint32_t nw = n / BN_UINT_BITS;
354     uint32_t nb = n % BN_UINT_BITS;
355     if (nw >= a->size) {
356         BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
357         return CRYPT_BN_SPACE_NOT_ENOUGH;
358     }
359     a->data[nw] &= (~(((BN_UINT)1) << nb));
360     // check whether the size changes
361     a->size = BinFixSize(a->data, a->size);
362     if (a->size == 0) {
363         a->sign = false;
364     }
365     return CRYPT_SUCCESS;
366 }
367 
BN_MaskBit(BN_BigNum * a,uint32_t n)368 int32_t BN_MaskBit(BN_BigNum *a, uint32_t n)
369 {
370     if (a == NULL) {
371         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
372         return CRYPT_NULL_INPUT;
373     }
374     uint32_t nw = n / BN_UINT_BITS;
375     uint32_t nb = n % BN_UINT_BITS;
376     if (a->size <= nw) {
377         BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
378         return CRYPT_BN_SPACE_NOT_ENOUGH;
379     }
380     if (nb == 0) {
381         a->size = nw;
382     } else {
383         a->size = nw + 1;
384         a->data[nw] &= ~(BN_MASK << nb);
385     }
386     a->size = BinFixSize(a->data, a->size);
387     if (a->size == 0) {
388         a->sign = false;
389     }
390     return CRYPT_SUCCESS;
391 }
392 
BN_Bits(const BN_BigNum * a)393 uint32_t BN_Bits(const BN_BigNum *a)
394 {
395     if (a == NULL) {
396         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
397         return 0;
398     }
399     return BinBits(a->data, a->size);
400 }
401 
BN_Bytes(const BN_BigNum * a)402 uint32_t BN_Bytes(const BN_BigNum *a)
403 {
404     return BN_BITS_TO_BYTES(BN_Bits(a));
405 }
406 
BnExtend(BN_BigNum * a,uint32_t words)407 int32_t BnExtend(BN_BigNum *a, uint32_t words)
408 {
409     if (a->room >= words) {
410         return CRYPT_SUCCESS;
411     }
412     if (a->flag == CRYPT_BN_FLAG_STATIC) {
413         BSL_ERR_PUSH_ERROR(CRYPT_BN_NOT_SUPPORT_EXTENSION);
414         return CRYPT_BN_NOT_SUPPORT_EXTENSION;
415     }
416     if (words > BITS_TO_BN_UNIT(BN_MAX_BITS)) {
417         BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX);
418         return CRYPT_BN_BITS_TOO_MAX;
419     }
420 
421     BN_UINT *tmp = (BN_UINT *)BSL_SAL_Calloc(1u, words * sizeof(BN_UINT));
422     if (tmp == NULL) {
423         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
424         return CRYPT_MEM_ALLOC_FAIL;
425     }
426     if (a->size > 0) {
427         (void)memcpy_s(tmp, a->size * sizeof(BN_UINT), a->data, a->size * sizeof(BN_UINT));
428         BSL_SAL_CleanseData(a->data, a->size * sizeof(BN_UINT));
429     }
430     BSL_SAL_FREE(a->data);
431     a->data = tmp;
432     a->room = words;
433     return CRYPT_SUCCESS;
434 }
435 
436 // ref. NIST.SP.800-57 Section 5.6.1.1
BN_SecBits(int32_t pubLen,int32_t prvLen)437 int32_t BN_SecBits(int32_t pubLen, int32_t prvLen)
438 {
439     int32_t bits = 256; // the secure length is initialized to a maximum of 256
440     int32_t level[] = {1024, 2048, 3072, 7680, 15360, INT32_MAX};
441     int32_t secbits[] = {0, 80, 112, 128, 192, 256};
442     for (int32_t loc = 0; loc < (int32_t)(sizeof(level) / sizeof(level[0])); loc++) {
443         if (pubLen < level[loc]) {
444             bits = secbits[loc];
445             break;
446         }
447     }
448 
449     if (prvLen == -1) { // In IFC algorithm, the security length only needs to consider the modulus number.
450         return bits;
451     }
452     bits = ((prvLen / 2) >= bits) ? bits : (prvLen / 2); // The security length of FFC algorithm is considering prvLen/2
453     // Encryption does not use the algorithm/key combination which security strength is less than 112 bits
454     // such as less than 80 bits
455     return (bits < 80) ? 0 : bits;
456 }
457 #endif /* HITLS_CRYPTO_BN */
458