xref: /dragonfly/crypto/libressl/crypto/bn/bn_lib.c (revision de0e0e4d)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: bn_lib.c,v 1.54 2022/06/27 12:25:49 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59f5b1c8a1SJohn Marino #ifndef BN_DEBUG
60f5b1c8a1SJohn Marino # undef NDEBUG /* avoid conflicting definitions */
61f5b1c8a1SJohn Marino # define NDEBUG
62f5b1c8a1SJohn Marino #endif
63f5b1c8a1SJohn Marino 
64f5b1c8a1SJohn Marino #include <assert.h>
65f5b1c8a1SJohn Marino #include <limits.h>
66f5b1c8a1SJohn Marino #include <stdio.h>
67f5b1c8a1SJohn Marino #include <string.h>
68f5b1c8a1SJohn Marino 
69f5b1c8a1SJohn Marino #include <openssl/opensslconf.h>
70f5b1c8a1SJohn Marino 
71f5b1c8a1SJohn Marino #include <openssl/err.h>
72f5b1c8a1SJohn Marino 
73f5b1c8a1SJohn Marino #include "bn_lcl.h"
74f5b1c8a1SJohn Marino 
75f5b1c8a1SJohn Marino /* This stuff appears to be completely unused, so is deprecated */
76f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DEPRECATED
77f5b1c8a1SJohn Marino /* For a 32 bit machine
78f5b1c8a1SJohn Marino  * 2 -   4 ==  128
79f5b1c8a1SJohn Marino  * 3 -   8 ==  256
80f5b1c8a1SJohn Marino  * 4 -  16 ==  512
81f5b1c8a1SJohn Marino  * 5 -  32 == 1024
82f5b1c8a1SJohn Marino  * 6 -  64 == 2048
83f5b1c8a1SJohn Marino  * 7 - 128 == 4096
84f5b1c8a1SJohn Marino  * 8 - 256 == 8192
85f5b1c8a1SJohn Marino  */
86f5b1c8a1SJohn Marino static int bn_limit_bits = 0;
87f5b1c8a1SJohn Marino static int bn_limit_num = 8;        /* (1<<bn_limit_bits) */
88f5b1c8a1SJohn Marino static int bn_limit_bits_low = 0;
89f5b1c8a1SJohn Marino static int bn_limit_num_low = 8;    /* (1<<bn_limit_bits_low) */
90f5b1c8a1SJohn Marino static int bn_limit_bits_high = 0;
91f5b1c8a1SJohn Marino static int bn_limit_num_high = 8;   /* (1<<bn_limit_bits_high) */
92f5b1c8a1SJohn Marino static int bn_limit_bits_mont = 0;
93f5b1c8a1SJohn Marino static int bn_limit_num_mont = 8;   /* (1<<bn_limit_bits_mont) */
94f5b1c8a1SJohn Marino 
95*de0e0e4dSAntonio Huete Jimenez BIGNUM *
BN_new(void)96*de0e0e4dSAntonio Huete Jimenez BN_new(void)
97*de0e0e4dSAntonio Huete Jimenez {
98*de0e0e4dSAntonio Huete Jimenez 	BIGNUM *ret;
99*de0e0e4dSAntonio Huete Jimenez 
100*de0e0e4dSAntonio Huete Jimenez 	if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
101*de0e0e4dSAntonio Huete Jimenez 		BNerror(ERR_R_MALLOC_FAILURE);
102*de0e0e4dSAntonio Huete Jimenez 		return (NULL);
103*de0e0e4dSAntonio Huete Jimenez 	}
104*de0e0e4dSAntonio Huete Jimenez 	ret->flags = BN_FLG_MALLOCED;
105*de0e0e4dSAntonio Huete Jimenez 	ret->top = 0;
106*de0e0e4dSAntonio Huete Jimenez 	ret->neg = 0;
107*de0e0e4dSAntonio Huete Jimenez 	ret->dmax = 0;
108*de0e0e4dSAntonio Huete Jimenez 	ret->d = NULL;
109*de0e0e4dSAntonio Huete Jimenez 	bn_check_top(ret);
110*de0e0e4dSAntonio Huete Jimenez 	return (ret);
111*de0e0e4dSAntonio Huete Jimenez }
112*de0e0e4dSAntonio Huete Jimenez 
113*de0e0e4dSAntonio Huete Jimenez void
BN_init(BIGNUM * a)114*de0e0e4dSAntonio Huete Jimenez BN_init(BIGNUM *a)
115*de0e0e4dSAntonio Huete Jimenez {
116*de0e0e4dSAntonio Huete Jimenez 	memset(a, 0, sizeof(BIGNUM));
117*de0e0e4dSAntonio Huete Jimenez 	bn_check_top(a);
118*de0e0e4dSAntonio Huete Jimenez }
119*de0e0e4dSAntonio Huete Jimenez 
120*de0e0e4dSAntonio Huete Jimenez void
BN_clear(BIGNUM * a)121*de0e0e4dSAntonio Huete Jimenez BN_clear(BIGNUM *a)
122*de0e0e4dSAntonio Huete Jimenez {
123*de0e0e4dSAntonio Huete Jimenez 	bn_check_top(a);
124*de0e0e4dSAntonio Huete Jimenez 	if (a->d != NULL)
125*de0e0e4dSAntonio Huete Jimenez 		explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
126*de0e0e4dSAntonio Huete Jimenez 	a->top = 0;
127*de0e0e4dSAntonio Huete Jimenez 	a->neg = 0;
128*de0e0e4dSAntonio Huete Jimenez }
129*de0e0e4dSAntonio Huete Jimenez 
130*de0e0e4dSAntonio Huete Jimenez void
BN_clear_free(BIGNUM * a)131*de0e0e4dSAntonio Huete Jimenez BN_clear_free(BIGNUM *a)
132*de0e0e4dSAntonio Huete Jimenez {
133*de0e0e4dSAntonio Huete Jimenez 	int i;
134*de0e0e4dSAntonio Huete Jimenez 
135*de0e0e4dSAntonio Huete Jimenez 	if (a == NULL)
136*de0e0e4dSAntonio Huete Jimenez 		return;
137*de0e0e4dSAntonio Huete Jimenez 	bn_check_top(a);
138*de0e0e4dSAntonio Huete Jimenez 	if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
139*de0e0e4dSAntonio Huete Jimenez 		freezero(a->d, a->dmax * sizeof(a->d[0]));
140*de0e0e4dSAntonio Huete Jimenez 	i = BN_get_flags(a, BN_FLG_MALLOCED);
141*de0e0e4dSAntonio Huete Jimenez 	explicit_bzero(a, sizeof(BIGNUM));
142*de0e0e4dSAntonio Huete Jimenez 	if (i)
143*de0e0e4dSAntonio Huete Jimenez 		free(a);
144*de0e0e4dSAntonio Huete Jimenez }
145*de0e0e4dSAntonio Huete Jimenez 
146*de0e0e4dSAntonio Huete Jimenez void
BN_free(BIGNUM * a)147*de0e0e4dSAntonio Huete Jimenez BN_free(BIGNUM *a)
148*de0e0e4dSAntonio Huete Jimenez {
149*de0e0e4dSAntonio Huete Jimenez 	BN_clear_free(a);
150*de0e0e4dSAntonio Huete Jimenez }
151*de0e0e4dSAntonio Huete Jimenez 
152f5b1c8a1SJohn Marino void
BN_set_params(int mult,int high,int low,int mont)153f5b1c8a1SJohn Marino BN_set_params(int mult, int high, int low, int mont)
154f5b1c8a1SJohn Marino {
155f5b1c8a1SJohn Marino 	if (mult >= 0) {
156f5b1c8a1SJohn Marino 		if (mult > (int)(sizeof(int) * 8) - 1)
157f5b1c8a1SJohn Marino 			mult = sizeof(int) * 8 - 1;
158f5b1c8a1SJohn Marino 		bn_limit_bits = mult;
159f5b1c8a1SJohn Marino 		bn_limit_num = 1 << mult;
160f5b1c8a1SJohn Marino 	}
161f5b1c8a1SJohn Marino 	if (high >= 0) {
162f5b1c8a1SJohn Marino 		if (high > (int)(sizeof(int) * 8) - 1)
163f5b1c8a1SJohn Marino 			high = sizeof(int) * 8 - 1;
164f5b1c8a1SJohn Marino 		bn_limit_bits_high = high;
165f5b1c8a1SJohn Marino 		bn_limit_num_high = 1 << high;
166f5b1c8a1SJohn Marino 	}
167f5b1c8a1SJohn Marino 	if (low >= 0) {
168f5b1c8a1SJohn Marino 		if (low > (int)(sizeof(int) * 8) - 1)
169f5b1c8a1SJohn Marino 			low = sizeof(int) * 8 - 1;
170f5b1c8a1SJohn Marino 		bn_limit_bits_low = low;
171f5b1c8a1SJohn Marino 		bn_limit_num_low = 1 << low;
172f5b1c8a1SJohn Marino 	}
173f5b1c8a1SJohn Marino 	if (mont >= 0) {
174f5b1c8a1SJohn Marino 		if (mont > (int)(sizeof(int) * 8) - 1)
175f5b1c8a1SJohn Marino 			mont = sizeof(int) * 8 - 1;
176f5b1c8a1SJohn Marino 		bn_limit_bits_mont = mont;
177f5b1c8a1SJohn Marino 		bn_limit_num_mont = 1 << mont;
178f5b1c8a1SJohn Marino 	}
179f5b1c8a1SJohn Marino }
180f5b1c8a1SJohn Marino 
181f5b1c8a1SJohn Marino int
BN_get_params(int which)182f5b1c8a1SJohn Marino BN_get_params(int which)
183f5b1c8a1SJohn Marino {
184f5b1c8a1SJohn Marino 	if (which == 0)
185f5b1c8a1SJohn Marino 		return (bn_limit_bits);
186f5b1c8a1SJohn Marino 	else if (which == 1)
187f5b1c8a1SJohn Marino 		return (bn_limit_bits_high);
188f5b1c8a1SJohn Marino 	else if (which == 2)
189f5b1c8a1SJohn Marino 		return (bn_limit_bits_low);
190f5b1c8a1SJohn Marino 	else if (which == 3)
191f5b1c8a1SJohn Marino 		return (bn_limit_bits_mont);
192f5b1c8a1SJohn Marino 	else
193f5b1c8a1SJohn Marino 		return (0);
194f5b1c8a1SJohn Marino }
195f5b1c8a1SJohn Marino #endif
196f5b1c8a1SJohn Marino 
197*de0e0e4dSAntonio Huete Jimenez void
BN_set_flags(BIGNUM * b,int n)198*de0e0e4dSAntonio Huete Jimenez BN_set_flags(BIGNUM *b, int n)
199*de0e0e4dSAntonio Huete Jimenez {
200*de0e0e4dSAntonio Huete Jimenez 	b->flags |= n;
201*de0e0e4dSAntonio Huete Jimenez }
202*de0e0e4dSAntonio Huete Jimenez 
203*de0e0e4dSAntonio Huete Jimenez int
BN_get_flags(const BIGNUM * b,int n)204*de0e0e4dSAntonio Huete Jimenez BN_get_flags(const BIGNUM *b, int n)
205*de0e0e4dSAntonio Huete Jimenez {
206*de0e0e4dSAntonio Huete Jimenez 	return b->flags & n;
207*de0e0e4dSAntonio Huete Jimenez }
208*de0e0e4dSAntonio Huete Jimenez 
209*de0e0e4dSAntonio Huete Jimenez void
BN_with_flags(BIGNUM * dest,const BIGNUM * b,int flags)210*de0e0e4dSAntonio Huete Jimenez BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
211*de0e0e4dSAntonio Huete Jimenez {
212*de0e0e4dSAntonio Huete Jimenez 	int dest_flags;
213*de0e0e4dSAntonio Huete Jimenez 
214*de0e0e4dSAntonio Huete Jimenez 	dest_flags = (dest->flags & BN_FLG_MALLOCED) |
215*de0e0e4dSAntonio Huete Jimenez 	    (b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags;
216*de0e0e4dSAntonio Huete Jimenez 
217*de0e0e4dSAntonio Huete Jimenez 	*dest = *b;
218*de0e0e4dSAntonio Huete Jimenez 	dest->flags = dest_flags;
219*de0e0e4dSAntonio Huete Jimenez }
220*de0e0e4dSAntonio Huete Jimenez 
221f5b1c8a1SJohn Marino const BIGNUM *
BN_value_one(void)222f5b1c8a1SJohn Marino BN_value_one(void)
223f5b1c8a1SJohn Marino {
224f5b1c8a1SJohn Marino 	static const BN_ULONG data_one = 1L;
225f5b1c8a1SJohn Marino 	static const BIGNUM const_one = {
226f5b1c8a1SJohn Marino 		(BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
227f5b1c8a1SJohn Marino 	};
228f5b1c8a1SJohn Marino 
229f5b1c8a1SJohn Marino 	return (&const_one);
230f5b1c8a1SJohn Marino }
231f5b1c8a1SJohn Marino 
232f5b1c8a1SJohn Marino int
BN_num_bits_word(BN_ULONG l)233f5b1c8a1SJohn Marino BN_num_bits_word(BN_ULONG l)
234f5b1c8a1SJohn Marino {
235cca6fc52SDaniel Fojt 	BN_ULONG x, mask;
236cca6fc52SDaniel Fojt 	int bits;
237cca6fc52SDaniel Fojt 	unsigned int shift;
238f5b1c8a1SJohn Marino 
239cca6fc52SDaniel Fojt 	/* Constant time calculation of floor(log2(l)) + 1. */
240cca6fc52SDaniel Fojt 	bits = (l != 0);
241cca6fc52SDaniel Fojt 	shift = BN_BITS4;	/* On _LP64 this is 32, otherwise 16. */
242cca6fc52SDaniel Fojt 	do {
243cca6fc52SDaniel Fojt 		x = l >> shift;
244cca6fc52SDaniel Fojt 		/* If x is 0, set mask to 0, otherwise set it to all 1s. */
245cca6fc52SDaniel Fojt 		mask = ((~x & (x - 1)) >> (BN_BITS2 - 1)) - 1;
246cca6fc52SDaniel Fojt 		bits += shift & mask;
247cca6fc52SDaniel Fojt 		/* If x is 0, leave l alone, otherwise set l = x. */
248cca6fc52SDaniel Fojt 		l ^= (x ^ l) & mask;
249cca6fc52SDaniel Fojt 	} while ((shift /= 2) != 0);
250cca6fc52SDaniel Fojt 
251cca6fc52SDaniel Fojt 	return bits;
252f5b1c8a1SJohn Marino }
253f5b1c8a1SJohn Marino 
254f5b1c8a1SJohn Marino int
BN_num_bits(const BIGNUM * a)255f5b1c8a1SJohn Marino BN_num_bits(const BIGNUM *a)
256f5b1c8a1SJohn Marino {
257f5b1c8a1SJohn Marino 	int i = a->top - 1;
258f5b1c8a1SJohn Marino 
259f5b1c8a1SJohn Marino 	bn_check_top(a);
260f5b1c8a1SJohn Marino 
261f5b1c8a1SJohn Marino 	if (BN_is_zero(a))
262f5b1c8a1SJohn Marino 		return 0;
263f5b1c8a1SJohn Marino 	return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
264f5b1c8a1SJohn Marino }
265f5b1c8a1SJohn Marino 
266f5b1c8a1SJohn Marino /* This is used both by bn_expand2() and bn_dup_expand() */
267f5b1c8a1SJohn Marino /* The caller MUST check that words > b->dmax before calling this */
268f5b1c8a1SJohn Marino static BN_ULONG *
bn_expand_internal(const BIGNUM * b,int words)269f5b1c8a1SJohn Marino bn_expand_internal(const BIGNUM *b, int words)
270f5b1c8a1SJohn Marino {
271f5b1c8a1SJohn Marino 	BN_ULONG *A, *a = NULL;
272f5b1c8a1SJohn Marino 	const BN_ULONG *B;
273f5b1c8a1SJohn Marino 	int i;
274f5b1c8a1SJohn Marino 
275f5b1c8a1SJohn Marino 	bn_check_top(b);
276f5b1c8a1SJohn Marino 
277f5b1c8a1SJohn Marino 	if (words > (INT_MAX/(4*BN_BITS2))) {
27872c33676SMaxim Ag 		BNerror(BN_R_BIGNUM_TOO_LONG);
279f5b1c8a1SJohn Marino 		return NULL;
280f5b1c8a1SJohn Marino 	}
281f5b1c8a1SJohn Marino 	if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
28272c33676SMaxim Ag 		BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
283f5b1c8a1SJohn Marino 		return (NULL);
284f5b1c8a1SJohn Marino 	}
285f5b1c8a1SJohn Marino 	a = A = reallocarray(NULL, words, sizeof(BN_ULONG));
286f5b1c8a1SJohn Marino 	if (A == NULL) {
28772c33676SMaxim Ag 		BNerror(ERR_R_MALLOC_FAILURE);
288f5b1c8a1SJohn Marino 		return (NULL);
289f5b1c8a1SJohn Marino 	}
290f5b1c8a1SJohn Marino #if 1
291f5b1c8a1SJohn Marino 	B = b->d;
292f5b1c8a1SJohn Marino 	/* Check if the previous number needs to be copied */
293f5b1c8a1SJohn Marino 	if (B != NULL) {
294f5b1c8a1SJohn Marino 		for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
295f5b1c8a1SJohn Marino 			/*
296f5b1c8a1SJohn Marino 			 * The fact that the loop is unrolled
297f5b1c8a1SJohn Marino 			 * 4-wise is a tribute to Intel. It's
298f5b1c8a1SJohn Marino 			 * the one that doesn't have enough
299f5b1c8a1SJohn Marino 			 * registers to accommodate more data.
300f5b1c8a1SJohn Marino 			 * I'd unroll it 8-wise otherwise:-)
301f5b1c8a1SJohn Marino 			 *
302f5b1c8a1SJohn Marino 			 *		<appro@fy.chalmers.se>
303f5b1c8a1SJohn Marino 			 */
304f5b1c8a1SJohn Marino 			BN_ULONG a0, a1, a2, a3;
305f5b1c8a1SJohn Marino 			a0 = B[0];
306f5b1c8a1SJohn Marino 			a1 = B[1];
307f5b1c8a1SJohn Marino 			a2 = B[2];
308f5b1c8a1SJohn Marino 			a3 = B[3];
309f5b1c8a1SJohn Marino 			A[0] = a0;
310f5b1c8a1SJohn Marino 			A[1] = a1;
311f5b1c8a1SJohn Marino 			A[2] = a2;
312f5b1c8a1SJohn Marino 			A[3] = a3;
313f5b1c8a1SJohn Marino 		}
314f5b1c8a1SJohn Marino 		switch (b->top & 3) {
315f5b1c8a1SJohn Marino 		case 3:
316f5b1c8a1SJohn Marino 			A[2] = B[2];
317f5b1c8a1SJohn Marino 		case 2:
318f5b1c8a1SJohn Marino 			A[1] = B[1];
319f5b1c8a1SJohn Marino 		case 1:
320f5b1c8a1SJohn Marino 			A[0] = B[0];
321f5b1c8a1SJohn Marino 		}
322f5b1c8a1SJohn Marino 	}
323f5b1c8a1SJohn Marino 
324f5b1c8a1SJohn Marino #else
325f5b1c8a1SJohn Marino 	memset(A, 0, sizeof(BN_ULONG) * words);
326f5b1c8a1SJohn Marino 	memcpy(A, b->d, sizeof(b->d[0]) * b->top);
327f5b1c8a1SJohn Marino #endif
328f5b1c8a1SJohn Marino 
329f5b1c8a1SJohn Marino 	return (a);
330f5b1c8a1SJohn Marino }
331f5b1c8a1SJohn Marino 
332f5b1c8a1SJohn Marino /* This is an internal function that can be used instead of bn_expand2()
333f5b1c8a1SJohn Marino  * when there is a need to copy BIGNUMs instead of only expanding the
334f5b1c8a1SJohn Marino  * data part, while still expanding them.
335f5b1c8a1SJohn Marino  * Especially useful when needing to expand BIGNUMs that are declared
336f5b1c8a1SJohn Marino  * 'const' and should therefore not be changed.
337f5b1c8a1SJohn Marino  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
338f5b1c8a1SJohn Marino  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
339f5b1c8a1SJohn Marino  * will allocate new memory for the BIGNUM data twice, and free it once,
340f5b1c8a1SJohn Marino  * while bn_dup_expand() makes sure allocation is made only once.
341f5b1c8a1SJohn Marino  */
342f5b1c8a1SJohn Marino 
343f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DEPRECATED
344f5b1c8a1SJohn Marino BIGNUM *
bn_dup_expand(const BIGNUM * b,int words)345f5b1c8a1SJohn Marino bn_dup_expand(const BIGNUM *b, int words)
346f5b1c8a1SJohn Marino {
347f5b1c8a1SJohn Marino 	BIGNUM *r = NULL;
348f5b1c8a1SJohn Marino 
349f5b1c8a1SJohn Marino 	bn_check_top(b);
350f5b1c8a1SJohn Marino 
351f5b1c8a1SJohn Marino 	/* This function does not work if
352f5b1c8a1SJohn Marino 	 *      words <= b->dmax && top < words
353f5b1c8a1SJohn Marino 	 * because BN_dup() does not preserve 'dmax'!
354f5b1c8a1SJohn Marino 	 * (But bn_dup_expand() is not used anywhere yet.)
355f5b1c8a1SJohn Marino 	 */
356f5b1c8a1SJohn Marino 
357f5b1c8a1SJohn Marino 	if (words > b->dmax) {
358f5b1c8a1SJohn Marino 		BN_ULONG *a = bn_expand_internal(b, words);
359f5b1c8a1SJohn Marino 
360f5b1c8a1SJohn Marino 		if (a) {
361f5b1c8a1SJohn Marino 			r = BN_new();
362f5b1c8a1SJohn Marino 			if (r) {
363f5b1c8a1SJohn Marino 				r->top = b->top;
364f5b1c8a1SJohn Marino 				r->dmax = words;
365f5b1c8a1SJohn Marino 				r->neg = b->neg;
366f5b1c8a1SJohn Marino 				r->d = a;
367f5b1c8a1SJohn Marino 			} else {
368f5b1c8a1SJohn Marino 				/* r == NULL, BN_new failure */
369f5b1c8a1SJohn Marino 				free(a);
370f5b1c8a1SJohn Marino 			}
371f5b1c8a1SJohn Marino 		}
372f5b1c8a1SJohn Marino 		/* If a == NULL, there was an error in allocation in
373f5b1c8a1SJohn Marino 		   bn_expand_internal(), and NULL should be returned */
374f5b1c8a1SJohn Marino 	} else {
375f5b1c8a1SJohn Marino 		r = BN_dup(b);
376f5b1c8a1SJohn Marino 	}
377f5b1c8a1SJohn Marino 
378f5b1c8a1SJohn Marino 	bn_check_top(r);
379f5b1c8a1SJohn Marino 	return r;
380f5b1c8a1SJohn Marino }
381f5b1c8a1SJohn Marino #endif
382f5b1c8a1SJohn Marino 
383f5b1c8a1SJohn Marino /* This is an internal function that should not be used in applications.
384f5b1c8a1SJohn Marino  * It ensures that 'b' has enough room for a 'words' word number
385f5b1c8a1SJohn Marino  * and initialises any unused part of b->d with leading zeros.
386f5b1c8a1SJohn Marino  * It is mostly used by the various BIGNUM routines. If there is an error,
387f5b1c8a1SJohn Marino  * NULL is returned. If not, 'b' is returned. */
388f5b1c8a1SJohn Marino 
389f5b1c8a1SJohn Marino BIGNUM *
bn_expand2(BIGNUM * b,int words)390f5b1c8a1SJohn Marino bn_expand2(BIGNUM *b, int words)
391f5b1c8a1SJohn Marino {
392f5b1c8a1SJohn Marino 	bn_check_top(b);
393f5b1c8a1SJohn Marino 
394f5b1c8a1SJohn Marino 	if (words > b->dmax) {
395f5b1c8a1SJohn Marino 		BN_ULONG *a = bn_expand_internal(b, words);
396f5b1c8a1SJohn Marino 		if (!a)
397f5b1c8a1SJohn Marino 			return NULL;
39872c33676SMaxim Ag 		if (b->d)
39972c33676SMaxim Ag 			freezero(b->d, b->dmax * sizeof(b->d[0]));
400f5b1c8a1SJohn Marino 		b->d = a;
401f5b1c8a1SJohn Marino 		b->dmax = words;
402f5b1c8a1SJohn Marino 	}
403f5b1c8a1SJohn Marino 
404f5b1c8a1SJohn Marino /* None of this should be necessary because of what b->top means! */
405f5b1c8a1SJohn Marino #if 0
406f5b1c8a1SJohn Marino 	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
407f5b1c8a1SJohn Marino 	if (b->top < b->dmax) {
408f5b1c8a1SJohn Marino 		int i;
409f5b1c8a1SJohn Marino 		BN_ULONG *A = &(b->d[b->top]);
410f5b1c8a1SJohn Marino 		for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
411f5b1c8a1SJohn Marino 			A[0] = 0;
412f5b1c8a1SJohn Marino 			A[1] = 0;
413f5b1c8a1SJohn Marino 			A[2] = 0;
414f5b1c8a1SJohn Marino 			A[3] = 0;
415f5b1c8a1SJohn Marino 			A[4] = 0;
416f5b1c8a1SJohn Marino 			A[5] = 0;
417f5b1c8a1SJohn Marino 			A[6] = 0;
418f5b1c8a1SJohn Marino 			A[7] = 0;
419f5b1c8a1SJohn Marino 		}
420f5b1c8a1SJohn Marino 		for (i = (b->dmax - b->top)&7; i > 0; i--, A++)
421f5b1c8a1SJohn Marino 			A[0] = 0;
422f5b1c8a1SJohn Marino 		assert(A == &(b->d[b->dmax]));
423f5b1c8a1SJohn Marino 	}
424f5b1c8a1SJohn Marino #endif
425f5b1c8a1SJohn Marino 	bn_check_top(b);
426f5b1c8a1SJohn Marino 	return b;
427f5b1c8a1SJohn Marino }
428f5b1c8a1SJohn Marino 
429f5b1c8a1SJohn Marino BIGNUM *
BN_dup(const BIGNUM * a)430f5b1c8a1SJohn Marino BN_dup(const BIGNUM *a)
431f5b1c8a1SJohn Marino {
432f5b1c8a1SJohn Marino 	BIGNUM *t;
433f5b1c8a1SJohn Marino 
434f5b1c8a1SJohn Marino 	if (a == NULL)
435f5b1c8a1SJohn Marino 		return NULL;
436f5b1c8a1SJohn Marino 	bn_check_top(a);
437f5b1c8a1SJohn Marino 
438f5b1c8a1SJohn Marino 	t = BN_new();
439f5b1c8a1SJohn Marino 	if (t == NULL)
440f5b1c8a1SJohn Marino 		return NULL;
441f5b1c8a1SJohn Marino 	if (!BN_copy(t, a)) {
442f5b1c8a1SJohn Marino 		BN_free(t);
443f5b1c8a1SJohn Marino 		return NULL;
444f5b1c8a1SJohn Marino 	}
445f5b1c8a1SJohn Marino 	bn_check_top(t);
446f5b1c8a1SJohn Marino 	return t;
447f5b1c8a1SJohn Marino }
448f5b1c8a1SJohn Marino 
449f5b1c8a1SJohn Marino BIGNUM *
BN_copy(BIGNUM * a,const BIGNUM * b)450f5b1c8a1SJohn Marino BN_copy(BIGNUM *a, const BIGNUM *b)
451f5b1c8a1SJohn Marino {
452f5b1c8a1SJohn Marino 	int i;
453f5b1c8a1SJohn Marino 	BN_ULONG *A;
454f5b1c8a1SJohn Marino 	const BN_ULONG *B;
455f5b1c8a1SJohn Marino 
456f5b1c8a1SJohn Marino 	bn_check_top(b);
457f5b1c8a1SJohn Marino 
458f5b1c8a1SJohn Marino 	if (a == b)
459f5b1c8a1SJohn Marino 		return (a);
460f5b1c8a1SJohn Marino 	if (bn_wexpand(a, b->top) == NULL)
461f5b1c8a1SJohn Marino 		return (NULL);
462f5b1c8a1SJohn Marino 
463f5b1c8a1SJohn Marino #if 1
464f5b1c8a1SJohn Marino 	A = a->d;
465f5b1c8a1SJohn Marino 	B = b->d;
466f5b1c8a1SJohn Marino 	for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
467f5b1c8a1SJohn Marino 		BN_ULONG a0, a1, a2, a3;
468f5b1c8a1SJohn Marino 		a0 = B[0];
469f5b1c8a1SJohn Marino 		a1 = B[1];
470f5b1c8a1SJohn Marino 		a2 = B[2];
471f5b1c8a1SJohn Marino 		a3 = B[3];
472f5b1c8a1SJohn Marino 		A[0] = a0;
473f5b1c8a1SJohn Marino 		A[1] = a1;
474f5b1c8a1SJohn Marino 		A[2] = a2;
475f5b1c8a1SJohn Marino 		A[3] = a3;
476f5b1c8a1SJohn Marino 	}
477f5b1c8a1SJohn Marino 	switch (b->top & 3) {
478f5b1c8a1SJohn Marino 	case 3:
479f5b1c8a1SJohn Marino 		A[2] = B[2];
480f5b1c8a1SJohn Marino 	case 2:
481f5b1c8a1SJohn Marino 		A[1] = B[1];
482f5b1c8a1SJohn Marino 	case 1:
483f5b1c8a1SJohn Marino 		A[0] = B[0];
484f5b1c8a1SJohn Marino 	}
485f5b1c8a1SJohn Marino #else
486f5b1c8a1SJohn Marino 	memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
487f5b1c8a1SJohn Marino #endif
488f5b1c8a1SJohn Marino 
489f5b1c8a1SJohn Marino 	a->top = b->top;
490f5b1c8a1SJohn Marino 	a->neg = b->neg;
491f5b1c8a1SJohn Marino 	bn_check_top(a);
492f5b1c8a1SJohn Marino 	return (a);
493f5b1c8a1SJohn Marino }
494f5b1c8a1SJohn Marino 
495f5b1c8a1SJohn Marino void
BN_swap(BIGNUM * a,BIGNUM * b)496f5b1c8a1SJohn Marino BN_swap(BIGNUM *a, BIGNUM *b)
497f5b1c8a1SJohn Marino {
498f5b1c8a1SJohn Marino 	int flags_old_a, flags_old_b;
499f5b1c8a1SJohn Marino 	BN_ULONG *tmp_d;
500f5b1c8a1SJohn Marino 	int tmp_top, tmp_dmax, tmp_neg;
501f5b1c8a1SJohn Marino 
502f5b1c8a1SJohn Marino 	bn_check_top(a);
503f5b1c8a1SJohn Marino 	bn_check_top(b);
504f5b1c8a1SJohn Marino 
505f5b1c8a1SJohn Marino 	flags_old_a = a->flags;
506f5b1c8a1SJohn Marino 	flags_old_b = b->flags;
507f5b1c8a1SJohn Marino 
508f5b1c8a1SJohn Marino 	tmp_d = a->d;
509f5b1c8a1SJohn Marino 	tmp_top = a->top;
510f5b1c8a1SJohn Marino 	tmp_dmax = a->dmax;
511f5b1c8a1SJohn Marino 	tmp_neg = a->neg;
512f5b1c8a1SJohn Marino 
513f5b1c8a1SJohn Marino 	a->d = b->d;
514f5b1c8a1SJohn Marino 	a->top = b->top;
515f5b1c8a1SJohn Marino 	a->dmax = b->dmax;
516f5b1c8a1SJohn Marino 	a->neg = b->neg;
517f5b1c8a1SJohn Marino 
518f5b1c8a1SJohn Marino 	b->d = tmp_d;
519f5b1c8a1SJohn Marino 	b->top = tmp_top;
520f5b1c8a1SJohn Marino 	b->dmax = tmp_dmax;
521f5b1c8a1SJohn Marino 	b->neg = tmp_neg;
522f5b1c8a1SJohn Marino 
523f5b1c8a1SJohn Marino 	a->flags = (flags_old_a & BN_FLG_MALLOCED) |
524f5b1c8a1SJohn Marino 	    (flags_old_b & BN_FLG_STATIC_DATA);
525f5b1c8a1SJohn Marino 	b->flags = (flags_old_b & BN_FLG_MALLOCED) |
526f5b1c8a1SJohn Marino 	    (flags_old_a & BN_FLG_STATIC_DATA);
527f5b1c8a1SJohn Marino 	bn_check_top(a);
528f5b1c8a1SJohn Marino 	bn_check_top(b);
529f5b1c8a1SJohn Marino }
530f5b1c8a1SJohn Marino 
531f5b1c8a1SJohn Marino BN_ULONG
BN_get_word(const BIGNUM * a)532f5b1c8a1SJohn Marino BN_get_word(const BIGNUM *a)
533f5b1c8a1SJohn Marino {
534f5b1c8a1SJohn Marino 	if (a->top > 1)
535f5b1c8a1SJohn Marino 		return BN_MASK2;
536f5b1c8a1SJohn Marino 	else if (a->top == 1)
537f5b1c8a1SJohn Marino 		return a->d[0];
538f5b1c8a1SJohn Marino 	/* a->top == 0 */
539f5b1c8a1SJohn Marino 	return 0;
540f5b1c8a1SJohn Marino }
541f5b1c8a1SJohn Marino 
542f5b1c8a1SJohn Marino BIGNUM *
bn_expand(BIGNUM * a,int bits)543f5b1c8a1SJohn Marino bn_expand(BIGNUM *a, int bits)
544f5b1c8a1SJohn Marino {
545f5b1c8a1SJohn Marino 	if (bits > (INT_MAX - BN_BITS2 + 1))
546f5b1c8a1SJohn Marino 		return (NULL);
547f5b1c8a1SJohn Marino 
548f5b1c8a1SJohn Marino 	if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax)
549f5b1c8a1SJohn Marino 		return (a);
550f5b1c8a1SJohn Marino 
551f5b1c8a1SJohn Marino 	return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2);
552f5b1c8a1SJohn Marino }
553f5b1c8a1SJohn Marino 
554f5b1c8a1SJohn Marino int
BN_set_word(BIGNUM * a,BN_ULONG w)555f5b1c8a1SJohn Marino BN_set_word(BIGNUM *a, BN_ULONG w)
556f5b1c8a1SJohn Marino {
557f5b1c8a1SJohn Marino 	bn_check_top(a);
558f5b1c8a1SJohn Marino 	if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
559f5b1c8a1SJohn Marino 		return (0);
560f5b1c8a1SJohn Marino 	a->neg = 0;
561f5b1c8a1SJohn Marino 	a->d[0] = w;
562f5b1c8a1SJohn Marino 	a->top = (w ? 1 : 0);
563f5b1c8a1SJohn Marino 	bn_check_top(a);
564f5b1c8a1SJohn Marino 	return (1);
565f5b1c8a1SJohn Marino }
566f5b1c8a1SJohn Marino 
567f5b1c8a1SJohn Marino BIGNUM *
BN_bin2bn(const unsigned char * s,int len,BIGNUM * ret)568f5b1c8a1SJohn Marino BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
569f5b1c8a1SJohn Marino {
570f5b1c8a1SJohn Marino 	unsigned int i, m;
571f5b1c8a1SJohn Marino 	unsigned int n;
572f5b1c8a1SJohn Marino 	BN_ULONG l;
573f5b1c8a1SJohn Marino 	BIGNUM *bn = NULL;
574f5b1c8a1SJohn Marino 
57572c33676SMaxim Ag 	if (len < 0)
57672c33676SMaxim Ag 		return (NULL);
577f5b1c8a1SJohn Marino 	if (ret == NULL)
578f5b1c8a1SJohn Marino 		ret = bn = BN_new();
579f5b1c8a1SJohn Marino 	if (ret == NULL)
580f5b1c8a1SJohn Marino 		return (NULL);
581f5b1c8a1SJohn Marino 	bn_check_top(ret);
582f5b1c8a1SJohn Marino 	l = 0;
583f5b1c8a1SJohn Marino 	n = len;
584f5b1c8a1SJohn Marino 	if (n == 0) {
585f5b1c8a1SJohn Marino 		ret->top = 0;
586f5b1c8a1SJohn Marino 		return (ret);
587f5b1c8a1SJohn Marino 	}
588f5b1c8a1SJohn Marino 	i = ((n - 1) / BN_BYTES) + 1;
589f5b1c8a1SJohn Marino 	m = ((n - 1) % (BN_BYTES));
590f5b1c8a1SJohn Marino 	if (bn_wexpand(ret, (int)i) == NULL) {
591f5b1c8a1SJohn Marino 		BN_free(bn);
592f5b1c8a1SJohn Marino 		return NULL;
593f5b1c8a1SJohn Marino 	}
594f5b1c8a1SJohn Marino 	ret->top = i;
595f5b1c8a1SJohn Marino 	ret->neg = 0;
596f5b1c8a1SJohn Marino 	while (n--) {
597f5b1c8a1SJohn Marino 		l = (l << 8L) | *(s++);
598f5b1c8a1SJohn Marino 		if (m-- == 0) {
599f5b1c8a1SJohn Marino 			ret->d[--i] = l;
600f5b1c8a1SJohn Marino 			l = 0;
601f5b1c8a1SJohn Marino 			m = BN_BYTES - 1;
602f5b1c8a1SJohn Marino 		}
603f5b1c8a1SJohn Marino 	}
604f5b1c8a1SJohn Marino 	/* need to call this due to clear byte at top if avoiding
605f5b1c8a1SJohn Marino 	 * having the top bit set (-ve number) */
606f5b1c8a1SJohn Marino 	bn_correct_top(ret);
607f5b1c8a1SJohn Marino 	return (ret);
608f5b1c8a1SJohn Marino }
609f5b1c8a1SJohn Marino 
610*de0e0e4dSAntonio Huete Jimenez typedef enum {
611*de0e0e4dSAntonio Huete Jimenez 	big,
612*de0e0e4dSAntonio Huete Jimenez 	little,
613*de0e0e4dSAntonio Huete Jimenez } endianness_t;
614*de0e0e4dSAntonio Huete Jimenez 
615f5b1c8a1SJohn Marino /* ignore negative */
616*de0e0e4dSAntonio Huete Jimenez static int
bn2binpad(const BIGNUM * a,unsigned char * to,int tolen,endianness_t endianness)617*de0e0e4dSAntonio Huete Jimenez bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
618*de0e0e4dSAntonio Huete Jimenez {
619*de0e0e4dSAntonio Huete Jimenez 	int n;
620*de0e0e4dSAntonio Huete Jimenez 	size_t i, lasti, j, atop, mask;
621*de0e0e4dSAntonio Huete Jimenez 	BN_ULONG l;
622*de0e0e4dSAntonio Huete Jimenez 
623*de0e0e4dSAntonio Huete Jimenez 	/*
624*de0e0e4dSAntonio Huete Jimenez 	 * In case |a| is fixed-top, BN_num_bytes can return bogus length,
625*de0e0e4dSAntonio Huete Jimenez 	 * but it's assumed that fixed-top inputs ought to be "nominated"
626*de0e0e4dSAntonio Huete Jimenez 	 * even for padded output, so it works out...
627*de0e0e4dSAntonio Huete Jimenez 	 */
628*de0e0e4dSAntonio Huete Jimenez 	n = BN_num_bytes(a);
629*de0e0e4dSAntonio Huete Jimenez 	if (tolen == -1)
630*de0e0e4dSAntonio Huete Jimenez 		tolen = n;
631*de0e0e4dSAntonio Huete Jimenez 	else if (tolen < n) {	/* uncommon/unlike case */
632*de0e0e4dSAntonio Huete Jimenez 		BIGNUM temp = *a;
633*de0e0e4dSAntonio Huete Jimenez 
634*de0e0e4dSAntonio Huete Jimenez 		bn_correct_top(&temp);
635*de0e0e4dSAntonio Huete Jimenez 
636*de0e0e4dSAntonio Huete Jimenez 		n = BN_num_bytes(&temp);
637*de0e0e4dSAntonio Huete Jimenez 		if (tolen < n)
638*de0e0e4dSAntonio Huete Jimenez 			return -1;
639*de0e0e4dSAntonio Huete Jimenez 	}
640*de0e0e4dSAntonio Huete Jimenez 
641*de0e0e4dSAntonio Huete Jimenez 	/* Swipe through whole available data and don't give away padded zero. */
642*de0e0e4dSAntonio Huete Jimenez 	atop = a->dmax * BN_BYTES;
643*de0e0e4dSAntonio Huete Jimenez 	if (atop == 0) {
644*de0e0e4dSAntonio Huete Jimenez 		explicit_bzero(to, tolen);
645*de0e0e4dSAntonio Huete Jimenez 		return tolen;
646*de0e0e4dSAntonio Huete Jimenez 	}
647*de0e0e4dSAntonio Huete Jimenez 
648*de0e0e4dSAntonio Huete Jimenez 	lasti = atop - 1;
649*de0e0e4dSAntonio Huete Jimenez 	atop = a->top * BN_BYTES;
650*de0e0e4dSAntonio Huete Jimenez 
651*de0e0e4dSAntonio Huete Jimenez 	if (endianness == big)
652*de0e0e4dSAntonio Huete Jimenez 		to += tolen; /* start from the end of the buffer */
653*de0e0e4dSAntonio Huete Jimenez 
654*de0e0e4dSAntonio Huete Jimenez 	for (i = 0, j = 0; j < (size_t)tolen; j++) {
655*de0e0e4dSAntonio Huete Jimenez 		unsigned char val;
656*de0e0e4dSAntonio Huete Jimenez 
657*de0e0e4dSAntonio Huete Jimenez 		l = a->d[i / BN_BYTES];
658*de0e0e4dSAntonio Huete Jimenez 		mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
659*de0e0e4dSAntonio Huete Jimenez 		val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
660*de0e0e4dSAntonio Huete Jimenez 
661*de0e0e4dSAntonio Huete Jimenez 		if (endianness == big)
662*de0e0e4dSAntonio Huete Jimenez 			*--to = val;
663*de0e0e4dSAntonio Huete Jimenez 		else
664*de0e0e4dSAntonio Huete Jimenez 			*to++ = val;
665*de0e0e4dSAntonio Huete Jimenez 
666*de0e0e4dSAntonio Huete Jimenez 		i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
667*de0e0e4dSAntonio Huete Jimenez 	}
668*de0e0e4dSAntonio Huete Jimenez 
669*de0e0e4dSAntonio Huete Jimenez 	return tolen;
670*de0e0e4dSAntonio Huete Jimenez }
671*de0e0e4dSAntonio Huete Jimenez 
672*de0e0e4dSAntonio Huete Jimenez int
BN_bn2binpad(const BIGNUM * a,unsigned char * to,int tolen)673*de0e0e4dSAntonio Huete Jimenez BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
674*de0e0e4dSAntonio Huete Jimenez {
675*de0e0e4dSAntonio Huete Jimenez 	if (tolen < 0)
676*de0e0e4dSAntonio Huete Jimenez 		return -1;
677*de0e0e4dSAntonio Huete Jimenez 	return bn2binpad(a, to, tolen, big);
678*de0e0e4dSAntonio Huete Jimenez }
679*de0e0e4dSAntonio Huete Jimenez 
680f5b1c8a1SJohn Marino int
BN_bn2bin(const BIGNUM * a,unsigned char * to)681f5b1c8a1SJohn Marino BN_bn2bin(const BIGNUM *a, unsigned char *to)
682f5b1c8a1SJohn Marino {
683*de0e0e4dSAntonio Huete Jimenez 	return bn2binpad(a, to, -1, big);
684f5b1c8a1SJohn Marino }
685*de0e0e4dSAntonio Huete Jimenez 
686*de0e0e4dSAntonio Huete Jimenez BIGNUM *
BN_lebin2bn(const unsigned char * s,int len,BIGNUM * ret)687*de0e0e4dSAntonio Huete Jimenez BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
688*de0e0e4dSAntonio Huete Jimenez {
689*de0e0e4dSAntonio Huete Jimenez 	unsigned int i, m, n;
690*de0e0e4dSAntonio Huete Jimenez 	BN_ULONG l;
691*de0e0e4dSAntonio Huete Jimenez 	BIGNUM *bn = NULL;
692*de0e0e4dSAntonio Huete Jimenez 
693*de0e0e4dSAntonio Huete Jimenez 	if (ret == NULL)
694*de0e0e4dSAntonio Huete Jimenez 		ret = bn = BN_new();
695*de0e0e4dSAntonio Huete Jimenez 	if (ret == NULL)
696*de0e0e4dSAntonio Huete Jimenez 		return NULL;
697*de0e0e4dSAntonio Huete Jimenez 
698*de0e0e4dSAntonio Huete Jimenez 	bn_check_top(ret);
699*de0e0e4dSAntonio Huete Jimenez 
700*de0e0e4dSAntonio Huete Jimenez 	s += len;
701*de0e0e4dSAntonio Huete Jimenez 	/* Skip trailing zeroes. */
702*de0e0e4dSAntonio Huete Jimenez 	for (; len > 0 && s[-1] == 0; s--, len--)
703*de0e0e4dSAntonio Huete Jimenez 		continue;
704*de0e0e4dSAntonio Huete Jimenez 
705*de0e0e4dSAntonio Huete Jimenez 	n = len;
706*de0e0e4dSAntonio Huete Jimenez 	if (n == 0) {
707*de0e0e4dSAntonio Huete Jimenez 		ret->top = 0;
708*de0e0e4dSAntonio Huete Jimenez 		return ret;
709*de0e0e4dSAntonio Huete Jimenez 	}
710*de0e0e4dSAntonio Huete Jimenez 
711*de0e0e4dSAntonio Huete Jimenez 	i = ((n - 1) / BN_BYTES) + 1;
712*de0e0e4dSAntonio Huete Jimenez 	m = (n - 1) % BN_BYTES;
713*de0e0e4dSAntonio Huete Jimenez 	if (bn_wexpand(ret, (int)i) == NULL) {
714*de0e0e4dSAntonio Huete Jimenez 		BN_free(bn);
715*de0e0e4dSAntonio Huete Jimenez 		return NULL;
716*de0e0e4dSAntonio Huete Jimenez 	}
717*de0e0e4dSAntonio Huete Jimenez 
718*de0e0e4dSAntonio Huete Jimenez 	ret->top = i;
719*de0e0e4dSAntonio Huete Jimenez 	ret->neg = 0;
720*de0e0e4dSAntonio Huete Jimenez 	l = 0;
721*de0e0e4dSAntonio Huete Jimenez 	while (n-- > 0) {
722*de0e0e4dSAntonio Huete Jimenez 		s--;
723*de0e0e4dSAntonio Huete Jimenez 		l = (l << 8L) | *s;
724*de0e0e4dSAntonio Huete Jimenez 		if (m-- == 0) {
725*de0e0e4dSAntonio Huete Jimenez 			ret->d[--i] = l;
726*de0e0e4dSAntonio Huete Jimenez 			l = 0;
727*de0e0e4dSAntonio Huete Jimenez 			m = BN_BYTES - 1;
728*de0e0e4dSAntonio Huete Jimenez 		}
729*de0e0e4dSAntonio Huete Jimenez 	}
730*de0e0e4dSAntonio Huete Jimenez 
731*de0e0e4dSAntonio Huete Jimenez 	/*
732*de0e0e4dSAntonio Huete Jimenez 	 * need to call this due to clear byte at top if avoiding having the
733*de0e0e4dSAntonio Huete Jimenez 	 * top bit set (-ve number)
734*de0e0e4dSAntonio Huete Jimenez 	 */
735*de0e0e4dSAntonio Huete Jimenez 	bn_correct_top(ret);
736*de0e0e4dSAntonio Huete Jimenez 
737*de0e0e4dSAntonio Huete Jimenez 	return ret;
738*de0e0e4dSAntonio Huete Jimenez }
739*de0e0e4dSAntonio Huete Jimenez 
740*de0e0e4dSAntonio Huete Jimenez int
BN_bn2lebinpad(const BIGNUM * a,unsigned char * to,int tolen)741*de0e0e4dSAntonio Huete Jimenez BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
742*de0e0e4dSAntonio Huete Jimenez {
743*de0e0e4dSAntonio Huete Jimenez 	if (tolen < 0)
744*de0e0e4dSAntonio Huete Jimenez 		return -1;
745*de0e0e4dSAntonio Huete Jimenez 
746*de0e0e4dSAntonio Huete Jimenez 	return bn2binpad(a, to, tolen, little);
747f5b1c8a1SJohn Marino }
748f5b1c8a1SJohn Marino 
749f5b1c8a1SJohn Marino int
BN_ucmp(const BIGNUM * a,const BIGNUM * b)750f5b1c8a1SJohn Marino BN_ucmp(const BIGNUM *a, const BIGNUM *b)
751f5b1c8a1SJohn Marino {
752f5b1c8a1SJohn Marino 	int i;
753f5b1c8a1SJohn Marino 	BN_ULONG t1, t2, *ap, *bp;
754f5b1c8a1SJohn Marino 
755f5b1c8a1SJohn Marino 	bn_check_top(a);
756f5b1c8a1SJohn Marino 	bn_check_top(b);
757f5b1c8a1SJohn Marino 
758f5b1c8a1SJohn Marino 	i = a->top - b->top;
759f5b1c8a1SJohn Marino 	if (i != 0)
760f5b1c8a1SJohn Marino 		return (i);
761f5b1c8a1SJohn Marino 	ap = a->d;
762f5b1c8a1SJohn Marino 	bp = b->d;
763f5b1c8a1SJohn Marino 	for (i = a->top - 1; i >= 0; i--) {
764f5b1c8a1SJohn Marino 		t1 = ap[i];
765f5b1c8a1SJohn Marino 		t2 = bp[i];
766f5b1c8a1SJohn Marino 		if (t1 != t2)
767f5b1c8a1SJohn Marino 			return ((t1 > t2) ? 1 : -1);
768f5b1c8a1SJohn Marino 	}
769f5b1c8a1SJohn Marino 	return (0);
770f5b1c8a1SJohn Marino }
771f5b1c8a1SJohn Marino 
772f5b1c8a1SJohn Marino int
BN_cmp(const BIGNUM * a,const BIGNUM * b)773f5b1c8a1SJohn Marino BN_cmp(const BIGNUM *a, const BIGNUM *b)
774f5b1c8a1SJohn Marino {
775f5b1c8a1SJohn Marino 	int i;
776f5b1c8a1SJohn Marino 	int gt, lt;
777f5b1c8a1SJohn Marino 	BN_ULONG t1, t2;
778f5b1c8a1SJohn Marino 
779f5b1c8a1SJohn Marino 	if ((a == NULL) || (b == NULL)) {
780f5b1c8a1SJohn Marino 		if (a != NULL)
781f5b1c8a1SJohn Marino 			return (-1);
782f5b1c8a1SJohn Marino 		else if (b != NULL)
783f5b1c8a1SJohn Marino 			return (1);
784f5b1c8a1SJohn Marino 		else
785f5b1c8a1SJohn Marino 			return (0);
786f5b1c8a1SJohn Marino 	}
787f5b1c8a1SJohn Marino 
788f5b1c8a1SJohn Marino 	bn_check_top(a);
789f5b1c8a1SJohn Marino 	bn_check_top(b);
790f5b1c8a1SJohn Marino 
791f5b1c8a1SJohn Marino 	if (a->neg != b->neg) {
792f5b1c8a1SJohn Marino 		if (a->neg)
793f5b1c8a1SJohn Marino 			return (-1);
794f5b1c8a1SJohn Marino 		else
795f5b1c8a1SJohn Marino 			return (1);
796f5b1c8a1SJohn Marino 	}
797f5b1c8a1SJohn Marino 	if (a->neg == 0) {
798f5b1c8a1SJohn Marino 		gt = 1;
799f5b1c8a1SJohn Marino 		lt = -1;
800f5b1c8a1SJohn Marino 	} else {
801f5b1c8a1SJohn Marino 		gt = -1;
802f5b1c8a1SJohn Marino 		lt = 1;
803f5b1c8a1SJohn Marino 	}
804f5b1c8a1SJohn Marino 
805f5b1c8a1SJohn Marino 	if (a->top > b->top)
806f5b1c8a1SJohn Marino 		return (gt);
807f5b1c8a1SJohn Marino 	if (a->top < b->top)
808f5b1c8a1SJohn Marino 		return (lt);
809f5b1c8a1SJohn Marino 	for (i = a->top - 1; i >= 0; i--) {
810f5b1c8a1SJohn Marino 		t1 = a->d[i];
811f5b1c8a1SJohn Marino 		t2 = b->d[i];
812f5b1c8a1SJohn Marino 		if (t1 > t2)
813f5b1c8a1SJohn Marino 			return (gt);
814f5b1c8a1SJohn Marino 		if (t1 < t2)
815f5b1c8a1SJohn Marino 			return (lt);
816f5b1c8a1SJohn Marino 	}
817f5b1c8a1SJohn Marino 	return (0);
818f5b1c8a1SJohn Marino }
819f5b1c8a1SJohn Marino 
820f5b1c8a1SJohn Marino int
BN_set_bit(BIGNUM * a,int n)821f5b1c8a1SJohn Marino BN_set_bit(BIGNUM *a, int n)
822f5b1c8a1SJohn Marino {
823f5b1c8a1SJohn Marino 	int i, j, k;
824f5b1c8a1SJohn Marino 
825f5b1c8a1SJohn Marino 	if (n < 0)
826f5b1c8a1SJohn Marino 		return 0;
827f5b1c8a1SJohn Marino 
828f5b1c8a1SJohn Marino 	i = n / BN_BITS2;
829f5b1c8a1SJohn Marino 	j = n % BN_BITS2;
830f5b1c8a1SJohn Marino 	if (a->top <= i) {
831f5b1c8a1SJohn Marino 		if (bn_wexpand(a, i + 1) == NULL)
832f5b1c8a1SJohn Marino 			return (0);
833f5b1c8a1SJohn Marino 		for (k = a->top; k < i + 1; k++)
834f5b1c8a1SJohn Marino 			a->d[k] = 0;
835f5b1c8a1SJohn Marino 		a->top = i + 1;
836f5b1c8a1SJohn Marino 	}
837f5b1c8a1SJohn Marino 
838f5b1c8a1SJohn Marino 	a->d[i] |= (((BN_ULONG)1) << j);
839f5b1c8a1SJohn Marino 	bn_check_top(a);
840f5b1c8a1SJohn Marino 	return (1);
841f5b1c8a1SJohn Marino }
842f5b1c8a1SJohn Marino 
843f5b1c8a1SJohn Marino int
BN_clear_bit(BIGNUM * a,int n)844f5b1c8a1SJohn Marino BN_clear_bit(BIGNUM *a, int n)
845f5b1c8a1SJohn Marino {
846f5b1c8a1SJohn Marino 	int i, j;
847f5b1c8a1SJohn Marino 
848f5b1c8a1SJohn Marino 	bn_check_top(a);
849f5b1c8a1SJohn Marino 	if (n < 0)
850f5b1c8a1SJohn Marino 		return 0;
851f5b1c8a1SJohn Marino 
852f5b1c8a1SJohn Marino 	i = n / BN_BITS2;
853f5b1c8a1SJohn Marino 	j = n % BN_BITS2;
854f5b1c8a1SJohn Marino 	if (a->top <= i)
855f5b1c8a1SJohn Marino 		return (0);
856f5b1c8a1SJohn Marino 
857f5b1c8a1SJohn Marino 	a->d[i] &= (~(((BN_ULONG)1) << j));
858f5b1c8a1SJohn Marino 	bn_correct_top(a);
859f5b1c8a1SJohn Marino 	return (1);
860f5b1c8a1SJohn Marino }
861f5b1c8a1SJohn Marino 
862f5b1c8a1SJohn Marino int
BN_is_bit_set(const BIGNUM * a,int n)863f5b1c8a1SJohn Marino BN_is_bit_set(const BIGNUM *a, int n)
864f5b1c8a1SJohn Marino {
865f5b1c8a1SJohn Marino 	int i, j;
866f5b1c8a1SJohn Marino 
867f5b1c8a1SJohn Marino 	bn_check_top(a);
868f5b1c8a1SJohn Marino 	if (n < 0)
869f5b1c8a1SJohn Marino 		return 0;
870f5b1c8a1SJohn Marino 	i = n / BN_BITS2;
871f5b1c8a1SJohn Marino 	j = n % BN_BITS2;
872f5b1c8a1SJohn Marino 	if (a->top <= i)
873f5b1c8a1SJohn Marino 		return 0;
874f5b1c8a1SJohn Marino 	return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
875f5b1c8a1SJohn Marino }
876f5b1c8a1SJohn Marino 
877f5b1c8a1SJohn Marino int
BN_mask_bits(BIGNUM * a,int n)878f5b1c8a1SJohn Marino BN_mask_bits(BIGNUM *a, int n)
879f5b1c8a1SJohn Marino {
880f5b1c8a1SJohn Marino 	int b, w;
881f5b1c8a1SJohn Marino 
882f5b1c8a1SJohn Marino 	bn_check_top(a);
883f5b1c8a1SJohn Marino 	if (n < 0)
884f5b1c8a1SJohn Marino 		return 0;
885f5b1c8a1SJohn Marino 
886f5b1c8a1SJohn Marino 	w = n / BN_BITS2;
887f5b1c8a1SJohn Marino 	b = n % BN_BITS2;
888f5b1c8a1SJohn Marino 	if (w >= a->top)
889f5b1c8a1SJohn Marino 		return 0;
890f5b1c8a1SJohn Marino 	if (b == 0)
891f5b1c8a1SJohn Marino 		a->top = w;
892f5b1c8a1SJohn Marino 	else {
893f5b1c8a1SJohn Marino 		a->top = w + 1;
894f5b1c8a1SJohn Marino 		a->d[w] &= ~(BN_MASK2 << b);
895f5b1c8a1SJohn Marino 	}
896f5b1c8a1SJohn Marino 	bn_correct_top(a);
897f5b1c8a1SJohn Marino 	return (1);
898f5b1c8a1SJohn Marino }
899f5b1c8a1SJohn Marino 
900f5b1c8a1SJohn Marino void
BN_set_negative(BIGNUM * a,int b)901f5b1c8a1SJohn Marino BN_set_negative(BIGNUM *a, int b)
902f5b1c8a1SJohn Marino {
903f5b1c8a1SJohn Marino 	if (b && !BN_is_zero(a))
904f5b1c8a1SJohn Marino 		a->neg = 1;
905f5b1c8a1SJohn Marino 	else
906f5b1c8a1SJohn Marino 		a->neg = 0;
907f5b1c8a1SJohn Marino }
908f5b1c8a1SJohn Marino 
909f5b1c8a1SJohn Marino int
bn_cmp_words(const BN_ULONG * a,const BN_ULONG * b,int n)910f5b1c8a1SJohn Marino bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
911f5b1c8a1SJohn Marino {
912f5b1c8a1SJohn Marino 	int i;
913f5b1c8a1SJohn Marino 	BN_ULONG aa, bb;
914f5b1c8a1SJohn Marino 
915f5b1c8a1SJohn Marino 	aa = a[n - 1];
916f5b1c8a1SJohn Marino 	bb = b[n - 1];
917f5b1c8a1SJohn Marino 	if (aa != bb)
918f5b1c8a1SJohn Marino 		return ((aa > bb) ? 1 : -1);
919f5b1c8a1SJohn Marino 	for (i = n - 2; i >= 0; i--) {
920f5b1c8a1SJohn Marino 		aa = a[i];
921f5b1c8a1SJohn Marino 		bb = b[i];
922f5b1c8a1SJohn Marino 		if (aa != bb)
923f5b1c8a1SJohn Marino 			return ((aa > bb) ? 1 : -1);
924f5b1c8a1SJohn Marino 	}
925f5b1c8a1SJohn Marino 	return (0);
926f5b1c8a1SJohn Marino }
927f5b1c8a1SJohn Marino 
928f5b1c8a1SJohn Marino /* Here follows a specialised variants of bn_cmp_words().  It has the
929f5b1c8a1SJohn Marino    property of performing the operation on arrays of different sizes.
930f5b1c8a1SJohn Marino    The sizes of those arrays is expressed through cl, which is the
931f5b1c8a1SJohn Marino    common length ( basicall, min(len(a),len(b)) ), and dl, which is the
932f5b1c8a1SJohn Marino    delta between the two lengths, calculated as len(a)-len(b).
933f5b1c8a1SJohn Marino    All lengths are the number of BN_ULONGs...  */
934f5b1c8a1SJohn Marino 
935f5b1c8a1SJohn Marino int
bn_cmp_part_words(const BN_ULONG * a,const BN_ULONG * b,int cl,int dl)936f5b1c8a1SJohn Marino bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
937f5b1c8a1SJohn Marino {
938f5b1c8a1SJohn Marino 	int n, i;
939f5b1c8a1SJohn Marino 
940f5b1c8a1SJohn Marino 	n = cl - 1;
941f5b1c8a1SJohn Marino 
942f5b1c8a1SJohn Marino 	if (dl < 0) {
943f5b1c8a1SJohn Marino 		for (i = dl; i < 0; i++) {
944f5b1c8a1SJohn Marino 			if (b[n - i] != 0)
945f5b1c8a1SJohn Marino 				return -1; /* a < b */
946f5b1c8a1SJohn Marino 		}
947f5b1c8a1SJohn Marino 	}
948f5b1c8a1SJohn Marino 	if (dl > 0) {
949f5b1c8a1SJohn Marino 		for (i = dl; i > 0; i--) {
950f5b1c8a1SJohn Marino 			if (a[n + i] != 0)
951f5b1c8a1SJohn Marino 				return 1; /* a > b */
952f5b1c8a1SJohn Marino 		}
953f5b1c8a1SJohn Marino 	}
954f5b1c8a1SJohn Marino 	return bn_cmp_words(a, b, cl);
955f5b1c8a1SJohn Marino }
956f5b1c8a1SJohn Marino 
957f5b1c8a1SJohn Marino /*
958f5b1c8a1SJohn Marino  * Constant-time conditional swap of a and b.
95972c33676SMaxim Ag  * a and b are swapped if condition is not 0.
96072c33676SMaxim Ag  * The code assumes that at most one bit of condition is set.
96172c33676SMaxim Ag  * nwords is the number of words to swap.
96272c33676SMaxim Ag  * The code assumes that at least nwords are allocated in both a and b,
963f5b1c8a1SJohn Marino  * and that no more than nwords are used by either a or b.
964f5b1c8a1SJohn Marino  * a and b cannot be the same number
965f5b1c8a1SJohn Marino  */
966f5b1c8a1SJohn Marino void
BN_consttime_swap(BN_ULONG condition,BIGNUM * a,BIGNUM * b,int nwords)967f5b1c8a1SJohn Marino BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
968f5b1c8a1SJohn Marino {
969f5b1c8a1SJohn Marino 	BN_ULONG t;
970f5b1c8a1SJohn Marino 	int i;
971f5b1c8a1SJohn Marino 
972f5b1c8a1SJohn Marino 	bn_wcheck_size(a, nwords);
973f5b1c8a1SJohn Marino 	bn_wcheck_size(b, nwords);
974f5b1c8a1SJohn Marino 
975f5b1c8a1SJohn Marino 	assert(a != b);
976f5b1c8a1SJohn Marino 	assert((condition & (condition - 1)) == 0);
977f5b1c8a1SJohn Marino 	assert(sizeof(BN_ULONG) >= sizeof(int));
978f5b1c8a1SJohn Marino 
979f5b1c8a1SJohn Marino 	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
980f5b1c8a1SJohn Marino 
981f5b1c8a1SJohn Marino 	t = (a->top^b->top) & condition;
982f5b1c8a1SJohn Marino 	a->top ^= t;
983f5b1c8a1SJohn Marino 	b->top ^= t;
984f5b1c8a1SJohn Marino 
985f5b1c8a1SJohn Marino #define BN_CONSTTIME_SWAP(ind) \
986f5b1c8a1SJohn Marino 	do { \
987f5b1c8a1SJohn Marino 		t = (a->d[ind] ^ b->d[ind]) & condition; \
988f5b1c8a1SJohn Marino 		a->d[ind] ^= t; \
989f5b1c8a1SJohn Marino 		b->d[ind] ^= t; \
990f5b1c8a1SJohn Marino 	} while (0)
991f5b1c8a1SJohn Marino 
992f5b1c8a1SJohn Marino 
993f5b1c8a1SJohn Marino 	switch (nwords) {
994f5b1c8a1SJohn Marino 	default:
995f5b1c8a1SJohn Marino 		for (i = 10; i < nwords; i++)
996f5b1c8a1SJohn Marino 			BN_CONSTTIME_SWAP(i);
997f5b1c8a1SJohn Marino 		/* Fallthrough */
998f5b1c8a1SJohn Marino 	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
999f5b1c8a1SJohn Marino 	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
1000f5b1c8a1SJohn Marino 	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
1001f5b1c8a1SJohn Marino 	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
1002f5b1c8a1SJohn Marino 	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
1003f5b1c8a1SJohn Marino 	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
1004f5b1c8a1SJohn Marino 	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
1005f5b1c8a1SJohn Marino 	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
1006f5b1c8a1SJohn Marino 	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
1007f5b1c8a1SJohn Marino 	case 1:
1008f5b1c8a1SJohn Marino 		BN_CONSTTIME_SWAP(0);
1009f5b1c8a1SJohn Marino 	}
1010f5b1c8a1SJohn Marino #undef BN_CONSTTIME_SWAP
1011f5b1c8a1SJohn Marino }
101272c33676SMaxim Ag 
101372c33676SMaxim Ag /*
101472c33676SMaxim Ag  * Constant-time conditional swap of a and b.
101572c33676SMaxim Ag  * a and b are swapped if condition is not 0.
101672c33676SMaxim Ag  * nwords is the number of words to swap.
101772c33676SMaxim Ag  */
101872c33676SMaxim Ag int
BN_swap_ct(BN_ULONG condition,BIGNUM * a,BIGNUM * b,size_t nwords)101972c33676SMaxim Ag BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords)
102072c33676SMaxim Ag {
102172c33676SMaxim Ag 	BN_ULONG t;
102272c33676SMaxim Ag 	int i, words;
102372c33676SMaxim Ag 
102472c33676SMaxim Ag 	if (a == b)
102572c33676SMaxim Ag 		return 1;
102672c33676SMaxim Ag 	if (nwords > INT_MAX)
102772c33676SMaxim Ag 		return 0;
102872c33676SMaxim Ag 	words = (int)nwords;
102972c33676SMaxim Ag 	if (bn_wexpand(a, words) == NULL || bn_wexpand(b, words) == NULL)
103072c33676SMaxim Ag 		return 0;
103172c33676SMaxim Ag 	if (a->top > words || b->top > words) {
103272c33676SMaxim Ag 		BNerror(BN_R_INVALID_LENGTH);
103372c33676SMaxim Ag 		return 0;
103472c33676SMaxim Ag 	}
103572c33676SMaxim Ag 
103672c33676SMaxim Ag 	/* Set condition to 0 (if it was zero) or all 1s otherwise. */
103772c33676SMaxim Ag 	condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1;
103872c33676SMaxim Ag 
103972c33676SMaxim Ag 	/* swap top field */
104072c33676SMaxim Ag 	t = (a->top ^ b->top) & condition;
104172c33676SMaxim Ag 	a->top ^= t;
104272c33676SMaxim Ag 	b->top ^= t;
104372c33676SMaxim Ag 
104472c33676SMaxim Ag 	/* swap neg field */
104572c33676SMaxim Ag 	t = (a->neg ^ b->neg) & condition;
104672c33676SMaxim Ag 	a->neg ^= t;
104772c33676SMaxim Ag 	b->neg ^= t;
104872c33676SMaxim Ag 
104972c33676SMaxim Ag 	/* swap BN_FLG_CONSTTIME from flag field */
105072c33676SMaxim Ag 	t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;
105172c33676SMaxim Ag 	a->flags ^= t;
105272c33676SMaxim Ag 	b->flags ^= t;
105372c33676SMaxim Ag 
105472c33676SMaxim Ag 	/* swap the data */
105572c33676SMaxim Ag 	for (i = 0; i < words; i++) {
105672c33676SMaxim Ag 		t = (a->d[i] ^ b->d[i]) & condition;
105772c33676SMaxim Ag 		a->d[i] ^= t;
105872c33676SMaxim Ag 		b->d[i] ^= t;
105972c33676SMaxim Ag 	}
106072c33676SMaxim Ag 
106172c33676SMaxim Ag 	return 1;
106272c33676SMaxim Ag }
106372c33676SMaxim Ag 
1064*de0e0e4dSAntonio Huete Jimenez void
BN_zero_ex(BIGNUM * a)1065*de0e0e4dSAntonio Huete Jimenez BN_zero_ex(BIGNUM *a)
1066*de0e0e4dSAntonio Huete Jimenez {
1067*de0e0e4dSAntonio Huete Jimenez 	a->neg = 0;
1068*de0e0e4dSAntonio Huete Jimenez 	a->top = 0;
1069*de0e0e4dSAntonio Huete Jimenez 	/* XXX: a->flags &= ~BN_FIXED_TOP */
1070*de0e0e4dSAntonio Huete Jimenez }
1071*de0e0e4dSAntonio Huete Jimenez 
1072*de0e0e4dSAntonio Huete Jimenez int
BN_abs_is_word(const BIGNUM * a,const BN_ULONG w)1073*de0e0e4dSAntonio Huete Jimenez BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
1074*de0e0e4dSAntonio Huete Jimenez {
1075*de0e0e4dSAntonio Huete Jimenez 	return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0);
1076*de0e0e4dSAntonio Huete Jimenez }
1077*de0e0e4dSAntonio Huete Jimenez 
1078*de0e0e4dSAntonio Huete Jimenez int
BN_is_zero(const BIGNUM * a)1079*de0e0e4dSAntonio Huete Jimenez BN_is_zero(const BIGNUM *a)
1080*de0e0e4dSAntonio Huete Jimenez {
1081*de0e0e4dSAntonio Huete Jimenez 	return a->top == 0;
1082*de0e0e4dSAntonio Huete Jimenez }
1083*de0e0e4dSAntonio Huete Jimenez 
1084*de0e0e4dSAntonio Huete Jimenez int
BN_is_one(const BIGNUM * a)1085*de0e0e4dSAntonio Huete Jimenez BN_is_one(const BIGNUM *a)
1086*de0e0e4dSAntonio Huete Jimenez {
1087*de0e0e4dSAntonio Huete Jimenez 	return BN_abs_is_word(a, 1) && !a->neg;
1088*de0e0e4dSAntonio Huete Jimenez }
1089*de0e0e4dSAntonio Huete Jimenez 
1090*de0e0e4dSAntonio Huete Jimenez int
BN_is_word(const BIGNUM * a,const BN_ULONG w)1091*de0e0e4dSAntonio Huete Jimenez BN_is_word(const BIGNUM *a, const BN_ULONG w)
1092*de0e0e4dSAntonio Huete Jimenez {
1093*de0e0e4dSAntonio Huete Jimenez 	return BN_abs_is_word(a, w) && (w == 0 || !a->neg);
1094*de0e0e4dSAntonio Huete Jimenez }
1095*de0e0e4dSAntonio Huete Jimenez 
1096*de0e0e4dSAntonio Huete Jimenez int
BN_is_odd(const BIGNUM * a)1097*de0e0e4dSAntonio Huete Jimenez BN_is_odd(const BIGNUM *a)
1098*de0e0e4dSAntonio Huete Jimenez {
1099*de0e0e4dSAntonio Huete Jimenez 	return a->top > 0 && (a->d[0] & 1);
1100*de0e0e4dSAntonio Huete Jimenez }
1101*de0e0e4dSAntonio Huete Jimenez 
1102*de0e0e4dSAntonio Huete Jimenez int
BN_is_negative(const BIGNUM * a)1103*de0e0e4dSAntonio Huete Jimenez BN_is_negative(const BIGNUM *a)
1104*de0e0e4dSAntonio Huete Jimenez {
1105*de0e0e4dSAntonio Huete Jimenez 	return a->neg != 0;
1106*de0e0e4dSAntonio Huete Jimenez }
1107*de0e0e4dSAntonio Huete Jimenez 
1108*de0e0e4dSAntonio Huete Jimenez /*
1109*de0e0e4dSAntonio Huete Jimenez  * Bits of security, see SP800-57, section 5.6.11, table 2.
1110*de0e0e4dSAntonio Huete Jimenez  */
1111*de0e0e4dSAntonio Huete Jimenez int
BN_security_bits(int L,int N)1112*de0e0e4dSAntonio Huete Jimenez BN_security_bits(int L, int N)
1113*de0e0e4dSAntonio Huete Jimenez {
1114*de0e0e4dSAntonio Huete Jimenez 	int secbits, bits;
1115*de0e0e4dSAntonio Huete Jimenez 
1116*de0e0e4dSAntonio Huete Jimenez 	if (L >= 15360)
1117*de0e0e4dSAntonio Huete Jimenez 		secbits = 256;
1118*de0e0e4dSAntonio Huete Jimenez 	else if (L >= 7680)
1119*de0e0e4dSAntonio Huete Jimenez 		secbits = 192;
1120*de0e0e4dSAntonio Huete Jimenez 	else if (L >= 3072)
1121*de0e0e4dSAntonio Huete Jimenez 		secbits = 128;
1122*de0e0e4dSAntonio Huete Jimenez 	else if (L >= 2048)
1123*de0e0e4dSAntonio Huete Jimenez 		secbits = 112;
1124*de0e0e4dSAntonio Huete Jimenez 	else if (L >= 1024)
1125*de0e0e4dSAntonio Huete Jimenez 		secbits = 80;
1126*de0e0e4dSAntonio Huete Jimenez 	else
1127*de0e0e4dSAntonio Huete Jimenez 		return 0;
1128*de0e0e4dSAntonio Huete Jimenez 
1129*de0e0e4dSAntonio Huete Jimenez 	if (N == -1)
1130*de0e0e4dSAntonio Huete Jimenez 		return secbits;
1131*de0e0e4dSAntonio Huete Jimenez 
1132*de0e0e4dSAntonio Huete Jimenez 	bits = N / 2;
1133*de0e0e4dSAntonio Huete Jimenez 	if (bits < 80)
1134*de0e0e4dSAntonio Huete Jimenez 		return 0;
1135*de0e0e4dSAntonio Huete Jimenez 
1136*de0e0e4dSAntonio Huete Jimenez 	return bits >= secbits ? secbits : bits;
1137*de0e0e4dSAntonio Huete Jimenez }
1138*de0e0e4dSAntonio Huete Jimenez 
113972c33676SMaxim Ag BN_GENCB *
BN_GENCB_new(void)114072c33676SMaxim Ag BN_GENCB_new(void)
114172c33676SMaxim Ag {
114272c33676SMaxim Ag 	BN_GENCB *cb;
114372c33676SMaxim Ag 
114472c33676SMaxim Ag 	if ((cb = calloc(1, sizeof(*cb))) == NULL)
114572c33676SMaxim Ag 		return NULL;
114672c33676SMaxim Ag 
114772c33676SMaxim Ag 	return cb;
114872c33676SMaxim Ag }
114972c33676SMaxim Ag 
115072c33676SMaxim Ag void
BN_GENCB_free(BN_GENCB * cb)115172c33676SMaxim Ag BN_GENCB_free(BN_GENCB *cb)
115272c33676SMaxim Ag {
115372c33676SMaxim Ag 	if (cb == NULL)
115472c33676SMaxim Ag 		return;
115572c33676SMaxim Ag 	free(cb);
115672c33676SMaxim Ag }
115772c33676SMaxim Ag 
1158*de0e0e4dSAntonio Huete Jimenez /* Populate a BN_GENCB structure with an "old"-style callback */
1159*de0e0e4dSAntonio Huete Jimenez void
BN_GENCB_set_old(BN_GENCB * gencb,void (* cb)(int,int,void *),void * cb_arg)1160*de0e0e4dSAntonio Huete Jimenez BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg)
1161*de0e0e4dSAntonio Huete Jimenez {
1162*de0e0e4dSAntonio Huete Jimenez 	gencb->ver = 1;
1163*de0e0e4dSAntonio Huete Jimenez 	gencb->cb.cb_1 = cb;
1164*de0e0e4dSAntonio Huete Jimenez 	gencb->arg = cb_arg;
1165*de0e0e4dSAntonio Huete Jimenez }
1166*de0e0e4dSAntonio Huete Jimenez 
1167*de0e0e4dSAntonio Huete Jimenez /* Populate a BN_GENCB structure with a "new"-style callback */
1168*de0e0e4dSAntonio Huete Jimenez void
BN_GENCB_set(BN_GENCB * gencb,int (* cb)(int,int,BN_GENCB *),void * cb_arg)1169*de0e0e4dSAntonio Huete Jimenez BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg)
1170*de0e0e4dSAntonio Huete Jimenez {
1171*de0e0e4dSAntonio Huete Jimenez 	gencb->ver = 2;
1172*de0e0e4dSAntonio Huete Jimenez 	gencb->cb.cb_2 = cb;
1173*de0e0e4dSAntonio Huete Jimenez 	gencb->arg = cb_arg;
1174*de0e0e4dSAntonio Huete Jimenez }
1175*de0e0e4dSAntonio Huete Jimenez 
117672c33676SMaxim Ag void *
BN_GENCB_get_arg(BN_GENCB * cb)117772c33676SMaxim Ag BN_GENCB_get_arg(BN_GENCB *cb)
117872c33676SMaxim Ag {
117972c33676SMaxim Ag 	return cb->arg;
118072c33676SMaxim Ag }
1181