]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bn/bn_lib.c
Allow for dynamic base in Win64 FIPS module.
[thirdparty/openssl.git] / crypto / bn / bn_lib.c
CommitLineData
d02b48c6 1/* crypto/bn/bn_lib.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
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
bbb8de09
BM
59#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
7edfe674
DSH
64#define OPENSSL_FIPSAPI
65
bbb8de09 66#include <assert.h>
addb309a 67#include <limits.h>
d02b48c6
RE
68#include <stdio.h>
69#include "cryptlib.h"
70#include "bn_lcl.h"
71
03e389cf 72__fips_constseg
560b79cb 73const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
dfeab068 74
df11e1e9
GT
75/* This stuff appears to be completely unused, so is deprecated */
76#ifndef OPENSSL_NO_DEPRECATED
dfeab068
RE
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 */
775c63fc
UM
86static int bn_limit_bits=0;
87static int bn_limit_num=8; /* (1<<bn_limit_bits) */
88static int bn_limit_bits_low=0;
89static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
90static int bn_limit_bits_high=0;
91static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
92static int bn_limit_bits_mont=0;
93static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
dfeab068 94
6b691a5c 95void BN_set_params(int mult, int high, int low, int mont)
dfeab068
RE
96 {
97 if (mult >= 0)
98 {
27545970 99 if (mult > (int)(sizeof(int)*8)-1)
dfeab068
RE
100 mult=sizeof(int)*8-1;
101 bn_limit_bits=mult;
102 bn_limit_num=1<<mult;
103 }
104 if (high >= 0)
105 {
27545970 106 if (high > (int)(sizeof(int)*8)-1)
dfeab068
RE
107 high=sizeof(int)*8-1;
108 bn_limit_bits_high=high;
109 bn_limit_num_high=1<<high;
110 }
111 if (low >= 0)
112 {
27545970 113 if (low > (int)(sizeof(int)*8)-1)
dfeab068
RE
114 low=sizeof(int)*8-1;
115 bn_limit_bits_low=low;
116 bn_limit_num_low=1<<low;
117 }
118 if (mont >= 0)
119 {
27545970 120 if (mont > (int)(sizeof(int)*8)-1)
dfeab068
RE
121 mont=sizeof(int)*8-1;
122 bn_limit_bits_mont=mont;
123 bn_limit_num_mont=1<<mont;
124 }
125 }
126
6b691a5c 127int BN_get_params(int which)
dfeab068
RE
128 {
129 if (which == 0) return(bn_limit_bits);
130 else if (which == 1) return(bn_limit_bits_high);
131 else if (which == 2) return(bn_limit_bits_low);
132 else if (which == 3) return(bn_limit_bits_mont);
133 else return(0);
134 }
df11e1e9 135#endif
d02b48c6 136
98499135 137const BIGNUM *BN_value_one(void)
d02b48c6 138 {
f1455b30
AP
139 static const BN_ULONG data_one=1L;
140 static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
d02b48c6
RE
141
142 return(&const_one);
143 }
144
6b691a5c 145int BN_num_bits_word(BN_ULONG l)
d02b48c6 146 {
03e389cf 147 __fips_constseg
f1455b30 148 static const unsigned char bits[256]={
d02b48c6
RE
149 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
150 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
151 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
152 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
153 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
154 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
155 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
156 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
157 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
158 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
159 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
160 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
161 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
162 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
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 };
166
dfeab068 167#if defined(SIXTY_FOUR_BIT_LONG)
d02b48c6
RE
168 if (l & 0xffffffff00000000L)
169 {
170 if (l & 0xffff000000000000L)
171 {
172 if (l & 0xff00000000000000L)
173 {
dfeab068 174 return(bits[(int)(l>>56)]+56);
d02b48c6 175 }
dfeab068 176 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
177 }
178 else
179 {
180 if (l & 0x0000ff0000000000L)
181 {
dfeab068 182 return(bits[(int)(l>>40)]+40);
d02b48c6 183 }
dfeab068 184 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
185 }
186 }
187 else
188#else
189#ifdef SIXTY_FOUR_BIT
190 if (l & 0xffffffff00000000LL)
191 {
192 if (l & 0xffff000000000000LL)
193 {
194 if (l & 0xff00000000000000LL)
195 {
dfeab068 196 return(bits[(int)(l>>56)]+56);
d02b48c6 197 }
dfeab068 198 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
199 }
200 else
201 {
202 if (l & 0x0000ff0000000000LL)
203 {
dfeab068 204 return(bits[(int)(l>>40)]+40);
d02b48c6 205 }
dfeab068 206 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
207 }
208 }
209 else
210#endif
211#endif
212 {
213#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
214 if (l & 0xffff0000L)
215 {
216 if (l & 0xff000000L)
dfeab068
RE
217 return(bits[(int)(l>>24L)]+24);
218 else return(bits[(int)(l>>16L)]+16);
d02b48c6
RE
219 }
220 else
221#endif
222 {
4a47f556 223#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
d02b48c6 224 if (l & 0xff00L)
dfeab068 225 return(bits[(int)(l>>8)]+8);
d02b48c6
RE
226 else
227#endif
dfeab068 228 return(bits[(int)(l )] );
d02b48c6
RE
229 }
230 }
231 }
232
84c15db5 233int BN_num_bits(const BIGNUM *a)
d02b48c6 234 {
2bfd2c74 235 int i = a->top - 1;
dfeab068
RE
236 bn_check_top(a);
237
2bfd2c74
GT
238 if (BN_is_zero(a)) return 0;
239 return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
d02b48c6
RE
240 }
241
6b691a5c 242void BN_clear_free(BIGNUM *a)
d02b48c6 243 {
dfeab068
RE
244 int i;
245
d02b48c6 246 if (a == NULL) return;
2bfd2c74 247 bn_check_top(a);
d02b48c6
RE
248 if (a->d != NULL)
249 {
43d60164 250 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
dfeab068 251 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
26a3a48d 252 OPENSSL_free(a->d);
d02b48c6 253 }
dfeab068 254 i=BN_get_flags(a,BN_FLG_MALLOCED);
43d60164 255 OPENSSL_cleanse(a,sizeof(BIGNUM));
dfeab068 256 if (i)
26a3a48d 257 OPENSSL_free(a);
d02b48c6
RE
258 }
259
6b691a5c 260void BN_free(BIGNUM *a)
d02b48c6
RE
261 {
262 if (a == NULL) return;
2bfd2c74 263 bn_check_top(a);
dfeab068 264 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
26a3a48d 265 OPENSSL_free(a->d);
dfeab068 266 if (a->flags & BN_FLG_MALLOCED)
26a3a48d 267 OPENSSL_free(a);
2ae1ea37
GT
268 else
269 {
270#ifndef OPENSSL_NO_DEPRECATED
271 a->flags|=BN_FLG_FREE;
272#endif
273 a->d = NULL;
274 }
dfeab068
RE
275 }
276
6b691a5c 277void BN_init(BIGNUM *a)
dfeab068
RE
278 {
279 memset(a,0,sizeof(BIGNUM));
d870740c 280 bn_check_top(a);
d02b48c6
RE
281 }
282
6b691a5c 283BIGNUM *BN_new(void)
d02b48c6
RE
284 {
285 BIGNUM *ret;
d02b48c6 286
26a3a48d 287 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
dfeab068
RE
288 {
289 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
290 return(NULL);
291 }
292 ret->flags=BN_FLG_MALLOCED;
d02b48c6
RE
293 ret->top=0;
294 ret->neg=0;
2d978cbd 295 ret->dmax=0;
dfeab068 296 ret->d=NULL;
d870740c 297 bn_check_top(ret);
d02b48c6 298 return(ret);
d02b48c6
RE
299 }
300
020fc820
RL
301/* This is used both by bn_expand2() and bn_dup_expand() */
302/* The caller MUST check that words > b->dmax before calling this */
6343829a 303static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
d02b48c6 304 {
020fc820 305 BN_ULONG *A,*a = NULL;
e14d4443
UM
306 const BN_ULONG *B;
307 int i;
dfeab068 308
2bfd2c74
GT
309 bn_check_top(b);
310
152a689c
BM
311 if (words > (INT_MAX/(4*BN_BITS2)))
312 {
e5164b70 313 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
152a689c
BM
314 return NULL;
315 }
020fc820 316 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
d02b48c6 317 {
a08bcccc 318 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
020fc820
RL
319 return(NULL);
320 }
e042540f 321 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
020fc820
RL
322 if (A == NULL)
323 {
a08bcccc 324 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
020fc820
RL
325 return(NULL);
326 }
dfeab068 327#if 1
020fc820
RL
328 B=b->d;
329 /* Check if the previous number needs to be copied */
330 if (B != NULL)
331 {
020fc820
RL
332 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
333 {
334 /*
335 * The fact that the loop is unrolled
336 * 4-wise is a tribute to Intel. It's
337 * the one that doesn't have enough
338 * registers to accomodate more data.
339 * I'd unroll it 8-wise otherwise:-)
340 *
341 * <appro@fy.chalmers.se>
342 */
343 BN_ULONG a0,a1,a2,a3;
344 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
345 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
953937bd 346 }
020fc820 347 switch (b->top&3)
953937bd 348 {
020fc820
RL
349 case 3: A[2]=B[2];
350 case 2: A[1]=B[1];
351 case 1: A[0]=B[0];
a08bcccc
BM
352 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
353 * the switch table by doing a=top&3; a--; goto jump_table[a];
354 * which fails for top== 0 */
355 ;
953937bd 356 }
020fc820
RL
357 }
358
dfeab068 359#else
e042540f 360 memset(A,0,sizeof(BN_ULONG)*words);
020fc820 361 memcpy(A,b->d,sizeof(b->d[0])*b->top);
dfeab068
RE
362#endif
363
020fc820
RL
364 return(a);
365 }
dfeab068 366
020fc820
RL
367/* This is an internal function that can be used instead of bn_expand2()
368 * when there is a need to copy BIGNUMs instead of only expanding the
369 * data part, while still expanding them.
370 * Especially useful when needing to expand BIGNUMs that are declared
371 * 'const' and should therefore not be changed.
372 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
373 * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
374 * will allocate new memory for the BIGNUM data twice, and free it once,
375 * while bn_dup_expand() makes sure allocation is made only once.
376 */
377
e042540f 378#ifndef OPENSSL_NO_DEPRECATED
6343829a 379BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
020fc820
RL
380 {
381 BIGNUM *r = NULL;
382
2bfd2c74
GT
383 bn_check_top(b);
384
12593e6f
BM
385 /* This function does not work if
386 * words <= b->dmax && top < words
387 * because BN_dup() does not preserve 'dmax'!
388 * (But bn_dup_expand() is not used anywhere yet.)
389 */
2bfd2c74 390
020fc820
RL
391 if (words > b->dmax)
392 {
a08bcccc 393 BN_ULONG *a = bn_expand_internal(b, words);
020fc820
RL
394
395 if (a)
396 {
397 r = BN_new();
58f0f52e
BM
398 if (r)
399 {
400 r->top = b->top;
401 r->dmax = words;
402 r->neg = b->neg;
403 r->d = a;
404 }
405 else
406 {
407 /* r == NULL, BN_new failure */
408 OPENSSL_free(a);
409 }
020fc820 410 }
58f0f52e 411 /* If a == NULL, there was an error in allocation in
a08bcccc 412 bn_expand_internal(), and NULL should be returned */
020fc820
RL
413 }
414 else
415 {
416 r = BN_dup(b);
417 }
418
d870740c 419 bn_check_top(r);
020fc820
RL
420 return r;
421 }
e042540f 422#endif
020fc820
RL
423
424/* This is an internal function that should not be used in applications.
12593e6f 425 * It ensures that 'b' has enough room for a 'words' word number
33d4e690 426 * and initialises any unused part of b->d with leading zeros.
020fc820
RL
427 * It is mostly used by the various BIGNUM routines. If there is an error,
428 * NULL is returned. If not, 'b' is returned. */
429
6343829a 430BIGNUM *bn_expand2(BIGNUM *b, int words)
020fc820 431 {
2bfd2c74
GT
432 bn_check_top(b);
433
020fc820
RL
434 if (words > b->dmax)
435 {
a08bcccc 436 BN_ULONG *a = bn_expand_internal(b, words);
2bfd2c74
GT
437 if(!a) return NULL;
438 if(b->d) OPENSSL_free(b->d);
439 b->d=a;
440 b->dmax=words;
d02b48c6 441 }
2bfd2c74 442
e042540f
GT
443/* None of this should be necessary because of what b->top means! */
444#if 0
12593e6f 445 /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
2bfd2c74 446 if (b->top < b->dmax)
12593e6f 447 {
e042540f
GT
448 int i;
449 BN_ULONG *A = &(b->d[b->top]);
18384774 450 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
33d4e690
BM
451 {
452 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
453 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
454 }
18384774 455 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
33d4e690 456 A[0]=0;
18384774 457 assert(A == &(b->d[b->dmax]));
12593e6f 458 }
e042540f 459#endif
2bfd2c74 460 bn_check_top(b);
020fc820 461 return b;
d02b48c6
RE
462 }
463
84c15db5 464BIGNUM *BN_dup(const BIGNUM *a)
d02b48c6 465 {
2bfd2c74 466 BIGNUM *t;
d02b48c6 467
8d85b33e 468 if (a == NULL) return NULL;
dfeab068
RE
469 bn_check_top(a);
470
e0bf5c11 471 t = BN_new();
2bfd2c74
GT
472 if (t == NULL) return NULL;
473 if(!BN_copy(t, a))
474 {
e0bf5c11 475 BN_free(t);
2bfd2c74
GT
476 return NULL;
477 }
478 bn_check_top(t);
479 return t;
d02b48c6
RE
480 }
481
84c15db5 482BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
d02b48c6 483 {
58964a49 484 int i;
e14d4443
UM
485 BN_ULONG *A;
486 const BN_ULONG *B;
58964a49 487
dfeab068
RE
488 bn_check_top(b);
489
58964a49
RE
490 if (a == b) return(a);
491 if (bn_wexpand(a,b->top) == NULL) return(NULL);
492
493#if 1
494 A=a->d;
495 B=b->d;
e14d4443 496 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
58964a49 497 {
e14d4443
UM
498 BN_ULONG a0,a1,a2,a3;
499 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
500 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
58964a49 501 }
e14d4443 502 switch (b->top&3)
58964a49 503 {
e14d4443
UM
504 case 3: A[2]=B[2];
505 case 2: A[1]=B[1];
506 case 1: A[0]=B[0];
a08bcccc 507 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
58964a49
RE
508 }
509#else
d02b48c6 510 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
58964a49
RE
511#endif
512
d02b48c6
RE
513 a->top=b->top;
514 a->neg=b->neg;
d870740c 515 bn_check_top(a);
d02b48c6
RE
516 return(a);
517 }
518
78a0c1f1
BM
519void BN_swap(BIGNUM *a, BIGNUM *b)
520 {
521 int flags_old_a, flags_old_b;
522 BN_ULONG *tmp_d;
523 int tmp_top, tmp_dmax, tmp_neg;
524
657a9195
GT
525 bn_check_top(a);
526 bn_check_top(b);
527
78a0c1f1
BM
528 flags_old_a = a->flags;
529 flags_old_b = b->flags;
530
531 tmp_d = a->d;
532 tmp_top = a->top;
533 tmp_dmax = a->dmax;
534 tmp_neg = a->neg;
535
536 a->d = b->d;
537 a->top = b->top;
538 a->dmax = b->dmax;
539 a->neg = b->neg;
540
541 b->d = tmp_d;
542 b->top = tmp_top;
543 b->dmax = tmp_dmax;
544 b->neg = tmp_neg;
545
546 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
547 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
d870740c
GT
548 bn_check_top(a);
549 bn_check_top(b);
78a0c1f1
BM
550 }
551
6b691a5c 552void BN_clear(BIGNUM *a)
d02b48c6 553 {
657a9195 554 bn_check_top(a);
dfeab068 555 if (a->d != NULL)
2d978cbd 556 memset(a->d,0,a->dmax*sizeof(a->d[0]));
d02b48c6
RE
557 a->top=0;
558 a->neg=0;
559 }
560
020fc820 561BN_ULONG BN_get_word(const BIGNUM *a)
d02b48c6 562 {
9088d5f2
GT
563 if (a->top > 1)
564 return BN_MASK2;
afbe74d3 565 else if (a->top == 1)
9088d5f2 566 return a->d[0];
afbe74d3
GT
567 /* a->top == 0 */
568 return 0;
d02b48c6
RE
569 }
570
e042540f
GT
571int BN_set_word(BIGNUM *a, BN_ULONG w)
572 {
573 bn_check_top(a);
574 if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
575 a->neg = 0;
576 a->d[0] = w;
577 a->top = (w ? 1 : 0);
578 bn_check_top(a);
579 return(1);
580 }
d02b48c6 581
6343829a 582BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
d02b48c6
RE
583 {
584 unsigned int i,m;
585 unsigned int n;
586 BN_ULONG l;
d459e390 587 BIGNUM *bn = NULL;
d02b48c6 588
d459e390
GT
589 if (ret == NULL)
590 ret = bn = BN_new();
d02b48c6 591 if (ret == NULL) return(NULL);
657a9195 592 bn_check_top(ret);
d02b48c6
RE
593 l=0;
594 n=len;
595 if (n == 0)
596 {
597 ret->top=0;
598 return(ret);
599 }
d02b48c6
RE
600 i=((n-1)/BN_BYTES)+1;
601 m=((n-1)%(BN_BYTES));
6343829a 602 if (bn_wexpand(ret, (int)i) == NULL)
d459e390
GT
603 {
604 if (bn) BN_free(bn);
605 return NULL;
606 }
91616729
BM
607 ret->top=i;
608 ret->neg=0;
d459e390 609 while (n--)
d02b48c6
RE
610 {
611 l=(l<<8L)| *(s++);
612 if (m-- == 0)
613 {
614 ret->d[--i]=l;
615 l=0;
616 m=BN_BYTES-1;
617 }
618 }
619 /* need to call this due to clear byte at top if avoiding
620 * having the top bit set (-ve number) */
d870740c 621 bn_correct_top(ret);
d02b48c6
RE
622 return(ret);
623 }
624
625/* ignore negative */
8623f693 626int BN_bn2bin(const BIGNUM *a, unsigned char *to)
d02b48c6
RE
627 {
628 int n,i;
629 BN_ULONG l;
630
657a9195 631 bn_check_top(a);
d02b48c6 632 n=i=BN_num_bytes(a);
d459e390 633 while (i--)
d02b48c6
RE
634 {
635 l=a->d[i/BN_BYTES];
636 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
637 }
638 return(n);
639 }
640
84c15db5 641int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
d02b48c6
RE
642 {
643 int i;
644 BN_ULONG t1,t2,*ap,*bp;
645
dfeab068
RE
646 bn_check_top(a);
647 bn_check_top(b);
648
d02b48c6
RE
649 i=a->top-b->top;
650 if (i != 0) return(i);
651 ap=a->d;
652 bp=b->d;
653 for (i=a->top-1; i>=0; i--)
654 {
655 t1= ap[i];
656 t2= bp[i];
657 if (t1 != t2)
2bfd2c74 658 return((t1 > t2) ? 1 : -1);
d02b48c6
RE
659 }
660 return(0);
661 }
662
84c15db5 663int BN_cmp(const BIGNUM *a, const BIGNUM *b)
d02b48c6
RE
664 {
665 int i;
666 int gt,lt;
667 BN_ULONG t1,t2;
668
669 if ((a == NULL) || (b == NULL))
670 {
671 if (a != NULL)
672 return(-1);
673 else if (b != NULL)
674 return(1);
675 else
676 return(0);
677 }
dfeab068
RE
678
679 bn_check_top(a);
680 bn_check_top(b);
681
d02b48c6
RE
682 if (a->neg != b->neg)
683 {
684 if (a->neg)
685 return(-1);
686 else return(1);
687 }
688 if (a->neg == 0)
689 { gt=1; lt= -1; }
690 else { gt= -1; lt=1; }
691
692 if (a->top > b->top) return(gt);
693 if (a->top < b->top) return(lt);
694 for (i=a->top-1; i>=0; i--)
695 {
696 t1=a->d[i];
697 t2=b->d[i];
698 if (t1 > t2) return(gt);
699 if (t1 < t2) return(lt);
700 }
701 return(0);
702 }
703
6b691a5c 704int BN_set_bit(BIGNUM *a, int n)
d02b48c6 705 {
6343829a 706 int i,j,k;
d02b48c6 707
1a017330
UM
708 if (n < 0)
709 return 0;
710
d02b48c6
RE
711 i=n/BN_BITS2;
712 j=n%BN_BITS2;
58964a49
RE
713 if (a->top <= i)
714 {
dfeab068
RE
715 if (bn_wexpand(a,i+1) == NULL) return(0);
716 for(k=a->top; k<i+1; k++)
717 a->d[k]=0;
58964a49
RE
718 a->top=i+1;
719 }
d02b48c6 720
e14d4443 721 a->d[i]|=(((BN_ULONG)1)<<j);
d870740c 722 bn_check_top(a);
d02b48c6
RE
723 return(1);
724 }
725
6b691a5c 726int BN_clear_bit(BIGNUM *a, int n)
d02b48c6
RE
727 {
728 int i,j;
729
2bfd2c74
GT
730 bn_check_top(a);
731 if (n < 0) return 0;
1a017330 732
d02b48c6
RE
733 i=n/BN_BITS2;
734 j=n%BN_BITS2;
735 if (a->top <= i) return(0);
736
e14d4443 737 a->d[i]&=(~(((BN_ULONG)1)<<j));
d870740c 738 bn_correct_top(a);
d02b48c6
RE
739 return(1);
740 }
741
84c15db5 742int BN_is_bit_set(const BIGNUM *a, int n)
d02b48c6
RE
743 {
744 int i,j;
745
2bfd2c74
GT
746 bn_check_top(a);
747 if (n < 0) return 0;
d02b48c6
RE
748 i=n/BN_BITS2;
749 j=n%BN_BITS2;
2bfd2c74 750 if (a->top <= i) return 0;
a68c7b91 751 return (int)(((a->d[i])>>j)&((BN_ULONG)1));
d02b48c6
RE
752 }
753
6b691a5c 754int BN_mask_bits(BIGNUM *a, int n)
d02b48c6
RE
755 {
756 int b,w;
757
2bfd2c74
GT
758 bn_check_top(a);
759 if (n < 0) return 0;
1a017330 760
d02b48c6
RE
761 w=n/BN_BITS2;
762 b=n%BN_BITS2;
2bfd2c74 763 if (w >= a->top) return 0;
d02b48c6
RE
764 if (b == 0)
765 a->top=w;
766 else
767 {
768 a->top=w+1;
769 a->d[w]&= ~(BN_MASK2<<b);
d02b48c6 770 }
d870740c 771 bn_correct_top(a);
d02b48c6
RE
772 return(1);
773 }
dfeab068 774
ff22e913
NL
775void 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
cbd48ba6 783int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
dfeab068
RE
784 {
785 int i;
786 BN_ULONG aa,bb;
787
788 aa=a[n-1];
789 bb=b[n-1];
790 if (aa != bb) return((aa > bb)?1:-1);
791 for (i=n-2; i>=0; i--)
792 {
793 aa=a[i];
794 bb=b[i];
795 if (aa != bb) return((aa > bb)?1:-1);
796 }
797 return(0);
798 }
52a1bab2 799
c21c35e6
RL
800/* Here follows a specialised variants of bn_cmp_words(). It has the
801 property of performing the operation on arrays of different sizes.
802 The sizes of those arrays is expressed through cl, which is the
803 common length ( basicall, min(len(a),len(b)) ), and dl, which is the
804 delta between the two lengths, calculated as len(a)-len(b).
805 All lengths are the number of BN_ULONGs... */
806
52a1bab2
UM
807int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
808 int cl, int dl)
809 {
810 int n,i;
811 n = cl-1;
812
813 if (dl < 0)
814 {
b26f84cb 815 for (i=dl; i<0; i++)
52a1bab2 816 {
b26f84cb 817 if (b[n-i] != 0)
52a1bab2
UM
818 return -1; /* a < b */
819 }
820 }
821 if (dl > 0)
822 {
823 for (i=dl; i>0; i--)
824 {
825 if (a[n+i] != 0)
826 return 1; /* a > b */
827 }
828 }
829 return bn_cmp_words(a,b,cl);
830 }