xref: /openbsd-src/lib/libcrypto/bn/bn_lib.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /* $OpenBSD: bn_lib.c,v 1.33 2014/07/12 16:03:36 miod 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 void
96 BN_set_params(int mult, int high, int low, int mont)
97 {
98 	if (mult >= 0) {
99 		if (mult > (int)(sizeof(int) * 8) - 1)
100 			mult = sizeof(int) * 8 - 1;
101 		bn_limit_bits = mult;
102 		bn_limit_num = 1 << mult;
103 	}
104 	if (high >= 0) {
105 		if (high > (int)(sizeof(int) * 8) - 1)
106 			high = sizeof(int) * 8 - 1;
107 		bn_limit_bits_high = high;
108 		bn_limit_num_high = 1 << high;
109 	}
110 	if (low >= 0) {
111 		if (low > (int)(sizeof(int) * 8) - 1)
112 			low = sizeof(int) * 8 - 1;
113 		bn_limit_bits_low = low;
114 		bn_limit_num_low = 1 << low;
115 	}
116 	if (mont >= 0) {
117 		if (mont > (int)(sizeof(int) * 8) - 1)
118 			mont = sizeof(int) * 8 - 1;
119 		bn_limit_bits_mont = mont;
120 		bn_limit_num_mont = 1 << mont;
121 	}
122 }
123 
124 int
125 BN_get_params(int which)
126 {
127 	if (which == 0)
128 		return (bn_limit_bits);
129 	else if (which == 1)
130 		return (bn_limit_bits_high);
131 	else if (which == 2)
132 		return (bn_limit_bits_low);
133 	else if (which == 3)
134 		return (bn_limit_bits_mont);
135 	else
136 		return (0);
137 }
138 #endif
139 
140 const BIGNUM *
141 BN_value_one(void)
142 {
143 	static const BN_ULONG data_one = 1L;
144 	static const BIGNUM const_one = {
145 		(BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
146 	};
147 
148 	return (&const_one);
149 }
150 
151 int
152 BN_num_bits_word(BN_ULONG l)
153 {
154 	static const unsigned char bits[256] = {
155 		0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
156 		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
157 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
158 		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
159 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
160 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
161 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
162 		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
163 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,  8, 8, 8, 8,
164 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
165 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
166 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
167 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
168 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
169 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
170 		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
171 	};
172 
173 #ifdef _LP64
174 	if (l & 0xffffffff00000000L) {
175 		if (l & 0xffff000000000000L) {
176 			if (l & 0xff00000000000000L) {
177 				return (bits[(int)(l >> 56)] + 56);
178 			} else
179 				return (bits[(int)(l >> 48)] + 48);
180 		} else {
181 			if (l & 0x0000ff0000000000L) {
182 				return (bits[(int)(l >> 40)] + 40);
183 			} else
184 				return (bits[(int)(l >> 32)] + 32);
185 		}
186 	} else
187 #endif
188 	{
189 		if (l & 0xffff0000L) {
190 			if (l & 0xff000000L)
191 				return (bits[(int)(l >> 24L)] + 24);
192 			else
193 				return (bits[(int)(l >> 16L)] + 16);
194 		} else {
195 			if (l & 0xff00L)
196 				return (bits[(int)(l >> 8)] + 8);
197 			else
198 				return (bits[(int)(l)]);
199 		}
200 	}
201 }
202 
203 int
204 BN_num_bits(const BIGNUM *a)
205 {
206 	int i = a->top - 1;
207 
208 	bn_check_top(a);
209 
210 	if (BN_is_zero(a))
211 		return 0;
212 	return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
213 }
214 
215 void
216 BN_clear_free(BIGNUM *a)
217 {
218 	int i;
219 
220 	if (a == NULL)
221 		return;
222 	bn_check_top(a);
223 	if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) {
224 		OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
225 		free(a->d);
226 	}
227 	i = BN_get_flags(a, BN_FLG_MALLOCED);
228 	OPENSSL_cleanse(a, sizeof(BIGNUM));
229 	if (i)
230 		free(a);
231 }
232 
233 void
234 BN_free(BIGNUM *a)
235 {
236 	BN_clear_free(a);
237 }
238 
239 void
240 BN_init(BIGNUM *a)
241 {
242 	memset(a, 0, sizeof(BIGNUM));
243 	bn_check_top(a);
244 }
245 
246 BIGNUM *
247 BN_new(void)
248 {
249 	BIGNUM *ret;
250 
251 	if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
252 		BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
253 		return (NULL);
254 	}
255 	ret->flags = BN_FLG_MALLOCED;
256 	ret->top = 0;
257 	ret->neg = 0;
258 	ret->dmax = 0;
259 	ret->d = NULL;
260 	bn_check_top(ret);
261 	return (ret);
262 }
263 
264 /* This is used both by bn_expand2() and bn_dup_expand() */
265 /* The caller MUST check that words > b->dmax before calling this */
266 static BN_ULONG *
267 bn_expand_internal(const BIGNUM *b, int words)
268 {
269 	BN_ULONG *A, *a = NULL;
270 	const BN_ULONG *B;
271 	int i;
272 
273 	bn_check_top(b);
274 
275 	if (words > (INT_MAX/(4*BN_BITS2))) {
276 		BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
277 		return NULL;
278 	}
279 	if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
280 		BNerr(BN_F_BN_EXPAND_INTERNAL,
281 		    BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
282 		return (NULL);
283 	}
284 	a = A = reallocarray(NULL, words, sizeof(BN_ULONG));
285 	if (A == NULL) {
286 		BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
287 		return (NULL);
288 	}
289 #if 1
290 	B = b->d;
291 	/* Check if the previous number needs to be copied */
292 	if (B != NULL) {
293 		for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
294 			/*
295 			 * The fact that the loop is unrolled
296 			 * 4-wise is a tribute to Intel. It's
297 			 * the one that doesn't have enough
298 			 * registers to accomodate more data.
299 			 * I'd unroll it 8-wise otherwise:-)
300 			 *
301 			 *		<appro@fy.chalmers.se>
302 			 */
303 			BN_ULONG a0, a1, a2, a3;
304 			a0 = B[0];
305 			a1 = B[1];
306 			a2 = B[2];
307 			a3 = B[3];
308 			A[0] = a0;
309 			A[1] = a1;
310 			A[2] = a2;
311 			A[3] = a3;
312 		}
313 		switch (b->top & 3) {
314 		case 3:
315 			A[2] = B[2];
316 		case 2:
317 			A[1] = B[1];
318 		case 1:
319 			A[0] = B[0];
320 		}
321 	}
322 
323 #else
324 	memset(A, 0, sizeof(BN_ULONG) * words);
325 	memcpy(A, b->d, sizeof(b->d[0]) * b->top);
326 #endif
327 
328 	return (a);
329 }
330 
331 /* This is an internal function that can be used instead of bn_expand2()
332  * when there is a need to copy BIGNUMs instead of only expanding the
333  * data part, while still expanding them.
334  * Especially useful when needing to expand BIGNUMs that are declared
335  * 'const' and should therefore not be changed.
336  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
337  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
338  * will allocate new memory for the BIGNUM data twice, and free it once,
339  * while bn_dup_expand() makes sure allocation is made only once.
340  */
341 
342 #ifndef OPENSSL_NO_DEPRECATED
343 BIGNUM *
344 bn_dup_expand(const BIGNUM *b, int words)
345 {
346 	BIGNUM *r = NULL;
347 
348 	bn_check_top(b);
349 
350 	/* This function does not work if
351 	 *      words <= b->dmax && top < words
352 	 * because BN_dup() does not preserve 'dmax'!
353 	 * (But bn_dup_expand() is not used anywhere yet.)
354 	 */
355 
356 	if (words > b->dmax) {
357 		BN_ULONG *a = bn_expand_internal(b, words);
358 
359 		if (a) {
360 			r = BN_new();
361 			if (r) {
362 				r->top = b->top;
363 				r->dmax = words;
364 				r->neg = b->neg;
365 				r->d = a;
366 			} else {
367 				/* r == NULL, BN_new failure */
368 				free(a);
369 			}
370 		}
371 		/* If a == NULL, there was an error in allocation in
372 		   bn_expand_internal(), and NULL should be returned */
373 	} else {
374 		r = BN_dup(b);
375 	}
376 
377 	bn_check_top(r);
378 	return r;
379 }
380 #endif
381 
382 /* This is an internal function that should not be used in applications.
383  * It ensures that 'b' has enough room for a 'words' word number
384  * and initialises any unused part of b->d with leading zeros.
385  * It is mostly used by the various BIGNUM routines. If there is an error,
386  * NULL is returned. If not, 'b' is returned. */
387 
388 BIGNUM *
389 bn_expand2(BIGNUM *b, int words)
390 {
391 	bn_check_top(b);
392 
393 	if (words > b->dmax) {
394 		BN_ULONG *a = bn_expand_internal(b, words);
395 		if (!a)
396 			return NULL;
397 		if (b->d) {
398 			OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));
399 			free(b->d);
400 		}
401 		b->d = a;
402 		b->dmax = words;
403 	}
404 
405 /* None of this should be necessary because of what b->top means! */
406 #if 0
407 	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
408 	if (b->top < b->dmax) {
409 		int i;
410 		BN_ULONG *A = &(b->d[b->top]);
411 		for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
412 			A[0] = 0;
413 			A[1] = 0;
414 			A[2] = 0;
415 			A[3] = 0;
416 			A[4] = 0;
417 			A[5] = 0;
418 			A[6] = 0;
419 			A[7] = 0;
420 		}
421 		for (i = (b->dmax - b->top)&7; i > 0; i--, A++)
422 			A[0] = 0;
423 		assert(A == &(b->d[b->dmax]));
424 	}
425 #endif
426 	bn_check_top(b);
427 	return b;
428 }
429 
430 BIGNUM *
431 BN_dup(const BIGNUM *a)
432 {
433 	BIGNUM *t;
434 
435 	if (a == NULL)
436 		return NULL;
437 	bn_check_top(a);
438 
439 	t = BN_new();
440 	if (t == NULL)
441 		return NULL;
442 	if (!BN_copy(t, a)) {
443 		BN_free(t);
444 		return NULL;
445 	}
446 	bn_check_top(t);
447 	return t;
448 }
449 
450 BIGNUM *
451 BN_copy(BIGNUM *a, const BIGNUM *b)
452 {
453 	int i;
454 	BN_ULONG *A;
455 	const BN_ULONG *B;
456 
457 	bn_check_top(b);
458 
459 	if (a == b)
460 		return (a);
461 	if (bn_wexpand(a, b->top) == NULL)
462 		return (NULL);
463 
464 #if 1
465 	A = a->d;
466 	B = b->d;
467 	for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
468 		BN_ULONG a0, a1, a2, a3;
469 		a0 = B[0];
470 		a1 = B[1];
471 		a2 = B[2];
472 		a3 = B[3];
473 		A[0] = a0;
474 		A[1] = a1;
475 		A[2] = a2;
476 		A[3] = a3;
477 	}
478 	switch (b->top & 3) {
479 	case 3:
480 		A[2] = B[2];
481 	case 2:
482 		A[1] = B[1];
483 	case 1:
484 		A[0] = B[0];
485 	}
486 #else
487 	memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
488 #endif
489 
490 	a->top = b->top;
491 	a->neg = b->neg;
492 	bn_check_top(a);
493 	return (a);
494 }
495 
496 void
497 BN_swap(BIGNUM *a, BIGNUM *b)
498 {
499 	int flags_old_a, flags_old_b;
500 	BN_ULONG *tmp_d;
501 	int tmp_top, tmp_dmax, tmp_neg;
502 
503 	bn_check_top(a);
504 	bn_check_top(b);
505 
506 	flags_old_a = a->flags;
507 	flags_old_b = b->flags;
508 
509 	tmp_d = a->d;
510 	tmp_top = a->top;
511 	tmp_dmax = a->dmax;
512 	tmp_neg = a->neg;
513 
514 	a->d = b->d;
515 	a->top = b->top;
516 	a->dmax = b->dmax;
517 	a->neg = b->neg;
518 
519 	b->d = tmp_d;
520 	b->top = tmp_top;
521 	b->dmax = tmp_dmax;
522 	b->neg = tmp_neg;
523 
524 	a->flags = (flags_old_a & BN_FLG_MALLOCED) |
525 	    (flags_old_b & BN_FLG_STATIC_DATA);
526 	b->flags = (flags_old_b & BN_FLG_MALLOCED) |
527 	    (flags_old_a & BN_FLG_STATIC_DATA);
528 	bn_check_top(a);
529 	bn_check_top(b);
530 }
531 
532 void
533 BN_clear(BIGNUM *a)
534 {
535 	bn_check_top(a);
536 	if (a->d != NULL)
537 		memset(a->d, 0, a->dmax * sizeof(a->d[0]));
538 	a->top = 0;
539 	a->neg = 0;
540 }
541 
542 BN_ULONG
543 BN_get_word(const BIGNUM *a)
544 {
545 	if (a->top > 1)
546 		return BN_MASK2;
547 	else if (a->top == 1)
548 		return a->d[0];
549 	/* a->top == 0 */
550 	return 0;
551 }
552 
553 int
554 BN_set_word(BIGNUM *a, BN_ULONG w)
555 {
556 	bn_check_top(a);
557 	if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
558 		return (0);
559 	a->neg = 0;
560 	a->d[0] = w;
561 	a->top = (w ? 1 : 0);
562 	bn_check_top(a);
563 	return (1);
564 }
565 
566 BIGNUM *
567 BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
568 {
569 	unsigned int i, m;
570 	unsigned int n;
571 	BN_ULONG l;
572 	BIGNUM *bn = NULL;
573 
574 	if (ret == NULL)
575 		ret = bn = BN_new();
576 	if (ret == NULL)
577 		return (NULL);
578 	bn_check_top(ret);
579 	l = 0;
580 	n = len;
581 	if (n == 0) {
582 		ret->top = 0;
583 		return (ret);
584 	}
585 	i = ((n - 1) / BN_BYTES) + 1;
586 	m = ((n - 1) % (BN_BYTES));
587 	if (bn_wexpand(ret, (int)i) == NULL) {
588 		BN_free(bn);
589 		return NULL;
590 	}
591 	ret->top = i;
592 	ret->neg = 0;
593 	while (n--) {
594 		l = (l << 8L) | *(s++);
595 		if (m-- == 0) {
596 			ret->d[--i] = l;
597 			l = 0;
598 			m = BN_BYTES - 1;
599 		}
600 	}
601 	/* need to call this due to clear byte at top if avoiding
602 	 * having the top bit set (-ve number) */
603 	bn_correct_top(ret);
604 	return (ret);
605 }
606 
607 /* ignore negative */
608 int
609 BN_bn2bin(const BIGNUM *a, unsigned char *to)
610 {
611 	int n, i;
612 	BN_ULONG l;
613 
614 	bn_check_top(a);
615 	n = i=BN_num_bytes(a);
616 	while (i--) {
617 		l = a->d[i / BN_BYTES];
618 		*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
619 	}
620 	return (n);
621 }
622 
623 int
624 BN_ucmp(const BIGNUM *a, const BIGNUM *b)
625 {
626 	int i;
627 	BN_ULONG t1, t2, *ap, *bp;
628 
629 	bn_check_top(a);
630 	bn_check_top(b);
631 
632 	i = a->top - b->top;
633 	if (i != 0)
634 		return (i);
635 	ap = a->d;
636 	bp = b->d;
637 	for (i = a->top - 1; i >= 0; i--) {
638 		t1 = ap[i];
639 		t2 = bp[i];
640 		if (t1 != t2)
641 			return ((t1 > t2) ? 1 : -1);
642 	}
643 	return (0);
644 }
645 
646 int
647 BN_cmp(const BIGNUM *a, const BIGNUM *b)
648 {
649 	int i;
650 	int gt, lt;
651 	BN_ULONG t1, t2;
652 
653 	if ((a == NULL) || (b == NULL)) {
654 		if (a != NULL)
655 			return (-1);
656 		else if (b != NULL)
657 			return (1);
658 		else
659 			return (0);
660 	}
661 
662 	bn_check_top(a);
663 	bn_check_top(b);
664 
665 	if (a->neg != b->neg) {
666 		if (a->neg)
667 			return (-1);
668 		else
669 			return (1);
670 	}
671 	if (a->neg == 0) {
672 		gt = 1;
673 		lt = -1;
674 	} else {
675 		gt = -1;
676 		lt = 1;
677 	}
678 
679 	if (a->top > b->top)
680 		return (gt);
681 	if (a->top < b->top)
682 		return (lt);
683 	for (i = a->top - 1; i >= 0; i--) {
684 		t1 = a->d[i];
685 		t2 = b->d[i];
686 		if (t1 > t2)
687 			return (gt);
688 		if (t1 < t2)
689 			return (lt);
690 	}
691 	return (0);
692 }
693 
694 int
695 BN_set_bit(BIGNUM *a, int n)
696 {
697 	int i, j, k;
698 
699 	if (n < 0)
700 		return 0;
701 
702 	i = n / BN_BITS2;
703 	j = n % BN_BITS2;
704 	if (a->top <= i) {
705 		if (bn_wexpand(a, i + 1) == NULL)
706 			return (0);
707 		for (k = a->top; k < i + 1; k++)
708 			a->d[k] = 0;
709 		a->top = i + 1;
710 	}
711 
712 	a->d[i] |= (((BN_ULONG)1) << j);
713 	bn_check_top(a);
714 	return (1);
715 }
716 
717 int
718 BN_clear_bit(BIGNUM *a, int n)
719 {
720 	int i, j;
721 
722 	bn_check_top(a);
723 	if (n < 0)
724 		return 0;
725 
726 	i = n / BN_BITS2;
727 	j = n % BN_BITS2;
728 	if (a->top <= i)
729 		return (0);
730 
731 	a->d[i] &= (~(((BN_ULONG)1) << j));
732 	bn_correct_top(a);
733 	return (1);
734 }
735 
736 int
737 BN_is_bit_set(const BIGNUM *a, int n)
738 {
739 	int i, j;
740 
741 	bn_check_top(a);
742 	if (n < 0)
743 		return 0;
744 	i = n / BN_BITS2;
745 	j = n % BN_BITS2;
746 	if (a->top <= i)
747 		return 0;
748 	return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
749 }
750 
751 int
752 BN_mask_bits(BIGNUM *a, int n)
753 {
754 	int b, w;
755 
756 	bn_check_top(a);
757 	if (n < 0)
758 		return 0;
759 
760 	w = n / BN_BITS2;
761 	b = n % BN_BITS2;
762 	if (w >= a->top)
763 		return 0;
764 	if (b == 0)
765 		a->top = w;
766 	else {
767 		a->top = w + 1;
768 		a->d[w] &= ~(BN_MASK2 << b);
769 	}
770 	bn_correct_top(a);
771 	return (1);
772 }
773 
774 void
775 BN_set_negative(BIGNUM *a, int b)
776 {
777 	if (b && !BN_is_zero(a))
778 		a->neg = 1;
779 	else
780 		a->neg = 0;
781 }
782 
783 int
784 bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
785 {
786 	int i;
787 	BN_ULONG aa, bb;
788 
789 	aa = a[n - 1];
790 	bb = b[n - 1];
791 	if (aa != bb)
792 		return ((aa > bb) ? 1 : -1);
793 	for (i = n - 2; i >= 0; i--) {
794 		aa = a[i];
795 		bb = b[i];
796 		if (aa != bb)
797 			return ((aa > bb) ? 1 : -1);
798 	}
799 	return (0);
800 }
801 
802 /* Here follows a specialised variants of bn_cmp_words().  It has the
803    property of performing the operation on arrays of different sizes.
804    The sizes of those arrays is expressed through cl, which is the
805    common length ( basicall, min(len(a),len(b)) ), and dl, which is the
806    delta between the two lengths, calculated as len(a)-len(b).
807    All lengths are the number of BN_ULONGs...  */
808 
809 int
810 bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
811 {
812 	int n, i;
813 
814 	n = cl - 1;
815 
816 	if (dl < 0) {
817 		for (i = dl; i < 0; i++) {
818 			if (b[n - i] != 0)
819 				return -1; /* a < b */
820 		}
821 	}
822 	if (dl > 0) {
823 		for (i = dl; i > 0; i--) {
824 			if (a[n + i] != 0)
825 				return 1; /* a > b */
826 		}
827 	}
828 	return bn_cmp_words(a, b, cl);
829 }
830 
831 /*
832  * Constant-time conditional swap of a and b.
833  * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
834  * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
835  * and that no more than nwords are used by either a or b.
836  * a and b cannot be the same number
837  */
838 void
839 BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
840 {
841 	BN_ULONG t;
842 	int i;
843 
844 	bn_wcheck_size(a, nwords);
845 	bn_wcheck_size(b, nwords);
846 
847 	assert(a != b);
848 	assert((condition & (condition - 1)) == 0);
849 	assert(sizeof(BN_ULONG) >= sizeof(int));
850 
851 	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
852 
853 	t = (a->top^b->top) & condition;
854 	a->top ^= t;
855 	b->top ^= t;
856 
857 #define BN_CONSTTIME_SWAP(ind) \
858 	do { \
859 		t = (a->d[ind] ^ b->d[ind]) & condition; \
860 		a->d[ind] ^= t; \
861 		b->d[ind] ^= t; \
862 	} while (0)
863 
864 
865 	switch (nwords) {
866 	default:
867 		for (i = 10; i < nwords; i++)
868 			BN_CONSTTIME_SWAP(i);
869 		/* Fallthrough */
870 	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
871 	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
872 	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
873 	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
874 	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
875 	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
876 	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
877 	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
878 	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
879 	case 1:
880 		BN_CONSTTIME_SWAP(0);
881 	}
882 #undef BN_CONSTTIME_SWAP
883 }
884