summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_lib.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libcrypto/bn/bn_lib.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/bn/bn_lib.c')
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c611
1 files changed, 611 insertions, 0 deletions
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
new file mode 100644
index 0000000000..bfe7628ad4
--- /dev/null
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -0,0 +1,611 @@
1/* crypto/bn/bn_lib.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include "bn_lcl.h"
62
63char *BN_version="Big Number part of SSLeay 0.9.0b 29-Jun-1998";
64
65BIGNUM *BN_value_one()
66 {
67 static BN_ULONG data_one=1L;
68 static BIGNUM const_one={&data_one,1,1,0};
69
70 return(&const_one);
71 }
72
73char *BN_options()
74 {
75 static int init=0;
76 static char data[16];
77
78 if (!init)
79 {
80 init++;
81#ifdef BN_LLONG
82 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
83 (int)sizeof(BN_ULONG)*8);
84#else
85 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
86 (int)sizeof(BN_ULONG)*8);
87#endif
88 }
89 return(data);
90 }
91
92int BN_num_bits_word(l)
93BN_ULONG l;
94 {
95 static char bits[256]={
96 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
97 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
98 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
99 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
100 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
101 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
102 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
104 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
105 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
106 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
107 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
108 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
109 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
110 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
111 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
112 };
113
114#ifdef SIXTY_FOUR_BIT_LONG
115 if (l & 0xffffffff00000000L)
116 {
117 if (l & 0xffff000000000000L)
118 {
119 if (l & 0xff00000000000000L)
120 {
121 return(bits[l>>56]+56);
122 }
123 else return(bits[l>>48]+48);
124 }
125 else
126 {
127 if (l & 0x0000ff0000000000L)
128 {
129 return(bits[l>>40]+40);
130 }
131 else return(bits[l>>32]+32);
132 }
133 }
134 else
135#else
136#ifdef SIXTY_FOUR_BIT
137 if (l & 0xffffffff00000000LL)
138 {
139 if (l & 0xffff000000000000LL)
140 {
141 if (l & 0xff00000000000000LL)
142 {
143 return(bits[l>>56]+56);
144 }
145 else return(bits[l>>48]+48);
146 }
147 else
148 {
149 if (l & 0x0000ff0000000000LL)
150 {
151 return(bits[l>>40]+40);
152 }
153 else return(bits[l>>32]+32);
154 }
155 }
156 else
157#endif
158#endif
159 {
160#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
161 if (l & 0xffff0000L)
162 {
163 if (l & 0xff000000L)
164 return(bits[l>>24L]+24);
165 else return(bits[l>>16L]+16);
166 }
167 else
168#endif
169 {
170#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
171 if (l & 0xff00L)
172 return(bits[l>>8]+8);
173 else
174#endif
175 return(bits[l ] );
176 }
177 }
178 }
179
180int BN_num_bits(a)
181BIGNUM *a;
182 {
183 BN_ULONG l;
184 int i;
185
186 if (a->top == 0) return(0);
187 l=a->d[a->top-1];
188 i=(a->top-1)*BN_BITS2;
189 if (l == 0)
190 {
191#if !defined(NO_STDIO) && !defined(WIN16)
192 fprintf(stderr,"BAD TOP VALUE\n");
193#endif
194 abort();
195 }
196 return(i+BN_num_bits_word(l));
197 }
198
199void BN_clear_free(a)
200BIGNUM *a;
201 {
202 if (a == NULL) return;
203 if (a->d != NULL)
204 {
205 memset(a->d,0,a->max*sizeof(a->d[0]));
206 Free(a->d);
207 }
208 memset(a,0,sizeof(BIGNUM));
209 Free(a);
210 }
211
212void BN_free(a)
213BIGNUM *a;
214 {
215 if (a == NULL) return;
216 if (a->d != NULL) Free(a->d);
217 Free(a);
218 }
219
220BIGNUM *BN_new()
221 {
222 BIGNUM *ret;
223 BN_ULONG *p;
224
225 ret=(BIGNUM *)Malloc(sizeof(BIGNUM));
226 if (ret == NULL) goto err;
227 ret->top=0;
228 ret->neg=0;
229 ret->max=(BN_DEFAULT_BITS/BN_BITS2);
230 p=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(ret->max+1));
231 if (p == NULL) goto err;
232 ret->d=p;
233
234 memset(p,0,(ret->max+1)*sizeof(p[0]));
235 return(ret);
236err:
237 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
238 return(NULL);
239 }
240
241BN_CTX *BN_CTX_new()
242 {
243 BN_CTX *ret;
244 BIGNUM *n;
245 int i,j;
246
247 ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
248 if (ret == NULL) goto err2;
249
250 for (i=0; i<BN_CTX_NUM; i++)
251 {
252 n=BN_new();
253 if (n == NULL) goto err;
254 ret->bn[i]=n;
255 }
256
257 /* There is actually an extra one, this is for debugging my
258 * stuff */
259 ret->bn[BN_CTX_NUM]=NULL;
260
261 ret->tos=0;
262 return(ret);
263err:
264 for (j=0; j<i; j++)
265 BN_free(ret->bn[j]);
266 Free(ret);
267err2:
268 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
269 return(NULL);
270 }
271
272void BN_CTX_free(c)
273BN_CTX *c;
274 {
275 int i;
276
277 for (i=0; i<BN_CTX_NUM; i++)
278 BN_clear_free(c->bn[i]);
279 Free(c);
280 }
281
282BIGNUM *bn_expand2(b, words)
283BIGNUM *b;
284int words;
285 {
286 BN_ULONG *p;
287
288 if (words > b->max)
289 {
290 p=(BN_ULONG *)Realloc(b->d,sizeof(BN_ULONG)*(words+1));
291 if (p == NULL)
292 {
293 BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
294 return(NULL);
295 }
296 b->d=p;
297 memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG));
298 b->max=words;
299 }
300 return(b);
301 }
302
303BIGNUM *BN_dup(a)
304BIGNUM *a;
305 {
306 BIGNUM *r;
307
308 r=BN_new();
309 if (r == NULL) return(NULL);
310 return((BIGNUM *)BN_copy(r,a));
311 }
312
313BIGNUM *BN_copy(a, b)
314BIGNUM *a;
315BIGNUM *b;
316 {
317 int i;
318 BN_ULONG *A,*B;
319
320 if (a == b) return(a);
321 if (bn_wexpand(a,b->top) == NULL) return(NULL);
322
323#if 1
324 A=a->d;
325 B=b->d;
326 for (i=b->top&(~7); i>0; i-=8)
327 {
328 A[0]=B[0];
329 A[1]=B[1];
330 A[2]=B[2];
331 A[3]=B[3];
332 A[4]=B[4];
333 A[5]=B[5];
334 A[6]=B[6];
335 A[7]=B[7];
336 A+=8;
337 B+=8;
338 }
339 switch (b->top&7)
340 {
341 case 7:
342 A[6]=B[6];
343 case 6:
344 A[5]=B[5];
345 case 5:
346 A[4]=B[4];
347 case 4:
348 A[3]=B[3];
349 case 3:
350 A[2]=B[2];
351 case 2:
352 A[1]=B[1];
353 case 1:
354 A[0]=B[0];
355 }
356#else
357 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
358#endif
359
360/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
361 a->top=b->top;
362 if (a->top == 0)
363 a->d[0]=0;
364 a->neg=b->neg;
365 return(a);
366 }
367
368void BN_clear(a)
369BIGNUM *a;
370 {
371 memset(a->d,0,a->max*sizeof(a->d[0]));
372 a->top=0;
373 a->neg=0;
374 }
375
376unsigned long BN_get_word(a)
377BIGNUM *a;
378 {
379 int i,n;
380 unsigned long ret=0;
381
382 n=BN_num_bytes(a);
383 if (n > sizeof(unsigned long))
384#ifdef SIXTY_FOUR_BIT_LONG
385 return(BN_MASK2);
386#else
387 return(0xFFFFFFFFL);
388#endif
389 for (i=a->top-1; i>=0; i--)
390 {
391#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
392 ret<<=BN_BITS4; /* stops the compiler complaining */
393 ret<<=BN_BITS4;
394#endif
395 ret|=a->d[i];
396 }
397 return(ret);
398 }
399
400int BN_set_word(a,w)
401BIGNUM *a;
402unsigned long w;
403 {
404 int i,n;
405 if (bn_expand(a,sizeof(unsigned long)*8) == NULL) return(0);
406
407 n=sizeof(unsigned long)/BN_BYTES;
408 a->neg=0;
409 a->top=0;
410 a->d[0]=(BN_ULONG)w&BN_MASK2;
411 if (a->d[0] != 0) a->top=1;
412 for (i=1; i<n; i++)
413 {
414 /* the following is done instead of
415 * w>>=BN_BITS2 so compilers don't complain
416 * on builds where sizeof(long) == BN_TYPES */
417#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
418 w>>=BN_BITS4;
419 w>>=BN_BITS4;
420#endif
421 a->d[i]=(BN_ULONG)w&BN_MASK2;
422 if (a->d[i] != 0) a->top=i+1;
423 }
424 return(1);
425 }
426
427/* ignore negative */
428BIGNUM *BN_bin2bn(s, len, ret)
429unsigned char *s;
430int len;
431BIGNUM *ret;
432 {
433 unsigned int i,m;
434 unsigned int n;
435 BN_ULONG l;
436
437 if (ret == NULL) ret=BN_new();
438 if (ret == NULL) return(NULL);
439 l=0;
440 n=len;
441 if (n == 0)
442 {
443 ret->top=0;
444 return(ret);
445 }
446 if (bn_expand(ret,(int)(n+2)*8) == NULL)
447 return(NULL);
448 i=((n-1)/BN_BYTES)+1;
449 m=((n-1)%(BN_BYTES));
450 ret->top=i;
451 while (n-- > 0)
452 {
453 l=(l<<8L)| *(s++);
454 if (m-- == 0)
455 {
456 ret->d[--i]=l;
457 l=0;
458 m=BN_BYTES-1;
459 }
460 }
461 /* need to call this due to clear byte at top if avoiding
462 * having the top bit set (-ve number) */
463 bn_fix_top(ret);
464 return(ret);
465 }
466
467/* ignore negative */
468int BN_bn2bin(a, to)
469BIGNUM *a;
470unsigned char *to;
471 {
472 int n,i;
473 BN_ULONG l;
474
475 n=i=BN_num_bytes(a);
476 while (i-- > 0)
477 {
478 l=a->d[i/BN_BYTES];
479 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
480 }
481 return(n);
482 }
483
484int BN_ucmp(a, b)
485BIGNUM *a;
486BIGNUM *b;
487 {
488 int i;
489 BN_ULONG t1,t2,*ap,*bp;
490
491 i=a->top-b->top;
492 if (i != 0) return(i);
493 ap=a->d;
494 bp=b->d;
495 for (i=a->top-1; i>=0; i--)
496 {
497 t1= ap[i];
498 t2= bp[i];
499 if (t1 != t2)
500 return(t1 > t2?1:-1);
501 }
502 return(0);
503 }
504
505int BN_cmp(a, b)
506BIGNUM *a;
507BIGNUM *b;
508 {
509 int i;
510 int gt,lt;
511 BN_ULONG t1,t2;
512
513 if ((a == NULL) || (b == NULL))
514 {
515 if (a != NULL)
516 return(-1);
517 else if (b != NULL)
518 return(1);
519 else
520 return(0);
521 }
522 if (a->neg != b->neg)
523 {
524 if (a->neg)
525 return(-1);
526 else return(1);
527 }
528 if (a->neg == 0)
529 { gt=1; lt= -1; }
530 else { gt= -1; lt=1; }
531
532 if (a->top > b->top) return(gt);
533 if (a->top < b->top) return(lt);
534 for (i=a->top-1; i>=0; i--)
535 {
536 t1=a->d[i];
537 t2=b->d[i];
538 if (t1 > t2) return(gt);
539 if (t1 < t2) return(lt);
540 }
541 return(0);
542 }
543
544int BN_set_bit(a, n)
545BIGNUM *a;
546int n;
547 {
548 int i,j;
549
550 i=n/BN_BITS2;
551 j=n%BN_BITS2;
552 if (a->top <= i)
553 {
554 if (bn_expand(a,n) == NULL) return(0);
555 a->top=i+1;
556 }
557
558 a->d[i]|=(1L<<j);
559 return(1);
560 }
561
562int BN_clear_bit(a, n)
563BIGNUM *a;
564int n;
565 {
566 int i,j;
567
568 i=n/BN_BITS2;
569 j=n%BN_BITS2;
570 if (a->top <= i) return(0);
571
572 a->d[i]&=(~(1L<<j));
573 return(1);
574 }
575
576int BN_is_bit_set(a, n)
577BIGNUM *a;
578int n;
579 {
580 int i,j;
581
582 if (n < 0) return(0);
583 i=n/BN_BITS2;
584 j=n%BN_BITS2;
585 if (a->top <= i) return(0);
586 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
587 }
588
589int BN_mask_bits(a,n)
590BIGNUM *a;
591int n;
592 {
593 int b,w;
594
595 w=n/BN_BITS2;
596 b=n%BN_BITS2;
597 if (w >= a->top) return(0);
598 if (b == 0)
599 a->top=w;
600 else
601 {
602 a->top=w+1;
603 a->d[w]&= ~(BN_MASK2<<b);
604 while ((w >= 0) && (a->d[w] == 0))
605 {
606 a->top--;
607 w--;
608 }
609 }
610 return(1);
611 }