xref: /dragonfly/crypto/libressl/crypto/bn/bn_lib.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /* $OpenBSD: bn_lib.c,v 1.54 2022/06/27 12:25:49 tb 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 #ifndef BN_DEBUG
60 # undef NDEBUG /* avoid conflicting definitions */
61 # define NDEBUG
62 #endif
63 
64 #include <assert.h>
65 #include <limits.h>
66 #include <stdio.h>
67 #include <string.h>
68 
69 #include <openssl/opensslconf.h>
70 
71 #include <openssl/err.h>
72 
73 #include "bn_lcl.h"
74 
75 /* This stuff appears to be completely unused, so is deprecated */
76 #ifndef OPENSSL_NO_DEPRECATED
77 /* For a 32 bit machine
78  * 2 -   4 ==  128
79  * 3 -   8 ==  256
80  * 4 -  16 ==  512
81  * 5 -  32 == 1024
82  * 6 -  64 == 2048
83  * 7 - 128 == 4096
84  * 8 - 256 == 8192
85  */
86 static int bn_limit_bits = 0;
87 static int bn_limit_num = 8;        /* (1<<bn_limit_bits) */
88 static int bn_limit_bits_low = 0;
89 static int bn_limit_num_low = 8;    /* (1<<bn_limit_bits_low) */
90 static int bn_limit_bits_high = 0;
91 static int bn_limit_num_high = 8;   /* (1<<bn_limit_bits_high) */
92 static int bn_limit_bits_mont = 0;
93 static int bn_limit_num_mont = 8;   /* (1<<bn_limit_bits_mont) */
94 
95 BIGNUM *
BN_new(void)96 BN_new(void)
97 {
98           BIGNUM *ret;
99 
100           if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
101                     BNerror(ERR_R_MALLOC_FAILURE);
102                     return (NULL);
103           }
104           ret->flags = BN_FLG_MALLOCED;
105           ret->top = 0;
106           ret->neg = 0;
107           ret->dmax = 0;
108           ret->d = NULL;
109           bn_check_top(ret);
110           return (ret);
111 }
112 
113 void
BN_init(BIGNUM * a)114 BN_init(BIGNUM *a)
115 {
116           memset(a, 0, sizeof(BIGNUM));
117           bn_check_top(a);
118 }
119 
120 void
BN_clear(BIGNUM * a)121 BN_clear(BIGNUM *a)
122 {
123           bn_check_top(a);
124           if (a->d != NULL)
125                     explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
126           a->top = 0;
127           a->neg = 0;
128 }
129 
130 void
BN_clear_free(BIGNUM * a)131 BN_clear_free(BIGNUM *a)
132 {
133           int i;
134 
135           if (a == NULL)
136                     return;
137           bn_check_top(a);
138           if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
139                     freezero(a->d, a->dmax * sizeof(a->d[0]));
140           i = BN_get_flags(a, BN_FLG_MALLOCED);
141           explicit_bzero(a, sizeof(BIGNUM));
142           if (i)
143                     free(a);
144 }
145 
146 void
BN_free(BIGNUM * a)147 BN_free(BIGNUM *a)
148 {
149           BN_clear_free(a);
150 }
151 
152 void
BN_set_params(int mult,int high,int low,int mont)153 BN_set_params(int mult, int high, int low, int mont)
154 {
155           if (mult >= 0) {
156                     if (mult > (int)(sizeof(int) * 8) - 1)
157                               mult = sizeof(int) * 8 - 1;
158                     bn_limit_bits = mult;
159                     bn_limit_num = 1 << mult;
160           }
161           if (high >= 0) {
162                     if (high > (int)(sizeof(int) * 8) - 1)
163                               high = sizeof(int) * 8 - 1;
164                     bn_limit_bits_high = high;
165                     bn_limit_num_high = 1 << high;
166           }
167           if (low >= 0) {
168                     if (low > (int)(sizeof(int) * 8) - 1)
169                               low = sizeof(int) * 8 - 1;
170                     bn_limit_bits_low = low;
171                     bn_limit_num_low = 1 << low;
172           }
173           if (mont >= 0) {
174                     if (mont > (int)(sizeof(int) * 8) - 1)
175                               mont = sizeof(int) * 8 - 1;
176                     bn_limit_bits_mont = mont;
177                     bn_limit_num_mont = 1 << mont;
178           }
179 }
180 
181 int
BN_get_params(int which)182 BN_get_params(int which)
183 {
184           if (which == 0)
185                     return (bn_limit_bits);
186           else if (which == 1)
187                     return (bn_limit_bits_high);
188           else if (which == 2)
189                     return (bn_limit_bits_low);
190           else if (which == 3)
191                     return (bn_limit_bits_mont);
192           else
193                     return (0);
194 }
195 #endif
196 
197 void
BN_set_flags(BIGNUM * b,int n)198 BN_set_flags(BIGNUM *b, int n)
199 {
200           b->flags |= n;
201 }
202 
203 int
BN_get_flags(const BIGNUM * b,int n)204 BN_get_flags(const BIGNUM *b, int n)
205 {
206           return b->flags & n;
207 }
208 
209 void
BN_with_flags(BIGNUM * dest,const BIGNUM * b,int flags)210 BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
211 {
212           int dest_flags;
213 
214           dest_flags = (dest->flags & BN_FLG_MALLOCED) |
215               (b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags;
216 
217           *dest = *b;
218           dest->flags = dest_flags;
219 }
220 
221 const BIGNUM *
BN_value_one(void)222 BN_value_one(void)
223 {
224           static const BN_ULONG data_one = 1L;
225           static const BIGNUM const_one = {
226                     (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
227           };
228 
229           return (&const_one);
230 }
231 
232 int
BN_num_bits_word(BN_ULONG l)233 BN_num_bits_word(BN_ULONG l)
234 {
235           BN_ULONG x, mask;
236           int bits;
237           unsigned int shift;
238 
239           /* Constant time calculation of floor(log2(l)) + 1. */
240           bits = (l != 0);
241           shift = BN_BITS4;   /* On _LP64 this is 32, otherwise 16. */
242           do {
243                     x = l >> shift;
244                     /* If x is 0, set mask to 0, otherwise set it to all 1s. */
245                     mask = ((~x & (x - 1)) >> (BN_BITS2 - 1)) - 1;
246                     bits += shift & mask;
247                     /* If x is 0, leave l alone, otherwise set l = x. */
248                     l ^= (x ^ l) & mask;
249           } while ((shift /= 2) != 0);
250 
251           return bits;
252 }
253 
254 int
BN_num_bits(const BIGNUM * a)255 BN_num_bits(const BIGNUM *a)
256 {
257           int i = a->top - 1;
258 
259           bn_check_top(a);
260 
261           if (BN_is_zero(a))
262                     return 0;
263           return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
264 }
265 
266 /* This is used both by bn_expand2() and bn_dup_expand() */
267 /* The caller MUST check that words > b->dmax before calling this */
268 static BN_ULONG *
bn_expand_internal(const BIGNUM * b,int words)269 bn_expand_internal(const BIGNUM *b, int words)
270 {
271           BN_ULONG *A, *a = NULL;
272           const BN_ULONG *B;
273           int i;
274 
275           bn_check_top(b);
276 
277           if (words > (INT_MAX/(4*BN_BITS2))) {
278                     BNerror(BN_R_BIGNUM_TOO_LONG);
279                     return NULL;
280           }
281           if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
282                     BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
283                     return (NULL);
284           }
285           a = A = reallocarray(NULL, words, sizeof(BN_ULONG));
286           if (A == NULL) {
287                     BNerror(ERR_R_MALLOC_FAILURE);
288                     return (NULL);
289           }
290 #if 1
291           B = b->d;
292           /* Check if the previous number needs to be copied */
293           if (B != NULL) {
294                     for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
295                               /*
296                                * The fact that the loop is unrolled
297                                * 4-wise is a tribute to Intel. It's
298                                * the one that doesn't have enough
299                                * registers to accommodate more data.
300                                * I'd unroll it 8-wise otherwise:-)
301                                *
302                                *                  <appro@fy.chalmers.se>
303                                */
304                               BN_ULONG a0, a1, a2, a3;
305                               a0 = B[0];
306                               a1 = B[1];
307                               a2 = B[2];
308                               a3 = B[3];
309                               A[0] = a0;
310                               A[1] = a1;
311                               A[2] = a2;
312                               A[3] = a3;
313                     }
314                     switch (b->top & 3) {
315                     case 3:
316                               A[2] = B[2];
317                     case 2:
318                               A[1] = B[1];
319                     case 1:
320                               A[0] = B[0];
321                     }
322           }
323 
324 #else
325           memset(A, 0, sizeof(BN_ULONG) * words);
326           memcpy(A, b->d, sizeof(b->d[0]) * b->top);
327 #endif
328 
329           return (a);
330 }
331 
332 /* This is an internal function that can be used instead of bn_expand2()
333  * when there is a need to copy BIGNUMs instead of only expanding the
334  * data part, while still expanding them.
335  * Especially useful when needing to expand BIGNUMs that are declared
336  * 'const' and should therefore not be changed.
337  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
338  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
339  * will allocate new memory for the BIGNUM data twice, and free it once,
340  * while bn_dup_expand() makes sure allocation is made only once.
341  */
342 
343 #ifndef OPENSSL_NO_DEPRECATED
344 BIGNUM *
bn_dup_expand(const BIGNUM * b,int words)345 bn_dup_expand(const BIGNUM *b, int words)
346 {
347           BIGNUM *r = NULL;
348 
349           bn_check_top(b);
350 
351           /* This function does not work if
352            *      words <= b->dmax && top < words
353            * because BN_dup() does not preserve 'dmax'!
354            * (But bn_dup_expand() is not used anywhere yet.)
355            */
356 
357           if (words > b->dmax) {
358                     BN_ULONG *a = bn_expand_internal(b, words);
359 
360                     if (a) {
361                               r = BN_new();
362                               if (r) {
363                                         r->top = b->top;
364                                         r->dmax = words;
365                                         r->neg = b->neg;
366                                         r->d = a;
367                               } else {
368                                         /* r == NULL, BN_new failure */
369                                         free(a);
370                               }
371                     }
372                     /* If a == NULL, there was an error in allocation in
373                        bn_expand_internal(), and NULL should be returned */
374           } else {
375                     r = BN_dup(b);
376           }
377 
378           bn_check_top(r);
379           return r;
380 }
381 #endif
382 
383 /* This is an internal function that should not be used in applications.
384  * It ensures that 'b' has enough room for a 'words' word number
385  * and initialises any unused part of b->d with leading zeros.
386  * It is mostly used by the various BIGNUM routines. If there is an error,
387  * NULL is returned. If not, 'b' is returned. */
388 
389 BIGNUM *
bn_expand2(BIGNUM * b,int words)390 bn_expand2(BIGNUM *b, int words)
391 {
392           bn_check_top(b);
393 
394           if (words > b->dmax) {
395                     BN_ULONG *a = bn_expand_internal(b, words);
396                     if (!a)
397                               return NULL;
398                     if (b->d)
399                               freezero(b->d, b->dmax * sizeof(b->d[0]));
400                     b->d = a;
401                     b->dmax = words;
402           }
403 
404 /* None of this should be necessary because of what b->top means! */
405 #if 0
406           /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
407           if (b->top < b->dmax) {
408                     int i;
409                     BN_ULONG *A = &(b->d[b->top]);
410                     for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
411                               A[0] = 0;
412                               A[1] = 0;
413                               A[2] = 0;
414                               A[3] = 0;
415                               A[4] = 0;
416                               A[5] = 0;
417                               A[6] = 0;
418                               A[7] = 0;
419                     }
420                     for (i = (b->dmax - b->top)&7; i > 0; i--, A++)
421                               A[0] = 0;
422                     assert(A == &(b->d[b->dmax]));
423           }
424 #endif
425           bn_check_top(b);
426           return b;
427 }
428 
429 BIGNUM *
BN_dup(const BIGNUM * a)430 BN_dup(const BIGNUM *a)
431 {
432           BIGNUM *t;
433 
434           if (a == NULL)
435                     return NULL;
436           bn_check_top(a);
437 
438           t = BN_new();
439           if (t == NULL)
440                     return NULL;
441           if (!BN_copy(t, a)) {
442                     BN_free(t);
443                     return NULL;
444           }
445           bn_check_top(t);
446           return t;
447 }
448 
449 BIGNUM *
BN_copy(BIGNUM * a,const BIGNUM * b)450 BN_copy(BIGNUM *a, const BIGNUM *b)
451 {
452           int i;
453           BN_ULONG *A;
454           const BN_ULONG *B;
455 
456           bn_check_top(b);
457 
458           if (a == b)
459                     return (a);
460           if (bn_wexpand(a, b->top) == NULL)
461                     return (NULL);
462 
463 #if 1
464           A = a->d;
465           B = b->d;
466           for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
467                     BN_ULONG a0, a1, a2, a3;
468                     a0 = B[0];
469                     a1 = B[1];
470                     a2 = B[2];
471                     a3 = B[3];
472                     A[0] = a0;
473                     A[1] = a1;
474                     A[2] = a2;
475                     A[3] = a3;
476           }
477           switch (b->top & 3) {
478           case 3:
479                     A[2] = B[2];
480           case 2:
481                     A[1] = B[1];
482           case 1:
483                     A[0] = B[0];
484           }
485 #else
486           memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
487 #endif
488 
489           a->top = b->top;
490           a->neg = b->neg;
491           bn_check_top(a);
492           return (a);
493 }
494 
495 void
BN_swap(BIGNUM * a,BIGNUM * b)496 BN_swap(BIGNUM *a, BIGNUM *b)
497 {
498           int flags_old_a, flags_old_b;
499           BN_ULONG *tmp_d;
500           int tmp_top, tmp_dmax, tmp_neg;
501 
502           bn_check_top(a);
503           bn_check_top(b);
504 
505           flags_old_a = a->flags;
506           flags_old_b = b->flags;
507 
508           tmp_d = a->d;
509           tmp_top = a->top;
510           tmp_dmax = a->dmax;
511           tmp_neg = a->neg;
512 
513           a->d = b->d;
514           a->top = b->top;
515           a->dmax = b->dmax;
516           a->neg = b->neg;
517 
518           b->d = tmp_d;
519           b->top = tmp_top;
520           b->dmax = tmp_dmax;
521           b->neg = tmp_neg;
522 
523           a->flags = (flags_old_a & BN_FLG_MALLOCED) |
524               (flags_old_b & BN_FLG_STATIC_DATA);
525           b->flags = (flags_old_b & BN_FLG_MALLOCED) |
526               (flags_old_a & BN_FLG_STATIC_DATA);
527           bn_check_top(a);
528           bn_check_top(b);
529 }
530 
531 BN_ULONG
BN_get_word(const BIGNUM * a)532 BN_get_word(const BIGNUM *a)
533 {
534           if (a->top > 1)
535                     return BN_MASK2;
536           else if (a->top == 1)
537                     return a->d[0];
538           /* a->top == 0 */
539           return 0;
540 }
541 
542 BIGNUM *
bn_expand(BIGNUM * a,int bits)543 bn_expand(BIGNUM *a, int bits)
544 {
545           if (bits > (INT_MAX - BN_BITS2 + 1))
546                     return (NULL);
547 
548           if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax)
549                     return (a);
550 
551           return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2);
552 }
553 
554 int
BN_set_word(BIGNUM * a,BN_ULONG w)555 BN_set_word(BIGNUM *a, BN_ULONG w)
556 {
557           bn_check_top(a);
558           if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
559                     return (0);
560           a->neg = 0;
561           a->d[0] = w;
562           a->top = (w ? 1 : 0);
563           bn_check_top(a);
564           return (1);
565 }
566 
567 BIGNUM *
BN_bin2bn(const unsigned char * s,int len,BIGNUM * ret)568 BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
569 {
570           unsigned int i, m;
571           unsigned int n;
572           BN_ULONG l;
573           BIGNUM *bn = NULL;
574 
575           if (len < 0)
576                     return (NULL);
577           if (ret == NULL)
578                     ret = bn = BN_new();
579           if (ret == NULL)
580                     return (NULL);
581           bn_check_top(ret);
582           l = 0;
583           n = len;
584           if (n == 0) {
585                     ret->top = 0;
586                     return (ret);
587           }
588           i = ((n - 1) / BN_BYTES) + 1;
589           m = ((n - 1) % (BN_BYTES));
590           if (bn_wexpand(ret, (int)i) == NULL) {
591                     BN_free(bn);
592                     return NULL;
593           }
594           ret->top = i;
595           ret->neg = 0;
596           while (n--) {
597                     l = (l << 8L) | *(s++);
598                     if (m-- == 0) {
599                               ret->d[--i] = l;
600                               l = 0;
601                               m = BN_BYTES - 1;
602                     }
603           }
604           /* need to call this due to clear byte at top if avoiding
605            * having the top bit set (-ve number) */
606           bn_correct_top(ret);
607           return (ret);
608 }
609 
610 typedef enum {
611           big,
612           little,
613 } endianness_t;
614 
615 /* ignore negative */
616 static int
bn2binpad(const BIGNUM * a,unsigned char * to,int tolen,endianness_t endianness)617 bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
618 {
619           int n;
620           size_t i, lasti, j, atop, mask;
621           BN_ULONG l;
622 
623           /*
624            * In case |a| is fixed-top, BN_num_bytes can return bogus length,
625            * but it's assumed that fixed-top inputs ought to be "nominated"
626            * even for padded output, so it works out...
627            */
628           n = BN_num_bytes(a);
629           if (tolen == -1)
630                     tolen = n;
631           else if (tolen < n) {         /* uncommon/unlike case */
632                     BIGNUM temp = *a;
633 
634                     bn_correct_top(&temp);
635 
636                     n = BN_num_bytes(&temp);
637                     if (tolen < n)
638                               return -1;
639           }
640 
641           /* Swipe through whole available data and don't give away padded zero. */
642           atop = a->dmax * BN_BYTES;
643           if (atop == 0) {
644                     explicit_bzero(to, tolen);
645                     return tolen;
646           }
647 
648           lasti = atop - 1;
649           atop = a->top * BN_BYTES;
650 
651           if (endianness == big)
652                     to += tolen; /* start from the end of the buffer */
653 
654           for (i = 0, j = 0; j < (size_t)tolen; j++) {
655                     unsigned char val;
656 
657                     l = a->d[i / BN_BYTES];
658                     mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
659                     val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
660 
661                     if (endianness == big)
662                               *--to = val;
663                     else
664                               *to++ = val;
665 
666                     i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
667           }
668 
669           return tolen;
670 }
671 
672 int
BN_bn2binpad(const BIGNUM * a,unsigned char * to,int tolen)673 BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
674 {
675           if (tolen < 0)
676                     return -1;
677           return bn2binpad(a, to, tolen, big);
678 }
679 
680 int
BN_bn2bin(const BIGNUM * a,unsigned char * to)681 BN_bn2bin(const BIGNUM *a, unsigned char *to)
682 {
683           return bn2binpad(a, to, -1, big);
684 }
685 
686 BIGNUM *
BN_lebin2bn(const unsigned char * s,int len,BIGNUM * ret)687 BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
688 {
689           unsigned int i, m, n;
690           BN_ULONG l;
691           BIGNUM *bn = NULL;
692 
693           if (ret == NULL)
694                     ret = bn = BN_new();
695           if (ret == NULL)
696                     return NULL;
697 
698           bn_check_top(ret);
699 
700           s += len;
701           /* Skip trailing zeroes. */
702           for (; len > 0 && s[-1] == 0; s--, len--)
703                     continue;
704 
705           n = len;
706           if (n == 0) {
707                     ret->top = 0;
708                     return ret;
709           }
710 
711           i = ((n - 1) / BN_BYTES) + 1;
712           m = (n - 1) % BN_BYTES;
713           if (bn_wexpand(ret, (int)i) == NULL) {
714                     BN_free(bn);
715                     return NULL;
716           }
717 
718           ret->top = i;
719           ret->neg = 0;
720           l = 0;
721           while (n-- > 0) {
722                     s--;
723                     l = (l << 8L) | *s;
724                     if (m-- == 0) {
725                               ret->d[--i] = l;
726                               l = 0;
727                               m = BN_BYTES - 1;
728                     }
729           }
730 
731           /*
732            * need to call this due to clear byte at top if avoiding having the
733            * top bit set (-ve number)
734            */
735           bn_correct_top(ret);
736 
737           return ret;
738 }
739 
740 int
BN_bn2lebinpad(const BIGNUM * a,unsigned char * to,int tolen)741 BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
742 {
743           if (tolen < 0)
744                     return -1;
745 
746           return bn2binpad(a, to, tolen, little);
747 }
748 
749 int
BN_ucmp(const BIGNUM * a,const BIGNUM * b)750 BN_ucmp(const BIGNUM *a, const BIGNUM *b)
751 {
752           int i;
753           BN_ULONG t1, t2, *ap, *bp;
754 
755           bn_check_top(a);
756           bn_check_top(b);
757 
758           i = a->top - b->top;
759           if (i != 0)
760                     return (i);
761           ap = a->d;
762           bp = b->d;
763           for (i = a->top - 1; i >= 0; i--) {
764                     t1 = ap[i];
765                     t2 = bp[i];
766                     if (t1 != t2)
767                               return ((t1 > t2) ? 1 : -1);
768           }
769           return (0);
770 }
771 
772 int
BN_cmp(const BIGNUM * a,const BIGNUM * b)773 BN_cmp(const BIGNUM *a, const BIGNUM *b)
774 {
775           int i;
776           int gt, lt;
777           BN_ULONG t1, t2;
778 
779           if ((a == NULL) || (b == NULL)) {
780                     if (a != NULL)
781                               return (-1);
782                     else if (b != NULL)
783                               return (1);
784                     else
785                               return (0);
786           }
787 
788           bn_check_top(a);
789           bn_check_top(b);
790 
791           if (a->neg != b->neg) {
792                     if (a->neg)
793                               return (-1);
794                     else
795                               return (1);
796           }
797           if (a->neg == 0) {
798                     gt = 1;
799                     lt = -1;
800           } else {
801                     gt = -1;
802                     lt = 1;
803           }
804 
805           if (a->top > b->top)
806                     return (gt);
807           if (a->top < b->top)
808                     return (lt);
809           for (i = a->top - 1; i >= 0; i--) {
810                     t1 = a->d[i];
811                     t2 = b->d[i];
812                     if (t1 > t2)
813                               return (gt);
814                     if (t1 < t2)
815                               return (lt);
816           }
817           return (0);
818 }
819 
820 int
BN_set_bit(BIGNUM * a,int n)821 BN_set_bit(BIGNUM *a, int n)
822 {
823           int i, j, k;
824 
825           if (n < 0)
826                     return 0;
827 
828           i = n / BN_BITS2;
829           j = n % BN_BITS2;
830           if (a->top <= i) {
831                     if (bn_wexpand(a, i + 1) == NULL)
832                               return (0);
833                     for (k = a->top; k < i + 1; k++)
834                               a->d[k] = 0;
835                     a->top = i + 1;
836           }
837 
838           a->d[i] |= (((BN_ULONG)1) << j);
839           bn_check_top(a);
840           return (1);
841 }
842 
843 int
BN_clear_bit(BIGNUM * a,int n)844 BN_clear_bit(BIGNUM *a, int n)
845 {
846           int i, j;
847 
848           bn_check_top(a);
849           if (n < 0)
850                     return 0;
851 
852           i = n / BN_BITS2;
853           j = n % BN_BITS2;
854           if (a->top <= i)
855                     return (0);
856 
857           a->d[i] &= (~(((BN_ULONG)1) << j));
858           bn_correct_top(a);
859           return (1);
860 }
861 
862 int
BN_is_bit_set(const BIGNUM * a,int n)863 BN_is_bit_set(const BIGNUM *a, int n)
864 {
865           int i, j;
866 
867           bn_check_top(a);
868           if (n < 0)
869                     return 0;
870           i = n / BN_BITS2;
871           j = n % BN_BITS2;
872           if (a->top <= i)
873                     return 0;
874           return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
875 }
876 
877 int
BN_mask_bits(BIGNUM * a,int n)878 BN_mask_bits(BIGNUM *a, int n)
879 {
880           int b, w;
881 
882           bn_check_top(a);
883           if (n < 0)
884                     return 0;
885 
886           w = n / BN_BITS2;
887           b = n % BN_BITS2;
888           if (w >= a->top)
889                     return 0;
890           if (b == 0)
891                     a->top = w;
892           else {
893                     a->top = w + 1;
894                     a->d[w] &= ~(BN_MASK2 << b);
895           }
896           bn_correct_top(a);
897           return (1);
898 }
899 
900 void
BN_set_negative(BIGNUM * a,int b)901 BN_set_negative(BIGNUM *a, int b)
902 {
903           if (b && !BN_is_zero(a))
904                     a->neg = 1;
905           else
906                     a->neg = 0;
907 }
908 
909 int
bn_cmp_words(const BN_ULONG * a,const BN_ULONG * b,int n)910 bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
911 {
912           int i;
913           BN_ULONG aa, bb;
914 
915           aa = a[n - 1];
916           bb = b[n - 1];
917           if (aa != bb)
918                     return ((aa > bb) ? 1 : -1);
919           for (i = n - 2; i >= 0; i--) {
920                     aa = a[i];
921                     bb = b[i];
922                     if (aa != bb)
923                               return ((aa > bb) ? 1 : -1);
924           }
925           return (0);
926 }
927 
928 /* Here follows a specialised variants of bn_cmp_words().  It has the
929    property of performing the operation on arrays of different sizes.
930    The sizes of those arrays is expressed through cl, which is the
931    common length ( basicall, min(len(a),len(b)) ), and dl, which is the
932    delta between the two lengths, calculated as len(a)-len(b).
933    All lengths are the number of BN_ULONGs...  */
934 
935 int
bn_cmp_part_words(const BN_ULONG * a,const BN_ULONG * b,int cl,int dl)936 bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
937 {
938           int n, i;
939 
940           n = cl - 1;
941 
942           if (dl < 0) {
943                     for (i = dl; i < 0; i++) {
944                               if (b[n - i] != 0)
945                                         return -1; /* a < b */
946                     }
947           }
948           if (dl > 0) {
949                     for (i = dl; i > 0; i--) {
950                               if (a[n + i] != 0)
951                                         return 1; /* a > b */
952                     }
953           }
954           return bn_cmp_words(a, b, cl);
955 }
956 
957 /*
958  * Constant-time conditional swap of a and b.
959  * a and b are swapped if condition is not 0.
960  * The code assumes that at most one bit of condition is set.
961  * nwords is the number of words to swap.
962  * The code assumes that at least nwords are allocated in both a and b,
963  * and that no more than nwords are used by either a or b.
964  * a and b cannot be the same number
965  */
966 void
BN_consttime_swap(BN_ULONG condition,BIGNUM * a,BIGNUM * b,int nwords)967 BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
968 {
969           BN_ULONG t;
970           int i;
971 
972           bn_wcheck_size(a, nwords);
973           bn_wcheck_size(b, nwords);
974 
975           assert(a != b);
976           assert((condition & (condition - 1)) == 0);
977           assert(sizeof(BN_ULONG) >= sizeof(int));
978 
979           condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
980 
981           t = (a->top^b->top) & condition;
982           a->top ^= t;
983           b->top ^= t;
984 
985 #define BN_CONSTTIME_SWAP(ind) \
986           do { \
987                     t = (a->d[ind] ^ b->d[ind]) & condition; \
988                     a->d[ind] ^= t; \
989                     b->d[ind] ^= t; \
990           } while (0)
991 
992 
993           switch (nwords) {
994           default:
995                     for (i = 10; i < nwords; i++)
996                               BN_CONSTTIME_SWAP(i);
997                     /* Fallthrough */
998           case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
999           case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
1000           case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
1001           case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
1002           case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
1003           case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
1004           case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
1005           case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
1006           case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
1007           case 1:
1008                     BN_CONSTTIME_SWAP(0);
1009           }
1010 #undef BN_CONSTTIME_SWAP
1011 }
1012 
1013 /*
1014  * Constant-time conditional swap of a and b.
1015  * a and b are swapped if condition is not 0.
1016  * nwords is the number of words to swap.
1017  */
1018 int
BN_swap_ct(BN_ULONG condition,BIGNUM * a,BIGNUM * b,size_t nwords)1019 BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords)
1020 {
1021           BN_ULONG t;
1022           int i, words;
1023 
1024           if (a == b)
1025                     return 1;
1026           if (nwords > INT_MAX)
1027                     return 0;
1028           words = (int)nwords;
1029           if (bn_wexpand(a, words) == NULL || bn_wexpand(b, words) == NULL)
1030                     return 0;
1031           if (a->top > words || b->top > words) {
1032                     BNerror(BN_R_INVALID_LENGTH);
1033                     return 0;
1034           }
1035 
1036           /* Set condition to 0 (if it was zero) or all 1s otherwise. */
1037           condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1;
1038 
1039           /* swap top field */
1040           t = (a->top ^ b->top) & condition;
1041           a->top ^= t;
1042           b->top ^= t;
1043 
1044           /* swap neg field */
1045           t = (a->neg ^ b->neg) & condition;
1046           a->neg ^= t;
1047           b->neg ^= t;
1048 
1049           /* swap BN_FLG_CONSTTIME from flag field */
1050           t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;
1051           a->flags ^= t;
1052           b->flags ^= t;
1053 
1054           /* swap the data */
1055           for (i = 0; i < words; i++) {
1056                     t = (a->d[i] ^ b->d[i]) & condition;
1057                     a->d[i] ^= t;
1058                     b->d[i] ^= t;
1059           }
1060 
1061           return 1;
1062 }
1063 
1064 void
BN_zero_ex(BIGNUM * a)1065 BN_zero_ex(BIGNUM *a)
1066 {
1067           a->neg = 0;
1068           a->top = 0;
1069           /* XXX: a->flags &= ~BN_FIXED_TOP */
1070 }
1071 
1072 int
BN_abs_is_word(const BIGNUM * a,const BN_ULONG w)1073 BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
1074 {
1075           return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0);
1076 }
1077 
1078 int
BN_is_zero(const BIGNUM * a)1079 BN_is_zero(const BIGNUM *a)
1080 {
1081           return a->top == 0;
1082 }
1083 
1084 int
BN_is_one(const BIGNUM * a)1085 BN_is_one(const BIGNUM *a)
1086 {
1087           return BN_abs_is_word(a, 1) && !a->neg;
1088 }
1089 
1090 int
BN_is_word(const BIGNUM * a,const BN_ULONG w)1091 BN_is_word(const BIGNUM *a, const BN_ULONG w)
1092 {
1093           return BN_abs_is_word(a, w) && (w == 0 || !a->neg);
1094 }
1095 
1096 int
BN_is_odd(const BIGNUM * a)1097 BN_is_odd(const BIGNUM *a)
1098 {
1099           return a->top > 0 && (a->d[0] & 1);
1100 }
1101 
1102 int
BN_is_negative(const BIGNUM * a)1103 BN_is_negative(const BIGNUM *a)
1104 {
1105           return a->neg != 0;
1106 }
1107 
1108 /*
1109  * Bits of security, see SP800-57, section 5.6.11, table 2.
1110  */
1111 int
BN_security_bits(int L,int N)1112 BN_security_bits(int L, int N)
1113 {
1114           int secbits, bits;
1115 
1116           if (L >= 15360)
1117                     secbits = 256;
1118           else if (L >= 7680)
1119                     secbits = 192;
1120           else if (L >= 3072)
1121                     secbits = 128;
1122           else if (L >= 2048)
1123                     secbits = 112;
1124           else if (L >= 1024)
1125                     secbits = 80;
1126           else
1127                     return 0;
1128 
1129           if (N == -1)
1130                     return secbits;
1131 
1132           bits = N / 2;
1133           if (bits < 80)
1134                     return 0;
1135 
1136           return bits >= secbits ? secbits : bits;
1137 }
1138 
1139 BN_GENCB *
BN_GENCB_new(void)1140 BN_GENCB_new(void)
1141 {
1142           BN_GENCB *cb;
1143 
1144           if ((cb = calloc(1, sizeof(*cb))) == NULL)
1145                     return NULL;
1146 
1147           return cb;
1148 }
1149 
1150 void
BN_GENCB_free(BN_GENCB * cb)1151 BN_GENCB_free(BN_GENCB *cb)
1152 {
1153           if (cb == NULL)
1154                     return;
1155           free(cb);
1156 }
1157 
1158 /* Populate a BN_GENCB structure with an "old"-style callback */
1159 void
BN_GENCB_set_old(BN_GENCB * gencb,void (* cb)(int,int,void *),void * cb_arg)1160 BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg)
1161 {
1162           gencb->ver = 1;
1163           gencb->cb.cb_1 = cb;
1164           gencb->arg = cb_arg;
1165 }
1166 
1167 /* Populate a BN_GENCB structure with a "new"-style callback */
1168 void
BN_GENCB_set(BN_GENCB * gencb,int (* cb)(int,int,BN_GENCB *),void * cb_arg)1169 BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg)
1170 {
1171           gencb->ver = 2;
1172           gencb->cb.cb_2 = cb;
1173           gencb->arg = cb_arg;
1174 }
1175 
1176 void *
BN_GENCB_get_arg(BN_GENCB * cb)1177 BN_GENCB_get_arg(BN_GENCB *cb)
1178 {
1179           return cb->arg;
1180 }
1181