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