bn_lib.c 20.7 KB
Newer Older
1
/* crypto/bn/bn_lib.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

59 60 61 62 63
#ifndef BN_DEBUG
# undef NDEBUG /* avoid conflicting definitions */
# define NDEBUG
#endif

D
Dr. Stephen Henson 已提交
64

65

66
#include <assert.h>
B
Bodo Möller 已提交
67
#include <limits.h>
68 69 70
#include "cryptlib.h"
#include "bn_lcl.h"

71
const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
72

73 74
/* This stuff appears to be completely unused, so is deprecated */
#ifndef OPENSSL_NO_DEPRECATED
75 76 77 78 79 80 81 82 83
/* For a 32 bit machine
 * 2 -   4 ==  128
 * 3 -   8 ==  256
 * 4 -  16 ==  512
 * 5 -  32 == 1024
 * 6 -  64 == 2048
 * 7 - 128 == 4096
 * 8 - 256 == 8192
 */
84 85 86 87 88 89 90 91
static int bn_limit_bits=0;
static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
static int bn_limit_bits_low=0;
static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
static int bn_limit_bits_high=0;
static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
static int bn_limit_bits_mont=0;
static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
92

U
Ulf Möller 已提交
93
void BN_set_params(int mult, int high, int low, int mont)
94 95 96
	{
	if (mult >= 0)
		{
97
		if (mult > (int)(sizeof(int)*8)-1)
98 99 100 101 102 103
			mult=sizeof(int)*8-1;
		bn_limit_bits=mult;
		bn_limit_num=1<<mult;
		}
	if (high >= 0)
		{
104
		if (high > (int)(sizeof(int)*8)-1)
105 106 107 108 109 110
			high=sizeof(int)*8-1;
		bn_limit_bits_high=high;
		bn_limit_num_high=1<<high;
		}
	if (low >= 0)
		{
111
		if (low > (int)(sizeof(int)*8)-1)
112 113 114 115 116 117
			low=sizeof(int)*8-1;
		bn_limit_bits_low=low;
		bn_limit_num_low=1<<low;
		}
	if (mont >= 0)
		{
118
		if (mont > (int)(sizeof(int)*8)-1)
119 120 121 122 123 124
			mont=sizeof(int)*8-1;
		bn_limit_bits_mont=mont;
		bn_limit_num_mont=1<<mont;
		}
	}

U
Ulf Möller 已提交
125
int BN_get_params(int which)
126 127 128 129 130 131 132
	{
	if      (which == 0) return(bn_limit_bits);
	else if (which == 1) return(bn_limit_bits_high);
	else if (which == 2) return(bn_limit_bits_low);
	else if (which == 3) return(bn_limit_bits_mont);
	else return(0);
	}
133
#endif
134

B
Bodo Möller 已提交
135
const BIGNUM *BN_value_one(void)
136
	{
137 138
	static const BN_ULONG data_one=1L;
	static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
139 140 141 142

	return(&const_one);
	}

U
Ulf Möller 已提交
143
int BN_num_bits_word(BN_ULONG l)
144
	{
145
	static const unsigned char bits[256]={
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		};

164
#if defined(SIXTY_FOUR_BIT_LONG)
165 166 167 168 169 170
	if (l & 0xffffffff00000000L)
		{
		if (l & 0xffff000000000000L)
			{
			if (l & 0xff00000000000000L)
				{
171
				return(bits[(int)(l>>56)]+56);
172
				}
173
			else	return(bits[(int)(l>>48)]+48);
174 175 176 177 178
			}
		else
			{
			if (l & 0x0000ff0000000000L)
				{
179
				return(bits[(int)(l>>40)]+40);
180
				}
181
			else	return(bits[(int)(l>>32)]+32);
182 183 184 185 186 187 188 189 190 191 192
			}
		}
	else
#else
#ifdef SIXTY_FOUR_BIT
	if (l & 0xffffffff00000000LL)
		{
		if (l & 0xffff000000000000LL)
			{
			if (l & 0xff00000000000000LL)
				{
193
				return(bits[(int)(l>>56)]+56);
194
				}
195
			else	return(bits[(int)(l>>48)]+48);
196 197 198 199 200
			}
		else
			{
			if (l & 0x0000ff0000000000LL)
				{
201
				return(bits[(int)(l>>40)]+40);
202
				}
203
			else	return(bits[(int)(l>>32)]+32);
204 205 206 207 208 209 210 211 212 213
			}
		}
	else
#endif
#endif
		{
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
		if (l & 0xffff0000L)
			{
			if (l & 0xff000000L)
214 215
				return(bits[(int)(l>>24L)]+24);
			else	return(bits[(int)(l>>16L)]+16);
216 217 218 219
			}
		else
#endif
			{
220
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
221
			if (l & 0xff00L)
222
				return(bits[(int)(l>>8)]+8);
223 224
			else	
#endif
225
				return(bits[(int)(l   )]  );
226 227 228 229
			}
		}
	}

230
int BN_num_bits(const BIGNUM *a)
231
	{
G
Geoff Thorpe 已提交
232
	int i = a->top - 1;
233 234
	bn_check_top(a);

G
Geoff Thorpe 已提交
235 236
	if (BN_is_zero(a)) return 0;
	return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
237 238
	}

U
Ulf Möller 已提交
239
void BN_clear_free(BIGNUM *a)
240
	{
241 242
	int i;

243
	if (a == NULL) return;
G
Geoff Thorpe 已提交
244
	bn_check_top(a);
245 246
	if (a->d != NULL)
		{
247
		OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
248
		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
249
			OPENSSL_free(a->d);
250
		}
251
	i=BN_get_flags(a,BN_FLG_MALLOCED);
252
	OPENSSL_cleanse(a,sizeof(BIGNUM));
253
	if (i)
254
		OPENSSL_free(a);
255 256
	}

U
Ulf Möller 已提交
257
void BN_free(BIGNUM *a)
258 259
	{
	if (a == NULL) return;
G
Geoff Thorpe 已提交
260
	bn_check_top(a);
261
	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
262
		OPENSSL_free(a->d);
263
	if (a->flags & BN_FLG_MALLOCED)
264
		OPENSSL_free(a);
265 266 267 268 269 270 271
	else
		{
#ifndef OPENSSL_NO_DEPRECATED
		a->flags|=BN_FLG_FREE;
#endif
		a->d = NULL;
		}
272 273
	}

U
Ulf Möller 已提交
274
void BN_init(BIGNUM *a)
275 276
	{
	memset(a,0,sizeof(BIGNUM));
277
	bn_check_top(a);
278 279
	}

U
Ulf Möller 已提交
280
BIGNUM *BN_new(void)
281 282 283
	{
	BIGNUM *ret;

284
	if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
285 286 287 288 289
		{
		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}
	ret->flags=BN_FLG_MALLOCED;
290 291
	ret->top=0;
	ret->neg=0;
292
	ret->dmax=0;
293
	ret->d=NULL;
294
	bn_check_top(ret);
295 296 297
	return(ret);
	}

298 299
/* This is used both by bn_expand2() and bn_dup_expand() */
/* The caller MUST check that words > b->dmax before calling this */
300
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
301
	{
302
	BN_ULONG *A,*a = NULL;
303 304
	const BN_ULONG *B;
	int i;
305

G
Geoff Thorpe 已提交
306 307
	bn_check_top(b);

308 309
	if (words > (INT_MAX/(4*BN_BITS2)))
		{
310
		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
311 312
		return NULL;
		}
313
	if (BN_get_flags(b,BN_FLG_STATIC_DATA))
314
		{
315
		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
316 317
		return(NULL);
		}
318
	a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
319 320
	if (A == NULL)
		{
321
		BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
322 323
		return(NULL);
		}
324 325 326 327 328 329 330 331 332
#ifdef PURIFY
	/* Valgrind complains in BN_consttime_swap because we process the whole
	 * array even if it's not initialised yet. This doesn't matter in that
	 * function - what's important is constant time operation (we're not
	 * actually going to use the data)
	*/
	memset(a, 0, sizeof(BN_ULONG)*words);
#endif

333
#if 1
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
	B=b->d;
	/* Check if the previous number needs to be copied */
	if (B != NULL)
		{
		for (i=b->top>>2; i>0; i--,A+=4,B+=4)
			{
			/*
			 * The fact that the loop is unrolled
			 * 4-wise is a tribute to Intel. It's
			 * the one that doesn't have enough
			 * registers to accomodate more data.
			 * I'd unroll it 8-wise otherwise:-)
			 *
			 *		<appro@fy.chalmers.se>
			 */
			BN_ULONG a0,a1,a2,a3;
			a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
			A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
352
			}
353
		switch (b->top&3)
354
			{
355 356 357
		case 3:	A[2]=B[2];
		case 2:	A[1]=B[1];
		case 1:	A[0]=B[0];
358 359 360 361
		case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
		         * the switch table by doing a=top&3; a--; goto jump_table[a];
		         * which fails for top== 0 */
			;
362
			}
363 364
		}

365
#else
366
	memset(A,0,sizeof(BN_ULONG)*words);
367
	memcpy(A,b->d,sizeof(b->d[0])*b->top);
368 369
#endif
		
370 371
	return(a);
	}
372

373
/* This is an internal function that should not be used in applications.
374
 * It ensures that 'b' has enough room for a 'words' word number
B
Bodo Möller 已提交
375
 * and initialises any unused part of b->d with leading zeros.
376 377 378
 * It is mostly used by the various BIGNUM routines. If there is an error,
 * NULL is returned. If not, 'b' is returned. */

379
BIGNUM *bn_expand2(BIGNUM *b, int words)
380
	{
G
Geoff Thorpe 已提交
381 382
	bn_check_top(b);

383 384
	if (words > b->dmax)
		{
385
		BN_ULONG *a = bn_expand_internal(b, words);
G
Geoff Thorpe 已提交
386 387 388 389
		if(!a) return NULL;
		if(b->d) OPENSSL_free(b->d);
		b->d=a;
		b->dmax=words;
390
		}
G
Geoff Thorpe 已提交
391

392 393
/* None of this should be necessary because of what b->top means! */
#if 0
394
	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
G
Geoff Thorpe 已提交
395
	if (b->top < b->dmax)
396
		{
397 398
		int i;
		BN_ULONG *A = &(b->d[b->top]);
B
Bodo Möller 已提交
399
		for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
B
Bodo Möller 已提交
400 401 402 403
			{
			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
			}
B
Bodo Möller 已提交
404
		for (i=(b->dmax - b->top)&7; i>0; i--,A++)
B
Bodo Möller 已提交
405
			A[0]=0;
B
Bodo Möller 已提交
406
		assert(A == &(b->d[b->dmax]));
407
		}
408
#endif
G
Geoff Thorpe 已提交
409
	bn_check_top(b);
410
	return b;
411 412
	}

413
BIGNUM *BN_dup(const BIGNUM *a)
414
	{
G
Geoff Thorpe 已提交
415
	BIGNUM *t;
416

417
	if (a == NULL) return NULL;
418 419
	bn_check_top(a);

420
	t = BN_new();
G
Geoff Thorpe 已提交
421 422 423
	if (t == NULL) return NULL;
	if(!BN_copy(t, a))
		{
424
		BN_free(t);
G
Geoff Thorpe 已提交
425 426 427 428
		return NULL;
		}
	bn_check_top(t);
	return t;
429 430
	}

431
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
432
	{
433
	int i;
434 435
	BN_ULONG *A;
	const BN_ULONG *B;
436

437 438
	bn_check_top(b);

439 440 441 442 443 444
	if (a == b) return(a);
	if (bn_wexpand(a,b->top) == NULL) return(NULL);

#if 1
	A=a->d;
	B=b->d;
445
	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
446
		{
447 448 449
		BN_ULONG a0,a1,a2,a3;
		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
450
		}
451
	switch (b->top&3)
452
		{
453 454 455
		case 3: A[2]=B[2];
		case 2: A[1]=B[1];
		case 1: A[0]=B[0];
456
		case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
457 458
		}
#else
459
	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
460 461
#endif

462 463
	a->top=b->top;
	a->neg=b->neg;
464
	bn_check_top(a);
465 466 467
	return(a);
	}

B
Bodo Möller 已提交
468 469 470 471 472 473
void BN_swap(BIGNUM *a, BIGNUM *b)
	{
	int flags_old_a, flags_old_b;
	BN_ULONG *tmp_d;
	int tmp_top, tmp_dmax, tmp_neg;
	
474 475 476
	bn_check_top(a);
	bn_check_top(b);

B
Bodo Möller 已提交
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
	flags_old_a = a->flags;
	flags_old_b = b->flags;

	tmp_d = a->d;
	tmp_top = a->top;
	tmp_dmax = a->dmax;
	tmp_neg = a->neg;
	
	a->d = b->d;
	a->top = b->top;
	a->dmax = b->dmax;
	a->neg = b->neg;
	
	b->d = tmp_d;
	b->top = tmp_top;
	b->dmax = tmp_dmax;
	b->neg = tmp_neg;
	
	a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
	b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
497 498
	bn_check_top(a);
	bn_check_top(b);
B
Bodo Möller 已提交
499 500
	}

U
Ulf Möller 已提交
501
void BN_clear(BIGNUM *a)
502
	{
503
	bn_check_top(a);
504
	if (a->d != NULL)
505
		memset(a->d,0,a->dmax*sizeof(a->d[0]));
506 507 508 509
	a->top=0;
	a->neg=0;
	}

510
BN_ULONG BN_get_word(const BIGNUM *a)
511
	{
G
Geoff Thorpe 已提交
512 513
	if (a->top > 1)
		return BN_MASK2;
514
	else if (a->top == 1)
G
Geoff Thorpe 已提交
515
		return a->d[0];
516 517
	/* a->top == 0 */
	return 0;
518 519
	}

520 521 522 523 524 525 526 527 528 529
int BN_set_word(BIGNUM *a, BN_ULONG w)
	{
	bn_check_top(a);
	if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
	a->neg = 0;
	a->d[0] = w;
	a->top = (w ? 1 : 0);
	bn_check_top(a);
	return(1);
	}
530

531
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
532 533 534 535
	{
	unsigned int i,m;
	unsigned int n;
	BN_ULONG l;
G
Geoff Thorpe 已提交
536
	BIGNUM  *bn = NULL;
537

G
Geoff Thorpe 已提交
538 539
	if (ret == NULL)
		ret = bn = BN_new();
540
	if (ret == NULL) return(NULL);
541
	bn_check_top(ret);
542 543 544 545 546 547 548 549 550
	l=0;
	n=len;
	if (n == 0)
		{
		ret->top=0;
		return(ret);
		}
	i=((n-1)/BN_BYTES)+1;
	m=((n-1)%(BN_BYTES));
551
	if (bn_wexpand(ret, (int)i) == NULL)
G
Geoff Thorpe 已提交
552 553 554 555
		{
		if (bn) BN_free(bn);
		return NULL;
		}
556 557
	ret->top=i;
	ret->neg=0;
G
Geoff Thorpe 已提交
558
	while (n--)
559 560 561 562 563 564 565 566 567 568 569
		{
		l=(l<<8L)| *(s++);
		if (m-- == 0)
			{
			ret->d[--i]=l;
			l=0;
			m=BN_BYTES-1;
			}
		}
	/* need to call this due to clear byte at top if avoiding
	 * having the top bit set (-ve number) */
570
	bn_correct_top(ret);
571 572 573 574
	return(ret);
	}

/* ignore negative */
575
int BN_bn2bin(const BIGNUM *a, unsigned char *to)
576 577 578 579
	{
	int n,i;
	BN_ULONG l;

580
	bn_check_top(a);
581
	n=i=BN_num_bytes(a);
G
Geoff Thorpe 已提交
582
	while (i--)
583 584 585 586 587 588 589
		{
		l=a->d[i/BN_BYTES];
		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
		}
	return(n);
	}

590
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
591 592 593 594
	{
	int i;
	BN_ULONG t1,t2,*ap,*bp;

595 596 597
	bn_check_top(a);
	bn_check_top(b);

598 599 600 601 602 603 604 605 606
	i=a->top-b->top;
	if (i != 0) return(i);
	ap=a->d;
	bp=b->d;
	for (i=a->top-1; i>=0; i--)
		{
		t1= ap[i];
		t2= bp[i];
		if (t1 != t2)
G
Geoff Thorpe 已提交
607
			return((t1 > t2) ? 1 : -1);
608 609 610 611
		}
	return(0);
	}

612
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
613 614 615 616 617 618 619 620 621 622 623 624 625 626
	{
	int i;
	int gt,lt;
	BN_ULONG t1,t2;

	if ((a == NULL) || (b == NULL))
		{
		if (a != NULL)
			return(-1);
		else if (b != NULL)
			return(1);
		else
			return(0);
		}
627 628 629 630

	bn_check_top(a);
	bn_check_top(b);

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
	if (a->neg != b->neg)
		{
		if (a->neg)
			return(-1);
		else	return(1);
		}
	if (a->neg == 0)
		{ gt=1; lt= -1; }
	else	{ gt= -1; lt=1; }

	if (a->top > b->top) return(gt);
	if (a->top < b->top) return(lt);
	for (i=a->top-1; i>=0; i--)
		{
		t1=a->d[i];
		t2=b->d[i];
		if (t1 > t2) return(gt);
		if (t1 < t2) return(lt);
		}
	return(0);
	}

U
Ulf Möller 已提交
653
int BN_set_bit(BIGNUM *a, int n)
654
	{
655
	int i,j,k;
656

657 658 659
	if (n < 0)
		return 0;

660 661
	i=n/BN_BITS2;
	j=n%BN_BITS2;
662 663
	if (a->top <= i)
		{
664 665 666
		if (bn_wexpand(a,i+1) == NULL) return(0);
		for(k=a->top; k<i+1; k++)
			a->d[k]=0;
667 668
		a->top=i+1;
		}
669

670
	a->d[i]|=(((BN_ULONG)1)<<j);
671
	bn_check_top(a);
672 673 674
	return(1);
	}

U
Ulf Möller 已提交
675
int BN_clear_bit(BIGNUM *a, int n)
676 677 678
	{
	int i,j;

G
Geoff Thorpe 已提交
679 680
	bn_check_top(a);
	if (n < 0) return 0;
681

682 683 684 685
	i=n/BN_BITS2;
	j=n%BN_BITS2;
	if (a->top <= i) return(0);

686
	a->d[i]&=(~(((BN_ULONG)1)<<j));
687
	bn_correct_top(a);
688 689 690
	return(1);
	}

691
int BN_is_bit_set(const BIGNUM *a, int n)
692 693 694
	{
	int i,j;

G
Geoff Thorpe 已提交
695 696
	bn_check_top(a);
	if (n < 0) return 0;
697 698
	i=n/BN_BITS2;
	j=n%BN_BITS2;
G
Geoff Thorpe 已提交
699
	if (a->top <= i) return 0;
700
	return (int)(((a->d[i])>>j)&((BN_ULONG)1));
701 702
	}

U
Ulf Möller 已提交
703
int BN_mask_bits(BIGNUM *a, int n)
704 705 706
	{
	int b,w;

G
Geoff Thorpe 已提交
707 708
	bn_check_top(a);
	if (n < 0) return 0;
709

710 711
	w=n/BN_BITS2;
	b=n%BN_BITS2;
G
Geoff Thorpe 已提交
712
	if (w >= a->top) return 0;
713 714 715 716 717 718 719
	if (b == 0)
		a->top=w;
	else
		{
		a->top=w+1;
		a->d[w]&= ~(BN_MASK2<<b);
		}
720
	bn_correct_top(a);
721 722
	return(1);
	}
723

724 725 726 727 728 729 730 731
void BN_set_negative(BIGNUM *a, int b)
	{
	if (b && !BN_is_zero(a))
		a->neg = 1;
	else
		a->neg = 0;
	}

732
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
	{
	int i;
	BN_ULONG aa,bb;

	aa=a[n-1];
	bb=b[n-1];
	if (aa != bb) return((aa > bb)?1:-1);
	for (i=n-2; i>=0; i--)
		{
		aa=a[i];
		bb=b[i];
		if (aa != bb) return((aa > bb)?1:-1);
		}
	return(0);
	}
748

749 750 751 752 753 754 755
/* Here follows a specialised variants of bn_cmp_words().  It has the
   property of performing the operation on arrays of different sizes.
   The sizes of those arrays is expressed through cl, which is the
   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
   delta between the two lengths, calculated as len(a)-len(b).
   All lengths are the number of BN_ULONGs...  */

756 757 758 759 760 761 762 763
int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
	int cl, int dl)
	{
	int n,i;
	n = cl-1;

	if (dl < 0)
		{
764
		for (i=dl; i<0; i++)
765
			{
766
			if (b[n-i] != 0)
767 768 769 770 771 772 773 774 775 776 777 778 779
				return -1; /* a < b */
			}
		}
	if (dl > 0)
		{
		for (i=dl; i>0; i--)
			{
			if (a[n+i] != 0)
				return 1; /* a > b */
			}
		}
	return bn_cmp_words(a,b,cl);
	}
D
Dr. Stephen Henson 已提交
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831

/* 
 * Constant-time conditional swap of a and b.  
 * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
 * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
 * and that no more than nwords are used by either a or b.
 * a and b cannot be the same number
 */
void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
	{
	BN_ULONG t;
	int i;

	bn_wcheck_size(a, nwords);
	bn_wcheck_size(b, nwords);

	assert(a != b);
	assert((condition & (condition - 1)) == 0);
	assert(sizeof(BN_ULONG) >= sizeof(int));

	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;

	t = (a->top^b->top) & condition;
	a->top ^= t;
	b->top ^= t;

#define BN_CONSTTIME_SWAP(ind) \
	do { \
		t = (a->d[ind] ^ b->d[ind]) & condition; \
		a->d[ind] ^= t; \
		b->d[ind] ^= t; \
	} while (0)


	switch (nwords) {
	default:
		for (i = 10; i < nwords; i++) 
			BN_CONSTTIME_SWAP(i);
		/* Fallthrough */
	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
	case 1: BN_CONSTTIME_SWAP(0);
	}
#undef BN_CONSTTIME_SWAP
}
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856

/* Bits of security, see SP800-57 */

int BN_security_bits(int L, int N)
	{
	int secbits, bits;
	if (L >= 15360)
		secbits = 256;
	else if (L >= 7690)
		secbits = 192;
	else if (L >= 3072)
		secbits = 128;
	else if (L >= 2048)
		secbits = 112;
	else if (L >= 1024)
		secbits = 80;
	else
		return 0;
	if (N == -1)
		return secbits;
	bits = N / 2;
	if (bits < 80)
		return 0;
	return bits >= secbits ? secbits : bits;
	}
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982


void BN_zero_ex(BIGNUM *a)
	{
	a->top = 0;
	a->neg = 0;
	}

int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
	{
	return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
	}

int BN_is_zero(const BIGNUM *a)
	{
	return a->top == 0;
	}

int BN_is_one(const BIGNUM *a)
	{
	return BN_abs_is_word(a, 1) && !a->neg;
	}

int BN_is_word(const BIGNUM *a, const BN_ULONG w)
	{
	return BN_abs_is_word(a, w) && (!w || !a->neg);
	}

int BN_is_odd(const BIGNUM *a)
	{
	return (a->top > 0) && (a->d[0] & 1);
	}

int BN_is_negative(const BIGNUM *a)
	{
	return (a->neg != 0);
	}

int BN_to_montgomery(BIGNUM *r,const BIGNUM *a,	BN_MONT_CTX *mont, BN_CTX *ctx)
	{
	return BN_mod_mul_montgomery(r,a,&(mont->RR),mont,ctx);
	}

void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int n)
	{
	dest->d=b->d;
	dest->top=b->top;
	dest->dmax=b->dmax;
	dest->neg=b->neg;
	dest->flags=((dest->flags & BN_FLG_MALLOCED)
		|  (b->flags & ~BN_FLG_MALLOCED)
		|  BN_FLG_STATIC_DATA
		|  n);
	}

BN_GENCB *BN_GENCB_new(void)
	{
	BN_GENCB *ret;

	if ((ret=(BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) == NULL)
		{
		BNerr(BN_F_BN_GENCB_NEW,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}

	return ret;
	}

void BN_GENCB_free(BN_GENCB *cb)
	{
	if (cb == NULL) return;
	OPENSSL_free(cb);
	}

void BN_set_flags(BIGNUM *b, int n)
	{
	b->flags|=n;
	}

int BN_get_flags(const BIGNUM *b, int n)
	{
	return b->flags&n;
	}

/* Populate a BN_GENCB structure with an "old"-style callback */
void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback)(int, int, void *), void *cb_arg)
	{
	BN_GENCB *tmp_gencb = gencb;
	tmp_gencb->ver = 1;
	tmp_gencb->arg = cb_arg;
	tmp_gencb->cb.cb_1 = callback;
	}

/* Populate a BN_GENCB structure with a "new"-style callback */
void BN_GENCB_set(BN_GENCB *gencb, int (*callback)(int, int, BN_GENCB *), void *cb_arg)
	{
	BN_GENCB *tmp_gencb = gencb;
	tmp_gencb->ver = 2;
	tmp_gencb->arg = cb_arg;
	tmp_gencb->cb.cb_2 = callback;
	}

void *BN_GENCB_get_arg(BN_GENCB *cb)
	{
	return cb->arg;
	}


BIGNUM *bn_wexpand(BIGNUM *a, int words)
	{
	return (words <= a->dmax)?a:bn_expand2(a,words);
	}

void bn_correct_top(BIGNUM *a)
	{
	BN_ULONG *ftl;
	int tmp_top = a->top;

	if (tmp_top > 0)
		{
		for (ftl= &(a->d[tmp_top-1]); tmp_top > 0; tmp_top--)
			if (*(ftl--)) break;
		a->top = tmp_top;
		}
	bn_pollute(a);
	}