xref: /openbsd/lib/libcrypto/bn/bn_lib.c (revision 6579a347)
1 /* $OpenBSD: bn_lib.c,v 1.93 2024/04/16 13:07:14 jsing Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <assert.h>
60 #include <limits.h>
61 #include <stdio.h>
62 #include <string.h>
63 
64 #include <openssl/opensslconf.h>
65 
66 #include <openssl/err.h>
67 
68 #include "bn_local.h"
69 #include "bn_internal.h"
70 
71 BIGNUM *
BN_new(void)72 BN_new(void)
73 {
74 	BIGNUM *bn;
75 
76 	if ((bn = calloc(1, sizeof(BIGNUM))) == NULL) {
77 		BNerror(ERR_R_MALLOC_FAILURE);
78 		return NULL;
79 	}
80 	bn->flags = BN_FLG_MALLOCED;
81 
82 	return bn;
83 }
84 LCRYPTO_ALIAS(BN_new);
85 
86 void
BN_init(BIGNUM * a)87 BN_init(BIGNUM *a)
88 {
89 	memset(a, 0, sizeof(BIGNUM));
90 }
91 
92 void
BN_clear(BIGNUM * a)93 BN_clear(BIGNUM *a)
94 {
95 	if (a->d != NULL)
96 		explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
97 	a->top = 0;
98 	a->neg = 0;
99 }
100 LCRYPTO_ALIAS(BN_clear);
101 
102 void
BN_free(BIGNUM * bn)103 BN_free(BIGNUM *bn)
104 {
105 	if (bn == NULL)
106 		return;
107 
108 	if (!BN_get_flags(bn, BN_FLG_STATIC_DATA))
109 		freezero(bn->d, bn->dmax * sizeof(bn->d[0]));
110 
111 	if (!BN_get_flags(bn, BN_FLG_MALLOCED)) {
112 		explicit_bzero(bn, sizeof(*bn));
113 		return;
114 	}
115 
116 	freezero(bn, sizeof(*bn));
117 }
118 LCRYPTO_ALIAS(BN_free);
119 
120 void
BN_clear_free(BIGNUM * bn)121 BN_clear_free(BIGNUM *bn)
122 {
123 	BN_free(bn);
124 }
125 LCRYPTO_ALIAS(BN_clear_free);
126 
127 void
BN_set_flags(BIGNUM * b,int n)128 BN_set_flags(BIGNUM *b, int n)
129 {
130 	b->flags |= n;
131 }
132 LCRYPTO_ALIAS(BN_set_flags);
133 
134 int
BN_get_flags(const BIGNUM * b,int n)135 BN_get_flags(const BIGNUM *b, int n)
136 {
137 	return b->flags & n;
138 }
139 LCRYPTO_ALIAS(BN_get_flags);
140 
141 void
BN_with_flags(BIGNUM * dest,const BIGNUM * b,int flags)142 BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
143 {
144 	int dest_flags;
145 
146 	dest_flags = (dest->flags & BN_FLG_MALLOCED) |
147 	    (b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags;
148 
149 	*dest = *b;
150 	dest->flags = dest_flags;
151 }
152 LCRYPTO_ALIAS(BN_with_flags);
153 
154 static const BN_ULONG bn_value_one_data = 1;
155 static const BIGNUM bn_value_one = {
156 	.d = (BN_ULONG *)&bn_value_one_data,
157 	.top = 1,
158 	.dmax = 1,
159 	.neg = 0,
160 	.flags = BN_FLG_STATIC_DATA,
161 };
162 
163 const BIGNUM *
BN_value_one(void)164 BN_value_one(void)
165 {
166 	return &bn_value_one;
167 }
168 LCRYPTO_ALIAS(BN_value_one);
169 
170 int
BN_num_bits_word(BN_ULONG w)171 BN_num_bits_word(BN_ULONG w)
172 {
173 	return BN_BITS2 - bn_clzw(w);
174 }
175 LCRYPTO_ALIAS(BN_num_bits_word);
176 
177 int
BN_num_bits(const BIGNUM * bn)178 BN_num_bits(const BIGNUM *bn)
179 {
180 	return bn_bitsize(bn);
181 }
182 LCRYPTO_ALIAS(BN_num_bits);
183 
184 void
bn_correct_top(BIGNUM * a)185 bn_correct_top(BIGNUM *a)
186 {
187 	while (a->top > 0 && a->d[a->top - 1] == 0)
188 		a->top--;
189 }
190 
191 static int
bn_expand_internal(BIGNUM * bn,int words)192 bn_expand_internal(BIGNUM *bn, int words)
193 {
194 	BN_ULONG *d;
195 
196 	if (words < 0) {
197 		BNerror(BN_R_BIGNUM_TOO_LONG); // XXX
198 		return 0;
199 	}
200 
201 	if (words > INT_MAX / (4 * BN_BITS2)) {
202 		BNerror(BN_R_BIGNUM_TOO_LONG);
203 		return 0;
204 	}
205 	if (BN_get_flags(bn, BN_FLG_STATIC_DATA)) {
206 		BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
207 		return 0;
208 	}
209 
210 	d = recallocarray(bn->d, bn->dmax, words, sizeof(BN_ULONG));
211 	if (d == NULL) {
212 		BNerror(ERR_R_MALLOC_FAILURE);
213 		return 0;
214 	}
215 	bn->d = d;
216 	bn->dmax = words;
217 
218 	return 1;
219 }
220 
221 int
bn_expand_bits(BIGNUM * bn,size_t bits)222 bn_expand_bits(BIGNUM *bn, size_t bits)
223 {
224 	int words;
225 
226 	if (bits > (INT_MAX - BN_BITS2 + 1))
227 		return 0;
228 
229 	words = (bits + BN_BITS2 - 1) / BN_BITS2;
230 
231 	return bn_wexpand(bn, words);
232 }
233 
234 int
bn_expand_bytes(BIGNUM * bn,size_t bytes)235 bn_expand_bytes(BIGNUM *bn, size_t bytes)
236 {
237 	int words;
238 
239 	if (bytes > (INT_MAX - BN_BYTES + 1))
240 		return 0;
241 
242 	words = (bytes + BN_BYTES - 1) / BN_BYTES;
243 
244 	return bn_wexpand(bn, words);
245 }
246 
247 int
bn_wexpand(BIGNUM * bn,int words)248 bn_wexpand(BIGNUM *bn, int words)
249 {
250 	if (words < 0)
251 		return 0;
252 
253 	if (words <= bn->dmax)
254 		return 1;
255 
256 	return bn_expand_internal(bn, words);
257 }
258 
259 BIGNUM *
BN_dup(const BIGNUM * a)260 BN_dup(const BIGNUM *a)
261 {
262 	BIGNUM *t;
263 
264 	if (a == NULL)
265 		return NULL;
266 
267 	t = BN_new();
268 	if (t == NULL)
269 		return NULL;
270 	if (!bn_copy(t, a)) {
271 		BN_free(t);
272 		return NULL;
273 	}
274 	return t;
275 }
276 LCRYPTO_ALIAS(BN_dup);
277 
278 static inline void
bn_copy_words(BN_ULONG * ap,const BN_ULONG * bp,int n)279 bn_copy_words(BN_ULONG *ap, const BN_ULONG *bp, int n)
280 {
281 	while (n > 0) {
282 		ap[0] = bp[0];
283 		ap++;
284 		bp++;
285 		n--;
286 	}
287 }
288 
289 BIGNUM *
BN_copy(BIGNUM * a,const BIGNUM * b)290 BN_copy(BIGNUM *a, const BIGNUM *b)
291 {
292 	if (a == b)
293 		return (a);
294 
295 	if (!bn_wexpand(a, b->top))
296 		return (NULL);
297 
298 	bn_copy_words(a->d, b->d, b->top);
299 
300 	/* Copy constant time flag from b, but make it sticky on a. */
301 	a->flags |= b->flags & BN_FLG_CONSTTIME;
302 
303 	a->top = b->top;
304 	a->neg = b->neg;
305 
306 	return (a);
307 }
308 LCRYPTO_ALIAS(BN_copy);
309 
310 int
bn_copy(BIGNUM * dst,const BIGNUM * src)311 bn_copy(BIGNUM *dst, const BIGNUM *src)
312 {
313 	return BN_copy(dst, src) != NULL;
314 }
315 
316 void
BN_swap(BIGNUM * a,BIGNUM * b)317 BN_swap(BIGNUM *a, BIGNUM *b)
318 {
319 	int flags_old_a, flags_old_b;
320 	BN_ULONG *tmp_d;
321 	int tmp_top, tmp_dmax, tmp_neg;
322 
323 
324 	flags_old_a = a->flags;
325 	flags_old_b = b->flags;
326 
327 	tmp_d = a->d;
328 	tmp_top = a->top;
329 	tmp_dmax = a->dmax;
330 	tmp_neg = a->neg;
331 
332 	a->d = b->d;
333 	a->top = b->top;
334 	a->dmax = b->dmax;
335 	a->neg = b->neg;
336 
337 	b->d = tmp_d;
338 	b->top = tmp_top;
339 	b->dmax = tmp_dmax;
340 	b->neg = tmp_neg;
341 
342 	a->flags = (flags_old_a & BN_FLG_MALLOCED) |
343 	    (flags_old_b & BN_FLG_STATIC_DATA);
344 	b->flags = (flags_old_b & BN_FLG_MALLOCED) |
345 	    (flags_old_a & BN_FLG_STATIC_DATA);
346 }
347 LCRYPTO_ALIAS(BN_swap);
348 
349 BN_ULONG
BN_get_word(const BIGNUM * a)350 BN_get_word(const BIGNUM *a)
351 {
352 	if (a->top > 1)
353 		return BN_MASK2;
354 	else if (a->top == 1)
355 		return a->d[0];
356 	/* a->top == 0 */
357 	return 0;
358 }
359 LCRYPTO_ALIAS(BN_get_word);
360 
361 int
BN_set_word(BIGNUM * a,BN_ULONG w)362 BN_set_word(BIGNUM *a, BN_ULONG w)
363 {
364 	if (!bn_wexpand(a, 1))
365 		return (0);
366 	a->neg = 0;
367 	a->d[0] = w;
368 	a->top = (w ? 1 : 0);
369 	return (1);
370 }
371 LCRYPTO_ALIAS(BN_set_word);
372 
373 int
BN_ucmp(const BIGNUM * a,const BIGNUM * b)374 BN_ucmp(const BIGNUM *a, const BIGNUM *b)
375 {
376 	int i;
377 
378 	if (a->top < b->top)
379 		return -1;
380 	if (a->top > b->top)
381 		return 1;
382 
383 	for (i = a->top - 1; i >= 0; i--) {
384 		if (a->d[i] != b->d[i])
385 			return (a->d[i] > b->d[i] ? 1 : -1);
386 	}
387 
388 	return 0;
389 }
390 LCRYPTO_ALIAS(BN_ucmp);
391 
392 int
BN_cmp(const BIGNUM * a,const BIGNUM * b)393 BN_cmp(const BIGNUM *a, const BIGNUM *b)
394 {
395 	if (a == NULL || b == NULL) {
396 		if (a != NULL)
397 			return -1;
398 		if (b != NULL)
399 			return 1;
400 		return 0;
401 	}
402 
403 	if (a->neg != b->neg)
404 		return b->neg - a->neg;
405 
406 	if (a->neg)
407 		return BN_ucmp(b, a);
408 
409 	return BN_ucmp(a, b);
410 }
411 LCRYPTO_ALIAS(BN_cmp);
412 
413 int
BN_set_bit(BIGNUM * a,int n)414 BN_set_bit(BIGNUM *a, int n)
415 {
416 	int i, j, k;
417 
418 	if (n < 0)
419 		return 0;
420 
421 	i = n / BN_BITS2;
422 	j = n % BN_BITS2;
423 	if (a->top <= i) {
424 		if (!bn_wexpand(a, i + 1))
425 			return (0);
426 		for (k = a->top; k < i + 1; k++)
427 			a->d[k] = 0;
428 		a->top = i + 1;
429 	}
430 
431 	a->d[i] |= (((BN_ULONG)1) << j);
432 	return (1);
433 }
434 LCRYPTO_ALIAS(BN_set_bit);
435 
436 int
BN_clear_bit(BIGNUM * a,int n)437 BN_clear_bit(BIGNUM *a, int n)
438 {
439 	int i, j;
440 
441 	if (n < 0)
442 		return 0;
443 
444 	i = n / BN_BITS2;
445 	j = n % BN_BITS2;
446 	if (a->top <= i)
447 		return (0);
448 
449 	a->d[i] &= (~(((BN_ULONG)1) << j));
450 	bn_correct_top(a);
451 
452 	BN_set_negative(a, a->neg);
453 
454 	return (1);
455 }
456 LCRYPTO_ALIAS(BN_clear_bit);
457 
458 int
BN_is_bit_set(const BIGNUM * a,int n)459 BN_is_bit_set(const BIGNUM *a, int n)
460 {
461 	int i, j;
462 
463 	if (n < 0)
464 		return 0;
465 	i = n / BN_BITS2;
466 	j = n % BN_BITS2;
467 	if (a->top <= i)
468 		return 0;
469 	return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
470 }
471 LCRYPTO_ALIAS(BN_is_bit_set);
472 
473 int
BN_mask_bits(BIGNUM * a,int n)474 BN_mask_bits(BIGNUM *a, int n)
475 {
476 	int b, w;
477 
478 	if (n < 0)
479 		return 0;
480 
481 	w = n / BN_BITS2;
482 	b = n % BN_BITS2;
483 	if (w >= a->top)
484 		return 0;
485 	if (b == 0)
486 		a->top = w;
487 	else {
488 		a->top = w + 1;
489 		a->d[w] &= ~(BN_MASK2 << b);
490 	}
491 	bn_correct_top(a);
492 
493 	BN_set_negative(a, a->neg);
494 
495 	return (1);
496 }
497 LCRYPTO_ALIAS(BN_mask_bits);
498 
499 void
BN_set_negative(BIGNUM * bn,int neg)500 BN_set_negative(BIGNUM *bn, int neg)
501 {
502 	bn->neg = ~BN_is_zero(bn) & bn_ct_ne_zero(neg);
503 }
504 LCRYPTO_ALIAS(BN_set_negative);
505 
506 /*
507  * Constant-time conditional swap of a and b.
508  * a and b are swapped if condition is not 0.
509  * The code assumes that at most one bit of condition is set.
510  * nwords is the number of words to swap.
511  * The code assumes that at least nwords are allocated in both a and b,
512  * and that no more than nwords are used by either a or b.
513  * a and b cannot be the same number
514  */
515 void
BN_consttime_swap(BN_ULONG condition,BIGNUM * a,BIGNUM * b,int nwords)516 BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
517 {
518 	BN_ULONG t;
519 	int i;
520 
521 	assert(a != b);
522 	assert((condition & (condition - 1)) == 0);
523 	assert(sizeof(BN_ULONG) >= sizeof(int));
524 
525 	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
526 
527 	t = (a->top^b->top) & condition;
528 	a->top ^= t;
529 	b->top ^= t;
530 
531 #define BN_CONSTTIME_SWAP(ind) \
532 	do { \
533 		t = (a->d[ind] ^ b->d[ind]) & condition; \
534 		a->d[ind] ^= t; \
535 		b->d[ind] ^= t; \
536 	} while (0)
537 
538 
539 	switch (nwords) {
540 	default:
541 		for (i = 10; i < nwords; i++)
542 			BN_CONSTTIME_SWAP(i);
543 		/* Fallthrough */
544 	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
545 	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
546 	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
547 	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
548 	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
549 	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
550 	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
551 	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
552 	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
553 	case 1:
554 		BN_CONSTTIME_SWAP(0);
555 	}
556 #undef BN_CONSTTIME_SWAP
557 }
558 LCRYPTO_ALIAS(BN_consttime_swap);
559 
560 /*
561  * Constant-time conditional swap of a and b.
562  * a and b are swapped if condition is not 0.
563  * nwords is the number of words to swap.
564  */
565 int
BN_swap_ct(BN_ULONG condition,BIGNUM * a,BIGNUM * b,size_t nwords)566 BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords)
567 {
568 	BN_ULONG t;
569 	int i, words;
570 
571 	if (a == b)
572 		return 1;
573 	if (nwords > INT_MAX)
574 		return 0;
575 	words = (int)nwords;
576 	if (!bn_wexpand(a, words) || !bn_wexpand(b, words))
577 		return 0;
578 	if (a->top > words || b->top > words) {
579 		BNerror(BN_R_INVALID_LENGTH);
580 		return 0;
581 	}
582 
583 	/* Set condition to 0 (if it was zero) or all 1s otherwise. */
584 	condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1;
585 
586 	/* swap top field */
587 	t = (a->top ^ b->top) & condition;
588 	a->top ^= t;
589 	b->top ^= t;
590 
591 	/* swap neg field */
592 	t = (a->neg ^ b->neg) & condition;
593 	a->neg ^= t;
594 	b->neg ^= t;
595 
596 	/* swap BN_FLG_CONSTTIME from flag field */
597 	t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;
598 	a->flags ^= t;
599 	b->flags ^= t;
600 
601 	/* swap the data */
602 	for (i = 0; i < words; i++) {
603 		t = (a->d[i] ^ b->d[i]) & condition;
604 		a->d[i] ^= t;
605 		b->d[i] ^= t;
606 	}
607 
608 	return 1;
609 }
610 
611 void
BN_zero(BIGNUM * a)612 BN_zero(BIGNUM *a)
613 {
614 	a->neg = 0;
615 	a->top = 0;
616 }
617 LCRYPTO_ALIAS(BN_zero);
618 
619 int
BN_one(BIGNUM * a)620 BN_one(BIGNUM *a)
621 {
622 	return BN_set_word(a, 1);
623 }
624 LCRYPTO_ALIAS(BN_one);
625 
626 int
BN_abs_is_word(const BIGNUM * a,const BN_ULONG w)627 BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
628 {
629 	return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0);
630 }
631 LCRYPTO_ALIAS(BN_abs_is_word);
632 
633 int
BN_is_zero(const BIGNUM * bn)634 BN_is_zero(const BIGNUM *bn)
635 {
636 	BN_ULONG bits = 0;
637 	int i;
638 
639 	for (i = 0; i < bn->top; i++)
640 		bits |= bn->d[i];
641 
642 	return bits == 0;
643 }
644 LCRYPTO_ALIAS(BN_is_zero);
645 
646 int
BN_is_one(const BIGNUM * a)647 BN_is_one(const BIGNUM *a)
648 {
649 	return BN_abs_is_word(a, 1) && !a->neg;
650 }
651 LCRYPTO_ALIAS(BN_is_one);
652 
653 int
BN_is_word(const BIGNUM * a,const BN_ULONG w)654 BN_is_word(const BIGNUM *a, const BN_ULONG w)
655 {
656 	return BN_abs_is_word(a, w) && (w == 0 || !a->neg);
657 }
658 LCRYPTO_ALIAS(BN_is_word);
659 
660 int
BN_is_odd(const BIGNUM * a)661 BN_is_odd(const BIGNUM *a)
662 {
663 	return a->top > 0 && (a->d[0] & 1);
664 }
665 LCRYPTO_ALIAS(BN_is_odd);
666 
667 int
BN_is_negative(const BIGNUM * a)668 BN_is_negative(const BIGNUM *a)
669 {
670 	return a->neg != 0;
671 }
672 LCRYPTO_ALIAS(BN_is_negative);
673 
674 /*
675  * Bits of security, see SP800-57, section 5.6.11, table 2.
676  */
677 int
BN_security_bits(int L,int N)678 BN_security_bits(int L, int N)
679 {
680 	int secbits, bits;
681 
682 	if (L >= 15360)
683 		secbits = 256;
684 	else if (L >= 7680)
685 		secbits = 192;
686 	else if (L >= 3072)
687 		secbits = 128;
688 	else if (L >= 2048)
689 		secbits = 112;
690 	else if (L >= 1024)
691 		secbits = 80;
692 	else
693 		return 0;
694 
695 	if (N == -1)
696 		return secbits;
697 
698 	bits = N / 2;
699 	if (bits < 80)
700 		return 0;
701 
702 	return bits >= secbits ? secbits : bits;
703 }
704 LCRYPTO_ALIAS(BN_security_bits);
705 
706 BN_GENCB *
BN_GENCB_new(void)707 BN_GENCB_new(void)
708 {
709 	BN_GENCB *cb;
710 
711 	if ((cb = calloc(1, sizeof(*cb))) == NULL)
712 		return NULL;
713 
714 	return cb;
715 }
716 LCRYPTO_ALIAS(BN_GENCB_new);
717 
718 void
BN_GENCB_free(BN_GENCB * cb)719 BN_GENCB_free(BN_GENCB *cb)
720 {
721 	if (cb == NULL)
722 		return;
723 	free(cb);
724 }
725 LCRYPTO_ALIAS(BN_GENCB_free);
726 
727 /* Populate a BN_GENCB structure with an "old"-style callback */
728 void
BN_GENCB_set_old(BN_GENCB * gencb,void (* cb)(int,int,void *),void * cb_arg)729 BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg)
730 {
731 	gencb->ver = 1;
732 	gencb->cb.cb_1 = cb;
733 	gencb->arg = cb_arg;
734 }
735 LCRYPTO_ALIAS(BN_GENCB_set_old);
736 
737 /* Populate a BN_GENCB structure with a "new"-style callback */
738 void
BN_GENCB_set(BN_GENCB * gencb,int (* cb)(int,int,BN_GENCB *),void * cb_arg)739 BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg)
740 {
741 	gencb->ver = 2;
742 	gencb->cb.cb_2 = cb;
743 	gencb->arg = cb_arg;
744 }
745 LCRYPTO_ALIAS(BN_GENCB_set);
746 
747 void *
BN_GENCB_get_arg(BN_GENCB * cb)748 BN_GENCB_get_arg(BN_GENCB *cb)
749 {
750 	return cb->arg;
751 }
752 LCRYPTO_ALIAS(BN_GENCB_get_arg);
753