summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn
diff options
context:
space:
mode:
authormarkus <>2002-09-05 12:51:50 +0000
committermarkus <>2002-09-05 12:51:50 +0000
commit15b5d84f9da2ce4bfae8580e56e34a859f74ad71 (patch)
treebf939e82d7fd73cc8a01cf6959002209972091bc /src/lib/libcrypto/bn
parent027351f729b9e837200dae6e1520cda6577ab930 (diff)
downloadopenbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.gz
openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.bz2
openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.zip
import openssl-0.9.7-beta1
Diffstat (limited to 'src/lib/libcrypto/bn')
-rw-r--r--src/lib/libcrypto/bn/asm/bn-586.pl295
-rw-r--r--src/lib/libcrypto/bn/asm/pa-risc2.s2024
-rw-r--r--src/lib/libcrypto/bn/asm/pa-risc2W.s2
-rw-r--r--src/lib/libcrypto/bn/bn.h290
-rw-r--r--src/lib/libcrypto/bn/bn_add.c206
-rw-r--r--src/lib/libcrypto/bn/bn_asm.c178
-rw-r--r--src/lib/libcrypto/bn/bn_blind.c47
-rw-r--r--src/lib/libcrypto/bn/bn_ctx.c17
-rw-r--r--src/lib/libcrypto/bn/bn_div.c221
-rw-r--r--src/lib/libcrypto/bn/bn_err.c142
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c600
-rw-r--r--src/lib/libcrypto/bn/bn_exp2.c382
-rw-r--r--src/lib/libcrypto/bn/bn_gcd.c389
-rw-r--r--src/lib/libcrypto/bn/bn_lcl.h291
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c571
-rw-r--r--src/lib/libcrypto/bn/bn_mod.c251
-rw-r--r--src/lib/libcrypto/bn/bn_mont.c335
-rw-r--r--src/lib/libcrypto/bn/bn_mpi.c11
-rw-r--r--src/lib/libcrypto/bn/bn_mul.c1158
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c459
-rw-r--r--src/lib/libcrypto/bn/bn_prime.h4
-rw-r--r--src/lib/libcrypto/bn/bn_prime.pl71
-rw-r--r--src/lib/libcrypto/bn/bn_print.c67
-rw-r--r--src/lib/libcrypto/bn/bn_rand.c216
-rw-r--r--src/lib/libcrypto/bn/bn_recp.c183
-rw-r--r--src/lib/libcrypto/bn/bn_shift.c27
-rw-r--r--src/lib/libcrypto/bn/bn_sqr.c214
-rw-r--r--src/lib/libcrypto/bn/bn_word.c47
28 files changed, 6630 insertions, 2068 deletions
diff --git a/src/lib/libcrypto/bn/asm/bn-586.pl b/src/lib/libcrypto/bn/asm/bn-586.pl
index 19d425ee96..33f6125920 100644
--- a/src/lib/libcrypto/bn/asm/bn-586.pl
+++ b/src/lib/libcrypto/bn/asm/bn-586.pl
@@ -1,18 +1,17 @@
1#!/usr/bin/perl
2#
3
4#!/usr/local/bin/perl 1#!/usr/local/bin/perl
5 2
6push(@INC,"perlasm","../../perlasm"); 3push(@INC,"perlasm","../../perlasm");
7require "x86asm.pl"; 4require "x86asm.pl";
8 5
9&asm_init($ARGV[0],"bn-586.pl"); 6&asm_init($ARGV[0],$0);
10 7
11&bn_mul_add_words("bn_mul_add_words"); 8&bn_mul_add_words("bn_mul_add_words");
12&bn_mul_words("bn_mul_words"); 9&bn_mul_words("bn_mul_words");
13&bn_sqr_words("bn_sqr_words"); 10&bn_sqr_words("bn_sqr_words");
14&bn_div64("bn_div64"); 11&bn_div_words("bn_div_words");
15&bn_add_words("bn_add_words"); 12&bn_add_words("bn_add_words");
13&bn_sub_words("bn_sub_words");
14&bn_sub_part_words("bn_sub_part_words");
16 15
17&asm_finish(); 16&asm_finish();
18 17
@@ -228,7 +227,7 @@ sub bn_sqr_words
228 &function_end($name); 227 &function_end($name);
229 } 228 }
230 229
231sub bn_div64 230sub bn_div_words
232 { 231 {
233 local($name)=@_; 232 local($name)=@_;
234 233
@@ -302,12 +301,292 @@ sub bn_add_words
302 &add($tmp1,$tmp2); 301 &add($tmp1,$tmp2);
303 &adc($c,0); 302 &adc($c,0);
304 &dec($num) if ($i != 6); 303 &dec($num) if ($i != 6);
305 &mov(&DWP($i*4,$r,"",0),$tmp1); # *a 304 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
306 &jz(&label("aw_end")) if ($i != 6); 305 &jz(&label("aw_end")) if ($i != 6);
307 } 306 }
308 &set_label("aw_end",0); 307 &set_label("aw_end",0);
309 308
310 &mov("eax",$c); 309# &mov("eax",$c); # $c is "eax"
310
311 &function_end($name);
312 }
313
314sub bn_sub_words
315 {
316 local($name)=@_;
317
318 &function_begin($name,"");
319
320 &comment("");
321 $a="esi";
322 $b="edi";
323 $c="eax";
324 $r="ebx";
325 $tmp1="ecx";
326 $tmp2="edx";
327 $num="ebp";
328
329 &mov($r,&wparam(0)); # get r
330 &mov($a,&wparam(1)); # get a
331 &mov($b,&wparam(2)); # get b
332 &mov($num,&wparam(3)); # get num
333 &xor($c,$c); # clear carry
334 &and($num,0xfffffff8); # num / 8
335
336 &jz(&label("aw_finish"));
337
338 &set_label("aw_loop",0);
339 for ($i=0; $i<8; $i++)
340 {
341 &comment("Round $i");
342
343 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
344 &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
345 &sub($tmp1,$c);
346 &mov($c,0);
347 &adc($c,$c);
348 &sub($tmp1,$tmp2);
349 &adc($c,0);
350 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
351 }
352
353 &comment("");
354 &add($a,32);
355 &add($b,32);
356 &add($r,32);
357 &sub($num,8);
358 &jnz(&label("aw_loop"));
359
360 &set_label("aw_finish",0);
361 &mov($num,&wparam(3)); # get num
362 &and($num,7);
363 &jz(&label("aw_end"));
364
365 for ($i=0; $i<7; $i++)
366 {
367 &comment("Tail Round $i");
368 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
369 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
370 &sub($tmp1,$c);
371 &mov($c,0);
372 &adc($c,$c);
373 &sub($tmp1,$tmp2);
374 &adc($c,0);
375 &dec($num) if ($i != 6);
376 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
377 &jz(&label("aw_end")) if ($i != 6);
378 }
379 &set_label("aw_end",0);
380
381# &mov("eax",$c); # $c is "eax"
382
383 &function_end($name);
384 }
385
386sub bn_sub_part_words
387 {
388 local($name)=@_;
389
390 &function_begin($name,"");
391
392 &comment("");
393 $a="esi";
394 $b="edi";
395 $c="eax";
396 $r="ebx";
397 $tmp1="ecx";
398 $tmp2="edx";
399 $num="ebp";
400
401 &mov($r,&wparam(0)); # get r
402 &mov($a,&wparam(1)); # get a
403 &mov($b,&wparam(2)); # get b
404 &mov($num,&wparam(3)); # get num
405 &xor($c,$c); # clear carry
406 &and($num,0xfffffff8); # num / 8
407
408 &jz(&label("aw_finish"));
409
410 &set_label("aw_loop",0);
411 for ($i=0; $i<8; $i++)
412 {
413 &comment("Round $i");
414
415 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
416 &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
417 &sub($tmp1,$c);
418 &mov($c,0);
419 &adc($c,$c);
420 &sub($tmp1,$tmp2);
421 &adc($c,0);
422 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
423 }
424
425 &comment("");
426 &add($a,32);
427 &add($b,32);
428 &add($r,32);
429 &sub($num,8);
430 &jnz(&label("aw_loop"));
431
432 &set_label("aw_finish",0);
433 &mov($num,&wparam(3)); # get num
434 &and($num,7);
435 &jz(&label("aw_end"));
436
437 for ($i=0; $i<7; $i++)
438 {
439 &comment("Tail Round $i");
440 &mov($tmp1,&DWP(0,$a,"",0)); # *a
441 &mov($tmp2,&DWP(0,$b,"",0));# *b
442 &sub($tmp1,$c);
443 &mov($c,0);
444 &adc($c,$c);
445 &sub($tmp1,$tmp2);
446 &adc($c,0);
447 &mov(&DWP(0,$r,"",0),$tmp1); # *r
448 &add($a, 4);
449 &add($b, 4);
450 &add($r, 4);
451 &dec($num) if ($i != 6);
452 &jz(&label("aw_end")) if ($i != 6);
453 }
454 &set_label("aw_end",0);
455
456 &cmp(&wparam(4),0);
457 &je(&label("pw_end"));
458
459 &mov($num,&wparam(4)); # get dl
460 &cmp($num,0);
461 &je(&label("pw_end"));
462 &jge(&label("pw_pos"));
463
464 &comment("pw_neg");
465 &mov($tmp2,0);
466 &sub($tmp2,$num);
467 &mov($num,$tmp2);
468 &and($num,0xfffffff8); # num / 8
469 &jz(&label("pw_neg_finish"));
470
471 &set_label("pw_neg_loop",0);
472 for ($i=0; $i<8; $i++)
473 {
474 &comment("dl<0 Round $i");
475
476 &mov($tmp1,0);
477 &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
478 &sub($tmp1,$c);
479 &mov($c,0);
480 &adc($c,$c);
481 &sub($tmp1,$tmp2);
482 &adc($c,0);
483 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
484 }
485
486 &comment("");
487 &add($b,32);
488 &add($r,32);
489 &sub($num,8);
490 &jnz(&label("pw_neg_loop"));
491
492 &set_label("pw_neg_finish",0);
493 &mov($tmp2,&wparam(4)); # get dl
494 &mov($num,0);
495 &sub($num,$tmp2);
496 &and($num,7);
497 &jz(&label("pw_end"));
498
499 for ($i=0; $i<7; $i++)
500 {
501 &comment("dl<0 Tail Round $i");
502 &mov($tmp1,0);
503 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
504 &sub($tmp1,$c);
505 &mov($c,0);
506 &adc($c,$c);
507 &sub($tmp1,$tmp2);
508 &adc($c,0);
509 &dec($num) if ($i != 6);
510 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
511 &jz(&label("pw_end")) if ($i != 6);
512 }
513
514 &jmp(&label("pw_end"));
515
516 &set_label("pw_pos",0);
517
518 &and($num,0xfffffff8); # num / 8
519 &jz(&label("pw_pos_finish"));
520
521 &set_label("pw_pos_loop",0);
522
523 for ($i=0; $i<8; $i++)
524 {
525 &comment("dl>0 Round $i");
526
527 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
528 &sub($tmp1,$c);
529 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
530 &jnc(&label("pw_nc".$i));
531 }
532
533 &comment("");
534 &add($a,32);
535 &add($r,32);
536 &sub($num,8);
537 &jnz(&label("pw_pos_loop"));
538
539 &set_label("pw_pos_finish",0);
540 &mov($num,&wparam(4)); # get dl
541 &and($num,7);
542 &jz(&label("pw_end"));
543
544 for ($i=0; $i<7; $i++)
545 {
546 &comment("dl>0 Tail Round $i");
547 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
548 &sub($tmp1,$c);
549 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
550 &jnc(&label("pw_tail_nc".$i));
551 &dec($num) if ($i != 6);
552 &jz(&label("pw_end")) if ($i != 6);
553 }
554 &mov($c,1);
555 &jmp(&label("pw_end"));
556
557 &set_label("pw_nc_loop",0);
558 for ($i=0; $i<8; $i++)
559 {
560 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
561 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
562 &set_label("pw_nc".$i,0);
563 }
564
565 &comment("");
566 &add($a,32);
567 &add($r,32);
568 &sub($num,8);
569 &jnz(&label("pw_nc_loop"));
570
571 &mov($num,&wparam(4)); # get dl
572 &and($num,7);
573 &jz(&label("pw_nc_end"));
574
575 for ($i=0; $i<7; $i++)
576 {
577 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
578 &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
579 &set_label("pw_tail_nc".$i,0);
580 &dec($num) if ($i != 6);
581 &jz(&label("pw_nc_end")) if ($i != 6);
582 }
583
584 &set_label("pw_nc_end",0);
585 &mov($c,0);
586
587 &set_label("pw_end",0);
588
589# &mov("eax",$c); # $c is "eax"
311 590
312 &function_end($name); 591 &function_end($name);
313 } 592 }
diff --git a/src/lib/libcrypto/bn/asm/pa-risc2.s b/src/lib/libcrypto/bn/asm/pa-risc2.s
index c2725996a4..af9730d062 100644
--- a/src/lib/libcrypto/bn/asm/pa-risc2.s
+++ b/src/lib/libcrypto/bn/asm/pa-risc2.s
@@ -1,416 +1,1618 @@
1 .SPACE $PRIVATE$ 1;
2 .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 2; PA-RISC 2.0 implementation of bn_asm code, based on the
3 .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 3; 64-bit version of the code. This code is effectively the
4 .SPACE $TEXT$ 4; same as the 64-bit version except the register model is
5 .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 5; slightly different given all values must be 32-bit between
6 .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY 6; function calls. Thus the 64-bit return values are returned
7 .IMPORT $global$,DATA 7; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
8 .IMPORT $$dyncall,MILLICODE 8;
9; gcc_compiled.: 9;
10 .SPACE $TEXT$ 10; This code is approximately 2x faster than the C version
11 .SUBSPA $CODE$ 11; for RSA/DSA.
12 12;
13 .align 4 13; See http://devresource.hp.com/ for more details on the PA-RISC
14 .EXPORT bn_mul_add_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR 14; architecture. Also see the book "PA-RISC 2.0 Architecture"
15; by Gerry Kane for information on the instruction set architecture.
16;
17; Code written by Chris Ruemmler (with some help from the HP C
18; compiler).
19;
20; The code compiles with HP's assembler
21;
22
23 .level 2.0N
24 .space $TEXT$
25 .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
26
27;
28; Global Register definitions used for the routines.
29;
30; Some information about HP's runtime architecture for 32-bits.
31;
32; "Caller save" means the calling function must save the register
33; if it wants the register to be preserved.
34; "Callee save" means if a function uses the register, it must save
35; the value before using it.
36;
37; For the floating point registers
38;
39; "caller save" registers: fr4-fr11, fr22-fr31
40; "callee save" registers: fr12-fr21
41; "special" registers: fr0-fr3 (status and exception registers)
42;
43; For the integer registers
44; value zero : r0
45; "caller save" registers: r1,r19-r26
46; "callee save" registers: r3-r18
47; return register : r2 (rp)
48; return values ; r28,r29 (ret0,ret1)
49; Stack pointer ; r30 (sp)
50; millicode return ptr ; r31 (also a caller save register)
51
52
53;
54; Arguments to the routines
55;
56r_ptr .reg %r26
57a_ptr .reg %r25
58b_ptr .reg %r24
59num .reg %r24
60n .reg %r23
61
62;
63; Note that the "w" argument for bn_mul_add_words and bn_mul_words
64; is passed on the stack at a delta of -56 from the top of stack
65; as the routine is entered.
66;
67
68;
69; Globals used in some routines
70;
71
72top_overflow .reg %r23
73high_mask .reg %r22 ; value 0xffffffff80000000L
74
75
76;------------------------------------------------------------------------------
77;
78; bn_mul_add_words
79;
80;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr,
81; int num, BN_ULONG w)
82;
83; arg0 = r_ptr
84; arg1 = a_ptr
85; arg3 = num
86; -56(sp) = w
87;
88; Local register definitions
89;
90
91fm1 .reg %fr22
92fm .reg %fr23
93ht_temp .reg %fr24
94ht_temp_1 .reg %fr25
95lt_temp .reg %fr26
96lt_temp_1 .reg %fr27
97fm1_1 .reg %fr28
98fm_1 .reg %fr29
99
100fw_h .reg %fr7L
101fw_l .reg %fr7R
102fw .reg %fr7
103
104fht_0 .reg %fr8L
105flt_0 .reg %fr8R
106t_float_0 .reg %fr8
107
108fht_1 .reg %fr9L
109flt_1 .reg %fr9R
110t_float_1 .reg %fr9
111
112tmp_0 .reg %r31
113tmp_1 .reg %r21
114m_0 .reg %r20
115m_1 .reg %r19
116ht_0 .reg %r1
117ht_1 .reg %r3
118lt_0 .reg %r4
119lt_1 .reg %r5
120m1_0 .reg %r6
121m1_1 .reg %r7
122rp_val .reg %r8
123rp_val_1 .reg %r9
124
15bn_mul_add_words 125bn_mul_add_words
16 .PROC 126 .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
17 .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=4 127 .proc
18 .ENTRY 128 .callinfo frame=128
19 stw %r2,-20(0,%r30) 129 .entry
20 stwm %r4,64(0,%r30) 130 .align 64
21 copy %r24,%r31 131
22 stw %r3,-60(0,%r30) 132 STD %r3,0(%sp) ; save r3
23 ldi 0,%r20 133 STD %r4,8(%sp) ; save r4
24 ldo 12(%r26),%r2 134 NOP ; Needed to make the loop 16-byte aligned
25 stw %r23,-16(0,%r30) 135 NOP ; needed to make the loop 16-byte aligned
26 copy %r25,%r3 136
27 ldo 12(%r3),%r1 137 STD %r5,16(%sp) ; save r5
28 fldws -16(0,%r30),%fr8L 138 NOP
29L$0010 139 STD %r6,24(%sp) ; save r6
30 copy %r20,%r25 140 STD %r7,32(%sp) ; save r7
31 ldi 0,%r24 141
32 fldws 0(0,%r3),%fr9L 142 STD %r8,40(%sp) ; save r8
33 ldw 0(0,%r26),%r19 143 STD %r9,48(%sp) ; save r9
34 xmpyu %fr8L,%fr9L,%fr9 144 COPY %r0,%ret1 ; return 0 by default
35 fstds %fr9,-16(0,%r30) 145 DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
36 copy %r19,%r23 146
37 ldw -16(0,%r30),%r28 147 CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit
38 ldw -12(0,%r30),%r29 148 LDO 128(%sp),%sp ; bump stack
39 ldi 0,%r22 149
40 add %r23,%r29,%r29 150 ;
41 addc %r22,%r28,%r28 151 ; The loop is unrolled twice, so if there is only 1 number
42 add %r25,%r29,%r29 152 ; then go straight to the cleanup code.
43 addc %r24,%r28,%r28 153 ;
44 copy %r28,%r21 154 CMPIB,= 1,num,bn_mul_add_words_single_top
45 ldi 0,%r20 155 FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l)
46 copy %r21,%r20 156
47 addib,= -1,%r31,L$0011 157 ;
48 stw %r29,0(0,%r26) 158 ; This loop is unrolled 2 times (64-byte aligned as well)
49 copy %r20,%r25 159 ;
50 ldi 0,%r24 160 ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
51 fldws -8(0,%r1),%fr9L 161 ; two 32-bit mutiplies can be issued per cycle.
52 ldw -8(0,%r2),%r19 162 ;
53 xmpyu %fr8L,%fr9L,%fr9 163bn_mul_add_words_unroll2
54 fstds %fr9,-16(0,%r30) 164
55 copy %r19,%r23 165 FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
56 ldw -16(0,%r30),%r28 166 FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
57 ldw -12(0,%r30),%r29 167 LDD 0(r_ptr),rp_val ; rp[0]
58 ldi 0,%r22 168 LDD 8(r_ptr),rp_val_1 ; rp[1]
59 add %r23,%r29,%r29 169
60 addc %r22,%r28,%r28 170 XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
61 add %r25,%r29,%r29 171 XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l
62 addc %r24,%r28,%r28 172 FSTD fm1,-16(%sp) ; -16(sp) = m1[0]
63 copy %r28,%r21 173 FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1]
64 ldi 0,%r20 174
65 copy %r21,%r20 175 XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h
66 addib,= -1,%r31,L$0011 176 XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h
67 stw %r29,-8(0,%r2) 177 FSTD fm,-8(%sp) ; -8(sp) = m[0]
68 copy %r20,%r25 178 FSTD fm_1,-40(%sp) ; -40(sp) = m[1]
69 ldi 0,%r24 179
70 fldws -4(0,%r1),%fr9L 180 XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
71 ldw -4(0,%r2),%r19 181 XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h
72 xmpyu %fr8L,%fr9L,%fr9 182 FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp
73 fstds %fr9,-16(0,%r30) 183 FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1
74 copy %r19,%r23 184
75 ldw -16(0,%r30),%r28 185 XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
76 ldw -12(0,%r30),%r29 186 XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
77 ldi 0,%r22 187 FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp
78 add %r23,%r29,%r29 188 FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1
79 addc %r22,%r28,%r28 189
80 add %r25,%r29,%r29 190 LDD -8(%sp),m_0 ; m[0]
81 addc %r24,%r28,%r28 191 LDD -40(%sp),m_1 ; m[1]
82 copy %r28,%r21 192 LDD -16(%sp),m1_0 ; m1[0]
83 ldi 0,%r20 193 LDD -48(%sp),m1_1 ; m1[1]
84 copy %r21,%r20 194
85 addib,= -1,%r31,L$0011 195 LDD -24(%sp),ht_0 ; ht[0]
86 stw %r29,-4(0,%r2) 196 LDD -56(%sp),ht_1 ; ht[1]
87 copy %r20,%r25 197 ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0];
88 ldi 0,%r24 198 ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1];
89 fldws 0(0,%r1),%fr9L 199
90 ldw 0(0,%r2),%r19 200 LDD -32(%sp),lt_0
91 xmpyu %fr8L,%fr9L,%fr9 201 LDD -64(%sp),lt_1
92 fstds %fr9,-16(0,%r30) 202 CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0])
93 copy %r19,%r23 203 ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32)
94 ldw -16(0,%r30),%r28 204
95 ldw -12(0,%r30),%r29 205 CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1])
96 ldi 0,%r22 206 ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32)
97 add %r23,%r29,%r29 207 EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32
98 addc %r22,%r28,%r28 208 DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32
99 add %r25,%r29,%r29 209
100 addc %r24,%r28,%r28 210 EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32
101 copy %r28,%r21 211 DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32
102 ldi 0,%r20 212 ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32)
103 copy %r21,%r20 213 ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32)
104 addib,= -1,%r31,L$0011 214
105 stw %r29,0(0,%r2) 215 ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0];
106 ldo 16(%r1),%r1 216 ADD,DC ht_0,%r0,ht_0 ; ht[0]++
107 ldo 16(%r3),%r3 217 ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1];
108 ldo 16(%r2),%r2 218 ADD,DC ht_1,%r0,ht_1 ; ht[1]++
109 bl L$0010,0 219
110 ldo 16(%r26),%r26 220 ADD %ret1,lt_0,lt_0 ; lt[0] = lt[0] + c;
111L$0011 221 ADD,DC ht_0,%r0,ht_0 ; ht[0]++
112 copy %r20,%r28 222 ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0]
113 ldw -84(0,%r30),%r2 223 ADD,DC ht_0,%r0,ht_0 ; ht[0]++
114 ldw -60(0,%r30),%r3 224
115 bv 0(%r2) 225 LDO -2(num),num ; num = num - 2;
116 ldwm -64(0,%r30),%r4 226 ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c);
117 .EXIT 227 ADD,DC ht_1,%r0,ht_1 ; ht[1]++
118 .PROCEND 228 STD lt_0,0(r_ptr) ; rp[0] = lt[0]
119 .align 4 229
120 .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR 230 ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1]
231 ADD,DC ht_1,%r0,%ret1 ; ht[1]++
232 LDO 16(a_ptr),a_ptr ; a_ptr += 2
233
234 STD lt_1,8(r_ptr) ; rp[1] = lt[1]
235 CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
236 LDO 16(r_ptr),r_ptr ; r_ptr += 2
237
238 CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
239
240 ;
241 ; Top of loop aligned on 64-byte boundary
242 ;
243bn_mul_add_words_single_top
244 FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
245 LDD 0(r_ptr),rp_val ; rp[0]
246 LDO 8(a_ptr),a_ptr ; a_ptr++
247 XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
248 FSTD fm1,-16(%sp) ; -16(sp) = m1
249 XMPYU flt_0,fw_h,fm ; m = lt*fw_h
250 FSTD fm,-8(%sp) ; -8(sp) = m
251 XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
252 FSTD ht_temp,-24(%sp) ; -24(sp) = ht
253 XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
254 FSTD lt_temp,-32(%sp) ; -32(sp) = lt
255
256 LDD -8(%sp),m_0
257 LDD -16(%sp),m1_0 ; m1 = temp1
258 ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
259 LDD -24(%sp),ht_0
260 LDD -32(%sp),lt_0
261
262 CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
263 ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
264
265 EXTRD,U tmp_0,31,32,m_0 ; m>>32
266 DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
267
268 ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
269 ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1;
270 ADD,DC ht_0,%r0,ht_0 ; ht++
271 ADD %ret1,tmp_0,lt_0 ; lt = lt + c;
272 ADD,DC ht_0,%r0,ht_0 ; ht++
273 ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0]
274 ADD,DC ht_0,%r0,%ret1 ; ht++
275 STD lt_0,0(r_ptr) ; rp[0] = lt
276
277bn_mul_add_words_exit
278 .EXIT
279
280 EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
281 LDD -80(%sp),%r9 ; restore r9
282 LDD -88(%sp),%r8 ; restore r8
283 LDD -96(%sp),%r7 ; restore r7
284 LDD -104(%sp),%r6 ; restore r6
285 LDD -112(%sp),%r5 ; restore r5
286 LDD -120(%sp),%r4 ; restore r4
287 BVE (%rp)
288 LDD,MB -128(%sp),%r3 ; restore r3
289 .PROCEND ;in=23,24,25,26,29;out=28;
290
291;----------------------------------------------------------------------------
292;
293;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
294;
295; arg0 = rp
296; arg1 = ap
297; arg3 = num
298; w on stack at -56(sp)
299
121bn_mul_words 300bn_mul_words
122 .PROC 301 .proc
123 .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=3 302 .callinfo frame=128
124 .ENTRY 303 .entry
125 stw %r2,-20(0,%r30) 304 .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
126 copy %r25,%r2 305 .align 64
127 stwm %r4,64(0,%r30) 306
128 copy %r24,%r19 307 STD %r3,0(%sp) ; save r3
129 ldi 0,%r28 308 STD %r4,8(%sp) ; save r4
130 stw %r23,-16(0,%r30) 309 NOP
131 ldo 12(%r26),%r31 310 STD %r5,16(%sp) ; save r5
132 ldo 12(%r2),%r29 311
133 fldws -16(0,%r30),%fr8L 312 STD %r6,24(%sp) ; save r6
134L$0026 313 STD %r7,32(%sp) ; save r7
135 fldws 0(0,%r2),%fr9L 314 COPY %r0,%ret1 ; return 0 by default
136 xmpyu %fr8L,%fr9L,%fr9 315 DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
137 fstds %fr9,-16(0,%r30) 316
138 copy %r28,%r21 317 CMPIB,>= 0,num,bn_mul_words_exit
139 ldi 0,%r20 318 LDO 128(%sp),%sp ; bump stack
140 ldw -16(0,%r30),%r24 319
141 ldw -12(0,%r30),%r25 320 ;
142 add %r21,%r25,%r25 321 ; See if only 1 word to do, thus just do cleanup
143 addc %r20,%r24,%r24 322 ;
144 copy %r24,%r23 323 CMPIB,= 1,num,bn_mul_words_single_top
145 ldi 0,%r22 324 FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l)
146 copy %r23,%r28 325
147 addib,= -1,%r19,L$0027 326 ;
148 stw %r25,0(0,%r26) 327 ; This loop is unrolled 2 times (64-byte aligned as well)
149 fldws -8(0,%r29),%fr9L 328 ;
150 xmpyu %fr8L,%fr9L,%fr9 329 ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
151 fstds %fr9,-16(0,%r30) 330 ; two 32-bit mutiplies can be issued per cycle.
152 copy %r28,%r21 331 ;
153 ldi 0,%r20 332bn_mul_words_unroll2
154 ldw -16(0,%r30),%r24 333
155 ldw -12(0,%r30),%r25 334 FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
156 add %r21,%r25,%r25 335 FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
157 addc %r20,%r24,%r24 336 XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
158 copy %r24,%r23 337 XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l
159 ldi 0,%r22 338
160 copy %r23,%r28 339 FSTD fm1,-16(%sp) ; -16(sp) = m1
161 addib,= -1,%r19,L$0027 340 FSTD fm1_1,-48(%sp) ; -48(sp) = m1
162 stw %r25,-8(0,%r31) 341 XMPYU flt_0,fw_h,fm ; m = lt*fw_h
163 fldws -4(0,%r29),%fr9L 342 XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h
164 xmpyu %fr8L,%fr9L,%fr9 343
165 fstds %fr9,-16(0,%r30) 344 FSTD fm,-8(%sp) ; -8(sp) = m
166 copy %r28,%r21 345 FSTD fm_1,-40(%sp) ; -40(sp) = m
167 ldi 0,%r20 346 XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
168 ldw -16(0,%r30),%r24 347 XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h
169 ldw -12(0,%r30),%r25 348
170 add %r21,%r25,%r25 349 FSTD ht_temp,-24(%sp) ; -24(sp) = ht
171 addc %r20,%r24,%r24 350 FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht
172 copy %r24,%r23 351 XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
173 ldi 0,%r22 352 XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
174 copy %r23,%r28 353
175 addib,= -1,%r19,L$0027 354 FSTD lt_temp,-32(%sp) ; -32(sp) = lt
176 stw %r25,-4(0,%r31) 355 FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt
177 fldws 0(0,%r29),%fr9L 356 LDD -8(%sp),m_0
178 xmpyu %fr8L,%fr9L,%fr9 357 LDD -40(%sp),m_1
179 fstds %fr9,-16(0,%r30) 358
180 copy %r28,%r21 359 LDD -16(%sp),m1_0
181 ldi 0,%r20 360 LDD -48(%sp),m1_1
182 ldw -16(0,%r30),%r24 361 LDD -24(%sp),ht_0
183 ldw -12(0,%r30),%r25 362 LDD -56(%sp),ht_1
184 add %r21,%r25,%r25 363
185 addc %r20,%r24,%r24 364 ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1;
186 copy %r24,%r23 365 ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1;
187 ldi 0,%r22 366 LDD -32(%sp),lt_0
188 copy %r23,%r28 367 LDD -64(%sp),lt_1
189 addib,= -1,%r19,L$0027 368
190 stw %r25,0(0,%r31) 369 CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1)
191 ldo 16(%r29),%r29 370 ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
192 ldo 16(%r2),%r2 371 CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1)
193 ldo 16(%r31),%r31 372 ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32)
194 bl L$0026,0 373
195 ldo 16(%r26),%r26 374 EXTRD,U tmp_0,31,32,m_0 ; m>>32
196L$0027 375 DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
197 ldw -84(0,%r30),%r2 376 EXTRD,U tmp_1,31,32,m_1 ; m>>32
198 bv 0(%r2) 377 DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32
199 ldwm -64(0,%r30),%r4 378
200 .EXIT 379 ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
201 .PROCEND 380 ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32)
202 .align 4 381 ADD lt_0,m1_0,lt_0 ; lt = lt+m1;
203 .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR 382 ADD,DC ht_0,%r0,ht_0 ; ht++
383
384 ADD lt_1,m1_1,lt_1 ; lt = lt+m1;
385 ADD,DC ht_1,%r0,ht_1 ; ht++
386 ADD %ret1,lt_0,lt_0 ; lt = lt + c (ret1);
387 ADD,DC ht_0,%r0,ht_0 ; ht++
388
389 ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0)
390 ADD,DC ht_1,%r0,ht_1 ; ht++
391 STD lt_0,0(r_ptr) ; rp[0] = lt
392 STD lt_1,8(r_ptr) ; rp[1] = lt
393
394 COPY ht_1,%ret1 ; carry = ht
395 LDO -2(num),num ; num = num - 2;
396 LDO 16(a_ptr),a_ptr ; ap += 2
397 CMPIB,<= 2,num,bn_mul_words_unroll2
398 LDO 16(r_ptr),r_ptr ; rp++
399
400 CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
401
402 ;
403 ; Top of loop aligned on 64-byte boundary
404 ;
405bn_mul_words_single_top
406 FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
407
408 XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
409 FSTD fm1,-16(%sp) ; -16(sp) = m1
410 XMPYU flt_0,fw_h,fm ; m = lt*fw_h
411 FSTD fm,-8(%sp) ; -8(sp) = m
412 XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
413 FSTD ht_temp,-24(%sp) ; -24(sp) = ht
414 XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
415 FSTD lt_temp,-32(%sp) ; -32(sp) = lt
416
417 LDD -8(%sp),m_0
418 LDD -16(%sp),m1_0
419 ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
420 LDD -24(%sp),ht_0
421 LDD -32(%sp),lt_0
422
423 CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
424 ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
425
426 EXTRD,U tmp_0,31,32,m_0 ; m>>32
427 DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
428
429 ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
430 ADD lt_0,m1_0,lt_0 ; lt= lt+m1;
431 ADD,DC ht_0,%r0,ht_0 ; ht++
432
433 ADD %ret1,lt_0,lt_0 ; lt = lt + c;
434 ADD,DC ht_0,%r0,ht_0 ; ht++
435
436 COPY ht_0,%ret1 ; copy carry
437 STD lt_0,0(r_ptr) ; rp[0] = lt
438
439bn_mul_words_exit
440 .EXIT
441 EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
442 LDD -96(%sp),%r7 ; restore r7
443 LDD -104(%sp),%r6 ; restore r6
444 LDD -112(%sp),%r5 ; restore r5
445 LDD -120(%sp),%r4 ; restore r4
446 BVE (%rp)
447 LDD,MB -128(%sp),%r3 ; restore r3
448 .PROCEND
449
450;----------------------------------------------------------------------------
451;
452;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
453;
454; arg0 = rp
455; arg1 = ap
456; arg2 = num
457;
458
204bn_sqr_words 459bn_sqr_words
460 .proc
461 .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
462 .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
463 .entry
464 .align 64
465
466 STD %r3,0(%sp) ; save r3
467 STD %r4,8(%sp) ; save r4
468 NOP
469 STD %r5,16(%sp) ; save r5
470
471 CMPIB,>= 0,num,bn_sqr_words_exit
472 LDO 128(%sp),%sp ; bump stack
473
474 ;
475 ; If only 1, the goto straight to cleanup
476 ;
477 CMPIB,= 1,num,bn_sqr_words_single_top
478 DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
479
480 ;
481 ; This loop is unrolled 2 times (64-byte aligned as well)
482 ;
483
484bn_sqr_words_unroll2
485 FLDD 0(a_ptr),t_float_0 ; a[0]
486 FLDD 8(a_ptr),t_float_1 ; a[1]
487 XMPYU fht_0,flt_0,fm ; m[0]
488 XMPYU fht_1,flt_1,fm_1 ; m[1]
489
490 FSTD fm,-24(%sp) ; store m[0]
491 FSTD fm_1,-56(%sp) ; store m[1]
492 XMPYU flt_0,flt_0,lt_temp ; lt[0]
493 XMPYU flt_1,flt_1,lt_temp_1 ; lt[1]
494
495 FSTD lt_temp,-16(%sp) ; store lt[0]
496 FSTD lt_temp_1,-48(%sp) ; store lt[1]
497 XMPYU fht_0,fht_0,ht_temp ; ht[0]
498 XMPYU fht_1,fht_1,ht_temp_1 ; ht[1]
499
500 FSTD ht_temp,-8(%sp) ; store ht[0]
501 FSTD ht_temp_1,-40(%sp) ; store ht[1]
502 LDD -24(%sp),m_0
503 LDD -56(%sp),m_1
504
505 AND m_0,high_mask,tmp_0 ; m[0] & Mask
506 AND m_1,high_mask,tmp_1 ; m[1] & Mask
507 DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1
508 DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1
509
510 LDD -16(%sp),lt_0
511 LDD -48(%sp),lt_1
512 EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1
513 EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1
514
515 LDD -8(%sp),ht_0
516 LDD -40(%sp),ht_1
517 ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0
518 ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1
519
520 ADD lt_0,m_0,lt_0 ; lt = lt+m
521 ADD,DC ht_0,%r0,ht_0 ; ht[0]++
522 STD lt_0,0(r_ptr) ; rp[0] = lt[0]
523 STD ht_0,8(r_ptr) ; rp[1] = ht[1]
524
525 ADD lt_1,m_1,lt_1 ; lt = lt+m
526 ADD,DC ht_1,%r0,ht_1 ; ht[1]++
527 STD lt_1,16(r_ptr) ; rp[2] = lt[1]
528 STD ht_1,24(r_ptr) ; rp[3] = ht[1]
529
530 LDO -2(num),num ; num = num - 2;
531 LDO 16(a_ptr),a_ptr ; ap += 2
532 CMPIB,<= 2,num,bn_sqr_words_unroll2
533 LDO 32(r_ptr),r_ptr ; rp += 4
534
535 CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
536
537 ;
538 ; Top of loop aligned on 64-byte boundary
539 ;
540bn_sqr_words_single_top
541 FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
542
543 XMPYU fht_0,flt_0,fm ; m
544 FSTD fm,-24(%sp) ; store m
545
546 XMPYU flt_0,flt_0,lt_temp ; lt
547 FSTD lt_temp,-16(%sp) ; store lt
548
549 XMPYU fht_0,fht_0,ht_temp ; ht
550 FSTD ht_temp,-8(%sp) ; store ht
551
552 LDD -24(%sp),m_0 ; load m
553 AND m_0,high_mask,tmp_0 ; m & Mask
554 DEPD,Z m_0,30,31,m_0 ; m << 32+1
555 LDD -16(%sp),lt_0 ; lt
556
557 LDD -8(%sp),ht_0 ; ht
558 EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1
559 ADD m_0,lt_0,lt_0 ; lt = lt+m
560 ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0
561 ADD,DC ht_0,%r0,ht_0 ; ht++
562
563 STD lt_0,0(r_ptr) ; rp[0] = lt
564 STD ht_0,8(r_ptr) ; rp[1] = ht
565
566bn_sqr_words_exit
567 .EXIT
568 LDD -112(%sp),%r5 ; restore r5
569 LDD -120(%sp),%r4 ; restore r4
570 BVE (%rp)
571 LDD,MB -128(%sp),%r3
572 .PROCEND ;in=23,24,25,26,29;out=28;
573
574
575;----------------------------------------------------------------------------
576;
577;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
578;
579; arg0 = rp
580; arg1 = ap
581; arg2 = bp
582; arg3 = n
583
584t .reg %r22
585b .reg %r21
586l .reg %r20
587
588bn_add_words
589 .proc
590 .entry
591 .callinfo
592 .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
593 .align 64
594
595 CMPIB,>= 0,n,bn_add_words_exit
596 COPY %r0,%ret1 ; return 0 by default
597
598 ;
599 ; If 2 or more numbers do the loop
600 ;
601 CMPIB,= 1,n,bn_add_words_single_top
602 NOP
603
604 ;
605 ; This loop is unrolled 2 times (64-byte aligned as well)
606 ;
607bn_add_words_unroll2
608 LDD 0(a_ptr),t
609 LDD 0(b_ptr),b
610 ADD t,%ret1,t ; t = t+c;
611 ADD,DC %r0,%r0,%ret1 ; set c to carry
612 ADD t,b,l ; l = t + b[0]
613 ADD,DC %ret1,%r0,%ret1 ; c+= carry
614 STD l,0(r_ptr)
615
616 LDD 8(a_ptr),t
617 LDD 8(b_ptr),b
618 ADD t,%ret1,t ; t = t+c;
619 ADD,DC %r0,%r0,%ret1 ; set c to carry
620 ADD t,b,l ; l = t + b[0]
621 ADD,DC %ret1,%r0,%ret1 ; c+= carry
622 STD l,8(r_ptr)
623
624 LDO -2(n),n
625 LDO 16(a_ptr),a_ptr
626 LDO 16(b_ptr),b_ptr
627
628 CMPIB,<= 2,n,bn_add_words_unroll2
629 LDO 16(r_ptr),r_ptr
630
631 CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
632
633bn_add_words_single_top
634 LDD 0(a_ptr),t
635 LDD 0(b_ptr),b
636
637 ADD t,%ret1,t ; t = t+c;
638 ADD,DC %r0,%r0,%ret1 ; set c to carry (could use CMPCLR??)
639 ADD t,b,l ; l = t + b[0]
640 ADD,DC %ret1,%r0,%ret1 ; c+= carry
641 STD l,0(r_ptr)
642
643bn_add_words_exit
644 .EXIT
645 BVE (%rp)
646 EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
647 .PROCEND ;in=23,24,25,26,29;out=28;
648
649;----------------------------------------------------------------------------
650;
651;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
652;
653; arg0 = rp
654; arg1 = ap
655; arg2 = bp
656; arg3 = n
657
658t1 .reg %r22
659t2 .reg %r21
660sub_tmp1 .reg %r20
661sub_tmp2 .reg %r19
662
663
664bn_sub_words
665 .proc
666 .callinfo
667 .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
668 .entry
669 .align 64
670
671 CMPIB,>= 0,n,bn_sub_words_exit
672 COPY %r0,%ret1 ; return 0 by default
673
674 ;
675 ; If 2 or more numbers do the loop
676 ;
677 CMPIB,= 1,n,bn_sub_words_single_top
678 NOP
679
680 ;
681 ; This loop is unrolled 2 times (64-byte aligned as well)
682 ;
683bn_sub_words_unroll2
684 LDD 0(a_ptr),t1
685 LDD 0(b_ptr),t2
686 SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
687 SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
688
689 CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
690 LDO 1(%r0),sub_tmp2
691
692 CMPCLR,*= t1,t2,%r0
693 COPY sub_tmp2,%ret1
694 STD sub_tmp1,0(r_ptr)
695
696 LDD 8(a_ptr),t1
697 LDD 8(b_ptr),t2
698 SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
699 SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
700 CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
701 LDO 1(%r0),sub_tmp2
702
703 CMPCLR,*= t1,t2,%r0
704 COPY sub_tmp2,%ret1
705 STD sub_tmp1,8(r_ptr)
706
707 LDO -2(n),n
708 LDO 16(a_ptr),a_ptr
709 LDO 16(b_ptr),b_ptr
710
711 CMPIB,<= 2,n,bn_sub_words_unroll2
712 LDO 16(r_ptr),r_ptr
713
714 CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
715
716bn_sub_words_single_top
717 LDD 0(a_ptr),t1
718 LDD 0(b_ptr),t2
719 SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
720 SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
721 CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
722 LDO 1(%r0),sub_tmp2
723
724 CMPCLR,*= t1,t2,%r0
725 COPY sub_tmp2,%ret1
726
727 STD sub_tmp1,0(r_ptr)
728
729bn_sub_words_exit
730 .EXIT
731 BVE (%rp)
732 EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
733 .PROCEND ;in=23,24,25,26,29;out=28;
734
735;------------------------------------------------------------------------------
736;
737; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
738;
739; arg0 = h
740; arg1 = l
741; arg2 = d
742;
743; This is mainly just output from the HP C compiler.
744;
745;------------------------------------------------------------------------------
746bn_div_words
205 .PROC 747 .PROC
206 .CALLINFO FRAME=0,NO_CALLS 748 .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
207 .ENTRY 749 .IMPORT BN_num_bits_word,CODE
208 ldo 28(%r26),%r19 750 .IMPORT __iob,DATA
209 ldo 12(%r25),%r28 751 .IMPORT fprintf,CODE
210L$0042 752 .IMPORT abort,CODE
211 fldws 0(0,%r25),%fr8L 753 .IMPORT $$div2U,MILLICODE
212 fldws 0(0,%r25),%fr8R 754 .CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
213 xmpyu %fr8L,%fr8R,%fr8 755 .ENTRY
214 fstds %fr8,-16(0,%r30) 756 STW %r2,-20(%r30) ;offset 0x8ec
215 ldw -16(0,%r30),%r22 757 STW,MA %r3,192(%r30) ;offset 0x8f0
216 ldw -12(0,%r30),%r23 758 STW %r4,-188(%r30) ;offset 0x8f4
217 stw %r23,0(0,%r26) 759 DEPD %r5,31,32,%r6 ;offset 0x8f8
218 copy %r22,%r21 760 STD %r6,-184(%r30) ;offset 0x8fc
219 ldi 0,%r20 761 DEPD %r7,31,32,%r8 ;offset 0x900
220 addib,= -1,%r24,L$0049 762 STD %r8,-176(%r30) ;offset 0x904
221 stw %r21,-24(0,%r19) 763 STW %r9,-168(%r30) ;offset 0x908
222 fldws -8(0,%r28),%fr8L 764 LDD -248(%r30),%r3 ;offset 0x90c
223 fldws -8(0,%r28),%fr8R 765 COPY %r26,%r4 ;offset 0x910
224 xmpyu %fr8L,%fr8R,%fr8 766 COPY %r24,%r5 ;offset 0x914
225 fstds %fr8,-16(0,%r30) 767 DEPD %r25,31,32,%r4 ;offset 0x918
226 ldw -16(0,%r30),%r22 768 CMPB,*<> %r3,%r0,$0006000C ;offset 0x91c
227 ldw -12(0,%r30),%r23 769 DEPD %r23,31,32,%r5 ;offset 0x920
228 stw %r23,-20(0,%r19) 770 MOVIB,TR -1,%r29,$00060002 ;offset 0x924
229 copy %r22,%r21 771 EXTRD,U %r29,31,32,%r28 ;offset 0x928
230 ldi 0,%r20 772$0006002A
231 addib,= -1,%r24,L$0049 773 LDO -1(%r29),%r29 ;offset 0x92c
232 stw %r21,-16(0,%r19) 774 SUB %r23,%r7,%r23 ;offset 0x930
233 fldws -4(0,%r28),%fr8L 775$00060024
234 fldws -4(0,%r28),%fr8R 776 SUB %r4,%r31,%r25 ;offset 0x934
235 xmpyu %fr8L,%fr8R,%fr8 777 AND %r25,%r19,%r26 ;offset 0x938
236 fstds %fr8,-16(0,%r30) 778 CMPB,*<>,N %r0,%r26,$00060046 ;offset 0x93c
237 ldw -16(0,%r30),%r22 779 DEPD,Z %r25,31,32,%r20 ;offset 0x940
238 ldw -12(0,%r30),%r23 780 OR %r20,%r24,%r21 ;offset 0x944
239 stw %r23,-12(0,%r19) 781 CMPB,*<<,N %r21,%r23,$0006002A ;offset 0x948
240 copy %r22,%r21 782 SUB %r31,%r2,%r31 ;offset 0x94c
241 ldi 0,%r20 783$00060046
242 addib,= -1,%r24,L$0049 784$0006002E
243 stw %r21,-8(0,%r19) 785 DEPD,Z %r23,31,32,%r25 ;offset 0x950
244 fldws 0(0,%r28),%fr8L 786 EXTRD,U %r23,31,32,%r26 ;offset 0x954
245 fldws 0(0,%r28),%fr8R 787 AND %r25,%r19,%r24 ;offset 0x958
246 xmpyu %fr8L,%fr8R,%fr8 788 ADD,L %r31,%r26,%r31 ;offset 0x95c
247 fstds %fr8,-16(0,%r30) 789 CMPCLR,*>>= %r5,%r24,%r0 ;offset 0x960
248 ldw -16(0,%r30),%r22 790 LDO 1(%r31),%r31 ;offset 0x964
249 ldw -12(0,%r30),%r23 791$00060032
250 stw %r23,-4(0,%r19) 792 CMPB,*<<=,N %r31,%r4,$00060036 ;offset 0x968
251 copy %r22,%r21 793 LDO -1(%r29),%r29 ;offset 0x96c
252 ldi 0,%r20 794 ADD,L %r4,%r3,%r4 ;offset 0x970
253 addib,= -1,%r24,L$0049 795$00060036
254 stw %r21,0(0,%r19) 796 ADDIB,=,N -1,%r8,$D0 ;offset 0x974
255 ldo 16(%r28),%r28 797 SUB %r5,%r24,%r28 ;offset 0x978
256 ldo 16(%r25),%r25 798$0006003A
257 ldo 32(%r19),%r19 799 SUB %r4,%r31,%r24 ;offset 0x97c
258 bl L$0042,0 800 SHRPD %r24,%r28,32,%r4 ;offset 0x980
259 ldo 32(%r26),%r26 801 DEPD,Z %r29,31,32,%r9 ;offset 0x984
260L$0049 802 DEPD,Z %r28,31,32,%r5 ;offset 0x988
261 bv,n 0(%r2) 803$0006001C
262 .EXIT 804 EXTRD,U %r4,31,32,%r31 ;offset 0x98c
263 .PROCEND 805 CMPB,*<>,N %r31,%r2,$00060020 ;offset 0x990
264 .IMPORT BN_num_bits_word,CODE 806 MOVB,TR %r6,%r29,$D1 ;offset 0x994
265 .IMPORT fprintf,CODE 807 STD %r29,-152(%r30) ;offset 0x998
266 .IMPORT __iob,DATA 808$0006000C
267 .SPACE $TEXT$ 809 EXTRD,U %r3,31,32,%r25 ;offset 0x99c
268 .SUBSPA $LIT$ 810 COPY %r3,%r26 ;offset 0x9a0
269 811 EXTRD,U %r3,31,32,%r9 ;offset 0x9a4
270 .align 4 812 EXTRD,U %r4,31,32,%r8 ;offset 0x9a8
271L$C0000 813 .CALL ARGW0=GR,ARGW1=GR,RTNVAL=GR ;in=25,26;out=28;
272 .STRING "Division would overflow (%d)\x0a\x00" 814 B,L BN_num_bits_word,%r2 ;offset 0x9ac
273 .IMPORT abort,CODE 815 EXTRD,U %r5,31,32,%r7 ;offset 0x9b0
274 .SPACE $TEXT$ 816 LDI 64,%r20 ;offset 0x9b4
275 .SUBSPA $CODE$ 817 DEPD %r7,31,32,%r5 ;offset 0x9b8
276 818 DEPD %r8,31,32,%r4 ;offset 0x9bc
277 .align 4 819 DEPD %r9,31,32,%r3 ;offset 0x9c0
278 .EXPORT bn_div64,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR 820 CMPB,= %r28,%r20,$00060012 ;offset 0x9c4
279bn_div64 821 COPY %r28,%r24 ;offset 0x9c8
822 MTSARCM %r24 ;offset 0x9cc
823 DEPDI,Z -1,%sar,1,%r19 ;offset 0x9d0
824 CMPB,*>>,N %r4,%r19,$D2 ;offset 0x9d4
825$00060012
826 SUBI 64,%r24,%r31 ;offset 0x9d8
827 CMPCLR,*<< %r4,%r3,%r0 ;offset 0x9dc
828 SUB %r4,%r3,%r4 ;offset 0x9e0
829$00060016
830 CMPB,= %r31,%r0,$0006001A ;offset 0x9e4
831 COPY %r0,%r9 ;offset 0x9e8
832 MTSARCM %r31 ;offset 0x9ec
833 DEPD,Z %r3,%sar,64,%r3 ;offset 0x9f0
834 SUBI 64,%r31,%r26 ;offset 0x9f4
835 MTSAR %r26 ;offset 0x9f8
836 SHRPD %r4,%r5,%sar,%r4 ;offset 0x9fc
837 MTSARCM %r31 ;offset 0xa00
838 DEPD,Z %r5,%sar,64,%r5 ;offset 0xa04
839$0006001A
840 DEPDI,Z -1,31,32,%r19 ;offset 0xa08
841 AND %r3,%r19,%r29 ;offset 0xa0c
842 EXTRD,U %r29,31,32,%r2 ;offset 0xa10
843 DEPDI,Z -1,63,32,%r6 ;offset 0xa14
844 MOVIB,TR 2,%r8,$0006001C ;offset 0xa18
845 EXTRD,U %r3,63,32,%r7 ;offset 0xa1c
846$D2
847 ADDIL LR'__iob-$global$,%r27,%r1 ;offset 0xa20
848 LDIL LR'C$7,%r21 ;offset 0xa24
849 LDO RR'__iob-$global$+32(%r1),%r26 ;offset 0xa28
850 .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR ;in=24,25,26;out=28;
851 B,L fprintf,%r2 ;offset 0xa2c
852 LDO RR'C$7(%r21),%r25 ;offset 0xa30
853 .CALL ;
854 B,L abort,%r2 ;offset 0xa34
855 NOP ;offset 0xa38
856 B $D3 ;offset 0xa3c
857 LDW -212(%r30),%r2 ;offset 0xa40
858$00060020
859 COPY %r4,%r26 ;offset 0xa44
860 EXTRD,U %r4,31,32,%r25 ;offset 0xa48
861 COPY %r2,%r24 ;offset 0xa4c
862 .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
863 B,L $$div2U,%r31 ;offset 0xa50
864 EXTRD,U %r2,31,32,%r23 ;offset 0xa54
865 DEPD %r28,31,32,%r29 ;offset 0xa58
866$00060022
867 STD %r29,-152(%r30) ;offset 0xa5c
868$D1
869 AND %r5,%r19,%r24 ;offset 0xa60
870 EXTRD,U %r24,31,32,%r24 ;offset 0xa64
871 STW %r2,-160(%r30) ;offset 0xa68
872 STW %r7,-128(%r30) ;offset 0xa6c
873 FLDD -152(%r30),%fr4 ;offset 0xa70
874 FLDD -152(%r30),%fr7 ;offset 0xa74
875 FLDW -160(%r30),%fr8L ;offset 0xa78
876 FLDW -128(%r30),%fr5L ;offset 0xa7c
877 XMPYU %fr8L,%fr7L,%fr10 ;offset 0xa80
878 FSTD %fr10,-136(%r30) ;offset 0xa84
879 XMPYU %fr8L,%fr7R,%fr22 ;offset 0xa88
880 FSTD %fr22,-144(%r30) ;offset 0xa8c
881 XMPYU %fr5L,%fr4L,%fr11 ;offset 0xa90
882 XMPYU %fr5L,%fr4R,%fr23 ;offset 0xa94
883 FSTD %fr11,-112(%r30) ;offset 0xa98
884 FSTD %fr23,-120(%r30) ;offset 0xa9c
885 LDD -136(%r30),%r28 ;offset 0xaa0
886 DEPD,Z %r28,31,32,%r31 ;offset 0xaa4
887 LDD -144(%r30),%r20 ;offset 0xaa8
888 ADD,L %r20,%r31,%r31 ;offset 0xaac
889 LDD -112(%r30),%r22 ;offset 0xab0
890 DEPD,Z %r22,31,32,%r22 ;offset 0xab4
891 LDD -120(%r30),%r21 ;offset 0xab8
892 B $00060024 ;offset 0xabc
893 ADD,L %r21,%r22,%r23 ;offset 0xac0
894$D0
895 OR %r9,%r29,%r29 ;offset 0xac4
896$00060040
897 EXTRD,U %r29,31,32,%r28 ;offset 0xac8
898$00060002
899$L2
900 LDW -212(%r30),%r2 ;offset 0xacc
901$D3
902 LDW -168(%r30),%r9 ;offset 0xad0
903 LDD -176(%r30),%r8 ;offset 0xad4
904 EXTRD,U %r8,31,32,%r7 ;offset 0xad8
905 LDD -184(%r30),%r6 ;offset 0xadc
906 EXTRD,U %r6,31,32,%r5 ;offset 0xae0
907 LDW -188(%r30),%r4 ;offset 0xae4
908 BVE (%r2) ;offset 0xae8
909 .EXIT
910 LDW,MB -192(%r30),%r3 ;offset 0xaec
911 .PROCEND ;in=23,25;out=28,29;fpin=105,107;
912
913
914
915
916;----------------------------------------------------------------------------
917;
918; Registers to hold 64-bit values to manipulate. The "L" part
919; of the register corresponds to the upper 32-bits, while the "R"
920; part corresponds to the lower 32-bits
921;
922; Note, that when using b6 and b7, the code must save these before
923; using them because they are callee save registers
924;
925;
926; Floating point registers to use to save values that
927; are manipulated. These don't collide with ftemp1-6 and
928; are all caller save registers
929;
930a0 .reg %fr22
931a0L .reg %fr22L
932a0R .reg %fr22R
933
934a1 .reg %fr23
935a1L .reg %fr23L
936a1R .reg %fr23R
937
938a2 .reg %fr24
939a2L .reg %fr24L
940a2R .reg %fr24R
941
942a3 .reg %fr25
943a3L .reg %fr25L
944a3R .reg %fr25R
945
946a4 .reg %fr26
947a4L .reg %fr26L
948a4R .reg %fr26R
949
950a5 .reg %fr27
951a5L .reg %fr27L
952a5R .reg %fr27R
953
954a6 .reg %fr28
955a6L .reg %fr28L
956a6R .reg %fr28R
957
958a7 .reg %fr29
959a7L .reg %fr29L
960a7R .reg %fr29R
961
962b0 .reg %fr30
963b0L .reg %fr30L
964b0R .reg %fr30R
965
966b1 .reg %fr31
967b1L .reg %fr31L
968b1R .reg %fr31R
969
970;
971; Temporary floating point variables, these are all caller save
972; registers
973;
974ftemp1 .reg %fr4
975ftemp2 .reg %fr5
976ftemp3 .reg %fr6
977ftemp4 .reg %fr7
978
979;
980; The B set of registers when used.
981;
982
983b2 .reg %fr8
984b2L .reg %fr8L
985b2R .reg %fr8R
986
987b3 .reg %fr9
988b3L .reg %fr9L
989b3R .reg %fr9R
990
991b4 .reg %fr10
992b4L .reg %fr10L
993b4R .reg %fr10R
994
995b5 .reg %fr11
996b5L .reg %fr11L
997b5R .reg %fr11R
998
999b6 .reg %fr12
1000b6L .reg %fr12L
1001b6R .reg %fr12R
1002
1003b7 .reg %fr13
1004b7L .reg %fr13L
1005b7R .reg %fr13R
1006
1007c1 .reg %r21 ; only reg
1008temp1 .reg %r20 ; only reg
1009temp2 .reg %r19 ; only reg
1010temp3 .reg %r31 ; only reg
1011
1012m1 .reg %r28
1013c2 .reg %r23
1014high_one .reg %r1
1015ht .reg %r6
1016lt .reg %r5
1017m .reg %r4
1018c3 .reg %r3
1019
1020SQR_ADD_C .macro A0L,A0R,C1,C2,C3
1021 XMPYU A0L,A0R,ftemp1 ; m
1022 FSTD ftemp1,-24(%sp) ; store m
1023
1024 XMPYU A0R,A0R,ftemp2 ; lt
1025 FSTD ftemp2,-16(%sp) ; store lt
1026
1027 XMPYU A0L,A0L,ftemp3 ; ht
1028 FSTD ftemp3,-8(%sp) ; store ht
1029
1030 LDD -24(%sp),m ; load m
1031 AND m,high_mask,temp2 ; m & Mask
1032 DEPD,Z m,30,31,temp3 ; m << 32+1
1033 LDD -16(%sp),lt ; lt
1034
1035 LDD -8(%sp),ht ; ht
1036 EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1
1037 ADD temp3,lt,lt ; lt = lt+m
1038 ADD,L ht,temp1,ht ; ht += temp1
1039 ADD,DC ht,%r0,ht ; ht++
1040
1041 ADD C1,lt,C1 ; c1=c1+lt
1042 ADD,DC ht,%r0,ht ; ht++
1043
1044 ADD C2,ht,C2 ; c2=c2+ht
1045 ADD,DC C3,%r0,C3 ; c3++
1046.endm
1047
1048SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3
1049 XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht
1050 FSTD ftemp1,-16(%sp) ;
1051 XMPYU A0R,A1L,ftemp2 ; m = bh*lt
1052 FSTD ftemp2,-8(%sp) ;
1053 XMPYU A0R,A1R,ftemp3 ; lt = bl*lt
1054 FSTD ftemp3,-32(%sp)
1055 XMPYU A0L,A1L,ftemp4 ; ht = bh*ht
1056 FSTD ftemp4,-24(%sp) ;
1057
1058 LDD -8(%sp),m ; r21 = m
1059 LDD -16(%sp),m1 ; r19 = m1
1060 ADD,L m,m1,m ; m+m1
1061
1062 DEPD,Z m,31,32,temp3 ; (m+m1<<32)
1063 LDD -24(%sp),ht ; r24 = ht
1064
1065 CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
1066 ADD,L ht,high_one,ht ; ht+=high_one
1067
1068 EXTRD,U m,31,32,temp1 ; m >> 32
1069 LDD -32(%sp),lt ; lt
1070 ADD,L ht,temp1,ht ; ht+= m>>32
1071 ADD lt,temp3,lt ; lt = lt+m1
1072 ADD,DC ht,%r0,ht ; ht++
1073
1074 ADD ht,ht,ht ; ht=ht+ht;
1075 ADD,DC C3,%r0,C3 ; add in carry (c3++)
1076
1077 ADD lt,lt,lt ; lt=lt+lt;
1078 ADD,DC ht,%r0,ht ; add in carry (ht++)
1079
1080 ADD C1,lt,C1 ; c1=c1+lt
1081 ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++)
1082 LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise
1083
1084 ADD C2,ht,C2 ; c2 = c2 + ht
1085 ADD,DC C3,%r0,C3 ; add in carry (c3++)
1086.endm
1087
1088;
1089;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
1090; arg0 = r_ptr
1091; arg1 = a_ptr
1092;
1093
1094bn_sqr_comba8
280 .PROC 1095 .PROC
281 .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=8 1096 .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
282 .ENTRY 1097 .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
283 stw %r2,-20(0,%r30) 1098 .ENTRY
284 stwm %r8,128(0,%r30) 1099 .align 64
285 stw %r7,-124(0,%r30) 1100
286 stw %r4,-112(0,%r30) 1101 STD %r3,0(%sp) ; save r3
287 stw %r3,-108(0,%r30) 1102 STD %r4,8(%sp) ; save r4
288 copy %r26,%r3 1103 STD %r5,16(%sp) ; save r5
289 copy %r25,%r4 1104 STD %r6,24(%sp) ; save r6
290 stw %r6,-120(0,%r30) 1105
291 ldi 0,%r7 1106 ;
292 stw %r5,-116(0,%r30) 1107 ; Zero out carries
293 movb,<> %r24,%r5,L$0051 1108 ;
294 ldi 2,%r6 1109 COPY %r0,c1
295 bl L$0068,0 1110 COPY %r0,c2
296 ldi -1,%r28 1111 COPY %r0,c3
297L$0051 1112
298 .CALL ARGW0=GR 1113 LDO 128(%sp),%sp ; bump stack
299 bl BN_num_bits_word,%r2 1114 DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
300 copy %r5,%r26 1115 DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
301 copy %r28,%r24 1116
302 ldi 32,%r19 1117 ;
303 comb,= %r19,%r24,L$0052 1118 ; Load up all of the values we are going to use
304 subi 31,%r24,%r19 1119 ;
305 mtsar %r19 1120 FLDD 0(a_ptr),a0
306 zvdepi 1,32,%r19 1121 FLDD 8(a_ptr),a1
307 comb,>>= %r19,%r3,L$0052 1122 FLDD 16(a_ptr),a2
308 addil LR'__iob-$global$+32,%r27 1123 FLDD 24(a_ptr),a3
309 ldo RR'__iob-$global$+32(%r1),%r26 1124 FLDD 32(a_ptr),a4
310 ldil LR'L$C0000,%r25 1125 FLDD 40(a_ptr),a5
311 .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR 1126 FLDD 48(a_ptr),a6
312 bl fprintf,%r2 1127 FLDD 56(a_ptr),a7
313 ldo RR'L$C0000(%r25),%r25 1128
314 .CALL 1129 SQR_ADD_C a0L,a0R,c1,c2,c3
315 bl abort,%r2 1130 STD c1,0(r_ptr) ; r[0] = c1;
316 nop 1131 COPY %r0,c1
317L$0052 1132
318 comb,>> %r5,%r3,L$0053 1133 SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
319 subi 32,%r24,%r24 1134 STD c2,8(r_ptr) ; r[1] = c2;
320 sub %r3,%r5,%r3 1135 COPY %r0,c2
321L$0053 1136
322 comib,= 0,%r24,L$0054 1137 SQR_ADD_C a1L,a1R,c3,c1,c2
323 subi 31,%r24,%r19 1138 SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
324 mtsar %r19 1139 STD c3,16(r_ptr) ; r[2] = c3;
325 zvdep %r5,32,%r5 1140 COPY %r0,c3
326 zvdep %r3,32,%r21 1141
327 subi 32,%r24,%r20 1142 SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
328 mtsar %r20 1143 SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
329 vshd 0,%r4,%r20 1144 STD c1,24(r_ptr) ; r[3] = c1;
330 or %r21,%r20,%r3 1145 COPY %r0,c1
331 mtsar %r19 1146
332 zvdep %r4,32,%r4 1147 SQR_ADD_C a2L,a2R,c2,c3,c1
333L$0054 1148 SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
334 extru %r5,15,16,%r23 1149 SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
335 extru %r5,31,16,%r28 1150 STD c2,32(r_ptr) ; r[4] = c2;
336L$0055 1151 COPY %r0,c2
337 extru %r3,15,16,%r19 1152
338 comb,<> %r23,%r19,L$0058 1153 SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
339 copy %r3,%r26 1154 SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
340 bl L$0059,0 1155 SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
341 zdepi -1,31,16,%r29 1156 STD c3,40(r_ptr) ; r[5] = c3;
342L$0058 1157 COPY %r0,c3
343 .IMPORT $$divU,MILLICODE 1158
344 bl $$divU,%r31 1159 SQR_ADD_C a3L,a3R,c1,c2,c3
345 copy %r23,%r25 1160 SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
346L$0059 1161 SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
347 stw %r29,-16(0,%r30) 1162 SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
348 fldws -16(0,%r30),%fr10L 1163 STD c1,48(r_ptr) ; r[6] = c1;
349 stw %r28,-16(0,%r30) 1164 COPY %r0,c1
350 fldws -16(0,%r30),%fr10R 1165
351 stw %r23,-16(0,%r30) 1166 SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
352 xmpyu %fr10L,%fr10R,%fr8 1167 SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
353 fldws -16(0,%r30),%fr10R 1168 SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
354 fstws %fr8R,-16(0,%r30) 1169 SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
355 xmpyu %fr10L,%fr10R,%fr9 1170 STD c2,56(r_ptr) ; r[7] = c2;
356 ldw -16(0,%r30),%r8 1171 COPY %r0,c2
357 fstws %fr9R,-16(0,%r30) 1172
358 copy %r8,%r22 1173 SQR_ADD_C a4L,a4R,c3,c1,c2
359 ldw -16(0,%r30),%r8 1174 SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
360 extru %r4,15,16,%r24 1175 SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
361 copy %r8,%r21 1176 SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
362L$0060 1177 STD c3,64(r_ptr) ; r[8] = c3;
363 sub %r3,%r21,%r20 1178 COPY %r0,c3
364 copy %r20,%r19 1179
365 depi 0,31,16,%r19 1180 SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
366 comib,<> 0,%r19,L$0061 1181 SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
367 zdep %r20,15,16,%r19 1182 SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
368 addl %r19,%r24,%r19 1183 STD c1,72(r_ptr) ; r[9] = c1;
369 comb,>>= %r19,%r22,L$0061 1184 COPY %r0,c1
370 sub %r22,%r28,%r22 1185
371 sub %r21,%r23,%r21 1186 SQR_ADD_C a5L,a5R,c2,c3,c1
372 bl L$0060,0 1187 SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
373 ldo -1(%r29),%r29 1188 SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
374L$0061 1189 STD c2,80(r_ptr) ; r[10] = c2;
375 stw %r29,-16(0,%r30) 1190 COPY %r0,c2
376 fldws -16(0,%r30),%fr10L 1191
377 stw %r28,-16(0,%r30) 1192 SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
378 fldws -16(0,%r30),%fr10R 1193 SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
379 xmpyu %fr10L,%fr10R,%fr8 1194 STD c3,88(r_ptr) ; r[11] = c3;
380 fstws %fr8R,-16(0,%r30) 1195 COPY %r0,c3
381 ldw -16(0,%r30),%r8 1196
382 stw %r23,-16(0,%r30) 1197 SQR_ADD_C a6L,a6R,c1,c2,c3
383 fldws -16(0,%r30),%fr10R 1198 SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
384 copy %r8,%r19 1199 STD c1,96(r_ptr) ; r[12] = c1;
385 xmpyu %fr10L,%fr10R,%fr8 1200 COPY %r0,c1
386 fstws %fr8R,-16(0,%r30) 1201
387 extru %r19,15,16,%r20 1202 SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
388 ldw -16(0,%r30),%r8 1203 STD c2,104(r_ptr) ; r[13] = c2;
389 zdep %r19,15,16,%r19 1204 COPY %r0,c2
390 addl %r8,%r20,%r20 1205
391 comclr,<<= %r19,%r4,0 1206 SQR_ADD_C a7L,a7R,c3,c1,c2
392 addi 1,%r20,%r20 1207 STD c3, 112(r_ptr) ; r[14] = c3
393 comb,<<= %r20,%r3,L$0066 1208 STD c1, 120(r_ptr) ; r[15] = c1
394 sub %r4,%r19,%r4 1209
395 addl %r3,%r5,%r3 1210 .EXIT
396 ldo -1(%r29),%r29 1211 LDD -104(%sp),%r6 ; restore r6
397L$0066 1212 LDD -112(%sp),%r5 ; restore r5
398 addib,= -1,%r6,L$0056 1213 LDD -120(%sp),%r4 ; restore r4
399 sub %r3,%r20,%r3 1214 BVE (%rp)
400 zdep %r29,15,16,%r7 1215 LDD,MB -128(%sp),%r3
401 shd %r3,%r4,16,%r3 1216
402 bl L$0055,0 1217 .PROCEND
403 zdep %r4,15,16,%r4 1218
404L$0056 1219;-----------------------------------------------------------------------------
405 or %r7,%r29,%r28 1220;
406L$0068 1221;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
407 ldw -148(0,%r30),%r2 1222; arg0 = r_ptr
408 ldw -124(0,%r30),%r7 1223; arg1 = a_ptr
409 ldw -120(0,%r30),%r6 1224;
410 ldw -116(0,%r30),%r5 1225
411 ldw -112(0,%r30),%r4 1226bn_sqr_comba4
412 ldw -108(0,%r30),%r3 1227 .proc
413 bv 0(%r2) 1228 .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
414 ldwm -128(0,%r30),%r8 1229 .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
415 .EXIT 1230 .entry
416 .PROCEND 1231 .align 64
1232 STD %r3,0(%sp) ; save r3
1233 STD %r4,8(%sp) ; save r4
1234 STD %r5,16(%sp) ; save r5
1235 STD %r6,24(%sp) ; save r6
1236
1237 ;
1238 ; Zero out carries
1239 ;
1240 COPY %r0,c1
1241 COPY %r0,c2
1242 COPY %r0,c3
1243
1244 LDO 128(%sp),%sp ; bump stack
1245 DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
1246 DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
1247
1248 ;
1249 ; Load up all of the values we are going to use
1250 ;
1251 FLDD 0(a_ptr),a0
1252 FLDD 8(a_ptr),a1
1253 FLDD 16(a_ptr),a2
1254 FLDD 24(a_ptr),a3
1255 FLDD 32(a_ptr),a4
1256 FLDD 40(a_ptr),a5
1257 FLDD 48(a_ptr),a6
1258 FLDD 56(a_ptr),a7
1259
1260 SQR_ADD_C a0L,a0R,c1,c2,c3
1261
1262 STD c1,0(r_ptr) ; r[0] = c1;
1263 COPY %r0,c1
1264
1265 SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
1266
1267 STD c2,8(r_ptr) ; r[1] = c2;
1268 COPY %r0,c2
1269
1270 SQR_ADD_C a1L,a1R,c3,c1,c2
1271 SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
1272
1273 STD c3,16(r_ptr) ; r[2] = c3;
1274 COPY %r0,c3
1275
1276 SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
1277 SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
1278
1279 STD c1,24(r_ptr) ; r[3] = c1;
1280 COPY %r0,c1
1281
1282 SQR_ADD_C a2L,a2R,c2,c3,c1
1283 SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
1284
1285 STD c2,32(r_ptr) ; r[4] = c2;
1286 COPY %r0,c2
1287
1288 SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
1289 STD c3,40(r_ptr) ; r[5] = c3;
1290 COPY %r0,c3
1291
1292 SQR_ADD_C a3L,a3R,c1,c2,c3
1293 STD c1,48(r_ptr) ; r[6] = c1;
1294 STD c2,56(r_ptr) ; r[7] = c2;
1295
1296 .EXIT
1297 LDD -104(%sp),%r6 ; restore r6
1298 LDD -112(%sp),%r5 ; restore r5
1299 LDD -120(%sp),%r4 ; restore r4
1300 BVE (%rp)
1301 LDD,MB -128(%sp),%r3
1302
1303 .PROCEND
1304
1305
1306;---------------------------------------------------------------------------
1307
1308MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3
1309 XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht
1310 FSTD ftemp1,-16(%sp) ;
1311 XMPYU A0R,B0L,ftemp2 ; m = bh*lt
1312 FSTD ftemp2,-8(%sp) ;
1313 XMPYU A0R,B0R,ftemp3 ; lt = bl*lt
1314 FSTD ftemp3,-32(%sp)
1315 XMPYU A0L,B0L,ftemp4 ; ht = bh*ht
1316 FSTD ftemp4,-24(%sp) ;
1317
1318 LDD -8(%sp),m ; r21 = m
1319 LDD -16(%sp),m1 ; r19 = m1
1320 ADD,L m,m1,m ; m+m1
1321
1322 DEPD,Z m,31,32,temp3 ; (m+m1<<32)
1323 LDD -24(%sp),ht ; r24 = ht
1324
1325 CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
1326 ADD,L ht,high_one,ht ; ht+=high_one
1327
1328 EXTRD,U m,31,32,temp1 ; m >> 32
1329 LDD -32(%sp),lt ; lt
1330 ADD,L ht,temp1,ht ; ht+= m>>32
1331 ADD lt,temp3,lt ; lt = lt+m1
1332 ADD,DC ht,%r0,ht ; ht++
1333
1334 ADD C1,lt,C1 ; c1=c1+lt
1335 ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise
1336
1337 ADD C2,ht,C2 ; c2 = c2 + ht
1338 ADD,DC C3,%r0,C3 ; add in carry (c3++)
1339.endm
1340
1341
1342;
1343;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
1344; arg0 = r_ptr
1345; arg1 = a_ptr
1346; arg2 = b_ptr
1347;
1348
1349bn_mul_comba8
1350 .proc
1351 .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1352 .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1353 .entry
1354 .align 64
1355
1356 STD %r3,0(%sp) ; save r3
1357 STD %r4,8(%sp) ; save r4
1358 STD %r5,16(%sp) ; save r5
1359 STD %r6,24(%sp) ; save r6
1360 FSTD %fr12,32(%sp) ; save r6
1361 FSTD %fr13,40(%sp) ; save r7
1362
1363 ;
1364 ; Zero out carries
1365 ;
1366 COPY %r0,c1
1367 COPY %r0,c2
1368 COPY %r0,c3
1369
1370 LDO 128(%sp),%sp ; bump stack
1371 DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
1372
1373 ;
1374 ; Load up all of the values we are going to use
1375 ;
1376 FLDD 0(a_ptr),a0
1377 FLDD 8(a_ptr),a1
1378 FLDD 16(a_ptr),a2
1379 FLDD 24(a_ptr),a3
1380 FLDD 32(a_ptr),a4
1381 FLDD 40(a_ptr),a5
1382 FLDD 48(a_ptr),a6
1383 FLDD 56(a_ptr),a7
1384
1385 FLDD 0(b_ptr),b0
1386 FLDD 8(b_ptr),b1
1387 FLDD 16(b_ptr),b2
1388 FLDD 24(b_ptr),b3
1389 FLDD 32(b_ptr),b4
1390 FLDD 40(b_ptr),b5
1391 FLDD 48(b_ptr),b6
1392 FLDD 56(b_ptr),b7
1393
1394 MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
1395 STD c1,0(r_ptr)
1396 COPY %r0,c1
1397
1398 MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
1399 MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
1400 STD c2,8(r_ptr)
1401 COPY %r0,c2
1402
1403 MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
1404 MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
1405 MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
1406 STD c3,16(r_ptr)
1407 COPY %r0,c3
1408
1409 MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
1410 MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
1411 MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
1412 MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
1413 STD c1,24(r_ptr)
1414 COPY %r0,c1
1415
1416 MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
1417 MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
1418 MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
1419 MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
1420 MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
1421 STD c2,32(r_ptr)
1422 COPY %r0,c2
1423
1424 MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
1425 MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
1426 MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
1427 MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
1428 MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
1429 MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
1430 STD c3,40(r_ptr)
1431 COPY %r0,c3
1432
1433 MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
1434 MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
1435 MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
1436 MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
1437 MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
1438 MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
1439 MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
1440 STD c1,48(r_ptr)
1441 COPY %r0,c1
1442
1443 MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
1444 MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
1445 MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
1446 MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
1447 MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
1448 MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
1449 MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
1450 MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
1451 STD c2,56(r_ptr)
1452 COPY %r0,c2
1453
1454 MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
1455 MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
1456 MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
1457 MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
1458 MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
1459 MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
1460 MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
1461 STD c3,64(r_ptr)
1462 COPY %r0,c3
1463
1464 MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
1465 MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
1466 MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
1467 MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
1468 MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
1469 MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
1470 STD c1,72(r_ptr)
1471 COPY %r0,c1
1472
1473 MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
1474 MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
1475 MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
1476 MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
1477 MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
1478 STD c2,80(r_ptr)
1479 COPY %r0,c2
1480
1481 MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
1482 MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
1483 MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
1484 MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
1485 STD c3,88(r_ptr)
1486 COPY %r0,c3
1487
1488 MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
1489 MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
1490 MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
1491 STD c1,96(r_ptr)
1492 COPY %r0,c1
1493
1494 MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
1495 MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
1496 STD c2,104(r_ptr)
1497 COPY %r0,c2
1498
1499 MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
1500 STD c3,112(r_ptr)
1501 STD c1,120(r_ptr)
1502
1503 .EXIT
1504 FLDD -88(%sp),%fr13
1505 FLDD -96(%sp),%fr12
1506 LDD -104(%sp),%r6 ; restore r6
1507 LDD -112(%sp),%r5 ; restore r5
1508 LDD -120(%sp),%r4 ; restore r4
1509 BVE (%rp)
1510 LDD,MB -128(%sp),%r3
1511
1512 .PROCEND
1513
1514;-----------------------------------------------------------------------------
1515;
1516;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
1517; arg0 = r_ptr
1518; arg1 = a_ptr
1519; arg2 = b_ptr
1520;
1521
1522bn_mul_comba4
1523 .proc
1524 .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1525 .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1526 .entry
1527 .align 64
1528
1529 STD %r3,0(%sp) ; save r3
1530 STD %r4,8(%sp) ; save r4
1531 STD %r5,16(%sp) ; save r5
1532 STD %r6,24(%sp) ; save r6
1533 FSTD %fr12,32(%sp) ; save r6
1534 FSTD %fr13,40(%sp) ; save r7
1535
1536 ;
1537 ; Zero out carries
1538 ;
1539 COPY %r0,c1
1540 COPY %r0,c2
1541 COPY %r0,c3
1542
1543 LDO 128(%sp),%sp ; bump stack
1544 DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
1545
1546 ;
1547 ; Load up all of the values we are going to use
1548 ;
1549 FLDD 0(a_ptr),a0
1550 FLDD 8(a_ptr),a1
1551 FLDD 16(a_ptr),a2
1552 FLDD 24(a_ptr),a3
1553
1554 FLDD 0(b_ptr),b0
1555 FLDD 8(b_ptr),b1
1556 FLDD 16(b_ptr),b2
1557 FLDD 24(b_ptr),b3
1558
1559 MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
1560 STD c1,0(r_ptr)
1561 COPY %r0,c1
1562
1563 MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
1564 MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
1565 STD c2,8(r_ptr)
1566 COPY %r0,c2
1567
1568 MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
1569 MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
1570 MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
1571 STD c3,16(r_ptr)
1572 COPY %r0,c3
1573
1574 MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
1575 MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
1576 MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
1577 MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
1578 STD c1,24(r_ptr)
1579 COPY %r0,c1
1580
1581 MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
1582 MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
1583 MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
1584 STD c2,32(r_ptr)
1585 COPY %r0,c2
1586
1587 MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
1588 MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
1589 STD c3,40(r_ptr)
1590 COPY %r0,c3
1591
1592 MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
1593 STD c1,48(r_ptr)
1594 STD c2,56(r_ptr)
1595
1596 .EXIT
1597 FLDD -88(%sp),%fr13
1598 FLDD -96(%sp),%fr12
1599 LDD -104(%sp),%r6 ; restore r6
1600 LDD -112(%sp),%r5 ; restore r5
1601 LDD -120(%sp),%r4 ; restore r4
1602 BVE (%rp)
1603 LDD,MB -128(%sp),%r3
1604
1605 .PROCEND
1606
1607
1608 .SPACE $TEXT$
1609 .SUBSPA $CODE$
1610 .SPACE $PRIVATE$,SORT=16
1611 .IMPORT $global$,DATA
1612 .SPACE $TEXT$
1613 .SUBSPA $CODE$
1614 .SUBSPA $LIT$,ACCESS=0x2c
1615C$7
1616 .ALIGN 8
1617 .STRINGZ "Division would overflow (%d)\n"
1618 .END
diff --git a/src/lib/libcrypto/bn/asm/pa-risc2W.s b/src/lib/libcrypto/bn/asm/pa-risc2W.s
index 54b6606252..a99545754d 100644
--- a/src/lib/libcrypto/bn/asm/pa-risc2W.s
+++ b/src/lib/libcrypto/bn/asm/pa-risc2W.s
@@ -1598,7 +1598,7 @@ bn_mul_comba4
1598 .IMPORT $global$,DATA 1598 .IMPORT $global$,DATA
1599 .SPACE $TEXT$ 1599 .SPACE $TEXT$
1600 .SUBSPA $CODE$ 1600 .SUBSPA $CODE$
1601 .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16 1601 .SUBSPA $LIT$,ACCESS=0x2c
1602C$4 1602C$4
1603 .ALIGN 8 1603 .ALIGN 8
1604 .STRINGZ "Division would overflow (%d)\n" 1604 .STRINGZ "Division would overflow (%d)\n"
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h
index f935e1ca79..1eaf879553 100644
--- a/src/lib/libcrypto/bn/bn.h
+++ b/src/lib/libcrypto/bn/bn.h
@@ -59,38 +59,39 @@
59#ifndef HEADER_BN_H 59#ifndef HEADER_BN_H
60#define HEADER_BN_H 60#define HEADER_BN_H
61 61
62#ifndef WIN16 62#include <openssl/e_os2.h>
63#ifndef OPENSSL_NO_FP_API
63#include <stdio.h> /* FILE */ 64#include <stdio.h> /* FILE */
64#endif 65#endif
65#include <openssl/opensslconf.h>
66 66
67#ifdef __cplusplus 67#ifdef __cplusplus
68extern "C" { 68extern "C" {
69#endif 69#endif
70 70
71#ifdef VMS 71#ifdef OPENSSL_SYS_VMS
72#undef BN_LLONG /* experimental, so far... */ 72#undef BN_LLONG /* experimental, so far... */
73#endif 73#endif
74 74
75#define BN_MUL_COMBA 75#define BN_MUL_COMBA
76#define BN_SQR_COMBA 76#define BN_SQR_COMBA
77#define BN_RECURSION 77#define BN_RECURSION
78#define RECP_MUL_MOD
79#define MONT_MUL_MOD
80 78
81/* This next option uses the C libraries (2 word)/(1 word) function. 79/* This next option uses the C libraries (2 word)/(1 word) function.
82 * If it is not defined, I use my C version (which is slower). 80 * If it is not defined, I use my C version (which is slower).
83 * The reason for this flag is that when the particular C compiler 81 * The reason for this flag is that when the particular C compiler
84 * library routine is used, and the library is linked with a different 82 * library routine is used, and the library is linked with a different
85 * compiler, the library is missing. This mostly happens when the 83 * compiler, the library is missing. This mostly happens when the
86 * library is built with gcc and then linked using nornal cc. This would 84 * library is built with gcc and then linked using normal cc. This would
87 * be a common occurance because gcc normally produces code that is 85 * be a common occurrence because gcc normally produces code that is
88 * 2 times faster than system compilers for the big number stuff. 86 * 2 times faster than system compilers for the big number stuff.
89 * For machines with only one compiler (or shared libraries), this should 87 * For machines with only one compiler (or shared libraries), this should
90 * be on. Again this in only really a problem on machines 88 * be on. Again this in only really a problem on machines
91 * using "long long's", are 32bit, and are not using my assember code. */ 89 * using "long long's", are 32bit, and are not using my assembler code. */
92#if defined(MSDOS) || defined(WINDOWS) || defined(linux) 90#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
93#define BN_DIV2W 91 defined(OPENSSL_SYS_WIN32) || defined(linux)
92# ifndef BN_DIV2W
93# define BN_DIV2W
94# endif
94#endif 95#endif
95 96
96/* assuming long is 64bit - this is the DEC Alpha 97/* assuming long is 64bit - this is the DEC Alpha
@@ -118,8 +119,8 @@ extern "C" {
118 119
119/* This is where the long long data type is 64 bits, but long is 32. 120/* This is where the long long data type is 64 bits, but long is 32.
120 * For machines where there are 64bit registers, this is the mode to use. 121 * For machines where there are 64bit registers, this is the mode to use.
121 * IRIX, on R4000 and above should use this mode, along with the relevent 122 * IRIX, on R4000 and above should use this mode, along with the relevant
122 * assember code :-). Do NOT define BN_LLONG. 123 * assembler code :-). Do NOT define BN_LLONG.
123 */ 124 */
124#ifdef SIXTY_FOUR_BIT 125#ifdef SIXTY_FOUR_BIT
125#undef BN_LLONG 126#undef BN_LLONG
@@ -135,14 +136,14 @@ extern "C" {
135#define BN_MASK2h (0xffffffff00000000LL) 136#define BN_MASK2h (0xffffffff00000000LL)
136#define BN_MASK2h1 (0xffffffff80000000LL) 137#define BN_MASK2h1 (0xffffffff80000000LL)
137#define BN_TBIT (0x8000000000000000LL) 138#define BN_TBIT (0x8000000000000000LL)
138#define BN_DEC_CONV (10000000000000000000LL) 139#define BN_DEC_CONV (10000000000000000000ULL)
139#define BN_DEC_FMT1 "%llu" 140#define BN_DEC_FMT1 "%llu"
140#define BN_DEC_FMT2 "%019llu" 141#define BN_DEC_FMT2 "%019llu"
141#define BN_DEC_NUM 19 142#define BN_DEC_NUM 19
142#endif 143#endif
143 144
144#ifdef THIRTY_TWO_BIT 145#ifdef THIRTY_TWO_BIT
145#if defined(WIN32) && !defined(__GNUC__) 146#if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
146#define BN_ULLONG unsigned _int64 147#define BN_ULLONG unsigned _int64
147#else 148#else
148#define BN_ULLONG unsigned long long 149#define BN_ULLONG unsigned long long
@@ -153,7 +154,7 @@ extern "C" {
153#define BN_BYTES 4 154#define BN_BYTES 4
154#define BN_BITS2 32 155#define BN_BITS2 32
155#define BN_BITS4 16 156#define BN_BITS4 16
156#ifdef WIN32 157#ifdef OPENSSL_SYS_WIN32
157/* VC++ doesn't like the LL suffix */ 158/* VC++ doesn't like the LL suffix */
158#define BN_MASK (0xffffffffffffffffL) 159#define BN_MASK (0xffffffffffffffffL)
159#else 160#else
@@ -233,19 +234,13 @@ typedef struct bignum_st
233 BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ 234 BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
234 int top; /* Index of last used d +1. */ 235 int top; /* Index of last used d +1. */
235 /* The next are internal book keeping for bn_expand. */ 236 /* The next are internal book keeping for bn_expand. */
236 int max; /* Size of the d array. */ 237 int dmax; /* Size of the d array. */
237 int neg; /* one if the number is negative */ 238 int neg; /* one if the number is negative */
238 int flags; 239 int flags;
239 } BIGNUM; 240 } BIGNUM;
240 241
241/* Used for temp variables */ 242/* Used for temp variables (declaration hidden in bn_lcl.h) */
242#define BN_CTX_NUM 12 243typedef struct bignum_ctx BN_CTX;
243typedef struct bignum_ctx
244 {
245 int tos;
246 BIGNUM bn[BN_CTX_NUM+1];
247 int flags;
248 } BN_CTX;
249 244
250typedef struct bn_blinding_st 245typedef struct bn_blinding_st
251 { 246 {
@@ -257,16 +252,15 @@ typedef struct bn_blinding_st
257 252
258/* Used for montgomery multiplication */ 253/* Used for montgomery multiplication */
259typedef struct bn_mont_ctx_st 254typedef struct bn_mont_ctx_st
260 { 255 {
261 int use_word; /* 0 for word form, 1 for long form */ 256 int ri; /* number of bits in R */
262 int ri; /* number of bits in R */ 257 BIGNUM RR; /* used to convert to montgomery form */
263 BIGNUM RR; /* used to convert to montgomery form */ 258 BIGNUM N; /* The modulus */
264 BIGNUM N; /* The modulus */ 259 BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
265 BIGNUM Ni; /* The inverse of N */ 260 * (Ni is only stored for bignum algorithm) */
266 BN_ULONG n0; /* word form of inverse, normally only one of 261 BN_ULONG n0; /* least significant word of Ni */
267 * Ni or n0 is defined */
268 int flags; 262 int flags;
269 } BN_MONT_CTX; 263 } BN_MONT_CTX;
270 264
271/* Used for reciprocal division/mod functions 265/* Used for reciprocal division/mod functions
272 * It cannot be shared between threads 266 * It cannot be shared between threads
@@ -280,97 +274,129 @@ typedef struct bn_recp_ctx_st
280 int flags; 274 int flags;
281 } BN_RECP_CTX; 275 } BN_RECP_CTX;
282 276
283#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ 277#define BN_prime_checks 0 /* default: select number of iterations
284 r,a,&((mont)->RR),(mont),ctx) 278 based on the size of the number */
285 279
286#define BN_prime_checks (5) 280/* number of Miller-Rabin iterations for an error rate of less than 2^-80
281 * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
282 * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
283 * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
284 * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
285#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \
286 (b) >= 850 ? 3 : \
287 (b) >= 650 ? 4 : \
288 (b) >= 550 ? 5 : \
289 (b) >= 450 ? 6 : \
290 (b) >= 400 ? 7 : \
291 (b) >= 350 ? 8 : \
292 (b) >= 300 ? 9 : \
293 (b) >= 250 ? 12 : \
294 (b) >= 200 ? 15 : \
295 (b) >= 150 ? 18 : \
296 /* b >= 100 */ 27)
287 297
288#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) 298#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
289#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) 299
290#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0)) 300/* Note that BN_abs_is_word does not work reliably for w == 0 */
291#define BN_is_one(a) (BN_is_word((a),1)) 301#define BN_abs_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
292#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) 302#define BN_is_zero(a) (((a)->top == 0) || BN_abs_is_word(a,0))
303#define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg)
304#define BN_is_word(a,w) ((w) ? BN_abs_is_word((a),(w)) && !(a)->neg : \
305 BN_is_zero((a)))
306#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
307
293#define BN_one(a) (BN_set_word((a),1)) 308#define BN_one(a) (BN_set_word((a),1))
294#define BN_zero(a) (BN_set_word((a),0)) 309#define BN_zero(a) (BN_set_word((a),0))
295 310
296/*#define BN_ascii2bn(a) BN_hex2bn(a) */ 311/*#define BN_ascii2bn(a) BN_hex2bn(a) */
297/*#define BN_bn2ascii(a) BN_bn2hex(a) */ 312/*#define BN_bn2ascii(a) BN_bn2hex(a) */
298 313
299#define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\ 314const BIGNUM *BN_value_one(void);
300 (n):bn_expand2((n),(b)/BN_BITS2+1))
301#define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b)))
302
303#define bn_fix_top(a) \
304 { \
305 BN_ULONG *ftl; \
306 if ((a)->top > 0) \
307 { \
308 for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
309 if (*(ftl--)) break; \
310 } \
311 }
312
313BIGNUM *BN_value_one(void);
314char * BN_options(void); 315char * BN_options(void);
315BN_CTX *BN_CTX_new(void); 316BN_CTX *BN_CTX_new(void);
316void BN_CTX_init(BN_CTX *c); 317void BN_CTX_init(BN_CTX *c);
317void BN_CTX_free(BN_CTX *c); 318void BN_CTX_free(BN_CTX *c);
319void BN_CTX_start(BN_CTX *ctx);
320BIGNUM *BN_CTX_get(BN_CTX *ctx);
321void BN_CTX_end(BN_CTX *ctx);
318int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); 322int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
323int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
324int BN_rand_range(BIGNUM *rnd, BIGNUM *range);
325int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
319int BN_num_bits(const BIGNUM *a); 326int BN_num_bits(const BIGNUM *a);
320int BN_num_bits_word(BN_ULONG); 327int BN_num_bits_word(BN_ULONG);
321BIGNUM *BN_new(void); 328BIGNUM *BN_new(void);
322void BN_init(BIGNUM *); 329void BN_init(BIGNUM *);
323void BN_clear_free(BIGNUM *a); 330void BN_clear_free(BIGNUM *a);
324BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); 331BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
332void BN_swap(BIGNUM *a, BIGNUM *b);
325BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret); 333BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
326int BN_bn2bin(const BIGNUM *a, unsigned char *to); 334int BN_bn2bin(const BIGNUM *a, unsigned char *to);
327BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret); 335BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret);
328int BN_bn2mpi(const BIGNUM *a, unsigned char *to); 336int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
329int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); 337int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
330int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); 338int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
331int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); 339int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
332int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); 340int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
333int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); 341int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
342int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
343
334int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, 344int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
335 BN_CTX *ctx); 345 BN_CTX *ctx);
336int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx); 346#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
337int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); 347int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
338BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w); 348int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
349int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
350int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
351int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
352int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
353 const BIGNUM *m, BN_CTX *ctx);
354int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
355int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
356int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
357int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
358int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
359
360BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
339BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); 361BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
340int BN_mul_word(BIGNUM *a, BN_ULONG w); 362int BN_mul_word(BIGNUM *a, BN_ULONG w);
341int BN_add_word(BIGNUM *a, BN_ULONG w); 363int BN_add_word(BIGNUM *a, BN_ULONG w);
342int BN_sub_word(BIGNUM *a, BN_ULONG w); 364int BN_sub_word(BIGNUM *a, BN_ULONG w);
343int BN_set_word(BIGNUM *a, BN_ULONG w); 365int BN_set_word(BIGNUM *a, BN_ULONG w);
344BN_ULONG BN_get_word(BIGNUM *a); 366BN_ULONG BN_get_word(const BIGNUM *a);
367
345int BN_cmp(const BIGNUM *a, const BIGNUM *b); 368int BN_cmp(const BIGNUM *a, const BIGNUM *b);
346void BN_free(BIGNUM *a); 369void BN_free(BIGNUM *a);
347int BN_is_bit_set(const BIGNUM *a, int n); 370int BN_is_bit_set(const BIGNUM *a, int n);
348int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); 371int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
349int BN_lshift1(BIGNUM *r, BIGNUM *a); 372int BN_lshift1(BIGNUM *r, const BIGNUM *a);
350int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx); 373int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
351int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 374
352 const BIGNUM *m,BN_CTX *ctx); 375int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
353int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 376 const BIGNUM *m,BN_CTX *ctx);
354 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 377int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
355int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2, 378 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
356 BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx); 379int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
357int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, 380 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
358 BIGNUM *m,BN_CTX *ctx); 381int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
382 const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
383 BN_CTX *ctx,BN_MONT_CTX *m_ctx);
384int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
385 const BIGNUM *m,BN_CTX *ctx);
386
359int BN_mask_bits(BIGNUM *a,int n); 387int BN_mask_bits(BIGNUM *a,int n);
360int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); 388#ifndef OPENSSL_NO_FP_API
361#ifndef WIN16 389int BN_print_fp(FILE *fp, const BIGNUM *a);
362int BN_print_fp(FILE *fp, BIGNUM *a);
363#endif 390#endif
364#ifdef HEADER_BIO_H 391#ifdef HEADER_BIO_H
365int BN_print(BIO *fp, const BIGNUM *a); 392int BN_print(BIO *fp, const BIGNUM *a);
366#else 393#else
367int BN_print(char *fp, const BIGNUM *a); 394int BN_print(void *fp, const BIGNUM *a);
368#endif 395#endif
369int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx); 396int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
370int BN_rshift(BIGNUM *r, BIGNUM *a, int n); 397int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
371int BN_rshift1(BIGNUM *r, BIGNUM *a); 398int BN_rshift1(BIGNUM *r, const BIGNUM *a);
372void BN_clear(BIGNUM *a); 399void BN_clear(BIGNUM *a);
373BIGNUM *bn_expand2(BIGNUM *b, int bits);
374BIGNUM *BN_dup(const BIGNUM *a); 400BIGNUM *BN_dup(const BIGNUM *a);
375int BN_ucmp(const BIGNUM *a, const BIGNUM *b); 401int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
376int BN_set_bit(BIGNUM *a, int n); 402int BN_set_bit(BIGNUM *a, int n);
@@ -379,26 +405,30 @@ char * BN_bn2hex(const BIGNUM *a);
379char * BN_bn2dec(const BIGNUM *a); 405char * BN_bn2dec(const BIGNUM *a);
380int BN_hex2bn(BIGNUM **a, const char *str); 406int BN_hex2bn(BIGNUM **a, const char *str);
381int BN_dec2bn(BIGNUM **a, const char *str); 407int BN_dec2bn(BIGNUM **a, const char *str);
382int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); 408int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
383BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); 409int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
384BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int strong,BIGNUM *add, 410BIGNUM *BN_mod_inverse(BIGNUM *ret,
385 BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg); 411 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
386int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *), 412BIGNUM *BN_mod_sqrt(BIGNUM *ret,
387 BN_CTX *ctx,void *cb_arg); 413 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
388void ERR_load_BN_strings(void ); 414BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
389 415 const BIGNUM *add, const BIGNUM *rem,
390BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); 416 void (*callback)(int,int,void *),void *cb_arg);
391BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); 417int BN_is_prime(const BIGNUM *p,int nchecks,
392void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num); 418 void (*callback)(int,int,void *),
393BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); 419 BN_CTX *ctx,void *cb_arg);
394BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num); 420int BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
395BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num); 421 void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
422 int do_trial_division);
396 423
397BN_MONT_CTX *BN_MONT_CTX_new(void ); 424BN_MONT_CTX *BN_MONT_CTX_new(void );
398void BN_MONT_CTX_init(BN_MONT_CTX *ctx); 425void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
399int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont, 426int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
400 BN_CTX *ctx); 427 BN_MONT_CTX *mont, BN_CTX *ctx);
401int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx); 428#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
429 (r),(a),&((mont)->RR),(mont),(ctx))
430int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
431 BN_MONT_CTX *mont, BN_CTX *ctx);
402void BN_MONT_CTX_free(BN_MONT_CTX *mont); 432void BN_MONT_CTX_free(BN_MONT_CTX *mont);
403int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx); 433int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
404BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); 434BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
@@ -416,18 +446,55 @@ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
416BN_RECP_CTX *BN_RECP_CTX_new(void); 446BN_RECP_CTX *BN_RECP_CTX_new(void);
417void BN_RECP_CTX_free(BN_RECP_CTX *recp); 447void BN_RECP_CTX_free(BN_RECP_CTX *recp);
418int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx); 448int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
419int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, 449int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
420 BN_RECP_CTX *recp,BN_CTX *ctx); 450 BN_RECP_CTX *recp,BN_CTX *ctx);
421int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 451int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
422 const BIGNUM *m, BN_CTX *ctx); 452 const BIGNUM *m, BN_CTX *ctx);
423int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, 453int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
424 BN_RECP_CTX *recp, BN_CTX *ctx); 454 BN_RECP_CTX *recp, BN_CTX *ctx);
455
456/* library internal functions */
457
458#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
459 (a):bn_expand2((a),(bits)/BN_BITS2+1))
460#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
461BIGNUM *bn_expand2(BIGNUM *a, int words);
462BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
463
464#define bn_fix_top(a) \
465 { \
466 BN_ULONG *ftl; \
467 if ((a)->top > 0) \
468 { \
469 for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
470 if (*(ftl--)) break; \
471 } \
472 }
425 473
474BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
475BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
476void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
477BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
478BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
479BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
480
481#ifdef BN_DEBUG
482void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n);
483# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
484 fprintf(stderr,"\n");}
485# define bn_dump(a,n) bn_dump1(stderr,#a,a,n);
486#else
487# define bn_print(a)
488# define bn_dump(a,b)
489#endif
490
491int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
426 492
427/* BEGIN ERROR CODES */ 493/* BEGIN ERROR CODES */
428/* The following lines are auto generated by the script mkerr.pl. Any changes 494/* The following lines are auto generated by the script mkerr.pl. Any changes
429 * made after this point may be overwritten when the script is next run. 495 * made after this point may be overwritten when the script is next run.
430 */ 496 */
497void ERR_load_BN_strings(void);
431 498
432/* Error codes for the BN functions. */ 499/* Error codes for the BN functions. */
433 500
@@ -438,30 +505,43 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
438#define BN_F_BN_BLINDING_UPDATE 103 505#define BN_F_BN_BLINDING_UPDATE 103
439#define BN_F_BN_BN2DEC 104 506#define BN_F_BN_BN2DEC 104
440#define BN_F_BN_BN2HEX 105 507#define BN_F_BN_BN2HEX 105
508#define BN_F_BN_CTX_GET 116
441#define BN_F_BN_CTX_NEW 106 509#define BN_F_BN_CTX_NEW 106
442#define BN_F_BN_DIV 107 510#define BN_F_BN_DIV 107
443#define BN_F_BN_EXPAND2 108 511#define BN_F_BN_EXPAND2 108
512#define BN_F_BN_EXPAND_INTERNAL 120
513#define BN_F_BN_MOD_EXP2_MONT 118
444#define BN_F_BN_MOD_EXP_MONT 109 514#define BN_F_BN_MOD_EXP_MONT 109
515#define BN_F_BN_MOD_EXP_MONT_WORD 117
445#define BN_F_BN_MOD_INVERSE 110 516#define BN_F_BN_MOD_INVERSE 110
517#define BN_F_BN_MOD_LSHIFT_QUICK 119
446#define BN_F_BN_MOD_MUL_RECIPROCAL 111 518#define BN_F_BN_MOD_MUL_RECIPROCAL 111
519#define BN_F_BN_MOD_SQRT 121
447#define BN_F_BN_MPI2BN 112 520#define BN_F_BN_MPI2BN 112
448#define BN_F_BN_NEW 113 521#define BN_F_BN_NEW 113
449#define BN_F_BN_RAND 114 522#define BN_F_BN_RAND 114
523#define BN_F_BN_RAND_RANGE 122
450#define BN_F_BN_USUB 115 524#define BN_F_BN_USUB 115
451 525
452/* Reason codes. */ 526/* Reason codes. */
453#define BN_R_ARG2_LT_ARG3 100 527#define BN_R_ARG2_LT_ARG3 100
454#define BN_R_BAD_RECIPROCAL 101 528#define BN_R_BAD_RECIPROCAL 101
529#define BN_R_BIGNUM_TOO_LONG 114
455#define BN_R_CALLED_WITH_EVEN_MODULUS 102 530#define BN_R_CALLED_WITH_EVEN_MODULUS 102
456#define BN_R_DIV_BY_ZERO 103 531#define BN_R_DIV_BY_ZERO 103
457#define BN_R_ENCODING_ERROR 104 532#define BN_R_ENCODING_ERROR 104
458#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 533#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
534#define BN_R_INPUT_NOT_REDUCED 110
459#define BN_R_INVALID_LENGTH 106 535#define BN_R_INVALID_LENGTH 106
536#define BN_R_INVALID_RANGE 115
537#define BN_R_NOT_A_SQUARE 111
460#define BN_R_NOT_INITIALIZED 107 538#define BN_R_NOT_INITIALIZED 107
461#define BN_R_NO_INVERSE 108 539#define BN_R_NO_INVERSE 108
540#define BN_R_P_IS_NOT_PRIME 112
541#define BN_R_TOO_MANY_ITERATIONS 113
542#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
462 543
463#ifdef __cplusplus 544#ifdef __cplusplus
464} 545}
465#endif 546#endif
466#endif 547#endif
467
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c
index efb2e312e8..6cba07e9f6 100644
--- a/src/lib/libcrypto/bn/bn_add.c
+++ b/src/lib/libcrypto/bn/bn_add.c
@@ -61,76 +61,70 @@
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63/* r can == a or b */ 63/* r can == a or b */
64int BN_add(r, a, b) 64int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
65BIGNUM *r;
66BIGNUM *a;
67BIGNUM *b;
68 { 65 {
69 int i; 66 const BIGNUM *tmp;
70 BIGNUM *tmp; 67 int a_neg = a->neg;
68
69 bn_check_top(a);
70 bn_check_top(b);
71 71
72 /* a + b a+b 72 /* a + b a+b
73 * a + -b a-b 73 * a + -b a-b
74 * -a + b b-a 74 * -a + b b-a
75 * -a + -b -(a+b) 75 * -a + -b -(a+b)
76 */ 76 */
77 if (a->neg ^ b->neg) 77 if (a_neg ^ b->neg)
78 { 78 {
79 /* only one is negative */ 79 /* only one is negative */
80 if (a->neg) 80 if (a_neg)
81 { tmp=a; a=b; b=tmp; } 81 { tmp=a; a=b; b=tmp; }
82 82
83 /* we are now a - b */ 83 /* we are now a - b */
84 84
85 if (BN_ucmp(a,b) < 0) 85 if (BN_ucmp(a,b) < 0)
86 { 86 {
87 if (bn_wexpand(r,b->top) == NULL) return(0); 87 if (!BN_usub(r,b,a)) return(0);
88 bn_qsub(r,b,a);
89 r->neg=1; 88 r->neg=1;
90 } 89 }
91 else 90 else
92 { 91 {
93 if (bn_wexpand(r,a->top) == NULL) return(0); 92 if (!BN_usub(r,a,b)) return(0);
94 bn_qsub(r,a,b);
95 r->neg=0; 93 r->neg=0;
96 } 94 }
97 return(1); 95 return(1);
98 } 96 }
99 97
100 if (a->neg) /* both are neg */ 98 if (!BN_uadd(r,a,b)) return(0);
99 if (a_neg) /* both are neg */
101 r->neg=1; 100 r->neg=1;
102 else 101 else
103 r->neg=0; 102 r->neg=0;
104
105 i=(a->top > b->top);
106
107 if (i)
108 {
109 if (bn_wexpand(r,a->top+1) == NULL) return(0);
110 bn_qadd(r,a,b);
111 }
112 else
113 {
114 if (bn_wexpand(r,b->top+1) == NULL) return(0);
115 bn_qadd(r,b,a);
116 }
117 return(1); 103 return(1);
118 } 104 }
119 105
120/* unsigned add of b to a, r must be large enough */ 106/* unsigned add of b to a, r must be large enough */
121void bn_qadd(r,a,b) 107int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
122BIGNUM *r;
123BIGNUM *a;
124BIGNUM *b;
125 { 108 {
126 register int i; 109 register int i;
127 int max,min; 110 int max,min;
128 BN_ULONG *ap,*bp,*rp,carry,t1; 111 BN_ULONG *ap,*bp,*rp,carry,t1;
112 const BIGNUM *tmp;
113
114 bn_check_top(a);
115 bn_check_top(b);
129 116
117 if (a->top < b->top)
118 { tmp=a; a=b; b=tmp; }
130 max=a->top; 119 max=a->top;
131 min=b->top; 120 min=b->top;
121
122 if (bn_wexpand(r,max+1) == NULL)
123 return(0);
124
132 r->top=max; 125 r->top=max;
133 126
127
134 ap=a->d; 128 ap=a->d;
135 bp=b->d; 129 bp=b->d;
136 rp=r->d; 130 rp=r->d;
@@ -160,8 +154,156 @@ BIGNUM *b;
160 r->top++; 154 r->top++;
161 } 155 }
162 } 156 }
163 for (; i<max; i++) 157 if (rp != ap)
164 *(rp++)= *(ap++); 158 {
159 for (; i<max; i++)
160 *(rp++)= *(ap++);
161 }
165 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/ 162 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
163 r->neg = 0;
164 return(1);
165 }
166
167/* unsigned subtraction of b from a, a must be larger than b. */
168int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
169 {
170 int max,min;
171 register BN_ULONG t1,t2,*ap,*bp,*rp;
172 int i,carry;
173#if defined(IRIX_CC_BUG) && !defined(LINT)
174 int dummy;
175#endif
176
177 bn_check_top(a);
178 bn_check_top(b);
179
180 if (a->top < b->top) /* hmm... should not be happening */
181 {
182 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
183 return(0);
184 }
185
186 max=a->top;
187 min=b->top;
188 if (bn_wexpand(r,max) == NULL) return(0);
189
190 ap=a->d;
191 bp=b->d;
192 rp=r->d;
193
194#if 1
195 carry=0;
196 for (i=0; i<min; i++)
197 {
198 t1= *(ap++);
199 t2= *(bp++);
200 if (carry)
201 {
202 carry=(t1 <= t2);
203 t1=(t1-t2-1)&BN_MASK2;
204 }
205 else
206 {
207 carry=(t1 < t2);
208 t1=(t1-t2)&BN_MASK2;
209 }
210#if defined(IRIX_CC_BUG) && !defined(LINT)
211 dummy=t1;
212#endif
213 *(rp++)=t1&BN_MASK2;
214 }
215#else
216 carry=bn_sub_words(rp,ap,bp,min);
217 ap+=min;
218 bp+=min;
219 rp+=min;
220 i=min;
221#endif
222 if (carry) /* subtracted */
223 {
224 while (i < max)
225 {
226 i++;
227 t1= *(ap++);
228 t2=(t1-1)&BN_MASK2;
229 *(rp++)=t2;
230 if (t1 > t2) break;
231 }
232 }
233#if 0
234 memcpy(rp,ap,sizeof(*rp)*(max-i));
235#else
236 if (rp != ap)
237 {
238 for (;;)
239 {
240 if (i++ >= max) break;
241 rp[0]=ap[0];
242 if (i++ >= max) break;
243 rp[1]=ap[1];
244 if (i++ >= max) break;
245 rp[2]=ap[2];
246 if (i++ >= max) break;
247 rp[3]=ap[3];
248 rp+=4;
249 ap+=4;
250 }
251 }
252#endif
253
254 r->top=max;
255 r->neg=0;
256 bn_fix_top(r);
257 return(1);
258 }
259
260int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
261 {
262 int max;
263 int add=0,neg=0;
264 const BIGNUM *tmp;
265
266 bn_check_top(a);
267 bn_check_top(b);
268
269 /* a - b a-b
270 * a - -b a+b
271 * -a - b -(a+b)
272 * -a - -b b-a
273 */
274 if (a->neg)
275 {
276 if (b->neg)
277 { tmp=a; a=b; b=tmp; }
278 else
279 { add=1; neg=1; }
280 }
281 else
282 {
283 if (b->neg) { add=1; neg=0; }
284 }
285
286 if (add)
287 {
288 if (!BN_uadd(r,a,b)) return(0);
289 r->neg=neg;
290 return(1);
291 }
292
293 /* We are actually doing a - b :-) */
294
295 max=(a->top > b->top)?a->top:b->top;
296 if (bn_wexpand(r,max) == NULL) return(0);
297 if (BN_ucmp(a,b) < 0)
298 {
299 if (!BN_usub(r,b,a)) return(0);
300 r->neg=1;
301 }
302 else
303 {
304 if (!BN_usub(r,a,b)) return(0);
305 r->neg=0;
306 }
307 return(1);
166 } 308 }
167 309
diff --git a/src/lib/libcrypto/bn/bn_asm.c b/src/lib/libcrypto/bn/bn_asm.c
index 4d3da16a0c..be8aa3ffc5 100644
--- a/src/lib/libcrypto/bn/bn_asm.c
+++ b/src/lib/libcrypto/bn/bn_asm.c
@@ -56,97 +56,95 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
59#include <stdio.h> 64#include <stdio.h>
65#include <assert.h>
60#include "cryptlib.h" 66#include "cryptlib.h"
61#include "bn_lcl.h" 67#include "bn_lcl.h"
62 68
63#ifdef BN_LLONG 69#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
64 70
65BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 71BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
66 { 72 {
67 BN_ULONG c1=0; 73 BN_ULONG c1=0;
68 74
69 bn_check_num(num); 75 assert(num >= 0);
70 if (num <= 0) return(c1); 76 if (num <= 0) return(c1);
71 77
72 for (;;) 78 while (num&~3)
73 { 79 {
74 mul_add(rp[0],ap[0],w,c1); 80 mul_add(rp[0],ap[0],w,c1);
75 if (--num == 0) break;
76 mul_add(rp[1],ap[1],w,c1); 81 mul_add(rp[1],ap[1],w,c1);
77 if (--num == 0) break;
78 mul_add(rp[2],ap[2],w,c1); 82 mul_add(rp[2],ap[2],w,c1);
79 if (--num == 0) break;
80 mul_add(rp[3],ap[3],w,c1); 83 mul_add(rp[3],ap[3],w,c1);
81 if (--num == 0) break; 84 ap+=4; rp+=4; num-=4;
82 ap+=4; 85 }
83 rp+=4; 86 if (num)
87 {
88 mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
89 mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
90 mul_add(rp[2],ap[2],w,c1); return c1;
84 } 91 }
85 92
86 return(c1); 93 return(c1);
87 } 94 }
88 95
89BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 96BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
90 { 97 {
91 BN_ULONG c1=0; 98 BN_ULONG c1=0;
92 99
93 bn_check_num(num); 100 assert(num >= 0);
94 if (num <= 0) return(c1); 101 if (num <= 0) return(c1);
95 102
96 /* for (;;) */ 103 while (num&~3)
97 while (1) /* circumvent egcs-1.1.2 bug */
98 { 104 {
99 mul(rp[0],ap[0],w,c1); 105 mul(rp[0],ap[0],w,c1);
100 if (--num == 0) break;
101 mul(rp[1],ap[1],w,c1); 106 mul(rp[1],ap[1],w,c1);
102 if (--num == 0) break;
103 mul(rp[2],ap[2],w,c1); 107 mul(rp[2],ap[2],w,c1);
104 if (--num == 0) break;
105 mul(rp[3],ap[3],w,c1); 108 mul(rp[3],ap[3],w,c1);
106 if (--num == 0) break; 109 ap+=4; rp+=4; num-=4;
107 ap+=4; 110 }
108 rp+=4; 111 if (num)
112 {
113 mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
114 mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
115 mul(rp[2],ap[2],w,c1);
109 } 116 }
110 return(c1); 117 return(c1);
111 } 118 }
112 119
113void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) 120void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
114 { 121 {
115 bn_check_num(n); 122 assert(n >= 0);
116 if (n <= 0) return; 123 if (n <= 0) return;
117 for (;;) 124 while (n&~3)
118 { 125 {
119 BN_ULLONG t; 126 sqr(r[0],r[1],a[0]);
120 127 sqr(r[2],r[3],a[1]);
121 t=(BN_ULLONG)(a[0])*(a[0]); 128 sqr(r[4],r[5],a[2]);
122 r[0]=Lw(t); r[1]=Hw(t); 129 sqr(r[6],r[7],a[3]);
123 if (--n == 0) break; 130 a+=4; r+=8; n-=4;
124 131 }
125 t=(BN_ULLONG)(a[1])*(a[1]); 132 if (n)
126 r[2]=Lw(t); r[3]=Hw(t); 133 {
127 if (--n == 0) break; 134 sqr(r[0],r[1],a[0]); if (--n == 0) return;
128 135 sqr(r[2],r[3],a[1]); if (--n == 0) return;
129 t=(BN_ULLONG)(a[2])*(a[2]); 136 sqr(r[4],r[5],a[2]);
130 r[4]=Lw(t); r[5]=Hw(t);
131 if (--n == 0) break;
132
133 t=(BN_ULLONG)(a[3])*(a[3]);
134 r[6]=Lw(t); r[7]=Hw(t);
135 if (--n == 0) break;
136
137 a+=4;
138 r+=8;
139 } 137 }
140 } 138 }
141 139
142#else 140#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
143 141
144BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 142BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
145 { 143 {
146 BN_ULONG c=0; 144 BN_ULONG c=0;
147 BN_ULONG bl,bh; 145 BN_ULONG bl,bh;
148 146
149 bn_check_num(num); 147 assert(num >= 0);
150 if (num <= 0) return((BN_ULONG)0); 148 if (num <= 0) return((BN_ULONG)0);
151 149
152 bl=LBITS(w); 150 bl=LBITS(w);
@@ -168,12 +166,12 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
168 return(c); 166 return(c);
169 } 167 }
170 168
171BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 169BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
172 { 170 {
173 BN_ULONG carry=0; 171 BN_ULONG carry=0;
174 BN_ULONG bl,bh; 172 BN_ULONG bl,bh;
175 173
176 bn_check_num(num); 174 assert(num >= 0);
177 if (num <= 0) return((BN_ULONG)0); 175 if (num <= 0) return((BN_ULONG)0);
178 176
179 bl=LBITS(w); 177 bl=LBITS(w);
@@ -195,9 +193,9 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
195 return(carry); 193 return(carry);
196 } 194 }
197 195
198void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) 196void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
199 { 197 {
200 bn_check_num(n); 198 assert(n >= 0);
201 if (n <= 0) return; 199 if (n <= 0) return;
202 for (;;) 200 for (;;)
203 { 201 {
@@ -218,7 +216,7 @@ void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
218 } 216 }
219 } 217 }
220 218
221#endif 219#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
222 220
223#if defined(BN_LLONG) && defined(BN_DIV2W) 221#if defined(BN_LLONG) && defined(BN_DIV2W)
224 222
@@ -229,7 +227,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
229 227
230#else 228#else
231 229
232/* Divide h-l by d and return the result. */ 230/* Divide h,l by d and return the result. */
233/* I need to test this some more :-( */ 231/* I need to test this some more :-( */
234BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) 232BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
235 { 233 {
@@ -239,13 +237,8 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
239 if (d == 0) return(BN_MASK2); 237 if (d == 0) return(BN_MASK2);
240 238
241 i=BN_num_bits_word(d); 239 i=BN_num_bits_word(d);
242 if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i)) 240 assert((i == BN_BITS2) || (h > (BN_ULONG)1<<i));
243 { 241
244#if !defined(NO_STDIO) && !defined(WIN16)
245 fprintf(stderr,"Division would overflow (%d)\n",i);
246#endif
247 abort();
248 }
249 i=BN_BITS2-i; 242 i=BN_BITS2-i;
250 if (h >= d) h-=d; 243 if (h >= d) h-=d;
251 244
@@ -300,14 +293,14 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
300 ret|=q; 293 ret|=q;
301 return(ret); 294 return(ret);
302 } 295 }
303#endif 296#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
304 297
305#ifdef BN_LLONG 298#ifdef BN_LLONG
306BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 299BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
307 { 300 {
308 BN_ULLONG ll=0; 301 BN_ULLONG ll=0;
309 302
310 bn_check_num(n); 303 assert(n >= 0);
311 if (n <= 0) return((BN_ULONG)0); 304 if (n <= 0) return((BN_ULONG)0);
312 305
313 for (;;) 306 for (;;)
@@ -338,12 +331,12 @@ BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
338 } 331 }
339 return((BN_ULONG)ll); 332 return((BN_ULONG)ll);
340 } 333 }
341#else 334#else /* !BN_LLONG */
342BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 335BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
343 { 336 {
344 BN_ULONG c,l,t; 337 BN_ULONG c,l,t;
345 338
346 bn_check_num(n); 339 assert(n >= 0);
347 if (n <= 0) return((BN_ULONG)0); 340 if (n <= 0) return((BN_ULONG)0);
348 341
349 c=0; 342 c=0;
@@ -387,14 +380,14 @@ BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
387 } 380 }
388 return((BN_ULONG)c); 381 return((BN_ULONG)c);
389 } 382 }
390#endif 383#endif /* !BN_LLONG */
391 384
392BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 385BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
393 { 386 {
394 BN_ULONG t1,t2; 387 BN_ULONG t1,t2;
395 int c=0; 388 int c=0;
396 389
397 bn_check_num(n); 390 assert(n >= 0);
398 if (n <= 0) return((BN_ULONG)0); 391 if (n <= 0) return((BN_ULONG)0);
399 392
400 for (;;) 393 for (;;)
@@ -433,6 +426,11 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
433#undef bn_sqr_comba8 426#undef bn_sqr_comba8
434#undef bn_sqr_comba4 427#undef bn_sqr_comba4
435 428
429/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
430/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
431/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
432/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
433
436#ifdef BN_LLONG 434#ifdef BN_LLONG
437#define mul_add_c(a,b,c0,c1,c2) \ 435#define mul_add_c(a,b,c0,c1,c2) \
438 t=(BN_ULLONG)a*b; \ 436 t=(BN_ULLONG)a*b; \
@@ -460,7 +458,39 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
460 458
461#define sqr_add_c2(a,i,j,c0,c1,c2) \ 459#define sqr_add_c2(a,i,j,c0,c1,c2) \
462 mul_add_c2((a)[i],(a)[j],c0,c1,c2) 460 mul_add_c2((a)[i],(a)[j],c0,c1,c2)
463#else 461
462#elif defined(BN_UMULT_HIGH)
463
464#define mul_add_c(a,b,c0,c1,c2) { \
465 BN_ULONG ta=(a),tb=(b); \
466 t1 = ta * tb; \
467 t2 = BN_UMULT_HIGH(ta,tb); \
468 c0 += t1; t2 += (c0<t1)?1:0; \
469 c1 += t2; c2 += (c1<t2)?1:0; \
470 }
471
472#define mul_add_c2(a,b,c0,c1,c2) { \
473 BN_ULONG ta=(a),tb=(b),t0; \
474 t1 = BN_UMULT_HIGH(ta,tb); \
475 t0 = ta * tb; \
476 t2 = t1+t1; c2 += (t2<t1)?1:0; \
477 t1 = t0+t0; t2 += (t1<t0)?1:0; \
478 c0 += t1; t2 += (c0<t1)?1:0; \
479 c1 += t2; c2 += (c1<t2)?1:0; \
480 }
481
482#define sqr_add_c(a,i,c0,c1,c2) { \
483 BN_ULONG ta=(a)[i]; \
484 t1 = ta * ta; \
485 t2 = BN_UMULT_HIGH(ta,ta); \
486 c0 += t1; t2 += (c0<t1)?1:0; \
487 c1 += t2; c2 += (c1<t2)?1:0; \
488 }
489
490#define sqr_add_c2(a,i,j,c0,c1,c2) \
491 mul_add_c2((a)[i],(a)[j],c0,c1,c2)
492
493#else /* !BN_LLONG */
464#define mul_add_c(a,b,c0,c1,c2) \ 494#define mul_add_c(a,b,c0,c1,c2) \
465 t1=LBITS(a); t2=HBITS(a); \ 495 t1=LBITS(a); t2=HBITS(a); \
466 bl=LBITS(b); bh=HBITS(b); \ 496 bl=LBITS(b); bh=HBITS(b); \
@@ -487,7 +517,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
487 517
488#define sqr_add_c2(a,i,j,c0,c1,c2) \ 518#define sqr_add_c2(a,i,j,c0,c1,c2) \
489 mul_add_c2((a)[i],(a)[j],c0,c1,c2) 519 mul_add_c2((a)[i],(a)[j],c0,c1,c2)
490#endif 520#endif /* !BN_LLONG */
491 521
492void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 522void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
493 { 523 {
@@ -643,7 +673,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
643 r[7]=c2; 673 r[7]=c2;
644 } 674 }
645 675
646void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) 676void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
647 { 677 {
648#ifdef BN_LLONG 678#ifdef BN_LLONG
649 BN_ULLONG t,tt; 679 BN_ULLONG t,tt;
@@ -724,7 +754,7 @@ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
724 r[15]=c1; 754 r[15]=c1;
725 } 755 }
726 756
727void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) 757void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
728 { 758 {
729#ifdef BN_LLONG 759#ifdef BN_LLONG
730 BN_ULLONG t,tt; 760 BN_ULLONG t,tt;
@@ -762,7 +792,7 @@ void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
762 r[6]=c1; 792 r[6]=c1;
763 r[7]=c2; 793 r[7]=c2;
764 } 794 }
765#else 795#else /* !BN_MUL_COMBA */
766 796
767/* hmm... is it faster just to do a multiply? */ 797/* hmm... is it faster just to do a multiply? */
768#undef bn_sqr_comba4 798#undef bn_sqr_comba4
@@ -799,4 +829,4 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
799 r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]); 829 r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
800 } 830 }
801 831
802#endif /* BN_COMBA */ 832#endif /* !BN_MUL_COMBA */
diff --git a/src/lib/libcrypto/bn/bn_blind.c b/src/lib/libcrypto/bn/bn_blind.c
index a7b34f0bf0..2d287e6d1b 100644
--- a/src/lib/libcrypto/bn/bn_blind.c
+++ b/src/lib/libcrypto/bn/bn_blind.c
@@ -60,15 +60,18 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63BN_BLINDING *BN_BLINDING_new(A,Ai,mod) 63BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod)
64BIGNUM *A;
65BIGNUM *Ai;
66BIGNUM *mod;
67 { 64 {
68 BN_BLINDING *ret=NULL; 65 BN_BLINDING *ret=NULL;
69 66
70 if ((ret=(BN_BLINDING *)Malloc(sizeof(BN_BLINDING))) == NULL) 67 bn_check_top(Ai);
68 bn_check_top(mod);
69
70 if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL)
71 {
71 BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE); 72 BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE);
73 return(NULL);
74 }
72 memset(ret,0,sizeof(BN_BLINDING)); 75 memset(ret,0,sizeof(BN_BLINDING));
73 if ((ret->A=BN_new()) == NULL) goto err; 76 if ((ret->A=BN_new()) == NULL) goto err;
74 if ((ret->Ai=BN_new()) == NULL) goto err; 77 if ((ret->Ai=BN_new()) == NULL) goto err;
@@ -78,26 +81,26 @@ BIGNUM *mod;
78 return(ret); 81 return(ret);
79err: 82err:
80 if (ret != NULL) BN_BLINDING_free(ret); 83 if (ret != NULL) BN_BLINDING_free(ret);
81 return(ret); 84 return(NULL);
82 } 85 }
83 86
84void BN_BLINDING_free(r) 87void BN_BLINDING_free(BN_BLINDING *r)
85BN_BLINDING *r;
86 { 88 {
89 if(r == NULL)
90 return;
91
87 if (r->A != NULL) BN_free(r->A ); 92 if (r->A != NULL) BN_free(r->A );
88 if (r->Ai != NULL) BN_free(r->Ai); 93 if (r->Ai != NULL) BN_free(r->Ai);
89 Free(r); 94 OPENSSL_free(r);
90 } 95 }
91 96
92int BN_BLINDING_update(b,ctx) 97int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
93BN_BLINDING *b;
94BN_CTX *ctx;
95 { 98 {
96 int ret=0; 99 int ret=0;
97 100
98 if ((b->A == NULL) || (b->Ai == NULL)) 101 if ((b->A == NULL) || (b->Ai == NULL))
99 { 102 {
100 BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITALISED); 103 BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED);
101 goto err; 104 goto err;
102 } 105 }
103 106
@@ -109,28 +112,26 @@ err:
109 return(ret); 112 return(ret);
110 } 113 }
111 114
112int BN_BLINDING_convert(n,b,ctx) 115int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
113BIGNUM *n;
114BN_BLINDING *b;
115BN_CTX *ctx;
116 { 116 {
117 bn_check_top(n);
118
117 if ((b->A == NULL) || (b->Ai == NULL)) 119 if ((b->A == NULL) || (b->Ai == NULL))
118 { 120 {
119 BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITALISED); 121 BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITIALIZED);
120 return(0); 122 return(0);
121 } 123 }
122 return(BN_mod_mul(n,n,b->A,b->mod,ctx)); 124 return(BN_mod_mul(n,n,b->A,b->mod,ctx));
123 } 125 }
124 126
125int BN_BLINDING_invert(n,b,ctx) 127int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
126BIGNUM *n;
127BN_BLINDING *b;
128BN_CTX *ctx;
129 { 128 {
130 int ret; 129 int ret;
130
131 bn_check_top(n);
131 if ((b->A == NULL) || (b->Ai == NULL)) 132 if ((b->A == NULL) || (b->Ai == NULL))
132 { 133 {
133 BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITALISED); 134 BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITIALIZED);
134 return(0); 135 return(0);
135 } 136 }
136 if ((ret=BN_mod_mul(n,n,b->Ai,b->mod,ctx)) >= 0) 137 if ((ret=BN_mod_mul(n,n,b->Ai,b->mod,ctx)) >= 0)
diff --git a/src/lib/libcrypto/bn/bn_ctx.c b/src/lib/libcrypto/bn/bn_ctx.c
index 46132fd180..7daf19eb84 100644
--- a/src/lib/libcrypto/bn/bn_ctx.c
+++ b/src/lib/libcrypto/bn/bn_ctx.c
@@ -61,15 +61,16 @@
61 61
62#include <stdio.h> 62#include <stdio.h>
63#include <assert.h> 63#include <assert.h>
64
64#include "cryptlib.h" 65#include "cryptlib.h"
65#include <openssl/bn.h> 66#include "bn_lcl.h"
66 67
67 68
68BN_CTX *BN_CTX_new(void) 69BN_CTX *BN_CTX_new(void)
69 { 70 {
70 BN_CTX *ret; 71 BN_CTX *ret;
71 72
72 ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); 73 ret=(BN_CTX *)OPENSSL_malloc(sizeof(BN_CTX));
73 if (ret == NULL) 74 if (ret == NULL)
74 { 75 {
75 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); 76 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
@@ -83,6 +84,7 @@ BN_CTX *BN_CTX_new(void)
83 84
84void BN_CTX_init(BN_CTX *ctx) 85void BN_CTX_init(BN_CTX *ctx)
85 { 86 {
87#if 0 /* explicit version */
86 int i; 88 int i;
87 ctx->tos = 0; 89 ctx->tos = 0;
88 ctx->flags = 0; 90 ctx->flags = 0;
@@ -90,6 +92,9 @@ void BN_CTX_init(BN_CTX *ctx)
90 ctx->too_many = 0; 92 ctx->too_many = 0;
91 for (i = 0; i < BN_CTX_NUM; i++) 93 for (i = 0; i < BN_CTX_NUM; i++)
92 BN_init(&(ctx->bn[i])); 94 BN_init(&(ctx->bn[i]));
95#else
96 memset(ctx, 0, sizeof *ctx);
97#endif
93 } 98 }
94 99
95void BN_CTX_free(BN_CTX *ctx) 100void BN_CTX_free(BN_CTX *ctx)
@@ -102,7 +107,7 @@ void BN_CTX_free(BN_CTX *ctx)
102 for (i=0; i < BN_CTX_NUM; i++) 107 for (i=0; i < BN_CTX_NUM; i++)
103 BN_clear_free(&(ctx->bn[i])); 108 BN_clear_free(&(ctx->bn[i]));
104 if (ctx->flags & BN_FLG_MALLOCED) 109 if (ctx->flags & BN_FLG_MALLOCED)
105 Free(ctx); 110 OPENSSL_free(ctx);
106 } 111 }
107 112
108void BN_CTX_start(BN_CTX *ctx) 113void BN_CTX_start(BN_CTX *ctx)
@@ -112,8 +117,14 @@ void BN_CTX_start(BN_CTX *ctx)
112 ctx->depth++; 117 ctx->depth++;
113 } 118 }
114 119
120
115BIGNUM *BN_CTX_get(BN_CTX *ctx) 121BIGNUM *BN_CTX_get(BN_CTX *ctx)
116 { 122 {
123 /* Note: If BN_CTX_get is ever changed to allocate BIGNUMs dynamically,
124 * make sure that if BN_CTX_get fails once it will return NULL again
125 * until BN_CTX_end is called. (This is so that callers have to check
126 * only the last return value.)
127 */
117 if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM) 128 if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
118 { 129 {
119 if (!ctx->too_many) 130 if (!ctx->too_many)
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index 2263bdc7da..f9a095e3b3 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -57,21 +57,22 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include <openssl/bn.h>
60#include "cryptlib.h" 61#include "cryptlib.h"
61#include "bn_lcl.h" 62#include "bn_lcl.h"
62 63
64
63/* The old slow way */ 65/* The old slow way */
64#if 0 66#if 0
65int BN_div(dv, rem, m, d,ctx) 67int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
66BIGNUM *dv; 68 BN_CTX *ctx)
67BIGNUM *rem;
68BIGNUM *m;
69BIGNUM *d;
70BN_CTX *ctx;
71 { 69 {
72 int i,nm,nd; 70 int i,nm,nd;
71 int ret = 0;
73 BIGNUM *D; 72 BIGNUM *D;
74 73
74 bn_check_top(m);
75 bn_check_top(d);
75 if (BN_is_zero(d)) 76 if (BN_is_zero(d))
76 { 77 {
77 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); 78 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
@@ -86,45 +87,83 @@ BN_CTX *ctx;
86 return(1); 87 return(1);
87 } 88 }
88 89
89 D=ctx->bn[ctx->tos]; 90 BN_CTX_start(ctx);
90 if (dv == NULL) dv=ctx->bn[ctx->tos+1]; 91 D = BN_CTX_get(ctx);
91 if (rem == NULL) rem=ctx->bn[ctx->tos+2]; 92 if (dv == NULL) dv = BN_CTX_get(ctx);
93 if (rem == NULL) rem = BN_CTX_get(ctx);
94 if (D == NULL || dv == NULL || rem == NULL)
95 goto end;
92 96
93 nd=BN_num_bits(d); 97 nd=BN_num_bits(d);
94 nm=BN_num_bits(m); 98 nm=BN_num_bits(m);
95 if (BN_copy(D,d) == NULL) return(0); 99 if (BN_copy(D,d) == NULL) goto end;
96 if (BN_copy(rem,m) == NULL) return(0); 100 if (BN_copy(rem,m) == NULL) goto end;
97 101
98 /* The next 2 are needed so we can do a dv->d[0]|=1 later 102 /* The next 2 are needed so we can do a dv->d[0]|=1 later
99 * since BN_lshift1 will only work once there is a value :-) */ 103 * since BN_lshift1 will only work once there is a value :-) */
100 BN_zero(dv); 104 BN_zero(dv);
105 bn_wexpand(dv,1);
101 dv->top=1; 106 dv->top=1;
102 107
103 if (!BN_lshift(D,D,nm-nd)) return(0); 108 if (!BN_lshift(D,D,nm-nd)) goto end;
104 for (i=nm-nd; i>=0; i--) 109 for (i=nm-nd; i>=0; i--)
105 { 110 {
106 if (!BN_lshift1(dv,dv)) return(0); 111 if (!BN_lshift1(dv,dv)) goto end;
107 if (BN_ucmp(rem,D) >= 0) 112 if (BN_ucmp(rem,D) >= 0)
108 { 113 {
109 dv->d[0]|=1; 114 dv->d[0]|=1;
110 bn_qsub(rem,rem,D); 115 if (!BN_usub(rem,rem,D)) goto end;
111 } 116 }
112/* CAN IMPROVE (and have now :=) */ 117/* CAN IMPROVE (and have now :=) */
113 if (!BN_rshift1(D,D)) return(0); 118 if (!BN_rshift1(D,D)) goto end;
114 } 119 }
115 rem->neg=BN_is_zero(rem)?0:m->neg; 120 rem->neg=BN_is_zero(rem)?0:m->neg;
116 dv->neg=m->neg^d->neg; 121 dv->neg=m->neg^d->neg;
117 return(1); 122 ret = 1;
123 end:
124 BN_CTX_end(ctx);
125 return(ret);
118 } 126 }
119 127
120#else 128#else
121 129
122int BN_div(dv, rm, num, divisor,ctx) 130#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
123BIGNUM *dv; 131 && !defined(PEDANTIC) && !defined(BN_DIV3W)
124BIGNUM *rm; 132# if defined(__GNUC__) && __GNUC__>=2
125BIGNUM *num; 133# if defined(__i386) || defined (__i386__)
126BIGNUM *divisor; 134 /*
127BN_CTX *ctx; 135 * There were two reasons for implementing this template:
136 * - GNU C generates a call to a function (__udivdi3 to be exact)
137 * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
138 * understand why...);
139 * - divl doesn't only calculate quotient, but also leaves
140 * remainder in %edx which we can definitely use here:-)
141 *
142 * <appro@fy.chalmers.se>
143 */
144# define bn_div_words(n0,n1,d0) \
145 ({ asm volatile ( \
146 "divl %4" \
147 : "=a"(q), "=d"(rem) \
148 : "a"(n1), "d"(n0), "g"(d0) \
149 : "cc"); \
150 q; \
151 })
152# define REMAINDER_IS_ALREADY_CALCULATED
153# endif /* __<cpu> */
154# endif /* __GNUC__ */
155#endif /* OPENSSL_NO_ASM */
156
157
158/* BN_div computes dv := num / divisor, rounding towards zero, and sets up
159 * rm such that dv*divisor + rm = num holds.
160 * Thus:
161 * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
162 * rm->neg == num->neg (unless the remainder is zero)
163 * If 'dv' or 'rm' is NULL, the respective value is not returned.
164 */
165int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
166 BN_CTX *ctx)
128 { 167 {
129 int norm_shift,i,j,loop; 168 int norm_shift,i,j,loop;
130 BIGNUM *tmp,wnum,*snum,*sdiv,*res; 169 BIGNUM *tmp,wnum,*snum,*sdiv,*res;
@@ -132,6 +171,9 @@ BN_CTX *ctx;
132 BN_ULONG d0,d1; 171 BN_ULONG d0,d1;
133 int num_n,div_n; 172 int num_n,div_n;
134 173
174 bn_check_top(num);
175 bn_check_top(divisor);
176
135 if (BN_is_zero(divisor)) 177 if (BN_is_zero(divisor))
136 { 178 {
137 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); 179 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
@@ -146,20 +188,22 @@ BN_CTX *ctx;
146 return(1); 188 return(1);
147 } 189 }
148 190
149 tmp=ctx->bn[ctx->tos]; 191 BN_CTX_start(ctx);
150 tmp->neg=0; 192 tmp=BN_CTX_get(ctx);
151 snum=ctx->bn[ctx->tos+1]; 193 snum=BN_CTX_get(ctx);
152 sdiv=ctx->bn[ctx->tos+2]; 194 sdiv=BN_CTX_get(ctx);
153 if (dv == NULL) 195 if (dv == NULL)
154 res=ctx->bn[ctx->tos+3]; 196 res=BN_CTX_get(ctx);
155 else res=dv; 197 else res=dv;
198 if (sdiv == NULL || res == NULL) goto err;
199 tmp->neg=0;
156 200
157 /* First we normalise the numbers */ 201 /* First we normalise the numbers */
158 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); 202 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
159 BN_lshift(sdiv,divisor,norm_shift); 203 if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
160 sdiv->neg=0; 204 sdiv->neg=0;
161 norm_shift+=BN_BITS2; 205 norm_shift+=BN_BITS2;
162 BN_lshift(snum,num,norm_shift); 206 if (!(BN_lshift(snum,num,norm_shift))) goto err;
163 snum->neg=0; 207 snum->neg=0;
164 div_n=sdiv->top; 208 div_n=sdiv->top;
165 num_n=snum->top; 209 num_n=snum->top;
@@ -168,10 +212,10 @@ BN_CTX *ctx;
168 /* Lets setup a 'window' into snum 212 /* Lets setup a 'window' into snum
169 * This is the part that corresponds to the current 213 * This is the part that corresponds to the current
170 * 'area' being divided */ 214 * 'area' being divided */
215 BN_init(&wnum);
171 wnum.d= &(snum->d[loop]); 216 wnum.d= &(snum->d[loop]);
172 wnum.top= div_n; 217 wnum.top= div_n;
173 wnum.max= snum->max; /* a bit of a lie */ 218 wnum.dmax= snum->dmax+1; /* a bit of a lie */
174 wnum.neg= 0;
175 219
176 /* Get the top 2 words of sdiv */ 220 /* Get the top 2 words of sdiv */
177 /* i=sdiv->top; */ 221 /* i=sdiv->top; */
@@ -183,8 +227,8 @@ BN_CTX *ctx;
183 227
184 /* Setup to 'res' */ 228 /* Setup to 'res' */
185 res->neg= (num->neg^divisor->neg); 229 res->neg= (num->neg^divisor->neg);
186 res->top=loop;
187 if (!bn_wexpand(res,(loop+1))) goto err; 230 if (!bn_wexpand(res,(loop+1))) goto err;
231 res->top=loop;
188 resp= &(res->d[loop-1]); 232 resp= &(res->d[loop-1]);
189 233
190 /* space for temp */ 234 /* space for temp */
@@ -192,74 +236,98 @@ BN_CTX *ctx;
192 236
193 if (BN_ucmp(&wnum,sdiv) >= 0) 237 if (BN_ucmp(&wnum,sdiv) >= 0)
194 { 238 {
195 bn_qsub(&wnum,&wnum,sdiv); 239 if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
196 *resp=1; 240 *resp=1;
197 res->d[res->top-1]=1; 241 res->d[res->top-1]=1;
198 } 242 }
199 else 243 else
200 res->top--; 244 res->top--;
245 if (res->top == 0)
246 res->neg = 0;
201 resp--; 247 resp--;
202 248
203 for (i=0; i<loop-1; i++) 249 for (i=0; i<loop-1; i++)
204 { 250 {
205 BN_ULONG q,n0,n1; 251 BN_ULONG q,l0;
206 BN_ULONG l0; 252#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
253 BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
254 q=bn_div_3_words(wnump,d1,d0);
255#else
256 BN_ULONG n0,n1,rem=0;
207 257
208 wnum.d--; wnum.top++;
209 n0=wnump[0]; 258 n0=wnump[0];
210 n1=wnump[-1]; 259 n1=wnump[-1];
211 if (n0 == d0) 260 if (n0 == d0)
212 q=BN_MASK2; 261 q=BN_MASK2;
213 else 262 else /* n0 < d0 */
214 q=bn_div64(n0,n1,d0);
215 {
216#ifdef BN_LLONG
217 BN_ULLONG t1,t2,rem;
218 t1=((BN_ULLONG)n0<<BN_BITS2)|n1;
219 for (;;)
220 { 263 {
264#ifdef BN_LLONG
265 BN_ULLONG t2;
266
267#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
268 q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
269#else
270 q=bn_div_words(n0,n1,d0);
271#endif
272
273#ifndef REMAINDER_IS_ALREADY_CALCULATED
274 /*
275 * rem doesn't have to be BN_ULLONG. The least we
276 * know it's less that d0, isn't it?
277 */
278 rem=(n1-q*d0)&BN_MASK2;
279#endif
221 t2=(BN_ULLONG)d1*q; 280 t2=(BN_ULLONG)d1*q;
222 rem=t1-(BN_ULLONG)q*d0; 281
223 if ((rem>>BN_BITS2) || 282 for (;;)
224 (t2 <= ((BN_ULLONG)(rem<<BN_BITS2)+wnump[-2]))) 283 {
225 break; 284 if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
226 q--; 285 break;
227 } 286 q--;
287 rem += d0;
288 if (rem < d0) break; /* don't let rem overflow */
289 t2 -= d1;
290 }
291#else /* !BN_LLONG */
292 BN_ULONG t2l,t2h,ql,qh;
293
294 q=bn_div_words(n0,n1,d0);
295#ifndef REMAINDER_IS_ALREADY_CALCULATED
296 rem=(n1-q*d0)&BN_MASK2;
297#endif
298
299#ifdef BN_UMULT_HIGH
300 t2l = d1 * q;
301 t2h = BN_UMULT_HIGH(d1,q);
228#else 302#else
229 BN_ULONG t1l,t1h,t2l,t2h,t3l,t3h,ql,qh,t3t;
230 t1h=n0;
231 t1l=n1;
232 for (;;)
233 {
234 t2l=LBITS(d1); t2h=HBITS(d1); 303 t2l=LBITS(d1); t2h=HBITS(d1);
235 ql =LBITS(q); qh =HBITS(q); 304 ql =LBITS(q); qh =HBITS(q);
236 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ 305 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
306#endif
237 307
238 t3t=LBITS(d0); t3h=HBITS(d0); 308 for (;;)
239 mul64(t3t,t3h,ql,qh); /* t3=t1-(BN_ULLONG)q*d0; */ 309 {
240 t3l=(t1l-t3t)&BN_MASK2; 310 if ((t2h < rem) ||
241 if (t3l > t1l) t3h++; 311 ((t2h == rem) && (t2l <= wnump[-2])))
242 t3h=(t1h-t3h)&BN_MASK2; 312 break;
243 313 q--;
244 /*if ((t3>>BN_BITS2) || 314 rem += d0;
245 (t2 <= ((t3<<BN_BITS2)+wnump[-2]))) 315 if (rem < d0) break; /* don't let rem overflow */
246 break; */ 316 if (t2l < d1) t2h--; t2l -= d1;
247 if (t3h) break; 317 }
248 if (t2h < t3l) break; 318#endif /* !BN_LLONG */
249 if ((t2h == t3l) && (t2l <= wnump[-2])) break;
250
251 q--;
252 } 319 }
253#endif 320#endif /* !BN_DIV3W */
254 } 321
255 l0=bn_mul_words(tmp->d,sdiv->d,div_n,q); 322 l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
323 wnum.d--; wnum.top++;
256 tmp->d[div_n]=l0; 324 tmp->d[div_n]=l0;
257 for (j=div_n+1; j>0; j--) 325 for (j=div_n+1; j>0; j--)
258 if (tmp->d[j-1]) break; 326 if (tmp->d[j-1]) break;
259 tmp->top=j; 327 tmp->top=j;
260 328
261 j=wnum.top; 329 j=wnum.top;
262 BN_sub(&wnum,&wnum,tmp); 330 if (!BN_sub(&wnum,&wnum,tmp)) goto err;
263 331
264 snum->top=snum->top+wnum.top-j; 332 snum->top=snum->top+wnum.top-j;
265 333
@@ -267,7 +335,7 @@ BN_CTX *ctx;
267 { 335 {
268 q--; 336 q--;
269 j=wnum.top; 337 j=wnum.top;
270 BN_add(&wnum,&wnum,sdiv); 338 if (!BN_add(&wnum,&wnum,sdiv)) goto err;
271 snum->top+=wnum.top-j; 339 snum->top+=wnum.top-j;
272 } 340 }
273 *(resp--)=q; 341 *(resp--)=q;
@@ -275,11 +343,18 @@ BN_CTX *ctx;
275 } 343 }
276 if (rm != NULL) 344 if (rm != NULL)
277 { 345 {
346 /* Keep a copy of the neg flag in num because if rm==num
347 * BN_rshift() will overwrite it.
348 */
349 int neg = num->neg;
278 BN_rshift(rm,snum,norm_shift); 350 BN_rshift(rm,snum,norm_shift);
279 rm->neg=num->neg; 351 if (!BN_is_zero(rm))
352 rm->neg = neg;
280 } 353 }
354 BN_CTX_end(ctx);
281 return(1); 355 return(1);
282err: 356err:
357 BN_CTX_end(ctx);
283 return(0); 358 return(0);
284 } 359 }
285 360
diff --git a/src/lib/libcrypto/bn/bn_err.c b/src/lib/libcrypto/bn/bn_err.c
index 029ae810d5..fb84ee96d8 100644
--- a/src/lib/libcrypto/bn/bn_err.c
+++ b/src/lib/libcrypto/bn/bn_err.c
@@ -1,66 +1,69 @@
1/* lib/bn/bn_err.c */ 1/* crypto/bn/bn_err.c */
2/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) 2/* ====================================================================
3 * All rights reserved. 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 * 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 5 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
25 * are met: 7 * are met:
26 * 1. Redistributions of source code must retain the copyright 8 *
27 * notice, this list of conditions and the following disclaimer. 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
28 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in
30 * documentation and/or other materials provided with the distribution. 14 * the documentation and/or other materials provided with the
31 * 3. All advertising materials mentioning features or use of this software 15 * distribution.
32 * must display the following acknowledgement: 16 *
33 * "This product includes cryptographic software written by 17 * 3. All advertising materials mentioning features or use of this
34 * Eric Young (eay@cryptsoft.com)" 18 * software must display the following acknowledgment:
35 * The word 'cryptographic' can be left out if the rouines from the library 19 * "This product includes software developed by the OpenSSL Project
36 * being used are not cryptographic related :-). 20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
37 * 4. If you include any Windows specific code (or a derivative thereof) from 21 *
38 * the apps directory (application code) you must include an acknowledgement: 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 23 * endorse or promote products derived from this software without
40 * 24 * prior written permission. For written permission, please contact
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 25 * openssl-core@OpenSSL.org.
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 *
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * 5. Products derived from this software may not be called "OpenSSL"
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 * nor may "OpenSSL" appear in their names without prior written
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * permission of the OpenSSL Project.
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 *
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * 6. Redistributions of any form whatsoever must retain the following
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * acknowledgment:
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * "This product includes software developed by the OpenSSL Project
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
51 * SUCH DAMAGE. 35 *
52 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
53 * The licence and distribution terms for any publically available version or 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 * copied and put under another distribution licence 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
56 * [including the GNU Public Licence.] 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
57 */ 54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
58#include <stdio.h> 61#include <stdio.h>
59#include "err.h" 62#include <openssl/err.h>
60#include "bn.h" 63#include <openssl/bn.h>
61 64
62/* BEGIN ERROR CODES */ 65/* BEGIN ERROR CODES */
63#ifndef NO_ERR 66#ifndef OPENSSL_NO_ERR
64static ERR_STRING_DATA BN_str_functs[]= 67static ERR_STRING_DATA BN_str_functs[]=
65 { 68 {
66{ERR_PACK(0,BN_F_BN_BLINDING_CONVERT,0), "BN_BLINDING_convert"}, 69{ERR_PACK(0,BN_F_BN_BLINDING_CONVERT,0), "BN_BLINDING_convert"},
@@ -69,40 +72,57 @@ static ERR_STRING_DATA BN_str_functs[]=
69{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"}, 72{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"},
70{ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"}, 73{ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"},
71{ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"}, 74{ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"},
75{ERR_PACK(0,BN_F_BN_CTX_GET,0), "BN_CTX_get"},
72{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"}, 76{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"},
73{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"}, 77{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
74{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"}, 78{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
79{ERR_PACK(0,BN_F_BN_EXPAND_INTERNAL,0), "BN_EXPAND_INTERNAL"},
80{ERR_PACK(0,BN_F_BN_MOD_EXP2_MONT,0), "BN_mod_exp2_mont"},
75{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"}, 81{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
82{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT_WORD,0), "BN_mod_exp_mont_word"},
76{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"}, 83{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"},
84{ERR_PACK(0,BN_F_BN_MOD_LSHIFT_QUICK,0), "BN_mod_lshift_quick"},
77{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"}, 85{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"},
86{ERR_PACK(0,BN_F_BN_MOD_SQRT,0), "BN_mod_sqrt"},
78{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"}, 87{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"},
79{ERR_PACK(0,BN_F_BN_NEW,0), "BN_new"}, 88{ERR_PACK(0,BN_F_BN_NEW,0), "BN_new"},
80{ERR_PACK(0,BN_F_BN_RAND,0), "BN_rand"}, 89{ERR_PACK(0,BN_F_BN_RAND,0), "BN_rand"},
81{0,NULL}, 90{ERR_PACK(0,BN_F_BN_RAND_RANGE,0), "BN_rand_range"},
91{ERR_PACK(0,BN_F_BN_USUB,0), "BN_usub"},
92{0,NULL}
82 }; 93 };
83 94
84static ERR_STRING_DATA BN_str_reasons[]= 95static ERR_STRING_DATA BN_str_reasons[]=
85 { 96 {
97{BN_R_ARG2_LT_ARG3 ,"arg2 lt arg3"},
86{BN_R_BAD_RECIPROCAL ,"bad reciprocal"}, 98{BN_R_BAD_RECIPROCAL ,"bad reciprocal"},
99{BN_R_BIGNUM_TOO_LONG ,"bignum too long"},
87{BN_R_CALLED_WITH_EVEN_MODULUS ,"called with even modulus"}, 100{BN_R_CALLED_WITH_EVEN_MODULUS ,"called with even modulus"},
88{BN_R_DIV_BY_ZERO ,"div by zero"}, 101{BN_R_DIV_BY_ZERO ,"div by zero"},
89{BN_R_ENCODING_ERROR ,"encoding error"}, 102{BN_R_ENCODING_ERROR ,"encoding error"},
103{BN_R_EXPAND_ON_STATIC_BIGNUM_DATA ,"expand on static bignum data"},
104{BN_R_INPUT_NOT_REDUCED ,"input not reduced"},
90{BN_R_INVALID_LENGTH ,"invalid length"}, 105{BN_R_INVALID_LENGTH ,"invalid length"},
91{BN_R_NOT_INITALISED ,"not initalised"}, 106{BN_R_INVALID_RANGE ,"invalid range"},
107{BN_R_NOT_A_SQUARE ,"not a square"},
108{BN_R_NOT_INITIALIZED ,"not initialized"},
92{BN_R_NO_INVERSE ,"no inverse"}, 109{BN_R_NO_INVERSE ,"no inverse"},
93{0,NULL}, 110{BN_R_P_IS_NOT_PRIME ,"p is not prime"},
111{BN_R_TOO_MANY_ITERATIONS ,"too many iterations"},
112{BN_R_TOO_MANY_TEMPORARY_VARIABLES ,"too many temporary variables"},
113{0,NULL}
94 }; 114 };
95 115
96#endif 116#endif
97 117
98void ERR_load_BN_strings() 118void ERR_load_BN_strings(void)
99 { 119 {
100 static int init=1; 120 static int init=1;
101 121
102 if (init); 122 if (init)
103 {; 123 {
104 init=0; 124 init=0;
105#ifndef NO_ERR 125#ifndef OPENSSL_NO_ERR
106 ERR_load_strings(ERR_LIB_BN,BN_str_functs); 126 ERR_load_strings(ERR_LIB_BN,BN_str_functs);
107 ERR_load_strings(ERR_LIB_BN,BN_str_reasons); 127 ERR_load_strings(ERR_LIB_BN,BN_str_reasons);
108#endif 128#endif
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index c056a5083f..afdfd580fb 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -55,112 +55,145 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
58 112
59#include <stdio.h>
60#include "cryptlib.h" 113#include "cryptlib.h"
61#include "bn_lcl.h" 114#include "bn_lcl.h"
62 115
63/* slow but works */ 116#define TABLE_SIZE 32
64int BN_mod_mul(ret, a, b, m, ctx)
65BIGNUM *ret;
66BIGNUM *a;
67BIGNUM *b;
68BIGNUM *m;
69BN_CTX *ctx;
70 {
71 BIGNUM *t;
72 int r=0;
73
74 t=ctx->bn[ctx->tos++];
75 if (a == b)
76 { if (!BN_sqr(t,a,ctx)) goto err; }
77 else
78 { if (!BN_mul(t,a,b)) goto err; }
79 if (!BN_mod(ret,t,m,ctx)) goto err;
80 r=1;
81err:
82 ctx->tos--;
83 return(r);
84 }
85 117
86#if 0
87/* this one works - simple but works */ 118/* this one works - simple but works */
88int BN_mod_exp(r,a,p,m,ctx) 119int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
89BIGNUM *r,*a,*p,*m;
90BN_CTX *ctx;
91 { 120 {
92 int i,bits,ret=0; 121 int i,bits,ret=0;
93 BIGNUM *v,*tmp; 122 BIGNUM *v,*rr;
94 123
95 v=ctx->bn[ctx->tos++]; 124 BN_CTX_start(ctx);
96 tmp=ctx->bn[ctx->tos++]; 125 if ((r == a) || (r == p))
126 rr = BN_CTX_get(ctx);
127 else
128 rr = r;
129 if ((v = BN_CTX_get(ctx)) == NULL) goto err;
97 130
98 if (BN_copy(v,a) == NULL) goto err; 131 if (BN_copy(v,a) == NULL) goto err;
99 bits=BN_num_bits(p); 132 bits=BN_num_bits(p);
100 133
101 if (BN_is_odd(p)) 134 if (BN_is_odd(p))
102 { if (BN_copy(r,a) == NULL) goto err; } 135 { if (BN_copy(rr,a) == NULL) goto err; }
103 else { if (BN_one(r)) goto err; } 136 else { if (!BN_one(rr)) goto err; }
104 137
105 for (i=1; i<bits; i++) 138 for (i=1; i<bits; i++)
106 { 139 {
107 if (!BN_sqr(tmp,v,ctx)) goto err; 140 if (!BN_sqr(v,v,ctx)) goto err;
108 if (!BN_mod(v,tmp,m,ctx)) goto err;
109 if (BN_is_bit_set(p,i)) 141 if (BN_is_bit_set(p,i))
110 { 142 {
111 if (!BN_mul(tmp,r,v)) goto err; 143 if (!BN_mul(rr,rr,v,ctx)) goto err;
112 if (!BN_mod(r,tmp,m,ctx)) goto err;
113 } 144 }
114 } 145 }
115 ret=1; 146 ret=1;
116err: 147err:
117 ctx->tos-=2; 148 if (r != rr) BN_copy(r,rr);
149 BN_CTX_end(ctx);
118 return(ret); 150 return(ret);
119 } 151 }
120 152
121#endif
122
123/* this one works - simple but works */
124int BN_exp(r,a,p,ctx)
125BIGNUM *r,*a,*p;
126BN_CTX *ctx;
127 {
128 int i,bits,ret=0;
129 BIGNUM *v,*tmp;
130
131 v=ctx->bn[ctx->tos++];
132 tmp=ctx->bn[ctx->tos++];
133
134 if (BN_copy(v,a) == NULL) goto err;
135 bits=BN_num_bits(p);
136
137 if (BN_is_odd(p))
138 { if (BN_copy(r,a) == NULL) goto err; }
139 else { if (BN_one(r)) goto err; }
140
141 for (i=1; i<bits; i++)
142 {
143 if (!BN_sqr(tmp,v,ctx)) goto err;
144 if (BN_is_bit_set(p,i))
145 {
146 if (!BN_mul(tmp,r,v)) goto err;
147 }
148 }
149 ret=1;
150err:
151 ctx->tos-=2;
152 return(ret);
153 }
154 153
155int BN_mod_exp(r,a,p,m,ctx) 154int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
156BIGNUM *r; 155 BN_CTX *ctx)
157BIGNUM *a;
158BIGNUM *p;
159BIGNUM *m;
160BN_CTX *ctx;
161 { 156 {
162 int ret; 157 int ret;
163 158
159 bn_check_top(a);
160 bn_check_top(p);
161 bn_check_top(m);
162
163 /* For even modulus m = 2^k*m_odd, it might make sense to compute
164 * a^p mod m_odd and a^p mod 2^k separately (with Montgomery
165 * exponentiation for the odd part), using appropriate exponent
166 * reductions, and combine the results using the CRT.
167 *
168 * For now, we use Montgomery only if the modulus is odd; otherwise,
169 * exponentiation using the reciprocal-based quick remaindering
170 * algorithm is used.
171 *
172 * (Timing obtained with expspeed.c [computations a^p mod m
173 * where a, p, m are of the same length: 256, 512, 1024, 2048,
174 * 4096, 8192 bits], compared to the running time of the
175 * standard algorithm:
176 *
177 * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
178 * 55 .. 77 % [UltraSparc processor, but
179 * debug-solaris-sparcv8-gcc conf.]
180 *
181 * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
182 * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
183 *
184 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
185 * at 2048 and more bits, but at 512 and 1024 bits, it was
186 * slower even than the standard algorithm!
187 *
188 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
189 * should be obtained when the new Montgomery reduction code
190 * has been integrated into OpenSSL.)
191 */
192
193#define MONT_MUL_MOD
194#define MONT_EXP_WORD
195#define RECP_MUL_MOD
196
164#ifdef MONT_MUL_MOD 197#ifdef MONT_MUL_MOD
165 /* I have finally been able to take out this pre-condition of 198 /* I have finally been able to take out this pre-condition of
166 * the top bit being set. It was caused by an error in BN_div 199 * the top bit being set. It was caused by an error in BN_div
@@ -169,7 +202,17 @@ BN_CTX *ctx;
169/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ 202/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
170 203
171 if (BN_is_odd(m)) 204 if (BN_is_odd(m))
172 { ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); } 205 {
206# ifdef MONT_EXP_WORD
207 if (a->top == 1 && !a->neg)
208 {
209 BN_ULONG A = a->d[0];
210 ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
211 }
212 else
213# endif
214 ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
215 }
173 else 216 else
174#endif 217#endif
175#ifdef RECP_MUL_MOD 218#ifdef RECP_MUL_MOD
@@ -181,55 +224,65 @@ BN_CTX *ctx;
181 return(ret); 224 return(ret);
182 } 225 }
183 226
184/* #ifdef RECP_MUL_MOD */ 227
185int BN_mod_exp_recp(r,a,p,m,ctx) 228int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
186BIGNUM *r; 229 const BIGNUM *m, BN_CTX *ctx)
187BIGNUM *a;
188BIGNUM *p;
189BIGNUM *m;
190BN_CTX *ctx;
191 { 230 {
192 int nb,i,j,bits,ret=0,wstart,wend,window,wvalue; 231 int i,j,bits,ret=0,wstart,wend,window,wvalue;
193 int start=1; 232 int start=1,ts=0;
194 BIGNUM *d,*aa; 233 BIGNUM *aa;
195 BIGNUM *val[16]; 234 BIGNUM val[TABLE_SIZE];
235 BN_RECP_CTX recp;
196 236
197 d=ctx->bn[ctx->tos++];
198 aa=ctx->bn[ctx->tos++];
199 bits=BN_num_bits(p); 237 bits=BN_num_bits(p);
200 238
201 if (bits == 0) 239 if (bits == 0)
202 { 240 {
203 BN_one(r); 241 ret = BN_one(r);
204 return(1); 242 return ret;
243 }
244
245 BN_CTX_start(ctx);
246 if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
247
248 BN_RECP_CTX_init(&recp);
249 if (m->neg)
250 {
251 /* ignore sign of 'm' */
252 if (!BN_copy(aa, m)) goto err;
253 aa->neg = 0;
254 if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
205 } 255 }
206 nb=BN_reciprocal(d,m,ctx);
207 if (nb == -1) goto err;
208
209 val[0]=BN_new();
210 if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */
211 if (!BN_mod_mul_reciprocal(aa,val[0],val[0],m,d,nb,ctx))
212 goto err; /* 2 */
213
214 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
215 window=1;
216 else if (bits >= 256)
217 window=5; /* max size of window */
218 else if (bits >= 128)
219 window=4;
220 else 256 else
221 window=3; 257 {
258 if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
259 }
260
261 BN_init(&(val[0]));
262 ts=1;
222 263
223 j=1<<(window-1); 264 if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */
224 for (i=1; i<j; i++) 265 if (BN_is_zero(&(val[0])))
225 { 266 {
226 val[i]=BN_new(); 267 ret = BN_zero(r);
227 if (!BN_mod_mul_reciprocal(val[i],val[i-1],aa,m,d,nb,ctx)) 268 goto err;
228 goto err;
229 } 269 }
230 for (; i<16; i++)
231 val[i]=NULL;
232 270
271 window = BN_window_bits_for_exponent_size(bits);
272 if (window > 1)
273 {
274 if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
275 goto err; /* 2 */
276 j=1<<(window-1);
277 for (i=1; i<j; i++)
278 {
279 BN_init(&val[i]);
280 if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
281 goto err;
282 }
283 ts=i;
284 }
285
233 start=1; /* This is used to avoid multiplication etc 286 start=1; /* This is used to avoid multiplication etc
234 * when there is only the value '1' in the 287 * when there is only the value '1' in the
235 * buffer. */ 288 * buffer. */
@@ -244,7 +297,7 @@ BN_CTX *ctx;
244 if (BN_is_bit_set(p,wstart) == 0) 297 if (BN_is_bit_set(p,wstart) == 0)
245 { 298 {
246 if (!start) 299 if (!start)
247 if (!BN_mod_mul_reciprocal(r,r,r,m,d,nb,ctx)) 300 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
248 goto err; 301 goto err;
249 if (wstart == 0) break; 302 if (wstart == 0) break;
250 wstart--; 303 wstart--;
@@ -274,12 +327,12 @@ BN_CTX *ctx;
274 if (!start) 327 if (!start)
275 for (i=0; i<j; i++) 328 for (i=0; i<j; i++)
276 { 329 {
277 if (!BN_mod_mul_reciprocal(r,r,r,m,d,nb,ctx)) 330 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
278 goto err; 331 goto err;
279 } 332 }
280 333
281 /* wvalue will be an odd number < 2^window */ 334 /* wvalue will be an odd number < 2^window */
282 if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],m,d,nb,ctx)) 335 if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
283 goto err; 336 goto err;
284 337
285 /* move the 'window' down further */ 338 /* move the 'window' down further */
@@ -290,84 +343,86 @@ BN_CTX *ctx;
290 } 343 }
291 ret=1; 344 ret=1;
292err: 345err:
293 ctx->tos-=2; 346 BN_CTX_end(ctx);
294 for (i=0; i<16; i++) 347 for (i=0; i<ts; i++)
295 if (val[i] != NULL) BN_clear_free(val[i]); 348 BN_clear_free(&(val[i]));
349 BN_RECP_CTX_free(&recp);
296 return(ret); 350 return(ret);
297 } 351 }
298/* #endif */ 352
299 353
300/* #ifdef MONT_MUL_MOD */ 354int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
301int BN_mod_exp_mont(r,a,p,m,ctx,in_mont) 355 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
302BIGNUM *r;
303BIGNUM *a;
304BIGNUM *p;
305BIGNUM *m;
306BN_CTX *ctx;
307BN_MONT_CTX *in_mont;
308 { 356 {
309#define TABLE_SIZE 16
310 int i,j,bits,ret=0,wstart,wend,window,wvalue; 357 int i,j,bits,ret=0,wstart,wend,window,wvalue;
311 int start=1; 358 int start=1,ts=0;
312 BIGNUM *d,*aa; 359 BIGNUM *d,*r;
313 BIGNUM *val[TABLE_SIZE]; 360 const BIGNUM *aa;
361 BIGNUM val[TABLE_SIZE];
314 BN_MONT_CTX *mont=NULL; 362 BN_MONT_CTX *mont=NULL;
315 363
364 bn_check_top(a);
365 bn_check_top(p);
366 bn_check_top(m);
367
316 if (!(m->d[0] & 1)) 368 if (!(m->d[0] & 1))
317 { 369 {
318 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); 370 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
319 return(0); 371 return(0);
320 } 372 }
321 d=ctx->bn[ctx->tos++];
322 bits=BN_num_bits(p); 373 bits=BN_num_bits(p);
323 if (bits == 0) 374 if (bits == 0)
324 { 375 {
325 BN_one(r); 376 ret = BN_one(rr);
326 return(1); 377 return ret;
327 } 378 }
328 379
380 BN_CTX_start(ctx);
381 d = BN_CTX_get(ctx);
382 r = BN_CTX_get(ctx);
383 if (d == NULL || r == NULL) goto err;
384
329 /* If this is not done, things will break in the montgomery 385 /* If this is not done, things will break in the montgomery
330 * part */ 386 * part */
331 387
332#if 1
333 if (in_mont != NULL) 388 if (in_mont != NULL)
334 mont=in_mont; 389 mont=in_mont;
335 else 390 else
336#endif
337 { 391 {
338 if ((mont=BN_MONT_CTX_new()) == NULL) goto err; 392 if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
339 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 393 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
340 } 394 }
341 395
342 val[0]=BN_new(); 396 BN_init(&val[0]);
343 if (BN_ucmp(a,m) >= 0) 397 ts=1;
398 if (a->neg || BN_ucmp(a,m) >= 0)
344 { 399 {
345 BN_mod(val[0],a,m,ctx); 400 if (!BN_nnmod(&(val[0]),a,m,ctx))
346 aa=val[0]; 401 goto err;
402 aa= &(val[0]);
347 } 403 }
348 else 404 else
349 aa=a; 405 aa=a;
350 if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */ 406 if (BN_is_zero(aa))
351 if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */ 407 {
352 408 ret = BN_zero(rr);
353 if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ 409 goto err;
354 window=1; 410 }
355 else if (bits > 250) 411 if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
356 window=5; /* max size of window */
357 else if (bits >= 120)
358 window=4;
359 else
360 window=3;
361 412
362 j=1<<(window-1); 413 window = BN_window_bits_for_exponent_size(bits);
363 for (i=1; i<j; i++) 414 if (window > 1)
364 { 415 {
365 val[i]=BN_new(); 416 if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
366 if (!BN_mod_mul_montgomery(val[i],val[i-1],d,mont,ctx)) 417 j=1<<(window-1);
367 goto err; 418 for (i=1; i<j; i++)
419 {
420 BN_init(&(val[i]));
421 if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))
422 goto err;
423 }
424 ts=i;
368 } 425 }
369 for (; i<TABLE_SIZE; i++)
370 val[i]=NULL;
371 426
372 start=1; /* This is used to avoid multiplication etc 427 start=1; /* This is used to avoid multiplication etc
373 * when there is only the value '1' in the 428 * when there is only the value '1' in the
@@ -376,7 +431,7 @@ BN_MONT_CTX *in_mont;
376 wstart=bits-1; /* The top bit of the window */ 431 wstart=bits-1; /* The top bit of the window */
377 wend=0; /* The bottom bit of the window */ 432 wend=0; /* The bottom bit of the window */
378 433
379 if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err; 434 if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
380 for (;;) 435 for (;;)
381 { 436 {
382 if (BN_is_bit_set(p,wstart) == 0) 437 if (BN_is_bit_set(p,wstart) == 0)
@@ -419,7 +474,7 @@ BN_MONT_CTX *in_mont;
419 } 474 }
420 475
421 /* wvalue will be an odd number < 2^window */ 476 /* wvalue will be an odd number < 2^window */
422 if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx)) 477 if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
423 goto err; 478 goto err;
424 479
425 /* move the 'window' down further */ 480 /* move the 'window' down further */
@@ -428,62 +483,201 @@ BN_MONT_CTX *in_mont;
428 start=0; 483 start=0;
429 if (wstart < 0) break; 484 if (wstart < 0) break;
430 } 485 }
431 BN_from_montgomery(r,r,mont,ctx); 486 if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
432 ret=1; 487 ret=1;
433err: 488err:
434 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 489 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
435 ctx->tos--; 490 BN_CTX_end(ctx);
436 for (i=0; i<TABLE_SIZE; i++) 491 for (i=0; i<ts; i++)
437 if (val[i] != NULL) BN_clear_free(val[i]); 492 BN_clear_free(&(val[i]));
438 return(ret); 493 return(ret);
439 } 494 }
440/* #endif */ 495
496int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
497 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
498 {
499 BN_MONT_CTX *mont = NULL;
500 int b, bits, ret=0;
501 int r_is_one;
502 BN_ULONG w, next_w;
503 BIGNUM *d, *r, *t;
504 BIGNUM *swap_tmp;
505#define BN_MOD_MUL_WORD(r, w, m) \
506 (BN_mul_word(r, (w)) && \
507 (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
508 (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
509 /* BN_MOD_MUL_WORD is only used with 'w' large,
510 * so the BN_ucmp test is probably more overhead
511 * than always using BN_mod (which uses BN_copy if
512 * a similar test returns true). */
513 /* We can use BN_mod and do not need BN_nnmod because our
514 * accumulator is never negative (the result of BN_mod does
515 * not depend on the sign of the modulus).
516 */
517#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
518 (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
519
520 bn_check_top(p);
521 bn_check_top(m);
522
523 if (m->top == 0 || !(m->d[0] & 1))
524 {
525 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
526 return(0);
527 }
528 if (m->top == 1)
529 a %= m->d[0]; /* make sure that 'a' is reduced */
530
531 bits = BN_num_bits(p);
532 if (bits == 0)
533 {
534 ret = BN_one(rr);
535 return ret;
536 }
537 if (a == 0)
538 {
539 ret = BN_zero(rr);
540 return ret;
541 }
542
543 BN_CTX_start(ctx);
544 d = BN_CTX_get(ctx);
545 r = BN_CTX_get(ctx);
546 t = BN_CTX_get(ctx);
547 if (d == NULL || r == NULL || t == NULL) goto err;
548
549 if (in_mont != NULL)
550 mont=in_mont;
551 else
552 {
553 if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
554 if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
555 }
556
557 r_is_one = 1; /* except for Montgomery factor */
558
559 /* bits-1 >= 0 */
560
561 /* The result is accumulated in the product r*w. */
562 w = a; /* bit 'bits-1' of 'p' is always set */
563 for (b = bits-2; b >= 0; b--)
564 {
565 /* First, square r*w. */
566 next_w = w*w;
567 if ((next_w/w) != w) /* overflow */
568 {
569 if (r_is_one)
570 {
571 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
572 r_is_one = 0;
573 }
574 else
575 {
576 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
577 }
578 next_w = 1;
579 }
580 w = next_w;
581 if (!r_is_one)
582 {
583 if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
584 }
585
586 /* Second, multiply r*w by 'a' if exponent bit is set. */
587 if (BN_is_bit_set(p, b))
588 {
589 next_w = w*a;
590 if ((next_w/a) != w) /* overflow */
591 {
592 if (r_is_one)
593 {
594 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
595 r_is_one = 0;
596 }
597 else
598 {
599 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
600 }
601 next_w = a;
602 }
603 w = next_w;
604 }
605 }
606
607 /* Finally, set r:=r*w. */
608 if (w != 1)
609 {
610 if (r_is_one)
611 {
612 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
613 r_is_one = 0;
614 }
615 else
616 {
617 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
618 }
619 }
620
621 if (r_is_one) /* can happen only if a == 1*/
622 {
623 if (!BN_one(rr)) goto err;
624 }
625 else
626 {
627 if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
628 }
629 ret = 1;
630err:
631 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
632 BN_CTX_end(ctx);
633 return(ret);
634 }
635
441 636
442/* The old fallback, simple version :-) */ 637/* The old fallback, simple version :-) */
443int BN_mod_exp_simple(r,a,p,m,ctx) 638int BN_mod_exp_simple(BIGNUM *r,
444BIGNUM *r; 639 const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
445BIGNUM *a; 640 BN_CTX *ctx)
446BIGNUM *p;
447BIGNUM *m;
448BN_CTX *ctx;
449 { 641 {
450 int i,j,bits,ret=0,wstart,wend,window,wvalue; 642 int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
451 int start=1; 643 int start=1;
452 BIGNUM *d; 644 BIGNUM *d;
453 BIGNUM *val[16]; 645 BIGNUM val[TABLE_SIZE];
454 646
455 d=ctx->bn[ctx->tos++];
456 bits=BN_num_bits(p); 647 bits=BN_num_bits(p);
457 648
458 if (bits == 0) 649 if (bits == 0)
459 { 650 {
460 BN_one(r); 651 ret = BN_one(r);
461 return(1); 652 return ret;
462 } 653 }
463 654
464 val[0]=BN_new(); 655 BN_CTX_start(ctx);
465 if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */ 656 if ((d = BN_CTX_get(ctx)) == NULL) goto err;
466 if (!BN_mod_mul(d,val[0],val[0],m,ctx))
467 goto err; /* 2 */
468
469 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
470 window=1;
471 else if (bits >= 256)
472 window=5; /* max size of window */
473 else if (bits >= 128)
474 window=4;
475 else
476 window=3;
477 657
478 j=1<<(window-1); 658 BN_init(&(val[0]));
479 for (i=1; i<j; i++) 659 ts=1;
660 if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */
661 if (BN_is_zero(&(val[0])))
480 { 662 {
481 val[i]=BN_new(); 663 ret = BN_zero(r);
482 if (!BN_mod_mul(val[i],val[i-1],d,m,ctx)) 664 goto err;
483 goto err; 665 }
666
667 window = BN_window_bits_for_exponent_size(bits);
668 if (window > 1)
669 {
670 if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
671 goto err; /* 2 */
672 j=1<<(window-1);
673 for (i=1; i<j; i++)
674 {
675 BN_init(&(val[i]));
676 if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
677 goto err;
678 }
679 ts=i;
484 } 680 }
485 for (; i<16; i++)
486 val[i]=NULL;
487 681
488 start=1; /* This is used to avoid multiplication etc 682 start=1; /* This is used to avoid multiplication etc
489 * when there is only the value '1' in the 683 * when there is only the value '1' in the
@@ -534,7 +728,7 @@ BN_CTX *ctx;
534 } 728 }
535 729
536 /* wvalue will be an odd number < 2^window */ 730 /* wvalue will be an odd number < 2^window */
537 if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx)) 731 if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
538 goto err; 732 goto err;
539 733
540 /* move the 'window' down further */ 734 /* move the 'window' down further */
@@ -545,9 +739,9 @@ BN_CTX *ctx;
545 } 739 }
546 ret=1; 740 ret=1;
547err: 741err:
548 ctx->tos--; 742 BN_CTX_end(ctx);
549 for (i=0; i<16; i++) 743 for (i=0; i<ts; i++)
550 if (val[i] != NULL) BN_clear_free(val[i]); 744 BN_clear_free(&(val[i]));
551 return(ret); 745 return(ret);
552 } 746 }
553 747
diff --git a/src/lib/libcrypto/bn/bn_exp2.c b/src/lib/libcrypto/bn/bn_exp2.c
index 1132d53365..73ccd58a83 100644
--- a/src/lib/libcrypto/bn/bn_exp2.c
+++ b/src/lib/libcrypto/bn/bn_exp2.c
@@ -1,27 +1,129 @@
1/* crypto/bn/bn_exp2.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 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
1#include <stdio.h> 112#include <stdio.h>
2#include "cryptlib.h" 113#include "cryptlib.h"
3#include "bn_lcl.h" 114#include "bn_lcl.h"
4 115
5/* I've done some timing with different table sizes. 116#define TABLE_SIZE 32
6 * The main hassle is that even with bits set at 3, this requires
7 * 63 BIGNUMs to store the pre-calculated values.
8 * 512 1024
9 * bits=1 75.4% 79.4%
10 * bits=2 61.2% 62.4%
11 * bits=3 61.3% 59.3%
12 * The lack of speed improvment is also a function of the pre-calculation
13 * which could be removed.
14 */
15#define EXP2_TABLE_BITS 2 /* 1 2 3 4 5 */
16#define EXP2_TABLE_SIZE 4 /* 2 4 8 16 32 */
17 117
18int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, 118int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
19 BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 119 const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
120 BN_CTX *ctx, BN_MONT_CTX *in_mont)
20 { 121 {
21 int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue; 122 int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2;
22 int start=1,ts=0,x,y; 123 int r_is_one=1,ts1=0,ts2=0;
23 BIGNUM *d,*aa1,*aa2,*r; 124 BIGNUM *d,*r;
24 BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE]; 125 const BIGNUM *a_mod_m;
126 BIGNUM val1[TABLE_SIZE], val2[TABLE_SIZE];
25 BN_MONT_CTX *mont=NULL; 127 BN_MONT_CTX *mont=NULL;
26 128
27 bn_check_top(a1); 129 bn_check_top(a1);
@@ -32,22 +134,23 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
32 134
33 if (!(m->d[0] & 1)) 135 if (!(m->d[0] & 1))
34 { 136 {
35 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); 137 BNerr(BN_F_BN_MOD_EXP2_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
36 return(0); 138 return(0);
37 } 139 }
38 d= &(ctx->bn[ctx->tos++]);
39 r= &(ctx->bn[ctx->tos++]);
40 bits1=BN_num_bits(p1); 140 bits1=BN_num_bits(p1);
41 bits2=BN_num_bits(p2); 141 bits2=BN_num_bits(p2);
42 if ((bits1 == 0) && (bits2 == 0)) 142 if ((bits1 == 0) && (bits2 == 0))
43 { 143 {
44 BN_one(r); 144 ret = BN_one(rr);
45 return(1); 145 return ret;
46 } 146 }
147
47 bits=(bits1 > bits2)?bits1:bits2; 148 bits=(bits1 > bits2)?bits1:bits2;
48 149
49 /* If this is not done, things will break in the montgomery 150 BN_CTX_start(ctx);
50 * part */ 151 d = BN_CTX_get(ctx);
152 r = BN_CTX_get(ctx);
153 if (d == NULL || r == NULL) goto err;
51 154
52 if (in_mont != NULL) 155 if (in_mont != NULL)
53 mont=in_mont; 156 mont=in_mont;
@@ -57,139 +160,154 @@ int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
57 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 160 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
58 } 161 }
59 162
60 BN_init(&(val[0][0])); 163 window1 = BN_window_bits_for_exponent_size(bits1);
61 BN_init(&(val[1][1])); 164 window2 = BN_window_bits_for_exponent_size(bits2);
62 BN_init(&(val[0][1])); 165
63 BN_init(&(val[1][0])); 166 /*
64 ts=1; 167 * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1)
65 if (BN_ucmp(a1,m) >= 0) 168 */
169 BN_init(&val1[0]);
170 ts1=1;
171 if (a1->neg || BN_ucmp(a1,m) >= 0)
66 { 172 {
67 BN_mod(&(val[1][0]),a1,m,ctx); 173 if (!BN_mod(&(val1[0]),a1,m,ctx))
68 aa1= &(val[1][0]); 174 goto err;
175 a_mod_m = &(val1[0]);
69 } 176 }
70 else 177 else
71 aa1=a1; 178 a_mod_m = a1;
72 if (BN_ucmp(a2,m) >= 0) 179 if (BN_is_zero(a_mod_m))
73 { 180 {
74 BN_mod(&(val[0][1]),a2,m,ctx); 181 ret = BN_zero(rr);
75 aa2= &(val[0][1]);
76 }
77 else
78 aa2=a2;
79 if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err;
80 if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err;
81 if (!BN_mod_mul_montgomery(&(val[1][1]),
82 &(val[1][0]),&(val[0][1]),mont,ctx))
83 goto err; 182 goto err;
183 }
84 184
85#if 0 185 if (!BN_to_montgomery(&(val1[0]),a_mod_m,mont,ctx)) goto err;
86 if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ 186 if (window1 > 1)
87 window=1;
88 else if (bits > 250)
89 window=5; /* max size of window */
90 else if (bits >= 120)
91 window=4;
92 else
93 window=3;
94#else
95 window=EXP2_TABLE_BITS;
96#endif
97
98 k=1<<window;
99 for (x=0; x<k; x++)
100 { 187 {
101 if (x >= 2) 188 if (!BN_mod_mul_montgomery(d,&(val1[0]),&(val1[0]),mont,ctx)) goto err;
189
190 j=1<<(window1-1);
191 for (i=1; i<j; i++)
102 { 192 {
103 BN_init(&(val[x][0])); 193 BN_init(&(val1[i]));
104 BN_init(&(val[x][1])); 194 if (!BN_mod_mul_montgomery(&(val1[i]),&(val1[i-1]),d,mont,ctx))
105 if (!BN_mod_mul_montgomery(&(val[x][0]), 195 goto err;
106 &(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err;
107 if (!BN_mod_mul_montgomery(&(val[x][1]),
108 &(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err;
109 } 196 }
110 for (y=2; y<k; y++) 197 ts1=i;
198 }
199
200
201 /*
202 * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1)
203 */
204 BN_init(&val2[0]);
205 ts2=1;
206 if (a2->neg || BN_ucmp(a2,m) >= 0)
207 {
208 if (!BN_mod(&(val2[0]),a2,m,ctx))
209 goto err;
210 a_mod_m = &(val2[0]);
211 }
212 else
213 a_mod_m = a2;
214 if (BN_is_zero(a_mod_m))
215 {
216 ret = BN_zero(rr);
217 goto err;
218 }
219 if (!BN_to_montgomery(&(val2[0]),a_mod_m,mont,ctx)) goto err;
220 if (window2 > 1)
221 {
222 if (!BN_mod_mul_montgomery(d,&(val2[0]),&(val2[0]),mont,ctx)) goto err;
223
224 j=1<<(window2-1);
225 for (i=1; i<j; i++)
111 { 226 {
112 BN_init(&(val[x][y])); 227 BN_init(&(val2[i]));
113 if (!BN_mod_mul_montgomery(&(val[x][y]), 228 if (!BN_mod_mul_montgomery(&(val2[i]),&(val2[i-1]),d,mont,ctx))
114 &(val[x][y-1]),&(val[0][1]),mont,ctx))
115 goto err; 229 goto err;
116 } 230 }
231 ts2=i;
117 } 232 }
118 ts=k; 233
119 234
120 start=1; /* This is used to avoid multiplication etc 235 /* Now compute the power product, using independent windows. */
121 * when there is only the value '1' in the 236 r_is_one=1;
122 * buffer. */ 237 wvalue1=0; /* The 'value' of the first window */
123 xvalue=0; /* The 'x value' of the window */ 238 wvalue2=0; /* The 'value' of the second window */
124 yvalue=0; /* The 'y value' of the window */ 239 wpos1=0; /* If wvalue1 > 0, the bottom bit of the first window */
125 wstart=bits-1; /* The top bit of the window */ 240 wpos2=0; /* If wvalue2 > 0, the bottom bit of the second window */
126 wend=0; /* The bottom bit of the window */ 241
127 242 if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
128 if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err; 243 for (b=bits-1; b>=0; b--)
129 for (;;)
130 { 244 {
131 xvalue=BN_is_bit_set(p1,wstart); 245 if (!r_is_one)
132 yvalue=BN_is_bit_set(p2,wstart);
133 if (!(xvalue || yvalue))
134 { 246 {
135 if (!start) 247 if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
248 goto err;
249 }
250
251 if (!wvalue1)
252 if (BN_is_bit_set(p1, b))
136 { 253 {
137 if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) 254 /* consider bits b-window1+1 .. b for this window */
138 goto err; 255 i = b-window1+1;
256 while (!BN_is_bit_set(p1, i)) /* works for i<0 */
257 i++;
258 wpos1 = i;
259 wvalue1 = 1;
260 for (i = b-1; i >= wpos1; i--)
261 {
262 wvalue1 <<= 1;
263 if (BN_is_bit_set(p1, i))
264 wvalue1++;
265 }
139 } 266 }
140 wstart--; 267
141 if (wstart < 0) break; 268 if (!wvalue2)
142 continue; 269 if (BN_is_bit_set(p2, b))
143 }
144 /* We now have wstart on a 'set' bit, we now need to work out
145 * how bit a window to do. To do this we need to scan
146 * forward until the last set bit before the end of the
147 * window */
148 j=wstart;
149 /* xvalue=BN_is_bit_set(p1,wstart); already set */
150 /* yvalue=BN_is_bit_set(p1,wstart); already set */
151 wend=0;
152 for (i=1; i<window; i++)
153 {
154 if (wstart-i < 0) break;
155 xvalue+=xvalue;
156 xvalue|=BN_is_bit_set(p1,wstart-i);
157 yvalue+=yvalue;
158 yvalue|=BN_is_bit_set(p2,wstart-i);
159 }
160
161 /* i is the size of the current window */
162 /* add the 'bytes above' */
163 if (!start)
164 for (j=0; j<i; j++)
165 { 270 {
166 if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) 271 /* consider bits b-window2+1 .. b for this window */
167 goto err; 272 i = b-window2+1;
273 while (!BN_is_bit_set(p2, i))
274 i++;
275 wpos2 = i;
276 wvalue2 = 1;
277 for (i = b-1; i >= wpos2; i--)
278 {
279 wvalue2 <<= 1;
280 if (BN_is_bit_set(p2, i))
281 wvalue2++;
282 }
168 } 283 }
284
285 if (wvalue1 && b == wpos1)
286 {
287 /* wvalue1 is odd and < 2^window1 */
288 if (!BN_mod_mul_montgomery(r,r,&(val1[wvalue1>>1]),mont,ctx))
289 goto err;
290 wvalue1 = 0;
291 r_is_one = 0;
292 }
169 293
170 /* wvalue will be an odd number < 2^window */ 294 if (wvalue2 && b == wpos2)
171 if (xvalue || yvalue)
172 { 295 {
173 if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]), 296 /* wvalue2 is odd and < 2^window2 */
174 mont,ctx)) goto err; 297 if (!BN_mod_mul_montgomery(r,r,&(val2[wvalue2>>1]),mont,ctx))
298 goto err;
299 wvalue2 = 0;
300 r_is_one = 0;
175 } 301 }
176
177 /* move the 'window' down further */
178 wstart-=i;
179 start=0;
180 if (wstart < 0) break;
181 } 302 }
182 BN_from_montgomery(rr,r,mont,ctx); 303 BN_from_montgomery(rr,r,mont,ctx);
183 ret=1; 304 ret=1;
184err: 305err:
185 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 306 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
186 ctx->tos-=2; 307 BN_CTX_end(ctx);
187 for (i=0; i<ts; i++) 308 for (i=0; i<ts1; i++)
188 { 309 BN_clear_free(&(val1[i]));
189 for (j=0; j<ts; j++) 310 for (i=0; i<ts2; i++)
190 { 311 BN_clear_free(&(val2[i]));
191 BN_clear_free(&(val[i][j]));
192 }
193 }
194 return(ret); 312 return(ret);
195 } 313 }
diff --git a/src/lib/libcrypto/bn/bn_gcd.c b/src/lib/libcrypto/bn/bn_gcd.c
index 071bba3b4b..7649f63fd2 100644
--- a/src/lib/libcrypto/bn/bn_gcd.c
+++ b/src/lib/libcrypto/bn/bn_gcd.c
@@ -55,29 +55,82 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#include <stdio.h>
60#include "cryptlib.h" 112#include "cryptlib.h"
61#include "bn_lcl.h" 113#include "bn_lcl.h"
62 114
63#ifndef NOPROTO
64static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); 115static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
65#else
66static BIGNUM *euclid();
67#endif
68 116
69int BN_gcd(r,in_a,in_b,ctx) 117int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
70BIGNUM *r,*in_a,*in_b;
71BN_CTX *ctx;
72 { 118 {
73 BIGNUM *a,*b,*t; 119 BIGNUM *a,*b,*t;
74 int ret=0; 120 int ret=0;
75 121
76 a=ctx->bn[ctx->tos]; 122 bn_check_top(in_a);
77 b=ctx->bn[ctx->tos+1]; 123 bn_check_top(in_b);
124
125 BN_CTX_start(ctx);
126 a = BN_CTX_get(ctx);
127 b = BN_CTX_get(ctx);
128 if (a == NULL || b == NULL) goto err;
78 129
79 if (BN_copy(a,in_a) == NULL) goto err; 130 if (BN_copy(a,in_a) == NULL) goto err;
80 if (BN_copy(b,in_b) == NULL) goto err; 131 if (BN_copy(b,in_b) == NULL) goto err;
132 a->neg = 0;
133 b->neg = 0;
81 134
82 if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; } 135 if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
83 t=euclid(a,b); 136 t=euclid(a,b);
@@ -86,19 +139,22 @@ BN_CTX *ctx;
86 if (BN_copy(r,t) == NULL) goto err; 139 if (BN_copy(r,t) == NULL) goto err;
87 ret=1; 140 ret=1;
88err: 141err:
142 BN_CTX_end(ctx);
89 return(ret); 143 return(ret);
90 } 144 }
91 145
92static BIGNUM *euclid(a,b) 146static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
93BIGNUM *a,*b;
94 { 147 {
95 BIGNUM *t; 148 BIGNUM *t;
96 int shifts=0; 149 int shifts=0;
97 150
98 for (;;) 151 bn_check_top(a);
152 bn_check_top(b);
153
154 /* 0 <= b <= a */
155 while (!BN_is_zero(b))
99 { 156 {
100 if (BN_is_zero(b)) 157 /* 0 < b <= a */
101 break;
102 158
103 if (BN_is_odd(a)) 159 if (BN_is_odd(a))
104 { 160 {
@@ -131,7 +187,9 @@ BIGNUM *a,*b;
131 shifts++; 187 shifts++;
132 } 188 }
133 } 189 }
190 /* 0 <= b <= a */
134 } 191 }
192
135 if (shifts) 193 if (shifts)
136 { 194 {
137 if (!BN_lshift(a,a,shifts)) goto err; 195 if (!BN_lshift(a,a,shifts)) goto err;
@@ -141,54 +199,284 @@ err:
141 return(NULL); 199 return(NULL);
142 } 200 }
143 201
202
144/* solves ax == 1 (mod n) */ 203/* solves ax == 1 (mod n) */
145BIGNUM *BN_mod_inverse(a, n, ctx) 204BIGNUM *BN_mod_inverse(BIGNUM *in,
146BIGNUM *a; 205 const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
147BIGNUM *n;
148BN_CTX *ctx;
149 { 206 {
150 BIGNUM *A,*B,*X,*Y,*M,*D,*R; 207 BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
151 BIGNUM *ret=NULL,*T; 208 BIGNUM *ret=NULL;
152 int sign; 209 int sign;
153 210
154 A=ctx->bn[ctx->tos]; 211 bn_check_top(a);
155 B=ctx->bn[ctx->tos+1]; 212 bn_check_top(n);
156 X=ctx->bn[ctx->tos+2]; 213
157 D=ctx->bn[ctx->tos+3]; 214 BN_CTX_start(ctx);
158 M=ctx->bn[ctx->tos+4]; 215 A = BN_CTX_get(ctx);
159 Y=ctx->bn[ctx->tos+5]; 216 B = BN_CTX_get(ctx);
160 ctx->tos+=6; 217 X = BN_CTX_get(ctx);
161 R=BN_new(); 218 D = BN_CTX_get(ctx);
219 M = BN_CTX_get(ctx);
220 Y = BN_CTX_get(ctx);
221 T = BN_CTX_get(ctx);
222 if (T == NULL) goto err;
223
224 if (in == NULL)
225 R=BN_new();
226 else
227 R=in;
162 if (R == NULL) goto err; 228 if (R == NULL) goto err;
163 229
164 BN_zero(X); 230 BN_one(X);
165 BN_one(Y); 231 BN_zero(Y);
166 if (BN_copy(A,a) == NULL) goto err; 232 if (BN_copy(B,a) == NULL) goto err;
167 if (BN_copy(B,n) == NULL) goto err; 233 if (BN_copy(A,n) == NULL) goto err;
168 sign=1; 234 A->neg = 0;
235 if (B->neg || (BN_ucmp(B, A) >= 0))
236 {
237 if (!BN_nnmod(B, B, A, ctx)) goto err;
238 }
239 sign = -1;
240 /* From B = a mod |n|, A = |n| it follows that
241 *
242 * 0 <= B < A,
243 * -sign*X*a == B (mod |n|),
244 * sign*Y*a == A (mod |n|).
245 */
246
247 if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
248 {
249 /* Binary inversion algorithm; requires odd modulus.
250 * This is faster than the general algorithm if the modulus
251 * is sufficiently small (about 400 .. 500 bits on 32-bit
252 * sytems, but much more on 64-bit systems) */
253 int shift;
254
255 while (!BN_is_zero(B))
256 {
257 /*
258 * 0 < B < |n|,
259 * 0 < A <= |n|,
260 * (1) -sign*X*a == B (mod |n|),
261 * (2) sign*Y*a == A (mod |n|)
262 */
263
264 /* Now divide B by the maximum possible power of two in the integers,
265 * and divide X by the same value mod |n|.
266 * When we're done, (1) still holds. */
267 shift = 0;
268 while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
269 {
270 shift++;
271
272 if (BN_is_odd(X))
273 {
274 if (!BN_uadd(X, X, n)) goto err;
275 }
276 /* now X is even, so we can easily divide it by two */
277 if (!BN_rshift1(X, X)) goto err;
278 }
279 if (shift > 0)
280 {
281 if (!BN_rshift(B, B, shift)) goto err;
282 }
283
169 284
170 while (!BN_is_zero(B)) 285 /* Same for A and Y. Afterwards, (2) still holds. */
286 shift = 0;
287 while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
288 {
289 shift++;
290
291 if (BN_is_odd(Y))
292 {
293 if (!BN_uadd(Y, Y, n)) goto err;
294 }
295 /* now Y is even */
296 if (!BN_rshift1(Y, Y)) goto err;
297 }
298 if (shift > 0)
299 {
300 if (!BN_rshift(A, A, shift)) goto err;
301 }
302
303
304 /* We still have (1) and (2).
305 * Both A and B are odd.
306 * The following computations ensure that
307 *
308 * 0 <= B < |n|,
309 * 0 < A < |n|,
310 * (1) -sign*X*a == B (mod |n|),
311 * (2) sign*Y*a == A (mod |n|),
312 *
313 * and that either A or B is even in the next iteration.
314 */
315 if (BN_ucmp(B, A) >= 0)
316 {
317 /* -sign*(X + Y)*a == B - A (mod |n|) */
318 if (!BN_uadd(X, X, Y)) goto err;
319 /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
320 * actually makes the algorithm slower */
321 if (!BN_usub(B, B, A)) goto err;
322 }
323 else
324 {
325 /* sign*(X + Y)*a == A - B (mod |n|) */
326 if (!BN_uadd(Y, Y, X)) goto err;
327 /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
328 if (!BN_usub(A, A, B)) goto err;
329 }
330 }
331 }
332 else
171 { 333 {
172 if (!BN_div(D,M,A,B,ctx)) goto err; 334 /* general inversion algorithm */
173 T=A; 335
174 A=B; 336 while (!BN_is_zero(B))
175 B=M; 337 {
176 /* T has a struct, M does not */ 338 BIGNUM *tmp;
177 339
178 if (!BN_mul(T,D,X)) goto err; 340 /*
179 if (!BN_add(T,T,Y)) goto err; 341 * 0 < B < A,
180 M=Y; 342 * (*) -sign*X*a == B (mod |n|),
181 Y=X; 343 * sign*Y*a == A (mod |n|)
182 X=T; 344 */
183 sign= -sign; 345
346 /* (D, M) := (A/B, A%B) ... */
347 if (BN_num_bits(A) == BN_num_bits(B))
348 {
349 if (!BN_one(D)) goto err;
350 if (!BN_sub(M,A,B)) goto err;
351 }
352 else if (BN_num_bits(A) == BN_num_bits(B) + 1)
353 {
354 /* A/B is 1, 2, or 3 */
355 if (!BN_lshift1(T,B)) goto err;
356 if (BN_ucmp(A,T) < 0)
357 {
358 /* A < 2*B, so D=1 */
359 if (!BN_one(D)) goto err;
360 if (!BN_sub(M,A,B)) goto err;
361 }
362 else
363 {
364 /* A >= 2*B, so D=2 or D=3 */
365 if (!BN_sub(M,A,T)) goto err;
366 if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
367 if (BN_ucmp(A,D) < 0)
368 {
369 /* A < 3*B, so D=2 */
370 if (!BN_set_word(D,2)) goto err;
371 /* M (= A - 2*B) already has the correct value */
372 }
373 else
374 {
375 /* only D=3 remains */
376 if (!BN_set_word(D,3)) goto err;
377 /* currently M = A - 2*B, but we need M = A - 3*B */
378 if (!BN_sub(M,M,B)) goto err;
379 }
380 }
381 }
382 else
383 {
384 if (!BN_div(D,M,A,B,ctx)) goto err;
385 }
386
387 /* Now
388 * A = D*B + M;
389 * thus we have
390 * (**) sign*Y*a == D*B + M (mod |n|).
391 */
392
393 tmp=A; /* keep the BIGNUM object, the value does not matter */
394
395 /* (A, B) := (B, A mod B) ... */
396 A=B;
397 B=M;
398 /* ... so we have 0 <= B < A again */
399
400 /* Since the former M is now B and the former B is now A,
401 * (**) translates into
402 * sign*Y*a == D*A + B (mod |n|),
403 * i.e.
404 * sign*Y*a - D*A == B (mod |n|).
405 * Similarly, (*) translates into
406 * -sign*X*a == A (mod |n|).
407 *
408 * Thus,
409 * sign*Y*a + D*sign*X*a == B (mod |n|),
410 * i.e.
411 * sign*(Y + D*X)*a == B (mod |n|).
412 *
413 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
414 * -sign*X*a == B (mod |n|),
415 * sign*Y*a == A (mod |n|).
416 * Note that X and Y stay non-negative all the time.
417 */
418
419 /* most of the time D is very small, so we can optimize tmp := D*X+Y */
420 if (BN_is_one(D))
421 {
422 if (!BN_add(tmp,X,Y)) goto err;
423 }
424 else
425 {
426 if (BN_is_word(D,2))
427 {
428 if (!BN_lshift1(tmp,X)) goto err;
429 }
430 else if (BN_is_word(D,4))
431 {
432 if (!BN_lshift(tmp,X,2)) goto err;
433 }
434 else if (D->top == 1)
435 {
436 if (!BN_copy(tmp,X)) goto err;
437 if (!BN_mul_word(tmp,D->d[0])) goto err;
438 }
439 else
440 {
441 if (!BN_mul(tmp,D,X,ctx)) goto err;
442 }
443 if (!BN_add(tmp,tmp,Y)) goto err;
444 }
445
446 M=Y; /* keep the BIGNUM object, the value does not matter */
447 Y=X;
448 X=tmp;
449 sign = -sign;
450 }
184 } 451 }
452
453 /*
454 * The while loop (Euclid's algorithm) ends when
455 * A == gcd(a,n);
456 * we have
457 * sign*Y*a == A (mod |n|),
458 * where Y is non-negative.
459 */
460
185 if (sign < 0) 461 if (sign < 0)
186 { 462 {
187 if (!BN_sub(Y,n,Y)) goto err; 463 if (!BN_sub(Y,n,Y)) goto err;
188 } 464 }
465 /* Now Y*a == A (mod |n|). */
466
189 467
190 if (BN_is_one(A)) 468 if (BN_is_one(A))
191 { if (!BN_mod(R,Y,n,ctx)) goto err; } 469 {
470 /* Y*a == 1 (mod |n|) */
471 if (!Y->neg && BN_ucmp(Y,n) < 0)
472 {
473 if (!BN_copy(R,Y)) goto err;
474 }
475 else
476 {
477 if (!BN_nnmod(R,Y,n,ctx)) goto err;
478 }
479 }
192 else 480 else
193 { 481 {
194 BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); 482 BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
@@ -196,8 +484,7 @@ BN_CTX *ctx;
196 } 484 }
197 ret=R; 485 ret=R;
198err: 486err:
199 if ((ret == NULL) && (R != NULL)) BN_free(R); 487 if ((ret == NULL) && (in == NULL)) BN_free(R);
200 ctx->tos-=6; 488 BN_CTX_end(ctx);
201 return(ret); 489 return(ret);
202 } 490 }
203
diff --git a/src/lib/libcrypto/bn/bn_lcl.h b/src/lib/libcrypto/bn/bn_lcl.h
index edfd788338..8a4dba375a 100644
--- a/src/lib/libcrypto/bn/bn_lcl.h
+++ b/src/lib/libcrypto/bn/bn_lcl.h
@@ -55,30 +55,228 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#ifndef HEADER_BN_LCL_H 112#ifndef HEADER_BN_LCL_H
60#define HEADER_BN_LCL_H 113#define HEADER_BN_LCL_H
61 114
62#include "bn.h" 115#include <openssl/bn.h>
63 116
64#ifdef __cplusplus 117#ifdef __cplusplus
65extern "C" { 118extern "C" {
66#endif 119#endif
67 120
121
122/* Used for temp variables */
123#define BN_CTX_NUM 32
124#define BN_CTX_NUM_POS 12
125struct bignum_ctx
126 {
127 int tos;
128 BIGNUM bn[BN_CTX_NUM];
129 int flags;
130 int depth;
131 int pos[BN_CTX_NUM_POS];
132 int too_many;
133 } /* BN_CTX */;
134
135
136/*
137 * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
138 *
139 *
140 * For window size 'w' (w >= 2) and a random 'b' bits exponent,
141 * the number of multiplications is a constant plus on average
142 *
143 * 2^(w-1) + (b-w)/(w+1);
144 *
145 * here 2^(w-1) is for precomputing the table (we actually need
146 * entries only for windows that have the lowest bit set), and
147 * (b-w)/(w+1) is an approximation for the expected number of
148 * w-bit windows, not counting the first one.
149 *
150 * Thus we should use
151 *
152 * w >= 6 if b > 671
153 * w = 5 if 671 > b > 239
154 * w = 4 if 239 > b > 79
155 * w = 3 if 79 > b > 23
156 * w <= 2 if 23 > b
157 *
158 * (with draws in between). Very small exponents are often selected
159 * with low Hamming weight, so we use w = 1 for b <= 23.
160 */
161#if 1
162#define BN_window_bits_for_exponent_size(b) \
163 ((b) > 671 ? 6 : \
164 (b) > 239 ? 5 : \
165 (b) > 79 ? 4 : \
166 (b) > 23 ? 3 : 1)
167#else
168/* Old SSLeay/OpenSSL table.
169 * Maximum window size was 5, so this table differs for b==1024;
170 * but it coincides for other interesting values (b==160, b==512).
171 */
172#define BN_window_bits_for_exponent_size(b) \
173 ((b) > 255 ? 5 : \
174 (b) > 127 ? 4 : \
175 (b) > 17 ? 3 : 1)
176#endif
177
178
179
180/* Pentium pro 16,16,16,32,64 */
181/* Alpha 16,16,16,16.64 */
182#define BN_MULL_SIZE_NORMAL (16) /* 32 */
183#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
184#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
185#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
186#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
187
188#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
189/*
190 * BN_UMULT_HIGH section.
191 *
192 * No, I'm not trying to overwhelm you when stating that the
193 * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
194 * you to be impressed when I say that if the compiler doesn't
195 * support 2*N integer type, then you have to replace every N*N
196 * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
197 * and additions which unavoidably results in severe performance
198 * penalties. Of course provided that the hardware is capable of
199 * producing 2*N result... That's when you normally start
200 * considering assembler implementation. However! It should be
201 * pointed out that some CPUs (most notably Alpha, PowerPC and
202 * upcoming IA-64 family:-) provide *separate* instruction
203 * calculating the upper half of the product placing the result
204 * into a general purpose register. Now *if* the compiler supports
205 * inline assembler, then it's not impossible to implement the
206 * "bignum" routines (and have the compiler optimize 'em)
207 * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
208 * macro is about:-)
209 *
210 * <appro@fy.chalmers.se>
211 */
212# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
213# if defined(__DECC)
214# include <c_asm.h>
215# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
216# elif defined(__GNUC__)
217# define BN_UMULT_HIGH(a,b) ({ \
218 register BN_ULONG ret; \
219 asm ("umulh %1,%2,%0" \
220 : "=r"(ret) \
221 : "r"(a), "r"(b)); \
222 ret; })
223# endif /* compiler */
224# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
225# if defined(__GNUC__)
226# define BN_UMULT_HIGH(a,b) ({ \
227 register BN_ULONG ret; \
228 asm ("mulhdu %0,%1,%2" \
229 : "=r"(ret) \
230 : "r"(a), "r"(b)); \
231 ret; })
232# endif /* compiler */
233# endif /* cpu */
234#endif /* OPENSSL_NO_ASM */
235
68/************************************************************* 236/*************************************************************
69 * Using the long long type 237 * Using the long long type
70 */ 238 */
71#define Lw(t) (((BN_ULONG)(t))&BN_MASK2) 239#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
72#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) 240#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
73 241
74#define bn_fix_top(a) \ 242/* This is used for internal error checking and is not normally used */
75 { \ 243#ifdef BN_DEBUG
76 BN_ULONG *fix_top_l; \ 244# include <assert.h>
77 for (fix_top_l= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ 245# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
78 if (*(fix_top_l--)) break; \ 246#else
247# define bn_check_top(a)
248#endif
249
250/* This macro is to add extra stuff for development checking */
251#ifdef BN_DEBUG
252#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
253#else
254#define bn_set_max(r)
255#endif
256
257/* These macros are used to 'take' a section of a bignum for read only use */
258#define bn_set_low(r,a,n) \
259 { \
260 (r)->top=((a)->top > (n))?(n):(a)->top; \
261 (r)->d=(a)->d; \
262 (r)->neg=(a)->neg; \
263 (r)->flags|=BN_FLG_STATIC_DATA; \
264 bn_set_max(r); \
79 } 265 }
80 266
81/* #define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) */ 267#define bn_set_high(r,a,n) \
268 { \
269 if ((a)->top > (n)) \
270 { \
271 (r)->top=(a)->top-n; \
272 (r)->d= &((a)->d[n]); \
273 } \
274 else \
275 (r)->top=0; \
276 (r)->neg=(a)->neg; \
277 (r)->flags|=BN_FLG_STATIC_DATA; \
278 bn_set_max(r); \
279 }
82 280
83#ifdef BN_LLONG 281#ifdef BN_LLONG
84#define mul_add(r,a,w,c) { \ 282#define mul_add(r,a,w,c) { \
@@ -95,6 +293,43 @@ extern "C" {
95 (c)= Hw(t); \ 293 (c)= Hw(t); \
96 } 294 }
97 295
296#define sqr(r0,r1,a) { \
297 BN_ULLONG t; \
298 t=(BN_ULLONG)(a)*(a); \
299 (r0)=Lw(t); \
300 (r1)=Hw(t); \
301 }
302
303#elif defined(BN_UMULT_HIGH)
304#define mul_add(r,a,w,c) { \
305 BN_ULONG high,low,ret,tmp=(a); \
306 ret = (r); \
307 high= BN_UMULT_HIGH(w,tmp); \
308 ret += (c); \
309 low = (w) * tmp; \
310 (c) = (ret<(c))?1:0; \
311 (c) += high; \
312 ret += low; \
313 (c) += (ret<low)?1:0; \
314 (r) = ret; \
315 }
316
317#define mul(r,a,w,c) { \
318 BN_ULONG high,low,ret,ta=(a); \
319 low = (w) * ta; \
320 high= BN_UMULT_HIGH(w,ta); \
321 ret = low + (c); \
322 (c) = high; \
323 (c) += (ret<low)?1:0; \
324 (r) = ret; \
325 }
326
327#define sqr(r0,r1,a) { \
328 BN_ULONG tmp=(a); \
329 (r0) = tmp * tmp; \
330 (r1) = BN_UMULT_HIGH(tmp,tmp); \
331 }
332
98#else 333#else
99/************************************************************* 334/*************************************************************
100 * No long long type 335 * No long long type
@@ -172,25 +407,31 @@ extern "C" {
172 (c)=h&BN_MASK2; \ 407 (c)=h&BN_MASK2; \
173 (r)=l&BN_MASK2; \ 408 (r)=l&BN_MASK2; \
174 } 409 }
410#endif /* !BN_LLONG */
175 411
176#endif 412void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
177 413void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
178#ifndef NOPROTO 414void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
179 415void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
180BIGNUM *bn_expand2(BIGNUM *b, int bits); 416void bn_sqr_comba8(BN_ULONG *r,const BN_ULONG *a);
181 417void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
182#ifdef X86_ASM 418int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
183void bn_add_words(BN_ULONG *r,BN_ULONG *a,int num); 419int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
184#endif 420 int cl, int dl);
185 421void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
186#else 422 int dna,int dnb,BN_ULONG *t);
187 423void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
188BIGNUM *bn_expand2(); 424 int n,int tna,int tnb,BN_ULONG *t);
189#ifdef X86_ASM 425void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t);
190BN_ULONG bn_add_words(); 426void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
191#endif 427void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
192 428 BN_ULONG *t);
193#endif 429void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
430 BN_ULONG *t);
431BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
432 int cl, int dl);
433BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
434 int cl, int dl);
194 435
195#ifdef __cplusplus 436#ifdef __cplusplus
196} 437}
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index bfe7628ad4..a016cb7f53 100644
--- a/src/lib/libcrypto/bn/bn_lib.c
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -56,13 +56,79 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
64#include <assert.h>
65#include <limits.h>
59#include <stdio.h> 66#include <stdio.h>
60#include "cryptlib.h" 67#include "cryptlib.h"
61#include "bn_lcl.h" 68#include "bn_lcl.h"
62 69
63char *BN_version="Big Number part of SSLeay 0.9.0b 29-Jun-1998"; 70const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
64 71
65BIGNUM *BN_value_one() 72/* For a 32 bit machine
73 * 2 - 4 == 128
74 * 3 - 8 == 256
75 * 4 - 16 == 512
76 * 5 - 32 == 1024
77 * 6 - 64 == 2048
78 * 7 - 128 == 4096
79 * 8 - 256 == 8192
80 */
81static int bn_limit_bits=0;
82static int bn_limit_num=8; /* (1<<bn_limit_bits) */
83static int bn_limit_bits_low=0;
84static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
85static int bn_limit_bits_high=0;
86static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
87static int bn_limit_bits_mont=0;
88static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
89
90void BN_set_params(int mult, int high, int low, int mont)
91 {
92 if (mult >= 0)
93 {
94 if (mult > (sizeof(int)*8)-1)
95 mult=sizeof(int)*8-1;
96 bn_limit_bits=mult;
97 bn_limit_num=1<<mult;
98 }
99 if (high >= 0)
100 {
101 if (high > (sizeof(int)*8)-1)
102 high=sizeof(int)*8-1;
103 bn_limit_bits_high=high;
104 bn_limit_num_high=1<<high;
105 }
106 if (low >= 0)
107 {
108 if (low > (sizeof(int)*8)-1)
109 low=sizeof(int)*8-1;
110 bn_limit_bits_low=low;
111 bn_limit_num_low=1<<low;
112 }
113 if (mont >= 0)
114 {
115 if (mont > (sizeof(int)*8)-1)
116 mont=sizeof(int)*8-1;
117 bn_limit_bits_mont=mont;
118 bn_limit_num_mont=1<<mont;
119 }
120 }
121
122int BN_get_params(int which)
123 {
124 if (which == 0) return(bn_limit_bits);
125 else if (which == 1) return(bn_limit_bits_high);
126 else if (which == 2) return(bn_limit_bits_low);
127 else if (which == 3) return(bn_limit_bits_mont);
128 else return(0);
129 }
130
131const BIGNUM *BN_value_one(void)
66 { 132 {
67 static BN_ULONG data_one=1L; 133 static BN_ULONG data_one=1L;
68 static BIGNUM const_one={&data_one,1,1,0}; 134 static BIGNUM const_one={&data_one,1,1,0};
@@ -70,7 +136,7 @@ BIGNUM *BN_value_one()
70 return(&const_one); 136 return(&const_one);
71 } 137 }
72 138
73char *BN_options() 139char *BN_options(void)
74 { 140 {
75 static int init=0; 141 static int init=0;
76 static char data[16]; 142 static char data[16];
@@ -89,10 +155,9 @@ char *BN_options()
89 return(data); 155 return(data);
90 } 156 }
91 157
92int BN_num_bits_word(l) 158int BN_num_bits_word(BN_ULONG l)
93BN_ULONG l;
94 { 159 {
95 static char bits[256]={ 160 static const char bits[256]={
96 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 161 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, 162 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, 163 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
@@ -111,24 +176,24 @@ BN_ULONG l;
111 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 176 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
112 }; 177 };
113 178
114#ifdef SIXTY_FOUR_BIT_LONG 179#if defined(SIXTY_FOUR_BIT_LONG)
115 if (l & 0xffffffff00000000L) 180 if (l & 0xffffffff00000000L)
116 { 181 {
117 if (l & 0xffff000000000000L) 182 if (l & 0xffff000000000000L)
118 { 183 {
119 if (l & 0xff00000000000000L) 184 if (l & 0xff00000000000000L)
120 { 185 {
121 return(bits[l>>56]+56); 186 return(bits[(int)(l>>56)]+56);
122 } 187 }
123 else return(bits[l>>48]+48); 188 else return(bits[(int)(l>>48)]+48);
124 } 189 }
125 else 190 else
126 { 191 {
127 if (l & 0x0000ff0000000000L) 192 if (l & 0x0000ff0000000000L)
128 { 193 {
129 return(bits[l>>40]+40); 194 return(bits[(int)(l>>40)]+40);
130 } 195 }
131 else return(bits[l>>32]+32); 196 else return(bits[(int)(l>>32)]+32);
132 } 197 }
133 } 198 }
134 else 199 else
@@ -140,17 +205,17 @@ BN_ULONG l;
140 { 205 {
141 if (l & 0xff00000000000000LL) 206 if (l & 0xff00000000000000LL)
142 { 207 {
143 return(bits[l>>56]+56); 208 return(bits[(int)(l>>56)]+56);
144 } 209 }
145 else return(bits[l>>48]+48); 210 else return(bits[(int)(l>>48)]+48);
146 } 211 }
147 else 212 else
148 { 213 {
149 if (l & 0x0000ff0000000000LL) 214 if (l & 0x0000ff0000000000LL)
150 { 215 {
151 return(bits[l>>40]+40); 216 return(bits[(int)(l>>40)]+40);
152 } 217 }
153 else return(bits[l>>32]+32); 218 else return(bits[(int)(l>>32)]+32);
154 } 219 }
155 } 220 }
156 else 221 else
@@ -161,161 +226,256 @@ BN_ULONG l;
161 if (l & 0xffff0000L) 226 if (l & 0xffff0000L)
162 { 227 {
163 if (l & 0xff000000L) 228 if (l & 0xff000000L)
164 return(bits[l>>24L]+24); 229 return(bits[(int)(l>>24L)]+24);
165 else return(bits[l>>16L]+16); 230 else return(bits[(int)(l>>16L)]+16);
166 } 231 }
167 else 232 else
168#endif 233#endif
169 { 234 {
170#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) 235#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
171 if (l & 0xff00L) 236 if (l & 0xff00L)
172 return(bits[l>>8]+8); 237 return(bits[(int)(l>>8)]+8);
173 else 238 else
174#endif 239#endif
175 return(bits[l ] ); 240 return(bits[(int)(l )] );
176 } 241 }
177 } 242 }
178 } 243 }
179 244
180int BN_num_bits(a) 245int BN_num_bits(const BIGNUM *a)
181BIGNUM *a;
182 { 246 {
183 BN_ULONG l; 247 BN_ULONG l;
184 int i; 248 int i;
185 249
250 bn_check_top(a);
251
186 if (a->top == 0) return(0); 252 if (a->top == 0) return(0);
187 l=a->d[a->top-1]; 253 l=a->d[a->top-1];
254 assert(l != 0);
188 i=(a->top-1)*BN_BITS2; 255 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)); 256 return(i+BN_num_bits_word(l));
197 } 257 }
198 258
199void BN_clear_free(a) 259void BN_clear_free(BIGNUM *a)
200BIGNUM *a;
201 { 260 {
261 int i;
262
202 if (a == NULL) return; 263 if (a == NULL) return;
203 if (a->d != NULL) 264 if (a->d != NULL)
204 { 265 {
205 memset(a->d,0,a->max*sizeof(a->d[0])); 266 memset(a->d,0,a->dmax*sizeof(a->d[0]));
206 Free(a->d); 267 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
268 OPENSSL_free(a->d);
207 } 269 }
270 i=BN_get_flags(a,BN_FLG_MALLOCED);
208 memset(a,0,sizeof(BIGNUM)); 271 memset(a,0,sizeof(BIGNUM));
209 Free(a); 272 if (i)
273 OPENSSL_free(a);
210 } 274 }
211 275
212void BN_free(a) 276void BN_free(BIGNUM *a)
213BIGNUM *a;
214 { 277 {
215 if (a == NULL) return; 278 if (a == NULL) return;
216 if (a->d != NULL) Free(a->d); 279 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
217 Free(a); 280 OPENSSL_free(a->d);
281 a->flags|=BN_FLG_FREE; /* REMOVE? */
282 if (a->flags & BN_FLG_MALLOCED)
283 OPENSSL_free(a);
218 } 284 }
219 285
220BIGNUM *BN_new() 286void BN_init(BIGNUM *a)
287 {
288 memset(a,0,sizeof(BIGNUM));
289 }
290
291BIGNUM *BN_new(void)
221 { 292 {
222 BIGNUM *ret; 293 BIGNUM *ret;
223 BN_ULONG *p;
224 294
225 ret=(BIGNUM *)Malloc(sizeof(BIGNUM)); 295 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
226 if (ret == NULL) goto err; 296 {
297 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
298 return(NULL);
299 }
300 ret->flags=BN_FLG_MALLOCED;
227 ret->top=0; 301 ret->top=0;
228 ret->neg=0; 302 ret->neg=0;
229 ret->max=(BN_DEFAULT_BITS/BN_BITS2); 303 ret->dmax=0;
230 p=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(ret->max+1)); 304 ret->d=NULL;
231 if (p == NULL) goto err;
232 ret->d=p;
233
234 memset(p,0,(ret->max+1)*sizeof(p[0]));
235 return(ret); 305 return(ret);
236err:
237 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
238 return(NULL);
239 } 306 }
240 307
241BN_CTX *BN_CTX_new() 308/* This is used both by bn_expand2() and bn_dup_expand() */
309/* The caller MUST check that words > b->dmax before calling this */
310static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
242 { 311 {
243 BN_CTX *ret; 312 BN_ULONG *A,*a = NULL;
244 BIGNUM *n; 313 const BN_ULONG *B;
245 int i,j; 314 int i;
246 315
247 ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); 316 if (words > (INT_MAX/(4*BN_BITS2)))
248 if (ret == NULL) goto err2; 317 {
318 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
319 return NULL;
320 }
249 321
250 for (i=0; i<BN_CTX_NUM; i++) 322 bn_check_top(b);
323 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
251 { 324 {
252 n=BN_new(); 325 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
253 if (n == NULL) goto err; 326 return(NULL);
254 ret->bn[i]=n; 327 }
328 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
329 if (A == NULL)
330 {
331 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
332 return(NULL);
333 }
334#if 1
335 B=b->d;
336 /* Check if the previous number needs to be copied */
337 if (B != NULL)
338 {
339 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
340 {
341 /*
342 * The fact that the loop is unrolled
343 * 4-wise is a tribute to Intel. It's
344 * the one that doesn't have enough
345 * registers to accomodate more data.
346 * I'd unroll it 8-wise otherwise:-)
347 *
348 * <appro@fy.chalmers.se>
349 */
350 BN_ULONG a0,a1,a2,a3;
351 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
352 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
353 }
354 switch (b->top&3)
355 {
356 case 3: A[2]=B[2];
357 case 2: A[1]=B[1];
358 case 1: A[0]=B[0];
359 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
360 * the switch table by doing a=top&3; a--; goto jump_table[a];
361 * which fails for top== 0 */
362 ;
363 }
255 } 364 }
256 365
257 /* There is actually an extra one, this is for debugging my 366 /* Now need to zero any data between b->top and b->max */
258 * stuff */ 367 /* XXX Why? */
259 ret->bn[BN_CTX_NUM]=NULL;
260 368
261 ret->tos=0; 369 A= &(a[b->top]);
262 return(ret); 370 for (i=(words - b->top)>>3; i>0; i--,A+=8)
263err: 371 {
264 for (j=0; j<i; j++) 372 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
265 BN_free(ret->bn[j]); 373 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
266 Free(ret); 374 }
267err2: 375 for (i=(words - b->top)&7; i>0; i--,A++)
268 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); 376 A[0]=0;
269 return(NULL); 377#else
378 memset(A,0,sizeof(BN_ULONG)*(words+1));
379 memcpy(A,b->d,sizeof(b->d[0])*b->top);
380#endif
381
382 return(a);
270 } 383 }
271 384
272void BN_CTX_free(c) 385/* This is an internal function that can be used instead of bn_expand2()
273BN_CTX *c; 386 * when there is a need to copy BIGNUMs instead of only expanding the
387 * data part, while still expanding them.
388 * Especially useful when needing to expand BIGNUMs that are declared
389 * 'const' and should therefore not be changed.
390 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
391 * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
392 * will allocate new memory for the BIGNUM data twice, and free it once,
393 * while bn_dup_expand() makes sure allocation is made only once.
394 */
395
396BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
274 { 397 {
275 int i; 398 BIGNUM *r = NULL;
399
400 if (words > b->dmax)
401 {
402 BN_ULONG *a = bn_expand_internal(b, words);
276 403
277 for (i=0; i<BN_CTX_NUM; i++) 404 if (a)
278 BN_clear_free(c->bn[i]); 405 {
279 Free(c); 406 r = BN_new();
407 if (r)
408 {
409 r->top = b->top;
410 r->dmax = words;
411 r->neg = b->neg;
412 r->d = a;
413 }
414 else
415 {
416 /* r == NULL, BN_new failure */
417 OPENSSL_free(a);
418 }
419 }
420 /* If a == NULL, there was an error in allocation in
421 bn_expand_internal(), and NULL should be returned */
422 }
423 else
424 {
425 r = BN_dup(b);
426 }
427
428 return r;
280 } 429 }
281 430
282BIGNUM *bn_expand2(b, words) 431/* This is an internal function that should not be used in applications.
283BIGNUM *b; 432 * It ensures that 'b' has enough room for a 'words' word number number.
284int words; 433 * It is mostly used by the various BIGNUM routines. If there is an error,
285 { 434 * NULL is returned. If not, 'b' is returned. */
286 BN_ULONG *p;
287 435
288 if (words > b->max) 436BIGNUM *bn_expand2(BIGNUM *b, int words)
437 {
438 if (words > b->dmax)
289 { 439 {
290 p=(BN_ULONG *)Realloc(b->d,sizeof(BN_ULONG)*(words+1)); 440 BN_ULONG *a = bn_expand_internal(b, words);
291 if (p == NULL) 441
442 if (a)
292 { 443 {
293 BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE); 444 if (b->d)
294 return(NULL); 445 OPENSSL_free(b->d);
446 b->d=a;
447 b->dmax=words;
295 } 448 }
296 b->d=p; 449 else
297 memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); 450 b = NULL;
298 b->max=words;
299 } 451 }
300 return(b); 452 return b;
301 } 453 }
302 454
303BIGNUM *BN_dup(a) 455BIGNUM *BN_dup(const BIGNUM *a)
304BIGNUM *a;
305 { 456 {
306 BIGNUM *r; 457 BIGNUM *r, *t;
307 458
308 r=BN_new(); 459 if (a == NULL) return NULL;
309 if (r == NULL) return(NULL); 460
310 return((BIGNUM *)BN_copy(r,a)); 461 bn_check_top(a);
462
463 t = BN_new();
464 if (t == NULL) return(NULL);
465 r = BN_copy(t, a);
466 /* now r == t || r == NULL */
467 if (r == NULL)
468 BN_free(t);
469 return r;
311 } 470 }
312 471
313BIGNUM *BN_copy(a, b) 472BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
314BIGNUM *a;
315BIGNUM *b;
316 { 473 {
317 int i; 474 int i;
318 BN_ULONG *A,*B; 475 BN_ULONG *A;
476 const BN_ULONG *B;
477
478 bn_check_top(b);
319 479
320 if (a == b) return(a); 480 if (a == b) return(a);
321 if (bn_wexpand(a,b->top) == NULL) return(NULL); 481 if (bn_wexpand(a,b->top) == NULL) return(NULL);
@@ -323,35 +483,18 @@ BIGNUM *b;
323#if 1 483#if 1
324 A=a->d; 484 A=a->d;
325 B=b->d; 485 B=b->d;
326 for (i=b->top&(~7); i>0; i-=8) 486 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
327 { 487 {
328 A[0]=B[0]; 488 BN_ULONG a0,a1,a2,a3;
329 A[1]=B[1]; 489 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
330 A[2]=B[2]; 490 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
331 A[3]=B[3]; 491 }
332 A[4]=B[4]; 492 switch (b->top&3)
333 A[5]=B[5]; 493 {
334 A[6]=B[6]; 494 case 3: A[2]=B[2];
335 A[7]=B[7]; 495 case 2: A[1]=B[1];
336 A+=8; 496 case 1: A[0]=B[0];
337 B+=8; 497 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
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 } 498 }
356#else 499#else
357 memcpy(a->d,b->d,sizeof(b->d[0])*b->top); 500 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
@@ -359,52 +502,76 @@ BIGNUM *b;
359 502
360/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/ 503/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
361 a->top=b->top; 504 a->top=b->top;
362 if (a->top == 0) 505 if ((a->top == 0) && (a->d != NULL))
363 a->d[0]=0; 506 a->d[0]=0;
364 a->neg=b->neg; 507 a->neg=b->neg;
365 return(a); 508 return(a);
366 } 509 }
367 510
368void BN_clear(a) 511void BN_swap(BIGNUM *a, BIGNUM *b)
369BIGNUM *a; 512 {
513 int flags_old_a, flags_old_b;
514 BN_ULONG *tmp_d;
515 int tmp_top, tmp_dmax, tmp_neg;
516
517 flags_old_a = a->flags;
518 flags_old_b = b->flags;
519
520 tmp_d = a->d;
521 tmp_top = a->top;
522 tmp_dmax = a->dmax;
523 tmp_neg = a->neg;
524
525 a->d = b->d;
526 a->top = b->top;
527 a->dmax = b->dmax;
528 a->neg = b->neg;
529
530 b->d = tmp_d;
531 b->top = tmp_top;
532 b->dmax = tmp_dmax;
533 b->neg = tmp_neg;
534
535 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
536 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
537 }
538
539
540void BN_clear(BIGNUM *a)
370 { 541 {
371 memset(a->d,0,a->max*sizeof(a->d[0])); 542 if (a->d != NULL)
543 memset(a->d,0,a->dmax*sizeof(a->d[0]));
372 a->top=0; 544 a->top=0;
373 a->neg=0; 545 a->neg=0;
374 } 546 }
375 547
376unsigned long BN_get_word(a) 548BN_ULONG BN_get_word(const BIGNUM *a)
377BIGNUM *a;
378 { 549 {
379 int i,n; 550 int i,n;
380 unsigned long ret=0; 551 BN_ULONG ret=0;
381 552
382 n=BN_num_bytes(a); 553 n=BN_num_bytes(a);
383 if (n > sizeof(unsigned long)) 554 if (n > sizeof(BN_ULONG))
384#ifdef SIXTY_FOUR_BIT_LONG
385 return(BN_MASK2); 555 return(BN_MASK2);
386#else
387 return(0xFFFFFFFFL);
388#endif
389 for (i=a->top-1; i>=0; i--) 556 for (i=a->top-1; i>=0; i--)
390 { 557 {
391#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ 558#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
392 ret<<=BN_BITS4; /* stops the compiler complaining */ 559 ret<<=BN_BITS4; /* stops the compiler complaining */
393 ret<<=BN_BITS4; 560 ret<<=BN_BITS4;
561#else
562 ret=0;
394#endif 563#endif
395 ret|=a->d[i]; 564 ret|=a->d[i];
396 } 565 }
397 return(ret); 566 return(ret);
398 } 567 }
399 568
400int BN_set_word(a,w) 569int BN_set_word(BIGNUM *a, BN_ULONG w)
401BIGNUM *a;
402unsigned long w;
403 { 570 {
404 int i,n; 571 int i,n;
405 if (bn_expand(a,sizeof(unsigned long)*8) == NULL) return(0); 572 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
406 573
407 n=sizeof(unsigned long)/BN_BYTES; 574 n=sizeof(BN_ULONG)/BN_BYTES;
408 a->neg=0; 575 a->neg=0;
409 a->top=0; 576 a->top=0;
410 a->d[0]=(BN_ULONG)w&BN_MASK2; 577 a->d[0]=(BN_ULONG)w&BN_MASK2;
@@ -417,6 +584,8 @@ unsigned long w;
417#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ 584#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
418 w>>=BN_BITS4; 585 w>>=BN_BITS4;
419 w>>=BN_BITS4; 586 w>>=BN_BITS4;
587#else
588 w=0;
420#endif 589#endif
421 a->d[i]=(BN_ULONG)w&BN_MASK2; 590 a->d[i]=(BN_ULONG)w&BN_MASK2;
422 if (a->d[i] != 0) a->top=i+1; 591 if (a->d[i] != 0) a->top=i+1;
@@ -424,11 +593,7 @@ unsigned long w;
424 return(1); 593 return(1);
425 } 594 }
426 595
427/* ignore negative */ 596BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
428BIGNUM *BN_bin2bn(s, len, ret)
429unsigned char *s;
430int len;
431BIGNUM *ret;
432 { 597 {
433 unsigned int i,m; 598 unsigned int i,m;
434 unsigned int n; 599 unsigned int n;
@@ -448,6 +613,7 @@ BIGNUM *ret;
448 i=((n-1)/BN_BYTES)+1; 613 i=((n-1)/BN_BYTES)+1;
449 m=((n-1)%(BN_BYTES)); 614 m=((n-1)%(BN_BYTES));
450 ret->top=i; 615 ret->top=i;
616 ret->neg=0;
451 while (n-- > 0) 617 while (n-- > 0)
452 { 618 {
453 l=(l<<8L)| *(s++); 619 l=(l<<8L)| *(s++);
@@ -465,9 +631,7 @@ BIGNUM *ret;
465 } 631 }
466 632
467/* ignore negative */ 633/* ignore negative */
468int BN_bn2bin(a, to) 634int BN_bn2bin(const BIGNUM *a, unsigned char *to)
469BIGNUM *a;
470unsigned char *to;
471 { 635 {
472 int n,i; 636 int n,i;
473 BN_ULONG l; 637 BN_ULONG l;
@@ -481,13 +645,14 @@ unsigned char *to;
481 return(n); 645 return(n);
482 } 646 }
483 647
484int BN_ucmp(a, b) 648int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
485BIGNUM *a;
486BIGNUM *b;
487 { 649 {
488 int i; 650 int i;
489 BN_ULONG t1,t2,*ap,*bp; 651 BN_ULONG t1,t2,*ap,*bp;
490 652
653 bn_check_top(a);
654 bn_check_top(b);
655
491 i=a->top-b->top; 656 i=a->top-b->top;
492 if (i != 0) return(i); 657 if (i != 0) return(i);
493 ap=a->d; 658 ap=a->d;
@@ -502,9 +667,7 @@ BIGNUM *b;
502 return(0); 667 return(0);
503 } 668 }
504 669
505int BN_cmp(a, b) 670int BN_cmp(const BIGNUM *a, const BIGNUM *b)
506BIGNUM *a;
507BIGNUM *b;
508 { 671 {
509 int i; 672 int i;
510 int gt,lt; 673 int gt,lt;
@@ -519,6 +682,10 @@ BIGNUM *b;
519 else 682 else
520 return(0); 683 return(0);
521 } 684 }
685
686 bn_check_top(a);
687 bn_check_top(b);
688
522 if (a->neg != b->neg) 689 if (a->neg != b->neg)
523 { 690 {
524 if (a->neg) 691 if (a->neg)
@@ -541,27 +708,25 @@ BIGNUM *b;
541 return(0); 708 return(0);
542 } 709 }
543 710
544int BN_set_bit(a, n) 711int BN_set_bit(BIGNUM *a, int n)
545BIGNUM *a;
546int n;
547 { 712 {
548 int i,j; 713 int i,j,k;
549 714
550 i=n/BN_BITS2; 715 i=n/BN_BITS2;
551 j=n%BN_BITS2; 716 j=n%BN_BITS2;
552 if (a->top <= i) 717 if (a->top <= i)
553 { 718 {
554 if (bn_expand(a,n) == NULL) return(0); 719 if (bn_wexpand(a,i+1) == NULL) return(0);
720 for(k=a->top; k<i+1; k++)
721 a->d[k]=0;
555 a->top=i+1; 722 a->top=i+1;
556 } 723 }
557 724
558 a->d[i]|=(1L<<j); 725 a->d[i]|=(((BN_ULONG)1)<<j);
559 return(1); 726 return(1);
560 } 727 }
561 728
562int BN_clear_bit(a, n) 729int BN_clear_bit(BIGNUM *a, int n)
563BIGNUM *a;
564int n;
565 { 730 {
566 int i,j; 731 int i,j;
567 732
@@ -569,13 +734,12 @@ int n;
569 j=n%BN_BITS2; 734 j=n%BN_BITS2;
570 if (a->top <= i) return(0); 735 if (a->top <= i) return(0);
571 736
572 a->d[i]&=(~(1L<<j)); 737 a->d[i]&=(~(((BN_ULONG)1)<<j));
738 bn_fix_top(a);
573 return(1); 739 return(1);
574 } 740 }
575 741
576int BN_is_bit_set(a, n) 742int BN_is_bit_set(const BIGNUM *a, int n)
577BIGNUM *a;
578int n;
579 { 743 {
580 int i,j; 744 int i,j;
581 745
@@ -586,9 +750,7 @@ int n;
586 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0); 750 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
587 } 751 }
588 752
589int BN_mask_bits(a,n) 753int BN_mask_bits(BIGNUM *a, int n)
590BIGNUM *a;
591int n;
592 { 754 {
593 int b,w; 755 int b,w;
594 756
@@ -601,11 +763,56 @@ int n;
601 { 763 {
602 a->top=w+1; 764 a->top=w+1;
603 a->d[w]&= ~(BN_MASK2<<b); 765 a->d[w]&= ~(BN_MASK2<<b);
604 while ((w >= 0) && (a->d[w] == 0)) 766 }
767 bn_fix_top(a);
768 return(1);
769 }
770
771int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
772 {
773 int i;
774 BN_ULONG aa,bb;
775
776 aa=a[n-1];
777 bb=b[n-1];
778 if (aa != bb) return((aa > bb)?1:-1);
779 for (i=n-2; i>=0; i--)
780 {
781 aa=a[i];
782 bb=b[i];
783 if (aa != bb) return((aa > bb)?1:-1);
784 }
785 return(0);
786 }
787
788/* Here follows a specialised variants of bn_cmp_words(). It has the
789 property of performing the operation on arrays of different sizes.
790 The sizes of those arrays is expressed through cl, which is the
791 common length ( basicall, min(len(a),len(b)) ), and dl, which is the
792 delta between the two lengths, calculated as len(a)-len(b).
793 All lengths are the number of BN_ULONGs... */
794
795int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
796 int cl, int dl)
797 {
798 int n,i;
799 n = cl-1;
800
801 if (dl < 0)
802 {
803 for (i=dl; i<0; i++)
605 { 804 {
606 a->top--; 805 if (b[n-i] != 0)
607 w--; 806 return -1; /* a < b */
608 } 807 }
609 } 808 }
610 return(1); 809 if (dl > 0)
810 {
811 for (i=dl; i>0; i--)
812 {
813 if (a[n+i] != 0)
814 return 1; /* a > b */
815 }
816 }
817 return bn_cmp_words(a,b,cl);
611 } 818 }
diff --git a/src/lib/libcrypto/bn/bn_mod.c b/src/lib/libcrypto/bn/bn_mod.c
index c351aac14f..5cf82480d7 100644
--- a/src/lib/libcrypto/bn/bn_mod.c
+++ b/src/lib/libcrypto/bn/bn_mod.c
@@ -1,4 +1,59 @@
1/* crypto/bn/bn_mod.c */ 1/* crypto/bn/bn_mod.c */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. */
4/* ====================================================================
5 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * openssl-core@openssl.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 57/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 58 * All rights reserved.
4 * 59 *
@@ -56,42 +111,186 @@
56 * [including the GNU Public Licence.] 111 * [including the GNU Public Licence.]
57 */ 112 */
58 113
59#include <stdio.h>
60#include "cryptlib.h" 114#include "cryptlib.h"
61#include "bn_lcl.h" 115#include "bn_lcl.h"
62 116
63/* rem != m */ 117
64int BN_mod(rem, m, d,ctx) 118#if 0 /* now just a #define */
65BIGNUM *rem; 119int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
66BIGNUM *m; 120 {
67BIGNUM *d; 121 return(BN_div(NULL,rem,m,d,ctx));
68BN_CTX *ctx; 122 /* note that rem->neg == m->neg (unless the remainder is zero) */
123 }
124#endif
125
126
127int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
128 {
129 /* like BN_mod, but returns non-negative remainder
130 * (i.e., 0 <= r < |d| always holds) */
131
132 if (!(BN_mod(r,m,d,ctx)))
133 return 0;
134 if (!r->neg)
135 return 1;
136 /* now -|d| < r < 0, so we have to set r := r + |d| */
137 return (d->neg ? BN_sub : BN_add)(r, r, d);
138}
139
140
141int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
142 {
143 if (!BN_add(r, a, b)) return 0;
144 return BN_nnmod(r, r, m, ctx);
145 }
146
147
148/* BN_mod_add variant that may be used if both a and b are non-negative
149 * and less than m */
150int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
151 {
152 if (!BN_add(r, a, b)) return 0;
153 if (BN_ucmp(r, m) >= 0)
154 return BN_usub(r, r, m);
155 return 1;
156 }
157
158
159int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
160 {
161 if (!BN_sub(r, a, b)) return 0;
162 return BN_nnmod(r, r, m, ctx);
163 }
164
165
166/* BN_mod_sub variant that may be used if both a and b are non-negative
167 * and less than m */
168int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
169 {
170 if (!BN_sub(r, a, b)) return 0;
171 if (r->neg)
172 return BN_add(r, r, m);
173 return 1;
174 }
175
176
177/* slow but works */
178int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
179 BN_CTX *ctx)
69 { 180 {
70#if 0 /* The old slow way */ 181 BIGNUM *t;
71 int i,nm,nd; 182 int ret=0;
72 BIGNUM *dv; 183
184 bn_check_top(a);
185 bn_check_top(b);
186 bn_check_top(m);
187
188 BN_CTX_start(ctx);
189 if ((t = BN_CTX_get(ctx)) == NULL) goto err;
190 if (a == b)
191 { if (!BN_sqr(t,a,ctx)) goto err; }
192 else
193 { if (!BN_mul(t,a,b,ctx)) goto err; }
194 if (!BN_nnmod(r,t,m,ctx)) goto err;
195 ret=1;
196err:
197 BN_CTX_end(ctx);
198 return(ret);
199 }
73 200
74 if (BN_ucmp(m,d) < 0)
75 return((BN_copy(rem,m) == NULL)?0:1);
76 201
77 dv=ctx->bn[ctx->tos]; 202int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
203 {
204 if (!BN_sqr(r, a, ctx)) return 0;
205 /* r->neg == 0, thus we don't need BN_nnmod */
206 return BN_mod(r, r, m, ctx);
207 }
78 208
79 if (!BN_copy(rem,m)) return(0);
80 209
81 nm=BN_num_bits(rem); 210int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
82 nd=BN_num_bits(d); 211 {
83 if (!BN_lshift(dv,d,nm-nd)) return(0); 212 if (!BN_lshift1(r, a)) return 0;
84 for (i=nm-nd; i>=0; i--) 213 return BN_nnmod(r, r, m, ctx);
214 }
215
216
217/* BN_mod_lshift1 variant that may be used if a is non-negative
218 * and less than m */
219int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
220 {
221 if (!BN_lshift1(r, a)) return 0;
222 if (BN_cmp(r, m) >= 0)
223 return BN_sub(r, r, m);
224 return 1;
225 }
226
227
228int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
229 {
230 BIGNUM *abs_m = NULL;
231 int ret;
232
233 if (!BN_nnmod(r, a, m, ctx)) return 0;
234
235 if (m->neg)
85 { 236 {
86 if (BN_cmp(rem,dv) >= 0) 237 abs_m = BN_dup(m);
238 if (abs_m == NULL) return 0;
239 abs_m->neg = 0;
240 }
241
242 ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
243
244 if (abs_m)
245 BN_free(abs_m);
246 return ret;
247 }
248
249
250/* BN_mod_lshift variant that may be used if a is non-negative
251 * and less than m */
252int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
253 {
254 if (r != a)
255 {
256 if (BN_copy(r, a) == NULL) return 0;
257 }
258
259 while (n > 0)
260 {
261 int max_shift;
262
263 /* 0 < r < m */
264 max_shift = BN_num_bits(m) - BN_num_bits(r);
265 /* max_shift >= 0 */
266
267 if (max_shift < 0)
268 {
269 BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
270 return 0;
271 }
272
273 if (max_shift > n)
274 max_shift = n;
275
276 if (max_shift)
277 {
278 if (!BN_lshift(r, r, max_shift)) return 0;
279 n -= max_shift;
280 }
281 else
282 {
283 if (!BN_lshift1(r, r)) return 0;
284 --n;
285 }
286
287 /* BN_num_bits(r) <= BN_num_bits(m) */
288
289 if (BN_cmp(r, m) >= 0)
87 { 290 {
88 if (!BN_sub(rem,rem,dv)) return(0); 291 if (!BN_sub(r, r, m)) return 0;
89 } 292 }
90 if (!BN_rshift1(dv,dv)) return(0);
91 } 293 }
92 return(1); 294
93#else 295 return 1;
94 return(BN_div(NULL,rem,m,d,ctx));
95#endif
96 } 296 }
97
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c
index e435df61f8..c9ebdbaabe 100644
--- a/src/lib/libcrypto/bn/bn_mont.c
+++ b/src/lib/libcrypto/bn/bn_mont.c
@@ -56,59 +56,67 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59/*
60 * Details about Montgomery multiplication algorithms can be found at
61 * http://security.ece.orst.edu/publications.html, e.g.
62 * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
63 * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
64 */
65
59#include <stdio.h> 66#include <stdio.h>
60#include "cryptlib.h" 67#include "cryptlib.h"
61#include "bn_lcl.h" 68#include "bn_lcl.h"
62 69
63int BN_mod_mul_montgomery(r,a,b,mont,ctx) 70#define MONT_WORD /* use the faster word-based algorithm */
64BIGNUM *r,*a,*b; 71
65BN_MONT_CTX *mont; 72int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
66BN_CTX *ctx; 73 BN_MONT_CTX *mont, BN_CTX *ctx)
67 { 74 {
68 BIGNUM *tmp; 75 BIGNUM *tmp;
76 int ret=0;
69 77
70 tmp=ctx->bn[ctx->tos++]; 78 BN_CTX_start(ctx);
79 tmp = BN_CTX_get(ctx);
80 if (tmp == NULL) goto err;
71 81
82 bn_check_top(tmp);
72 if (a == b) 83 if (a == b)
73 { 84 {
74 if (!BN_sqr(tmp,a,ctx)) goto err; 85 if (!BN_sqr(tmp,a,ctx)) goto err;
75 } 86 }
76 else 87 else
77 { 88 {
78 if (!BN_mul(tmp,a,b)) goto err; 89 if (!BN_mul(tmp,a,b,ctx)) goto err;
79 } 90 }
80 /* reduce from aRR to aR */ 91 /* reduce from aRR to aR */
81 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; 92 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
82 ctx->tos--; 93 ret=1;
83 return(1);
84err: 94err:
85 return(0); 95 BN_CTX_end(ctx);
96 return(ret);
86 } 97 }
87 98
88#define MONT_WORD 99int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
100 BN_CTX *ctx)
101 {
102 int retn=0;
89 103
90#ifdef MONT_WORD 104#ifdef MONT_WORD
91int BN_from_montgomery(ret,a,mont,ctx) 105 BIGNUM *n,*r;
92BIGNUM *ret; 106 BN_ULONG *ap,*np,*rp,n0,v,*nrp;
93BIGNUM *a;
94BN_MONT_CTX *mont;
95BN_CTX *ctx;
96 {
97 BIGNUM *n,*t1,*r;
98 BN_ULONG *ap,*np,*rp,n0,v;
99 int al,nl,max,i,x,ri; 107 int al,nl,max,i,x,ri;
100 int retn=0;
101 108
102 t1=ctx->bn[ctx->tos]; 109 BN_CTX_start(ctx);
103 r=ctx->bn[ctx->tos+1]; 110 if ((r = BN_CTX_get(ctx)) == NULL) goto err;
104 111
105 if (!BN_copy(r,a)) goto err; 112 if (!BN_copy(r,a)) goto err;
106 n=mont->N; 113 n= &(mont->N);
107 114
108 ap=a->d; 115 ap=a->d;
109 /* mont->ri is the size of mont->N in bits/words */ 116 /* mont->ri is the size of mont->N in bits (rounded up
117 to the word size) */
110 al=ri=mont->ri/BN_BITS2; 118 al=ri=mont->ri/BN_BITS2;
111 119
112 nl=n->top; 120 nl=n->top;
113 if ((al == 0) || (nl == 0)) { r->top=0; return(1); } 121 if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
114 122
@@ -119,6 +127,7 @@ BN_CTX *ctx;
119 r->neg=a->neg^n->neg; 127 r->neg=a->neg^n->neg;
120 np=n->d; 128 np=n->d;
121 rp=r->d; 129 rp=r->d;
130 nrp= &(r->d[nl]);
122 131
123 /* clear the top words of T */ 132 /* clear the top words of T */
124#if 1 133#if 1
@@ -131,176 +140,210 @@ BN_CTX *ctx;
131 r->top=max; 140 r->top=max;
132 n0=mont->n0; 141 n0=mont->n0;
133 142
143#ifdef BN_COUNT
144 fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl);
145#endif
134 for (i=0; i<nl; i++) 146 for (i=0; i<nl; i++)
135 { 147 {
136#if 0 148#ifdef __TANDEM
137 int x1,x2; 149 {
138 150 long long t1;
139 if (i+4 > nl) 151 long long t2;
140 { 152 long long t3;
141 x2=nl; 153 t1 = rp[0] * (n0 & 0177777);
142 x1=0; 154 t2 = 037777600000l;
143 } 155 t2 = n0 & t2;
144 else 156 t3 = rp[0] & 0177777;
145 { 157 t2 = (t3 * t2) & BN_MASK2;
146 x2=i+4; 158 t1 = t1 + t2;
147 x1=nl-x2; 159 v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
148 } 160 }
149 v=bn_mul_add_words(&(rp[x1]),&(np[x1]),x2,(rp[x1]*n0)&BN_MASK2);
150#else 161#else
151 v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); 162 v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
152#endif 163#endif
153 164 nrp++;
154 if (((rp[nl]+=v)&BN_MASK2) < v) 165 rp++;
166 if (((nrp[-1]+=v)&BN_MASK2) >= v)
167 continue;
168 else
155 { 169 {
156 for (x=(nl+1); (((++rp[x])&BN_MASK2) == 0); x++) 170 if (((++nrp[0])&BN_MASK2) != 0) continue;
157 ; 171 if (((++nrp[1])&BN_MASK2) != 0) continue;
172 for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
158 } 173 }
159 rp++;
160 } 174 }
161 while (r->d[r->top-1] == 0) 175 bn_fix_top(r);
162 r->top--; 176
163
164 /* mont->ri will be a multiple of the word size */ 177 /* mont->ri will be a multiple of the word size */
165#if 0 178#if 0
166 BN_rshift(ret,r,mont->ri); 179 BN_rshift(ret,r,mont->ri);
167#else 180#else
168 ap=r->d; 181 ret->neg = r->neg;
169 rp=ret->d;
170 x=ri; 182 x=ri;
171 al=r->top-x; 183 rp=ret->d;
172 for (i=0; i<al; i++) 184 ap= &(r->d[x]);
173 { 185 if (r->top < x)
174 rp[i]=ap[i+x]; 186 al=0;
175 } 187 else
188 al=r->top-x;
176 ret->top=al; 189 ret->top=al;
177#endif 190 al-=4;
178 191 for (i=0; i<al; i+=4)
179 if (BN_ucmp(ret,mont->N) >= 0)
180 { 192 {
181 bn_qsub(ret,ret,mont->N); /* XXX */ 193 BN_ULONG t1,t2,t3,t4;
194
195 t1=ap[i+0];
196 t2=ap[i+1];
197 t3=ap[i+2];
198 t4=ap[i+3];
199 rp[i+0]=t1;
200 rp[i+1]=t2;
201 rp[i+2]=t3;
202 rp[i+3]=t4;
182 } 203 }
183 retn=1; 204 al+=4;
184err: 205 for (; i<al; i++)
185 return(retn); 206 rp[i]=ap[i];
186 } 207#endif
187#else 208#else /* !MONT_WORD */
188int BN_from_montgomery(r,a,mont,ctx)
189BIGNUM *r;
190BIGNUM *a;
191BN_MONT_CTX *mont;
192BN_CTX *ctx;
193 {
194 BIGNUM *t1,*t2; 209 BIGNUM *t1,*t2;
195 210
196 t1=ctx->bn[ctx->tos]; 211 BN_CTX_start(ctx);
197 t2=ctx->bn[ctx->tos+1]; 212 t1 = BN_CTX_get(ctx);
198 213 t2 = BN_CTX_get(ctx);
214 if (t1 == NULL || t2 == NULL) goto err;
215
199 if (!BN_copy(t1,a)) goto err; 216 if (!BN_copy(t1,a)) goto err;
200 /* can cheat */
201 BN_mask_bits(t1,mont->ri); 217 BN_mask_bits(t1,mont->ri);
202 218
203 if (!BN_mul(t2,t1,mont->Ni)) goto err; 219 if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
204 BN_mask_bits(t2,mont->ri); 220 BN_mask_bits(t2,mont->ri);
205 221
206 if (!BN_mul(t1,t2,mont->N)) goto err; 222 if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
207 if (!BN_add(t2,a,t1)) goto err; 223 if (!BN_add(t2,a,t1)) goto err;
208 BN_rshift(r,t2,mont->ri); 224 if (!BN_rshift(ret,t2,mont->ri)) goto err;
225#endif /* MONT_WORD */
209 226
210 if (BN_ucmp(r,mont->N) >= 0) 227 if (BN_ucmp(ret, &(mont->N)) >= 0)
211 bn_qsub(r,r,mont->N); 228 {
212 229 if (!BN_usub(ret,ret,&(mont->N))) goto err;
213 return(1); 230 }
214err: 231 retn=1;
215 return(0); 232 err:
233 BN_CTX_end(ctx);
234 return(retn);
216 } 235 }
217#endif
218 236
219BN_MONT_CTX *BN_MONT_CTX_new() 237BN_MONT_CTX *BN_MONT_CTX_new(void)
220 { 238 {
221 BN_MONT_CTX *ret; 239 BN_MONT_CTX *ret;
222 240
223 if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL) 241 if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
224 return(NULL);
225 ret->ri=0;
226 ret->RR=BN_new();
227 ret->N=BN_new();
228 ret->Ni=NULL;
229 if ((ret->RR == NULL) || (ret->N == NULL))
230 {
231 BN_MONT_CTX_free(ret);
232 return(NULL); 242 return(NULL);
233 } 243
244 BN_MONT_CTX_init(ret);
245 ret->flags=BN_FLG_MALLOCED;
234 return(ret); 246 return(ret);
235 } 247 }
236 248
237void BN_MONT_CTX_free(mont) 249void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
238BN_MONT_CTX *mont;
239 { 250 {
240 if (mont->RR != NULL) BN_free(mont->RR); 251 ctx->ri=0;
241 if (mont->N != NULL) BN_free(mont->N); 252 BN_init(&(ctx->RR));
242 if (mont->Ni != NULL) BN_free(mont->Ni); 253 BN_init(&(ctx->N));
243 Free(mont); 254 BN_init(&(ctx->Ni));
255 ctx->flags=0;
244 } 256 }
245 257
246int BN_MONT_CTX_set(mont,mod,ctx) 258void BN_MONT_CTX_free(BN_MONT_CTX *mont)
247BN_MONT_CTX *mont;
248BIGNUM *mod;
249BN_CTX *ctx;
250 { 259 {
251 BIGNUM *Ri=NULL,*R=NULL; 260 if(mont == NULL)
261 return;
262
263 BN_free(&(mont->RR));
264 BN_free(&(mont->N));
265 BN_free(&(mont->Ni));
266 if (mont->flags & BN_FLG_MALLOCED)
267 OPENSSL_free(mont);
268 }
252 269
253 if (mont->RR == NULL) mont->RR=BN_new(); 270int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
254 if (mont->N == NULL) mont->N=BN_new(); 271 {
272 BIGNUM Ri,*R;
255 273
256 R=mont->RR; /* grab RR as a temp */ 274 BN_init(&Ri);
257 BN_copy(mont->N,mod); /* Set N */ 275 R= &(mont->RR); /* grab RR as a temp */
276 BN_copy(&(mont->N),mod); /* Set N */
277 mont->N.neg = 0;
258 278
259#ifdef MONT_WORD 279#ifdef MONT_WORD
260{ 280 {
261 BIGNUM tmod; 281 BIGNUM tmod;
262 BN_ULONG buf[2]; 282 BN_ULONG buf[2];
263 /* int z; */ 283
264 284 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
265 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; 285 if (!(BN_zero(R))) goto err;
266 BN_lshift(R,BN_value_one(),BN_BITS2); /* R */ 286 if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
267 /* I was bad, this modification of a passed variable was 287
268 * breaking the multithreaded stuff :-( 288 buf[0]=mod->d[0]; /* tmod = N mod word size */
269 * z=mod->top; 289 buf[1]=0;
270 * mod->top=1; */ 290 tmod.d=buf;
271 291 tmod.top=1;
272 buf[0]=mod->d[0]; 292 tmod.dmax=2;
273 buf[1]=0; 293 tmod.neg=0;
274 tmod.d=buf; 294 /* Ri = R^-1 mod N*/
275 tmod.top=1; 295 if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
276 tmod.max=mod->max; 296 goto err;
277 tmod.neg=mod->neg; 297 if (!BN_lshift(&Ri,&Ri,BN_BITS2)) goto err; /* R*Ri */
278 298 if (!BN_is_zero(&Ri))
279 if ((Ri=BN_mod_inverse(R,&tmod,ctx)) == NULL) goto err; /* Ri */ 299 {
280 BN_lshift(Ri,Ri,BN_BITS2); /* R*Ri */ 300 if (!BN_sub_word(&Ri,1)) goto err;
281 bn_qsub(Ri,Ri,BN_value_one()); /* R*Ri - 1 */ 301 }
282 BN_div(Ri,NULL,Ri,&tmod,ctx); 302 else /* if N mod word size == 1 */
283 mont->n0=Ri->d[0]; 303 {
284 BN_free(Ri); 304 if (!BN_set_word(&Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */
285 /* mod->top=z; */ 305 }
286} 306 if (!BN_div(&Ri,NULL,&Ri,&tmod,ctx)) goto err;
287#else 307 /* Ni = (R*Ri-1)/N,
288 mont->ri=BN_num_bits(mod); 308 * keep only least significant word: */
289 BN_lshift(R,BN_value_one(),mont->ri); /* R */ 309 mont->n0 = (Ri.top > 0) ? Ri.d[0] : 0;
290 if ((Ri=BN_mod_inverse(R,mod,ctx)) == NULL) goto err; /* Ri */ 310 BN_free(&Ri);
291 BN_lshift(Ri,Ri,mont->ri); /* R*Ri */ 311 }
292 bn_qsub(Ri,Ri,BN_value_one()); /* R*Ri - 1 */ 312#else /* !MONT_WORD */
293 BN_div(Ri,NULL,Ri,mod,ctx); 313 { /* bignum version */
294 if (mont->Ni != NULL) BN_free(mont->Ni); 314 mont->ri=BN_num_bits(&mont->N);
295 mont->Ni=Ri; /* Ni=(R*Ri-1)/N */ 315 if (!BN_zero(R)) goto err;
316 if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */
317 /* Ri = R^-1 mod N*/
318 if ((BN_mod_inverse(&Ri,R,&mont->N,ctx)) == NULL)
319 goto err;
320 if (!BN_lshift(&Ri,&Ri,mont->ri)) goto err; /* R*Ri */
321 if (!BN_sub_word(&Ri,1)) goto err;
322 /* Ni = (R*Ri-1) / N */
323 if (!BN_div(&(mont->Ni),NULL,&Ri,&mont->N,ctx)) goto err;
324 BN_free(&Ri);
325 }
296#endif 326#endif
297 327
298 /* setup RR for conversions */ 328 /* setup RR for conversions */
299 BN_lshift(mont->RR,BN_value_one(),mont->ri*2); 329 if (!BN_zero(&(mont->RR))) goto err;
300 BN_mod(mont->RR,mont->RR,mont->N,ctx); 330 if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
331 if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
301 332
302 return(1); 333 return(1);
303err: 334err:
304 return(0); 335 return(0);
305 } 336 }
306 337
338BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
339 {
340 if (to == from) return(to);
341
342 if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
343 if (!BN_copy(&(to->N),&(from->N))) return NULL;
344 if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
345 to->ri=from->ri;
346 to->n0=from->n0;
347 return(to);
348 }
349
diff --git a/src/lib/libcrypto/bn/bn_mpi.c b/src/lib/libcrypto/bn/bn_mpi.c
index 53945c1057..05fa9d1e9a 100644
--- a/src/lib/libcrypto/bn/bn_mpi.c
+++ b/src/lib/libcrypto/bn/bn_mpi.c
@@ -60,9 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63int BN_bn2mpi(a,d) 63int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
64BIGNUM *a;
65unsigned char *d;
66 { 64 {
67 int bits; 65 int bits;
68 int num=0; 66 int num=0;
@@ -90,10 +88,7 @@ unsigned char *d;
90 return(num+4+ext); 88 return(num+4+ext);
91 } 89 }
92 90
93BIGNUM *BN_mpi2bn(d,n,a) 91BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
94unsigned char *d;
95int n;
96BIGNUM *a;
97 { 92 {
98 long len; 93 long len;
99 int neg=0; 94 int neg=0;
@@ -103,7 +98,7 @@ BIGNUM *a;
103 BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH); 98 BNerr(BN_F_BN_MPI2BN,BN_R_INVALID_LENGTH);
104 return(NULL); 99 return(NULL);
105 } 100 }
106 len=(d[0]<<24)|(d[1]<<16)|(d[2]<<8)|d[3]; 101 len=((long)d[0]<<24)|((long)d[1]<<16)|((int)d[2]<<8)|(int)d[3];
107 if ((len+4) != n) 102 if ((len+4) != n)
108 { 103 {
109 BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR); 104 BNerr(BN_F_BN_MPI2BN,BN_R_ENCODING_ERROR);
diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c
index d0c04e1d4b..fd598b8b3d 100644
--- a/src/lib/libcrypto/bn/bn_mul.c
+++ b/src/lib/libcrypto/bn/bn_mul.c
@@ -56,154 +56,1108 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
59#include <stdio.h> 64#include <stdio.h>
65#include <assert.h>
60#include "cryptlib.h" 66#include "cryptlib.h"
61#include "bn_lcl.h" 67#include "bn_lcl.h"
62 68
63/* r must be different to a and b */ 69#if defined(OPENSSL_NO_ASM) || !(defined(__i386) || defined(__i386__))/* Assembler implementation exists only for x86 */
64/* int BN_mmul(r, a, b) */ 70/* Here follows specialised variants of bn_add_words() and
65int BN_mul(r, a, b) 71 bn_sub_words(). They have the property performing operations on
66BIGNUM *r; 72 arrays of different sizes. The sizes of those arrays is expressed through
67BIGNUM *a; 73 cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
68BIGNUM *b; 74 which is the delta between the two lengths, calculated as len(a)-len(b).
75 All lengths are the number of BN_ULONGs... For the operations that require
76 a result array as parameter, it must have the length cl+abs(dl).
77 These functions should probably end up in bn_asm.c as soon as there are
78 assembler counterparts for the systems that use assembler files. */
79
80BN_ULONG bn_sub_part_words(BN_ULONG *r,
81 const BN_ULONG *a, const BN_ULONG *b,
82 int cl, int dl)
69 { 83 {
70 int i; 84 BN_ULONG c, t;
71 int max,al,bl;
72 BN_ULONG *ap,*bp,*rp;
73 85
74 al=a->top; 86 assert(cl >= 0);
75 bl=b->top; 87 c = bn_sub_words(r, a, b, cl);
76 if ((al == 0) || (bl == 0)) 88
89 if (dl == 0)
90 return c;
91
92 r += cl;
93 a += cl;
94 b += cl;
95
96 if (dl < 0)
77 { 97 {
78 r->top=0; 98#ifdef BN_COUNT
79 return(1); 99 fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
80 } 100#endif
101 for (;;)
102 {
103 t = b[0];
104 r[0] = (0-t-c)&BN_MASK2;
105 if (t != 0) c=1;
106 if (++dl >= 0) break;
107
108 t = b[1];
109 r[1] = (0-t-c)&BN_MASK2;
110 if (t != 0) c=1;
111 if (++dl >= 0) break;
112
113 t = b[2];
114 r[2] = (0-t-c)&BN_MASK2;
115 if (t != 0) c=1;
116 if (++dl >= 0) break;
81 117
82 max=(al+bl); 118 t = b[3];
83 if (bn_wexpand(r,max) == NULL) return(0); 119 r[3] = (0-t-c)&BN_MASK2;
84 r->top=max; 120 if (t != 0) c=1;
85 r->neg=a->neg^b->neg; 121 if (++dl >= 0) break;
86 ap=a->d;
87 bp=b->d;
88 rp=r->d;
89 122
90 rp[al]=bn_mul_words(rp,ap,al,*(bp++)); 123 b += 4;
91 rp++; 124 r += 4;
92 for (i=1; i<bl; i++) 125 }
126 }
127 else
93 { 128 {
94 rp[al]=bn_mul_add_words(rp,ap,al,*(bp++)); 129 int save_dl = dl;
95 rp++; 130#ifdef BN_COUNT
131 fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
132#endif
133 while(c)
134 {
135 t = a[0];
136 r[0] = (t-c)&BN_MASK2;
137 if (t != 0) c=0;
138 if (--dl <= 0) break;
139
140 t = a[1];
141 r[1] = (t-c)&BN_MASK2;
142 if (t != 0) c=0;
143 if (--dl <= 0) break;
144
145 t = a[2];
146 r[2] = (t-c)&BN_MASK2;
147 if (t != 0) c=0;
148 if (--dl <= 0) break;
149
150 t = a[3];
151 r[3] = (t-c)&BN_MASK2;
152 if (t != 0) c=0;
153 if (--dl <= 0) break;
154
155 save_dl = dl;
156 a += 4;
157 r += 4;
158 }
159 if (dl > 0)
160 {
161#ifdef BN_COUNT
162 fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
163#endif
164 if (save_dl > dl)
165 {
166 switch (save_dl - dl)
167 {
168 case 1:
169 r[1] = a[1];
170 if (--dl <= 0) break;
171 case 2:
172 r[2] = a[2];
173 if (--dl <= 0) break;
174 case 3:
175 r[3] = a[3];
176 if (--dl <= 0) break;
177 }
178 a += 4;
179 r += 4;
180 }
181 }
182 if (dl > 0)
183 {
184#ifdef BN_COUNT
185 fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
186#endif
187 for(;;)
188 {
189 r[0] = a[0];
190 if (--dl <= 0) break;
191 r[1] = a[1];
192 if (--dl <= 0) break;
193 r[2] = a[2];
194 if (--dl <= 0) break;
195 r[3] = a[3];
196 if (--dl <= 0) break;
197
198 a += 4;
199 r += 4;
200 }
201 }
96 } 202 }
97 if (r->d[max-1] == 0) r->top--; 203 return c;
98 return(1);
99 } 204 }
205#endif
100 206
101#if 0 207BN_ULONG bn_add_part_words(BN_ULONG *r,
102#include "stack.h" 208 const BN_ULONG *a, const BN_ULONG *b,
209 int cl, int dl)
210 {
211 BN_ULONG c, l, t;
212
213 assert(cl >= 0);
214 c = bn_add_words(r, a, b, cl);
215
216 if (dl == 0)
217 return c;
218
219 r += cl;
220 a += cl;
221 b += cl;
222
223 if (dl < 0)
224 {
225 int save_dl = dl;
226#ifdef BN_COUNT
227 fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
228#endif
229 while (c)
230 {
231 l=(c+b[0])&BN_MASK2;
232 c=(l < c);
233 r[0]=l;
234 if (++dl >= 0) break;
235
236 l=(c+b[1])&BN_MASK2;
237 c=(l < c);
238 r[1]=l;
239 if (++dl >= 0) break;
240
241 l=(c+b[2])&BN_MASK2;
242 c=(l < c);
243 r[2]=l;
244 if (++dl >= 0) break;
103 245
104int limit=16; 246 l=(c+b[3])&BN_MASK2;
247 c=(l < c);
248 r[3]=l;
249 if (++dl >= 0) break;
105 250
106typedef struct bn_pool_st 251 save_dl = dl;
252 b+=4;
253 r+=4;
254 }
255 if (dl < 0)
256 {
257#ifdef BN_COUNT
258 fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
259#endif
260 if (save_dl < dl)
261 {
262 switch (dl - save_dl)
263 {
264 case 1:
265 r[1] = b[1];
266 if (++dl >= 0) break;
267 case 2:
268 r[2] = b[2];
269 if (++dl >= 0) break;
270 case 3:
271 r[3] = b[3];
272 if (++dl >= 0) break;
273 }
274 b += 4;
275 r += 4;
276 }
277 }
278 if (dl < 0)
279 {
280#ifdef BN_COUNT
281 fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
282#endif
283 for(;;)
284 {
285 r[0] = b[0];
286 if (++dl >= 0) break;
287 r[1] = b[1];
288 if (++dl >= 0) break;
289 r[2] = b[2];
290 if (++dl >= 0) break;
291 r[3] = b[3];
292 if (++dl >= 0) break;
293
294 b += 4;
295 r += 4;
296 }
297 }
298 }
299 else
300 {
301 int save_dl = dl;
302#ifdef BN_COUNT
303 fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
304#endif
305 while (c)
306 {
307 t=(a[0]+c)&BN_MASK2;
308 c=(t < c);
309 r[0]=t;
310 if (--dl <= 0) break;
311
312 t=(a[1]+c)&BN_MASK2;
313 c=(t < c);
314 r[1]=t;
315 if (--dl <= 0) break;
316
317 t=(a[2]+c)&BN_MASK2;
318 c=(t < c);
319 r[2]=t;
320 if (--dl <= 0) break;
321
322 t=(a[3]+c)&BN_MASK2;
323 c=(t < c);
324 r[3]=t;
325 if (--dl <= 0) break;
326
327 save_dl = dl;
328 a+=4;
329 r+=4;
330 }
331#ifdef BN_COUNT
332 fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
333#endif
334 if (dl > 0)
335 {
336 if (save_dl > dl)
337 {
338 switch (save_dl - dl)
339 {
340 case 1:
341 r[1] = a[1];
342 if (--dl <= 0) break;
343 case 2:
344 r[2] = a[2];
345 if (--dl <= 0) break;
346 case 3:
347 r[3] = a[3];
348 if (--dl <= 0) break;
349 }
350 a += 4;
351 r += 4;
352 }
353 }
354 if (dl > 0)
355 {
356#ifdef BN_COUNT
357 fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
358#endif
359 for(;;)
360 {
361 r[0] = a[0];
362 if (--dl <= 0) break;
363 r[1] = a[1];
364 if (--dl <= 0) break;
365 r[2] = a[2];
366 if (--dl <= 0) break;
367 r[3] = a[3];
368 if (--dl <= 0) break;
369
370 a += 4;
371 r += 4;
372 }
373 }
374 }
375 return c;
376 }
377
378#ifdef BN_RECURSION
379/* Karatsuba recursive multiplication algorithm
380 * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
381
382/* r is 2*n2 words in size,
383 * a and b are both n2 words in size.
384 * n2 must be a power of 2.
385 * We multiply and return the result.
386 * t must be 2*n2 words in size
387 * We calculate
388 * a[0]*b[0]
389 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
390 * a[1]*b[1]
391 */
392void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
393 int dna, int dnb, BN_ULONG *t)
107 { 394 {
108 int used; 395 int n=n2/2,c1,c2;
109 int tos; 396 int tna=n+dna, tnb=n+dnb;
110 STACK *sk; 397 unsigned int neg,zero;
111 } BN_POOL; 398 BN_ULONG ln,lo,*p;
399
400# ifdef BN_COUNT
401 fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2);
402# endif
403# ifdef BN_MUL_COMBA
404# if 0
405 if (n2 == 4)
406 {
407 bn_mul_comba4(r,a,b);
408 return;
409 }
410# endif
411 /* Only call bn_mul_comba 8 if n2 == 8 and the
412 * two arrays are complete [steve]
413 */
414 if (n2 == 8 && dna == 0 && dnb == 0)
415 {
416 bn_mul_comba8(r,a,b);
417 return;
418 }
419# endif /* BN_MUL_COMBA */
420 /* Else do normal multiply */
421 if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
422 {
423 bn_mul_normal(r,a,n2+dna,b,n2+dnb);
424 if ((dna + dnb) < 0)
425 memset(&r[2*n2 + dna + dnb], 0,
426 sizeof(BN_ULONG) * -(dna + dnb));
427 return;
428 }
429 /* r=(a[0]-a[1])*(b[1]-b[0]) */
430 c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
431 c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
432 zero=neg=0;
433 switch (c1*3+c2)
434 {
435 case -4:
436 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
437 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
438 break;
439 case -3:
440 zero=1;
441 break;
442 case -2:
443 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
444 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
445 neg=1;
446 break;
447 case -1:
448 case 0:
449 case 1:
450 zero=1;
451 break;
452 case 2:
453 bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
454 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
455 neg=1;
456 break;
457 case 3:
458 zero=1;
459 break;
460 case 4:
461 bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
462 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
463 break;
464 }
465
466# ifdef BN_MUL_COMBA
467 if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
468 extra args to do this well */
469 {
470 if (!zero)
471 bn_mul_comba4(&(t[n2]),t,&(t[n]));
472 else
473 memset(&(t[n2]),0,8*sizeof(BN_ULONG));
474
475 bn_mul_comba4(r,a,b);
476 bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
477 }
478 else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
479 take extra args to do this
480 well */
481 {
482 if (!zero)
483 bn_mul_comba8(&(t[n2]),t,&(t[n]));
484 else
485 memset(&(t[n2]),0,16*sizeof(BN_ULONG));
486
487 bn_mul_comba8(r,a,b);
488 bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
489 }
490 else
491# endif /* BN_MUL_COMBA */
492 {
493 p= &(t[n2*2]);
494 if (!zero)
495 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
496 else
497 memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
498 bn_mul_recursive(r,a,b,n,0,0,p);
499 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
500 }
112 501
113BIGNUM *BN_POOL_push(bp) 502 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
114BN_POOL *bp; 503 * r[10] holds (a[0]*b[0])
504 * r[32] holds (b[1]*b[1])
505 */
506
507 c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
508
509 if (neg) /* if t[32] is negative */
510 {
511 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
512 }
513 else
514 {
515 /* Might have a carry */
516 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
517 }
518
519 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
520 * r[10] holds (a[0]*b[0])
521 * r[32] holds (b[1]*b[1])
522 * c1 holds the carry bits
523 */
524 c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
525 if (c1)
526 {
527 p= &(r[n+n2]);
528 lo= *p;
529 ln=(lo+c1)&BN_MASK2;
530 *p=ln;
531
532 /* The overflow will stop before we over write
533 * words we should not overwrite */
534 if (ln < (BN_ULONG)c1)
535 {
536 do {
537 p++;
538 lo= *p;
539 ln=(lo+1)&BN_MASK2;
540 *p=ln;
541 } while (ln == 0);
542 }
543 }
544 }
545
546/* n+tn is the word length
547 * t needs to be n*4 is size, as does r */
548void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
549 int tna, int tnb, BN_ULONG *t)
115 { 550 {
116 BIGNUM *ret; 551 int i,j,n2=n*2;
552 unsigned int c1,c2,neg,zero;
553 BN_ULONG ln,lo,*p;
554
555# ifdef BN_COUNT
556 fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n",
557 tna, n, tnb, n);
558# endif
559 if (n < 8)
560 {
561 bn_mul_normal(r,a,n+tna,b,n+tnb);
562 return;
563 }
117 564
118 if (bp->used >= bp->tos) 565 /* r=(a[0]-a[1])*(b[1]-b[0]) */
566 c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
567 c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
568 zero=neg=0;
569 switch (c1*3+c2)
570 {
571 case -4:
572 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
573 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
574 break;
575 case -3:
576 zero=1;
577 /* break; */
578 case -2:
579 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
580 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
581 neg=1;
582 break;
583 case -1:
584 case 0:
585 case 1:
586 zero=1;
587 /* break; */
588 case 2:
589 bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
590 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
591 neg=1;
592 break;
593 case 3:
594 zero=1;
595 /* break; */
596 case 4:
597 bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
598 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
599 break;
600 }
601 /* The zero case isn't yet implemented here. The speedup
602 would probably be negligible. */
603# if 0
604 if (n == 4)
119 { 605 {
120 ret=BN_new(); 606 bn_mul_comba4(&(t[n2]),t,&(t[n]));
121 sk_push(bp->sk,(char *)ret); 607 bn_mul_comba4(r,a,b);
122 bp->tos++; 608 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
123 bp->used++; 609 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
124 } 610 }
125 else 611 else
612# endif
613 if (n == 8)
126 { 614 {
127 ret=(BIGNUM *)sk_value(bp->sk,bp->used); 615 bn_mul_comba8(&(t[n2]),t,&(t[n]));
128 bp->used++; 616 bn_mul_comba8(r,a,b);
617 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
618 memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
619 }
620 else
621 {
622 p= &(t[n2*2]);
623 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
624 bn_mul_recursive(r,a,b,n,0,0,p);
625 i=n/2;
626 /* If there is only a bottom half to the number,
627 * just do it */
628 if (tna > tnb)
629 j = tna - i;
630 else
631 j = tnb - i;
632 if (j == 0)
633 {
634 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
635 i,tna-i,tnb-i,p);
636 memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
637 }
638 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
639 {
640 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
641 i,tna-i,tnb-i,p);
642 memset(&(r[n2+tna+tnb]),0,
643 sizeof(BN_ULONG)*(n2-tna-tnb));
644 }
645 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
646 {
647 memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
648 if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
649 && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
650 {
651 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
652 }
653 else
654 {
655 for (;;)
656 {
657 i/=2;
658 if (i < tna && i < tnb)
659 {
660 bn_mul_part_recursive(&(r[n2]),
661 &(a[n]),&(b[n]),
662 i,tna-i,tnb-i,p);
663 break;
664 }
665 else if (i <= tna && i <= tnb)
666 {
667 bn_mul_recursive(&(r[n2]),
668 &(a[n]),&(b[n]),
669 i,tna-i,tnb-i,p);
670 break;
671 }
672 }
673 }
674 }
675 }
676
677 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
678 * r[10] holds (a[0]*b[0])
679 * r[32] holds (b[1]*b[1])
680 */
681
682 c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
683
684 if (neg) /* if t[32] is negative */
685 {
686 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
687 }
688 else
689 {
690 /* Might have a carry */
691 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
692 }
693
694 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
695 * r[10] holds (a[0]*b[0])
696 * r[32] holds (b[1]*b[1])
697 * c1 holds the carry bits
698 */
699 c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
700 if (c1)
701 {
702 p= &(r[n+n2]);
703 lo= *p;
704 ln=(lo+c1)&BN_MASK2;
705 *p=ln;
706
707 /* The overflow will stop before we over write
708 * words we should not overwrite */
709 if (ln < c1)
710 {
711 do {
712 p++;
713 lo= *p;
714 ln=(lo+1)&BN_MASK2;
715 *p=ln;
716 } while (ln == 0);
717 }
129 } 718 }
130 return(ret);
131 } 719 }
132 720
133void BN_POOL_pop(bp,num) 721/* a and b must be the same size, which is n2.
134BN_POOL *bp; 722 * r needs to be n2 words and t needs to be n2*2
135int num; 723 */
724void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
725 BN_ULONG *t)
136 { 726 {
137 bp->used-=num; 727 int n=n2/2;
728
729# ifdef BN_COUNT
730 fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
731# endif
732
733 bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
734 if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
735 {
736 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
737 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
738 bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
739 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
740 }
741 else
742 {
743 bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
744 bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
745 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
746 bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
747 }
138 } 748 }
139 749
140int BN_mul(r,a,b) 750/* a and b must be the same size, which is n2.
141BIGNUM *r,*a,*b; 751 * r needs to be n2 words and t needs to be n2*2
752 * l is the low words of the output.
753 * t needs to be n2*3
754 */
755void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
756 BN_ULONG *t)
142 { 757 {
143 static BN_POOL bp; 758 int i,n;
144 static init=1; 759 int c1,c2;
760 int neg,oneg,zero;
761 BN_ULONG ll,lc,*lp,*mp;
762
763# ifdef BN_COUNT
764 fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
765# endif
766 n=n2/2;
767
768 /* Calculate (al-ah)*(bh-bl) */
769 neg=zero=0;
770 c1=bn_cmp_words(&(a[0]),&(a[n]),n);
771 c2=bn_cmp_words(&(b[n]),&(b[0]),n);
772 switch (c1*3+c2)
773 {
774 case -4:
775 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
776 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
777 break;
778 case -3:
779 zero=1;
780 break;
781 case -2:
782 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
783 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
784 neg=1;
785 break;
786 case -1:
787 case 0:
788 case 1:
789 zero=1;
790 break;
791 case 2:
792 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
793 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
794 neg=1;
795 break;
796 case 3:
797 zero=1;
798 break;
799 case 4:
800 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
801 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
802 break;
803 }
804
805 oneg=neg;
806 /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
807 /* r[10] = (a[1]*b[1]) */
808# ifdef BN_MUL_COMBA
809 if (n == 8)
810 {
811 bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
812 bn_mul_comba8(r,&(a[n]),&(b[n]));
813 }
814 else
815# endif
816 {
817 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
818 bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
819 }
820
821 /* s0 == low(al*bl)
822 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
823 * We know s0 and s1 so the only unknown is high(al*bl)
824 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
825 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
826 */
827 if (l != NULL)
828 {
829 lp= &(t[n2+n]);
830 c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
831 }
832 else
833 {
834 c1=0;
835 lp= &(r[0]);
836 }
837
838 if (neg)
839 neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
840 else
841 {
842 bn_add_words(&(t[n2]),lp,&(t[0]),n);
843 neg=0;
844 }
845
846 if (l != NULL)
847 {
848 bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
849 }
850 else
851 {
852 lp= &(t[n2+n]);
853 mp= &(t[n2]);
854 for (i=0; i<n; i++)
855 lp[i]=((~mp[i])+1)&BN_MASK2;
856 }
145 857
146 if (init) 858 /* s[0] = low(al*bl)
859 * t[3] = high(al*bl)
860 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
861 * r[10] = (a[1]*b[1])
862 */
863 /* R[10] = al*bl
864 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
865 * R[32] = ah*bh
866 */
867 /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
868 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
869 * R[3]=r[1]+(carry/borrow)
870 */
871 if (l != NULL)
872 {
873 lp= &(t[n2]);
874 c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
875 }
876 else
147 { 877 {
148 bp.used=0; 878 lp= &(t[n2+n]);
149 bp.tos=0; 879 c1=0;
150 bp.sk=sk_new_null(); 880 }
151 init=0; 881 c1+=(int)(bn_add_words(&(t[n2]),lp, &(r[0]),n));
882 if (oneg)
883 c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
884 else
885 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
886
887 c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
888 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
889 if (oneg)
890 c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
891 else
892 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
893
894 if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
895 {
896 i=0;
897 if (c1 > 0)
898 {
899 lc=c1;
900 do {
901 ll=(r[i]+lc)&BN_MASK2;
902 r[i++]=ll;
903 lc=(lc > ll);
904 } while (lc);
905 }
906 else
907 {
908 lc= -c1;
909 do {
910 ll=r[i];
911 r[i++]=(ll-lc)&BN_MASK2;
912 lc=(lc > ll);
913 } while (lc);
914 }
915 }
916 if (c2 != 0) /* Add starting at r[1] */
917 {
918 i=n;
919 if (c2 > 0)
920 {
921 lc=c2;
922 do {
923 ll=(r[i]+lc)&BN_MASK2;
924 r[i++]=ll;
925 lc=(lc > ll);
926 } while (lc);
927 }
928 else
929 {
930 lc= -c2;
931 do {
932 ll=r[i];
933 r[i++]=(ll-lc)&BN_MASK2;
934 lc=(lc > ll);
935 } while (lc);
936 }
152 } 937 }
153 return(BN_mm(r,a,b,&bp));
154 } 938 }
939#endif /* BN_RECURSION */
155 940
156/* r must be different to a and b */ 941int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
157int BN_mm(m, A, B, bp)
158BIGNUM *m,*A,*B;
159BN_POOL *bp;
160 { 942 {
161 int i,num; 943 int ret=0;
162 int an,bn; 944 int top,al,bl;
163 BIGNUM *a,*b,*c,*d,*ac,*bd; 945 BIGNUM *rr;
946#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
947 int i;
948#endif
949#ifdef BN_RECURSION
950 BIGNUM *t=NULL;
951 int j=0,k;
952#endif
953
954#ifdef BN_COUNT
955 fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
956#endif
164 957
165 an=A->top; 958 bn_check_top(a);
166 bn=B->top; 959 bn_check_top(b);
167 if ((an <= limit) || (bn <= limit)) 960 bn_check_top(r);
961
962 al=a->top;
963 bl=b->top;
964
965 if ((al == 0) || (bl == 0))
168 { 966 {
169 return(BN_mmul(m,A,B)); 967 if (!BN_zero(r)) goto err;
968 return(1);
170 } 969 }
970 top=al+bl;
171 971
172 a=BN_POOL_push(bp); 972 BN_CTX_start(ctx);
173 b=BN_POOL_push(bp); 973 if ((r == a) || (r == b))
174 c=BN_POOL_push(bp); 974 {
175 d=BN_POOL_push(bp); 975 if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
176 ac=BN_POOL_push(bp); 976 }
177 bd=BN_POOL_push(bp); 977 else
978 rr = r;
979 rr->neg=a->neg^b->neg;
178 980
179 num=(an <= bn)?an:bn; 981#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
180 num=1<<(BN_num_bits_word(num-1)-1); 982 i = al-bl;
983#endif
984#ifdef BN_MUL_COMBA
985 if (i == 0)
986 {
987# if 0
988 if (al == 4)
989 {
990 if (bn_wexpand(rr,8) == NULL) goto err;
991 rr->top=8;
992 bn_mul_comba4(rr->d,a->d,b->d);
993 goto end;
994 }
995# endif
996 if (al == 8)
997 {
998 if (bn_wexpand(rr,16) == NULL) goto err;
999 rr->top=16;
1000 bn_mul_comba8(rr->d,a->d,b->d);
1001 goto end;
1002 }
1003 }
1004#endif /* BN_MUL_COMBA */
1005#ifdef BN_RECURSION
1006 if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
1007 {
1008 if (i >= -1 && i <= 1)
1009 {
1010 int sav_j =0;
1011 /* Find out the power of two lower or equal
1012 to the longest of the two numbers */
1013 if (i >= 0)
1014 {
1015 j = BN_num_bits_word((BN_ULONG)al);
1016 }
1017 if (i == -1)
1018 {
1019 j = BN_num_bits_word((BN_ULONG)bl);
1020 }
1021 sav_j = j;
1022 j = 1<<(j-1);
1023 assert(j <= al || j <= bl);
1024 k = j+j;
1025 t = BN_CTX_get(ctx);
1026 if (al > j || bl > j)
1027 {
1028 bn_wexpand(t,k*4);
1029 bn_wexpand(rr,k*4);
1030 bn_mul_part_recursive(rr->d,a->d,b->d,
1031 j,al-j,bl-j,t->d);
1032 }
1033 else /* al <= j || bl <= j */
1034 {
1035 bn_wexpand(t,k*2);
1036 bn_wexpand(rr,k*2);
1037 bn_mul_recursive(rr->d,a->d,b->d,
1038 j,al-j,bl-j,t->d);
1039 }
1040 rr->top=top;
1041 goto end;
1042 }
1043#if 0
1044 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
1045 {
1046 BIGNUM *tmp_bn = (BIGNUM *)b;
1047 if (bn_wexpand(tmp_bn,al) == NULL) goto err;
1048 tmp_bn->d[bl]=0;
1049 bl++;
1050 i--;
1051 }
1052 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
1053 {
1054 BIGNUM *tmp_bn = (BIGNUM *)a;
1055 if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
1056 tmp_bn->d[al]=0;
1057 al++;
1058 i++;
1059 }
1060 if (i == 0)
1061 {
1062 /* symmetric and > 4 */
1063 /* 16 or larger */
1064 j=BN_num_bits_word((BN_ULONG)al);
1065 j=1<<(j-1);
1066 k=j+j;
1067 t = BN_CTX_get(ctx);
1068 if (al == j) /* exact multiple */
1069 {
1070 if (bn_wexpand(t,k*2) == NULL) goto err;
1071 if (bn_wexpand(rr,k*2) == NULL) goto err;
1072 bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
1073 }
1074 else
1075 {
1076 if (bn_wexpand(t,k*4) == NULL) goto err;
1077 if (bn_wexpand(rr,k*4) == NULL) goto err;
1078 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
1079 }
1080 rr->top=top;
1081 goto end;
1082 }
1083#endif
1084 }
1085#endif /* BN_RECURSION */
1086 if (bn_wexpand(rr,top) == NULL) goto err;
1087 rr->top=top;
1088 bn_mul_normal(rr->d,a->d,al,b->d,bl);
181 1089
182 /* Are going to now chop things into 'num' word chunks. */ 1090#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
183 num*=BN_BITS2; 1091end:
1092#endif
1093 bn_fix_top(rr);
1094 if (r != rr) BN_copy(r,rr);
1095 ret=1;
1096err:
1097 BN_CTX_end(ctx);
1098 return(ret);
1099 }
184 1100
185 BN_copy(a,A); 1101void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
186 BN_mask_bits(a,num); 1102 {
187 BN_rshift(b,A,num); 1103 BN_ULONG *rr;
188 1104
189 BN_copy(c,B); 1105#ifdef BN_COUNT
190 BN_mask_bits(c,num); 1106 fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
191 BN_rshift(d,B,num); 1107#endif
192 1108
193 BN_sub(ac ,b,a); 1109 if (na < nb)
194 BN_sub(bd,c,d); 1110 {
195 BN_mm(m,ac,bd,bp); 1111 int itmp;
196 BN_mm(ac,a,c,bp); 1112 BN_ULONG *ltmp;
197 BN_mm(bd,b,d,bp);
198 1113
199 BN_add(m,m,ac); 1114 itmp=na; na=nb; nb=itmp;
200 BN_add(m,m,bd); 1115 ltmp=a; a=b; b=ltmp;
201 BN_lshift(m,m,num);
202 BN_lshift(bd,bd,num*2);
203 1116
204 BN_add(m,m,ac); 1117 }
205 BN_add(m,m,bd); 1118 rr= &(r[na]);
206 BN_POOL_pop(bp,6); 1119 if (nb <= 0)
207 return(1); 1120 {
1121 (void)bn_mul_words(r,a,na,0);
1122 return;
1123 }
1124 else
1125 rr[0]=bn_mul_words(r,a,na,b[0]);
1126
1127 for (;;)
1128 {
1129 if (--nb <= 0) return;
1130 rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
1131 if (--nb <= 0) return;
1132 rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
1133 if (--nb <= 0) return;
1134 rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
1135 if (--nb <= 0) return;
1136 rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
1137 rr+=4;
1138 r+=4;
1139 b+=4;
1140 }
208 } 1141 }
1142
1143void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
1144 {
1145#ifdef BN_COUNT
1146 fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
209#endif 1147#endif
1148 bn_mul_words(r,a,n,b[0]);
1149
1150 for (;;)
1151 {
1152 if (--n <= 0) return;
1153 bn_mul_add_words(&(r[1]),a,n,b[1]);
1154 if (--n <= 0) return;
1155 bn_mul_add_words(&(r[2]),a,n,b[2]);
1156 if (--n <= 0) return;
1157 bn_mul_add_words(&(r[3]),a,n,b[3]);
1158 if (--n <= 0) return;
1159 bn_mul_add_words(&(r[4]),a,n,b[4]);
1160 r+=4;
1161 b+=4;
1162 }
1163 }
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index 0c85f70b59..918b9237c6 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -55,53 +55,100 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#include <stdio.h> 112#include <stdio.h>
60#include <time.h> 113#include <time.h>
61#include "cryptlib.h" 114#include "cryptlib.h"
62#include "bn_lcl.h" 115#include "bn_lcl.h"
63#include "rand.h" 116#include <openssl/rand.h>
64 117
65/* The quick seive algorithm approach to weeding out primes is 118/* The quick sieve algorithm approach to weeding out primes is
66 * Philip Zimmermann's, as implemented in PGP. I have had a read of 119 * Philip Zimmermann's, as implemented in PGP. I have had a read of
67 * his comments and implemented my own version. 120 * his comments and implemented my own version.
68 */ 121 */
69#include "bn_prime.h" 122#include "bn_prime.h"
70 123
71#ifndef NOPROTO 124static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
72static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2, 125 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
73 BN_MONT_CTX *mont);
74static int probable_prime(BIGNUM *rnd, int bits); 126static int probable_prime(BIGNUM *rnd, int bits);
75static int probable_prime_dh(BIGNUM *rnd, int bits, 127static int probable_prime_dh(BIGNUM *rnd, int bits,
76 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 128 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
77static int probable_prime_dh_strong(BIGNUM *rnd, int bits, 129static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
78 BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); 130 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
79#else 131
80static int witness(); 132BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
81static int probable_prime(); 133 const BIGNUM *add, const BIGNUM *rem,
82static int probable_prime_dh(); 134 void (*callback)(int,int,void *), void *cb_arg)
83static int probable_prime_dh_strong();
84#endif
85
86BIGNUM *BN_generate_prime(bits,strong,add,rem,callback,cb_arg)
87int bits;
88int strong;
89BIGNUM *add;
90BIGNUM *rem;
91void (*callback)(P_I_I_P);
92char *cb_arg;
93 { 135 {
94 BIGNUM *rnd=NULL; 136 BIGNUM *rnd=NULL;
95 BIGNUM *ret=NULL; 137 BIGNUM t;
96 BIGNUM *t=NULL; 138 int found=0;
97 int i,j,c1=0; 139 int i,j,c1=0;
98 BN_CTX *ctx; 140 BN_CTX *ctx;
141 int checks = BN_prime_checks_for_size(bits);
99 142
100 ctx=BN_CTX_new(); 143 ctx=BN_CTX_new();
101 if (ctx == NULL) goto err; 144 if (ctx == NULL) goto err;
102 if ((rnd=BN_new()) == NULL) goto err; 145 if (ret == NULL)
103 if (strong) 146 {
104 if ((t=BN_new()) == NULL) goto err; 147 if ((rnd=BN_new()) == NULL) goto err;
148 }
149 else
150 rnd=ret;
151 BN_init(&t);
105loop: 152loop:
106 /* make a random number and set the top and bottom bits */ 153 /* make a random number and set the top and bottom bits */
107 if (add == NULL) 154 if (add == NULL)
@@ -110,9 +157,9 @@ loop:
110 } 157 }
111 else 158 else
112 { 159 {
113 if (strong) 160 if (safe)
114 { 161 {
115 if (!probable_prime_dh_strong(rnd,bits,add,rem,ctx)) 162 if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx))
116 goto err; 163 goto err;
117 } 164 }
118 else 165 else
@@ -124,171 +171,188 @@ loop:
124 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ 171 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */
125 if (callback != NULL) callback(0,c1++,cb_arg); 172 if (callback != NULL) callback(0,c1++,cb_arg);
126 173
127 if (!strong) 174 if (!safe)
128 { 175 {
129 i=BN_is_prime(rnd,BN_prime_checks,callback,ctx,cb_arg); 176 i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0);
130 if (i == -1) goto err; 177 if (i == -1) goto err;
131 if (i == 0) goto loop; 178 if (i == 0) goto loop;
132 } 179 }
133 else 180 else
134 { 181 {
135 /* for a strong prime generation, 182 /* for "safe prime" generation,
136 * check that (p-1)/2 is prime. 183 * check that (p-1)/2 is prime.
137 * Since a prime is odd, We just 184 * Since a prime is odd, We just
138 * need to divide by 2 */ 185 * need to divide by 2 */
139 if (!BN_rshift1(t,rnd)) goto err; 186 if (!BN_rshift1(&t,rnd)) goto err;
140 187
141 for (i=0; i<BN_prime_checks; i++) 188 for (i=0; i<checks; i++)
142 { 189 {
143 j=BN_is_prime(rnd,1,callback,ctx,cb_arg); 190 j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0);
144 if (j == -1) goto err; 191 if (j == -1) goto err;
145 if (j == 0) goto loop; 192 if (j == 0) goto loop;
146 193
147 j=BN_is_prime(t,1,callback,ctx,cb_arg); 194 j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0);
148 if (j == -1) goto err; 195 if (j == -1) goto err;
149 if (j == 0) goto loop; 196 if (j == 0) goto loop;
150 197
151 if (callback != NULL) callback(2,c1-1,cb_arg); 198 if (callback != NULL) callback(2,c1-1,cb_arg);
152 /* We have a strong prime test pass */ 199 /* We have a safe prime test pass */
153 } 200 }
154 } 201 }
155 /* we have a prime :-) */ 202 /* we have a prime :-) */
156 ret=rnd; 203 found = 1;
157err: 204err:
158 if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); 205 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
159 if (t != NULL) BN_free(t); 206 BN_free(&t);
160 if (ctx != NULL) BN_CTX_free(ctx); 207 if (ctx != NULL) BN_CTX_free(ctx);
161 return(ret); 208 return(found ? rnd : NULL);
162 } 209 }
163 210
164int BN_is_prime(a,checks,callback,ctx_passed,cb_arg) 211int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *),
165BIGNUM *a; 212 BN_CTX *ctx_passed, void *cb_arg)
166int checks;
167void (*callback)(P_I_I_P);
168BN_CTX *ctx_passed;
169char *cb_arg;
170 { 213 {
171 int i,j,c2=0,ret= -1; 214 return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0);
172 BIGNUM *check; 215 }
173 BN_CTX *ctx=NULL,*ctx2=NULL;
174 BN_MONT_CTX *mont=NULL;
175 216
217int BN_is_prime_fasttest(const BIGNUM *a, int checks,
218 void (*callback)(int,int,void *),
219 BN_CTX *ctx_passed, void *cb_arg,
220 int do_trial_division)
221 {
222 int i, j, ret = -1;
223 int k;
224 BN_CTX *ctx = NULL;
225 BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
226 BN_MONT_CTX *mont = NULL;
227 const BIGNUM *A = NULL;
228
229 if (BN_cmp(a, BN_value_one()) <= 0)
230 return 0;
231
232 if (checks == BN_prime_checks)
233 checks = BN_prime_checks_for_size(BN_num_bits(a));
234
235 /* first look for small factors */
176 if (!BN_is_odd(a)) 236 if (!BN_is_odd(a))
177 return(0); 237 return 0;
238 if (do_trial_division)
239 {
240 for (i = 1; i < NUMPRIMES; i++)
241 if (BN_mod_word(a, primes[i]) == 0)
242 return 0;
243 if (callback != NULL) callback(1, -1, cb_arg);
244 }
245
178 if (ctx_passed != NULL) 246 if (ctx_passed != NULL)
179 ctx=ctx_passed; 247 ctx = ctx_passed;
180 else 248 else
181 if ((ctx=BN_CTX_new()) == NULL) goto err; 249 if ((ctx=BN_CTX_new()) == NULL)
182 250 goto err;
183 if ((ctx2=BN_CTX_new()) == NULL) goto err; 251 BN_CTX_start(ctx);
184 if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
185
186 check=ctx->bn[ctx->tos++];
187 252
188 /* Setup the montgomery structure */ 253 /* A := abs(a) */
189 if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err; 254 if (a->neg)
255 {
256 BIGNUM *t;
257 if ((t = BN_CTX_get(ctx)) == NULL) goto err;
258 BN_copy(t, a);
259 t->neg = 0;
260 A = t;
261 }
262 else
263 A = a;
264 A1 = BN_CTX_get(ctx);
265 A1_odd = BN_CTX_get(ctx);
266 check = BN_CTX_get(ctx);
267 if (check == NULL) goto err;
268
269 /* compute A1 := A - 1 */
270 if (!BN_copy(A1, A))
271 goto err;
272 if (!BN_sub_word(A1, 1))
273 goto err;
274 if (BN_is_zero(A1))
275 {
276 ret = 0;
277 goto err;
278 }
190 279
191 for (i=0; i<checks; i++) 280 /* write A1 as A1_odd * 2^k */
281 k = 1;
282 while (!BN_is_bit_set(A1, k))
283 k++;
284 if (!BN_rshift(A1_odd, A1, k))
285 goto err;
286
287 /* Montgomery setup for computations mod A */
288 mont = BN_MONT_CTX_new();
289 if (mont == NULL)
290 goto err;
291 if (!BN_MONT_CTX_set(mont, A, ctx))
292 goto err;
293
294 for (i = 0; i < checks; i++)
192 { 295 {
193 if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err; 296 if (!BN_pseudo_rand_range(check, A1))
194 j=witness(check,a,ctx,ctx2,mont); 297 goto err;
298 if (!BN_add_word(check, 1))
299 goto err;
300 /* now 1 <= check < A */
301
302 j = witness(check, A, A1, A1_odd, k, ctx, mont);
195 if (j == -1) goto err; 303 if (j == -1) goto err;
196 if (j) 304 if (j)
197 { 305 {
198 ret=0; 306 ret=0;
199 goto err; 307 goto err;
200 } 308 }
201 if (callback != NULL) callback(1,c2++,cb_arg); 309 if (callback != NULL) callback(1,i,cb_arg);
202 } 310 }
203 ret=1; 311 ret=1;
204err: 312err:
205 ctx->tos--; 313 if (ctx != NULL)
206 if ((ctx_passed == NULL) && (ctx != NULL)) 314 {
207 BN_CTX_free(ctx); 315 BN_CTX_end(ctx);
208 if (ctx2 != NULL) 316 if (ctx_passed == NULL)
209 BN_CTX_free(ctx2); 317 BN_CTX_free(ctx);
210 if (mont != NULL) BN_MONT_CTX_free(mont); 318 }
211 319 if (mont != NULL)
320 BN_MONT_CTX_free(mont);
321
212 return(ret); 322 return(ret);
213 } 323 }
214 324
215#define RECP_MUL_MOD 325static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
216 326 const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont)
217static int witness(a,n,ctx,ctx2,mont)
218BIGNUM *a;
219BIGNUM *n;
220BN_CTX *ctx,*ctx2;
221BN_MONT_CTX *mont;
222 { 327 {
223 int k,i,ret= -1,good; 328 if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
224 BIGNUM *d,*dd,*tmp,*d1,*d2,*n1; 329 return -1;
225 BIGNUM *mont_one,*mont_n1,*mont_a; 330 if (BN_is_one(w))
226 331 return 0; /* probably prime */
227 d1=ctx->bn[ctx->tos]; 332 if (BN_cmp(w, a1) == 0)
228 d2=ctx->bn[ctx->tos+1]; 333 return 0; /* w == -1 (mod a), 'a' is probably prime */
229 n1=ctx->bn[ctx->tos+2]; 334 while (--k)
230 ctx->tos+=3;
231
232 mont_one=ctx2->bn[ctx2->tos];
233 mont_n1=ctx2->bn[ctx2->tos+1];
234 mont_a=ctx2->bn[ctx2->tos+2];
235 ctx2->tos+=3;
236
237 d=d1;
238 dd=d2;
239 if (!BN_one(d)) goto err;
240 if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
241 k=BN_num_bits(n1);
242
243 if (!BN_to_montgomery(mont_one,BN_value_one(),mont,ctx2)) goto err;
244 if (!BN_to_montgomery(mont_n1,n1,mont,ctx2)) goto err;
245 if (!BN_to_montgomery(mont_a,a,mont,ctx2)) goto err;
246
247 BN_copy(d,mont_one);
248 for (i=k-1; i>=0; i--)
249 { 335 {
250 if ( (BN_cmp(d,mont_one) != 0) && 336 if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
251 (BN_cmp(d,mont_n1) != 0)) 337 return -1;
252 good=1; 338 if (BN_is_one(w))
253 else 339 return 1; /* 'a' is composite, otherwise a previous 'w' would
254 good=0; 340 * have been == -1 (mod 'a') */
255 341 if (BN_cmp(w, a1) == 0)
256 BN_mod_mul_montgomery(dd,d,d,mont,ctx2); 342 return 0; /* w == -1 (mod a), 'a' is probably prime */
257
258 if (good && (BN_cmp(dd,mont_one) == 0))
259 {
260 ret=1;
261 goto err;
262 }
263 if (BN_is_bit_set(n1,i))
264 {
265 BN_mod_mul_montgomery(d,dd,mont_a,mont,ctx2);
266 }
267 else
268 {
269 tmp=d;
270 d=dd;
271 dd=tmp;
272 }
273 } 343 }
274 if (BN_cmp(d,mont_one) == 0) 344 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
275 i=0; 345 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
276 else i=1; 346 return 1;
277 ret=i;
278err:
279 ctx->tos-=3;
280 ctx2->tos-=3;
281 return(ret);
282 } 347 }
283 348
284static int probable_prime(rnd, bits) 349static int probable_prime(BIGNUM *rnd, int bits)
285BIGNUM *rnd;
286int bits;
287 { 350 {
288 int i; 351 int i;
289 MS_STATIC BN_ULONG mods[NUMPRIMES]; 352 BN_ULONG mods[NUMPRIMES];
290 BN_ULONG delta; 353 BN_ULONG delta,d;
291 354
355again:
292 if (!BN_rand(rnd,bits,1,1)) return(0); 356 if (!BN_rand(rnd,bits,1,1)) return(0);
293 /* we now have a random number 'rand' to test. */ 357 /* we now have a random number 'rand' to test. */
294 for (i=1; i<NUMPRIMES; i++) 358 for (i=1; i<NUMPRIMES; i++)
@@ -300,9 +364,12 @@ int bits;
300 * that gcd(rnd-1,primes) == 1 (except for 2) */ 364 * that gcd(rnd-1,primes) == 1 (except for 2) */
301 if (((mods[i]+delta)%primes[i]) <= 1) 365 if (((mods[i]+delta)%primes[i]) <= 1)
302 { 366 {
367 d=delta;
303 delta+=2; 368 delta+=2;
304 /* perhaps need to check for overflow of 369 /* perhaps need to check for overflow of
305 * delta (but delta can be upto 2^32) */ 370 * delta (but delta can be up to 2^32)
371 * 21-May-98 eay - added overflow check */
372 if (delta < d) goto again;
306 goto loop; 373 goto loop;
307 } 374 }
308 } 375 }
@@ -310,17 +377,14 @@ int bits;
310 return(1); 377 return(1);
311 } 378 }
312 379
313static int probable_prime_dh(rnd, bits, add, rem,ctx) 380static int probable_prime_dh(BIGNUM *rnd, int bits,
314BIGNUM *rnd; 381 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
315int bits;
316BIGNUM *add;
317BIGNUM *rem;
318BN_CTX *ctx;
319 { 382 {
320 int i,ret=0; 383 int i,ret=0;
321 BIGNUM *t1; 384 BIGNUM *t1;
322 385
323 t1=ctx->bn[ctx->tos++]; 386 BN_CTX_start(ctx);
387 if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
324 388
325 if (!BN_rand(rnd,bits,0,1)) goto err; 389 if (!BN_rand(rnd,bits,0,1)) goto err;
326 390
@@ -338,7 +402,7 @@ BN_CTX *ctx;
338 loop: for (i=1; i<NUMPRIMES; i++) 402 loop: for (i=1; i<NUMPRIMES; i++)
339 { 403 {
340 /* check that rnd is a prime */ 404 /* check that rnd is a prime */
341 if (BN_mod_word(rnd,(BN_LONG)primes[i]) <= 1) 405 if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
342 { 406 {
343 if (!BN_add(rnd,rnd,add)) goto err; 407 if (!BN_add(rnd,rnd,add)) goto err;
344 goto loop; 408 goto loop;
@@ -346,24 +410,22 @@ BN_CTX *ctx;
346 } 410 }
347 ret=1; 411 ret=1;
348err: 412err:
349 ctx->tos--; 413 BN_CTX_end(ctx);
350 return(ret); 414 return(ret);
351 } 415 }
352 416
353static int probable_prime_dh_strong(p, bits, padd, rem,ctx) 417static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
354BIGNUM *p; 418 const BIGNUM *rem, BN_CTX *ctx)
355int bits;
356BIGNUM *padd;
357BIGNUM *rem;
358BN_CTX *ctx;
359 { 419 {
360 int i,ret=0; 420 int i,ret=0;
361 BIGNUM *t1,*qadd=NULL,*q=NULL; 421 BIGNUM *t1,*qadd,*q;
362 422
363 bits--; 423 bits--;
364 t1=ctx->bn[ctx->tos++]; 424 BN_CTX_start(ctx);
365 q=ctx->bn[ctx->tos++]; 425 t1 = BN_CTX_get(ctx);
366 qadd=ctx->bn[ctx->tos++]; 426 q = BN_CTX_get(ctx);
427 qadd = BN_CTX_get(ctx);
428 if (qadd == NULL) goto err;
367 429
368 if (!BN_rshift1(qadd,padd)) goto err; 430 if (!BN_rshift1(qadd,padd)) goto err;
369 431
@@ -389,8 +451,8 @@ BN_CTX *ctx;
389 /* check that p and q are prime */ 451 /* check that p and q are prime */
390 /* check that for p and q 452 /* check that for p and q
391 * gcd(p-1,primes) == 1 (except for 2) */ 453 * gcd(p-1,primes) == 1 (except for 2) */
392 if ( (BN_mod_word(p,(BN_LONG)primes[i]) == 0) || 454 if ( (BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
393 (BN_mod_word(q,(BN_LONG)primes[i]) == 0)) 455 (BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
394 { 456 {
395 if (!BN_add(p,p,padd)) goto err; 457 if (!BN_add(p,p,padd)) goto err;
396 if (!BN_add(q,q,qadd)) goto err; 458 if (!BN_add(q,q,qadd)) goto err;
@@ -399,75 +461,6 @@ BN_CTX *ctx;
399 } 461 }
400 ret=1; 462 ret=1;
401err: 463err:
402 ctx->tos-=3; 464 BN_CTX_end(ctx);
403 return(ret);
404 }
405
406#if 0
407static int witness(a, n,ctx)
408BIGNUM *a;
409BIGNUM *n;
410BN_CTX *ctx;
411 {
412 int k,i,nb,ret= -1;
413 BIGNUM *d,*dd,*tmp;
414 BIGNUM *d1,*d2,*x,*n1,*inv;
415
416 d1=ctx->bn[ctx->tos];
417 d2=ctx->bn[ctx->tos+1];
418 x=ctx->bn[ctx->tos+2];
419 n1=ctx->bn[ctx->tos+3];
420 inv=ctx->bn[ctx->tos+4];
421 ctx->tos+=5;
422
423 d=d1;
424 dd=d2;
425 if (!BN_one(d)) goto err;
426 if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
427 k=BN_num_bits(n1);
428
429 /* i=BN_num_bits(n); */
430#ifdef RECP_MUL_MOD
431 nb=BN_reciprocal(inv,n,ctx); /**/
432 if (nb == -1) goto err;
433#endif
434
435 for (i=k-1; i>=0; i--)
436 {
437 if (BN_copy(x,d) == NULL) goto err;
438#ifndef RECP_MUL_MOD
439 if (!BN_mod_mul(dd,d,d,n,ctx)) goto err;
440#else
441 if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err;
442#endif
443 if ( BN_is_one(dd) &&
444 !BN_is_one(x) &&
445 (BN_cmp(x,n1) != 0))
446 {
447 ret=1;
448 goto err;
449 }
450 if (BN_is_bit_set(n1,i))
451 {
452#ifndef RECP_MUL_MOD
453 if (!BN_mod_mul(d,dd,a,n,ctx)) goto err;
454#else
455 if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err;
456#endif
457 }
458 else
459 {
460 tmp=d;
461 d=dd;
462 dd=tmp;
463 }
464 }
465 if (BN_is_one(d))
466 i=0;
467 else i=1;
468 ret=i;
469err:
470 ctx->tos-=5;
471 return(ret); 465 return(ret);
472 } 466 }
473#endif
diff --git a/src/lib/libcrypto/bn/bn_prime.h b/src/lib/libcrypto/bn/bn_prime.h
index 6fce0210cd..b7cf9a9bfe 100644
--- a/src/lib/libcrypto/bn/bn_prime.h
+++ b/src/lib/libcrypto/bn/bn_prime.h
@@ -1,4 +1,4 @@
1/* crypto/bn/bn_prime.h */ 1/* Auto generated by bn_prime.pl */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -61,7 +61,7 @@
61#else 61#else
62#define NUMPRIMES 54 62#define NUMPRIMES 54
63#endif 63#endif
64static unsigned int primes[NUMPRIMES]= 64static const unsigned int primes[NUMPRIMES]=
65 { 65 {
66 2, 3, 5, 7, 11, 13, 17, 19, 66 2, 3, 5, 7, 11, 13, 17, 19,
67 23, 29, 31, 37, 41, 43, 47, 53, 67 23, 29, 31, 37, 41, 43, 47, 53,
diff --git a/src/lib/libcrypto/bn/bn_prime.pl b/src/lib/libcrypto/bn/bn_prime.pl
index 1b00c21a77..9fc3765486 100644
--- a/src/lib/libcrypto/bn/bn_prime.pl
+++ b/src/lib/libcrypto/bn/bn_prime.pl
@@ -1,4 +1,4 @@
1#!/usr/bin/perl 1#!/usr/local/bin/perl
2# bn_prime.pl 2# bn_prime.pl
3 3
4$num=2048; 4$num=2048;
@@ -18,13 +18,74 @@ loop: while ($#primes < $num-1)
18 push(@primes,$p); 18 push(@primes,$p);
19 } 19 }
20 20
21print <<"EOF"; 21# print <<"EOF";
22# /* Auto generated by bn_prime.pl */
23# /* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au).
24# * All rights reserved.
25# * Copyright remains Eric Young's, and as such any Copyright notices in
26# * the code are not to be removed.
27# * See the COPYRIGHT file in the SSLeay distribution for more details.
28# */
29#
30# EOF
31
32print <<\EOF;
22/* Auto generated by bn_prime.pl */ 33/* Auto generated by bn_prime.pl */
23/* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au). 34/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
24 * All rights reserved. 35 * All rights reserved.
36 *
37 * This package is an SSL implementation written
38 * by Eric Young (eay@cryptsoft.com).
39 * The implementation was written so as to conform with Netscapes SSL.
40 *
41 * This library is free for commercial and non-commercial use as long as
42 * the following conditions are aheared to. The following conditions
43 * apply to all code found in this distribution, be it the RC4, RSA,
44 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
45 * included with this distribution is covered by the same copyright terms
46 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
47 *
25 * Copyright remains Eric Young's, and as such any Copyright notices in 48 * Copyright remains Eric Young's, and as such any Copyright notices in
26 * the code are not to be removed. 49 * the code are not to be removed.
27 * See the COPYRIGHT file in the SSLeay distribution for more details. 50 * If this package is used in a product, Eric Young should be given attribution
51 * as the author of the parts of the library used.
52 * This can be in the form of a textual message at program startup or
53 * in documentation (online or textual) provided with the package.
54 *
55 * Redistribution and use in source and binary forms, with or without
56 * modification, are permitted provided that the following conditions
57 * are met:
58 * 1. Redistributions of source code must retain the copyright
59 * notice, this list of conditions and the following disclaimer.
60 * 2. Redistributions in binary form must reproduce the above copyright
61 * notice, this list of conditions and the following disclaimer in the
62 * documentation and/or other materials provided with the distribution.
63 * 3. All advertising materials mentioning features or use of this software
64 * must display the following acknowledgement:
65 * "This product includes cryptographic software written by
66 * Eric Young (eay@cryptsoft.com)"
67 * The word 'cryptographic' can be left out if the rouines from the library
68 * being used are not cryptographic related :-).
69 * 4. If you include any Windows specific code (or a derivative thereof) from
70 * the apps directory (application code) you must include an acknowledgement:
71 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
72 *
73 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83 * SUCH DAMAGE.
84 *
85 * The licence and distribution terms for any publically available version or
86 * derivative of this code cannot be changed. i.e. this code cannot simply be
87 * copied and put under another distribution licence
88 * [including the GNU Public Licence.]
28 */ 89 */
29 90
30EOF 91EOF
@@ -43,7 +104,7 @@ printf "#define NUMPRIMES %d\n",$num;
43printf "#else\n"; 104printf "#else\n";
44printf "#define NUMPRIMES %d\n",$eight; 105printf "#define NUMPRIMES %d\n",$eight;
45printf "#endif\n"; 106printf "#endif\n";
46print "static unsigned int primes[NUMPRIMES]=\n\t{\n\t"; 107print "static const unsigned int primes[NUMPRIMES]=\n\t{\n\t";
47$init=0; 108$init=0;
48for ($i=0; $i <= $#primes; $i++) 109for ($i=0; $i <= $#primes; $i++)
49 { 110 {
diff --git a/src/lib/libcrypto/bn/bn_print.c b/src/lib/libcrypto/bn/bn_print.c
index 2bcc11c852..5f46b1826c 100644
--- a/src/lib/libcrypto/bn/bn_print.c
+++ b/src/lib/libcrypto/bn/bn_print.c
@@ -59,20 +59,19 @@
59#include <stdio.h> 59#include <stdio.h>
60#include <ctype.h> 60#include <ctype.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include "buffer.h" 62#include <openssl/buffer.h>
63#include "bn_lcl.h" 63#include "bn_lcl.h"
64 64
65static char *Hex="0123456789ABCDEF"; 65static const char *Hex="0123456789ABCDEF";
66 66
67/* Must 'Free' the returned data */ 67/* Must 'OPENSSL_free' the returned data */
68char *BN_bn2hex(a) 68char *BN_bn2hex(const BIGNUM *a)
69BIGNUM *a;
70 { 69 {
71 int i,j,v,z=0; 70 int i,j,v,z=0;
72 char *buf; 71 char *buf;
73 char *p; 72 char *p;
74 73
75 buf=(char *)Malloc(a->top*BN_BYTES*2+2); 74 buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
76 if (buf == NULL) 75 if (buf == NULL)
77 { 76 {
78 BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE); 77 BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
@@ -100,9 +99,8 @@ err:
100 return(buf); 99 return(buf);
101 } 100 }
102 101
103/* Must 'Free' the returned data */ 102/* Must 'OPENSSL_free' the returned data */
104char *BN_bn2dec(a) 103char *BN_bn2dec(const BIGNUM *a)
105BIGNUM *a;
106 { 104 {
107 int i=0,num; 105 int i=0,num;
108 char *buf=NULL; 106 char *buf=NULL;
@@ -112,8 +110,8 @@ BIGNUM *a;
112 110
113 i=BN_num_bits(a)*3; 111 i=BN_num_bits(a)*3;
114 num=(i/10+i/1000+3)+1; 112 num=(i/10+i/1000+3)+1;
115 bn_data=(BN_ULONG *)Malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG)); 113 bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
116 buf=(char *)Malloc(num+3); 114 buf=(char *)OPENSSL_malloc(num+3);
117 if ((buf == NULL) || (bn_data == NULL)) 115 if ((buf == NULL) || (bn_data == NULL))
118 { 116 {
119 BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE); 117 BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE);
@@ -139,7 +137,7 @@ BIGNUM *a;
139 } 137 }
140 lp--; 138 lp--;
141 /* We now have a series of blocks, BN_DEC_NUM chars 139 /* We now have a series of blocks, BN_DEC_NUM chars
142 * in length, where the last one needs trucation. 140 * in length, where the last one needs truncation.
143 * The blocks need to be reversed in order. */ 141 * The blocks need to be reversed in order. */
144 sprintf(p,BN_DEC_FMT1,*lp); 142 sprintf(p,BN_DEC_FMT1,*lp);
145 while (*p) p++; 143 while (*p) p++;
@@ -151,14 +149,12 @@ BIGNUM *a;
151 } 149 }
152 } 150 }
153err: 151err:
154 if (bn_data != NULL) Free(bn_data); 152 if (bn_data != NULL) OPENSSL_free(bn_data);
155 if (t != NULL) BN_free(t); 153 if (t != NULL) BN_free(t);
156 return(buf); 154 return(buf);
157 } 155 }
158 156
159int BN_hex2bn(bn,a) 157int BN_hex2bn(BIGNUM **bn, const char *a)
160BIGNUM **bn;
161char *a;
162 { 158 {
163 BIGNUM *ret=NULL; 159 BIGNUM *ret=NULL;
164 BN_ULONG l=0; 160 BN_ULONG l=0;
@@ -169,13 +165,13 @@ char *a;
169 165
170 if (*a == '-') { neg=1; a++; } 166 if (*a == '-') { neg=1; a++; }
171 167
172 for (i=0; isxdigit(a[i]); i++) 168 for (i=0; isxdigit((unsigned char) a[i]); i++)
173 ; 169 ;
174 170
175 num=i+neg; 171 num=i+neg;
176 if (bn == NULL) return(num); 172 if (bn == NULL) return(num);
177 173
178 /* a is the start of the hex digets, and it is 'i' long */ 174 /* a is the start of the hex digits, and it is 'i' long */
179 if (*bn == NULL) 175 if (*bn == NULL)
180 { 176 {
181 if ((ret=BN_new()) == NULL) return(0); 177 if ((ret=BN_new()) == NULL) return(0);
@@ -189,7 +185,7 @@ char *a;
189 /* i is the number of hex digests; */ 185 /* i is the number of hex digests; */
190 if (bn_expand(ret,i*4) == NULL) goto err; 186 if (bn_expand(ret,i*4) == NULL) goto err;
191 187
192 j=i; /* least significate 'hex' */ 188 j=i; /* least significant 'hex' */
193 m=0; 189 m=0;
194 h=0; 190 h=0;
195 while (j > 0) 191 while (j > 0)
@@ -224,9 +220,7 @@ err:
224 return(0); 220 return(0);
225 } 221 }
226 222
227int BN_dec2bn(bn,a) 223int BN_dec2bn(BIGNUM **bn, const char *a)
228BIGNUM **bn;
229char *a;
230 { 224 {
231 BIGNUM *ret=NULL; 225 BIGNUM *ret=NULL;
232 BN_ULONG l=0; 226 BN_ULONG l=0;
@@ -236,14 +230,14 @@ char *a;
236 if ((a == NULL) || (*a == '\0')) return(0); 230 if ((a == NULL) || (*a == '\0')) return(0);
237 if (*a == '-') { neg=1; a++; } 231 if (*a == '-') { neg=1; a++; }
238 232
239 for (i=0; isdigit(a[i]); i++) 233 for (i=0; isdigit((unsigned char) a[i]); i++)
240 ; 234 ;
241 235
242 num=i+neg; 236 num=i+neg;
243 if (bn == NULL) return(num); 237 if (bn == NULL) return(num);
244 238
245 /* a is the start of the digets, and it is 'i' long. 239 /* a is the start of the digits, and it is 'i' long.
246 * We chop it into BN_DEC_NUM digets at a time */ 240 * We chop it into BN_DEC_NUM digits at a time */
247 if (*bn == NULL) 241 if (*bn == NULL)
248 { 242 {
249 if ((ret=BN_new()) == NULL) return(0); 243 if ((ret=BN_new()) == NULL) return(0);
@@ -283,12 +277,9 @@ err:
283 return(0); 277 return(0);
284 } 278 }
285 279
286#ifndef NO_BIO 280#ifndef OPENSSL_NO_BIO
287 281#ifndef OPENSSL_NO_FP_API
288#ifndef NO_FP_API 282int BN_print_fp(FILE *fp, const BIGNUM *a)
289int BN_print_fp(fp, a)
290FILE *fp;
291BIGNUM *a;
292 { 283 {
293 BIO *b; 284 BIO *b;
294 int ret; 285 int ret;
@@ -302,9 +293,7 @@ BIGNUM *a;
302 } 293 }
303#endif 294#endif
304 295
305int BN_print(bp, a) 296int BN_print(BIO *bp, const BIGNUM *a)
306BIO *bp;
307BIGNUM *a;
308 { 297 {
309 int i,j,v,z=0; 298 int i,j,v,z=0;
310 int ret=0; 299 int ret=0;
@@ -329,5 +318,15 @@ BIGNUM *a;
329end: 318end:
330 return(ret); 319 return(ret);
331 } 320 }
321#endif
332 322
323#ifdef BN_DEBUG
324void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n)
325 {
326 int i;
327 fprintf(o, "%s=", a);
328 for (i=n-1;i>=0;i--)
329 fprintf(o, "%08lX", b[i]); /* assumes 32-bit BN_ULONG */
330 fprintf(o, "\n");
331 }
333#endif 332#endif
diff --git a/src/lib/libcrypto/bn/bn_rand.c b/src/lib/libcrypto/bn/bn_rand.c
index 75b6b0493b..9e08ccd22e 100644
--- a/src/lib/libcrypto/bn/bn_rand.c
+++ b/src/lib/libcrypto/bn/bn_rand.c
@@ -55,28 +55,83 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#include <stdio.h> 112#include <stdio.h>
60#include <time.h> 113#include <time.h>
61#include "cryptlib.h" 114#include "cryptlib.h"
62#include "bn_lcl.h" 115#include "bn_lcl.h"
63#include "rand.h" 116#include <openssl/rand.h>
64 117
65int BN_rand(rnd, bits, top, bottom) 118static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
66BIGNUM *rnd;
67int bits;
68int top;
69int bottom;
70 { 119 {
71 unsigned char *buf=NULL; 120 unsigned char *buf=NULL;
72 int ret=0,bit,bytes,mask; 121 int ret=0,bit,bytes,mask;
73 time_t tim; 122 time_t tim;
74 123
124 if (bits == 0)
125 {
126 BN_zero(rnd);
127 return 1;
128 }
129
75 bytes=(bits+7)/8; 130 bytes=(bits+7)/8;
76 bit=(bits-1)%8; 131 bit=(bits-1)%8;
77 mask=0xff<<bit; 132 mask=0xff<<(bit+1);
78 133
79 buf=(unsigned char *)Malloc(bytes); 134 buf=(unsigned char *)OPENSSL_malloc(bytes);
80 if (buf == NULL) 135 if (buf == NULL)
81 { 136 {
82 BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE); 137 BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE);
@@ -85,28 +140,61 @@ int bottom;
85 140
86 /* make a random number and set the top and bottom bits */ 141 /* make a random number and set the top and bottom bits */
87 time(&tim); 142 time(&tim);
88 RAND_seed((unsigned char *)&tim,sizeof(tim)); 143 RAND_add(&tim,sizeof(tim),0);
89 144
90 RAND_bytes(buf,(int)bytes); 145 if (pseudorand)
91 if (top)
92 { 146 {
93 if (bit == 0) 147 if (RAND_pseudo_bytes(buf, bytes) == -1)
148 goto err;
149 }
150 else
151 {
152 if (RAND_bytes(buf, bytes) <= 0)
153 goto err;
154 }
155
156#if 1
157 if (pseudorand == 2)
158 {
159 /* generate patterns that are more likely to trigger BN
160 library bugs */
161 int i;
162 unsigned char c;
163
164 for (i = 0; i < bytes; i++)
94 { 165 {
95 buf[0]=1; 166 RAND_pseudo_bytes(&c, 1);
96 buf[1]|=0x80; 167 if (c >= 128 && i > 0)
168 buf[i] = buf[i-1];
169 else if (c < 42)
170 buf[i] = 0;
171 else if (c < 84)
172 buf[i] = 255;
173 }
174 }
175#endif
176
177 if (top != -1)
178 {
179 if (top)
180 {
181 if (bit == 0)
182 {
183 buf[0]=1;
184 buf[1]|=0x80;
185 }
186 else
187 {
188 buf[0]|=(3<<(bit-1));
189 }
97 } 190 }
98 else 191 else
99 { 192 {
100 buf[0]|=(3<<(bit-1)); 193 buf[0]|=(1<<bit);
101 buf[0]&= ~(mask<<1);
102 } 194 }
103 } 195 }
104 else 196 buf[0] &= ~mask;
105 { 197 if (bottom) /* set bottom bit if requested */
106 buf[0]|=(1<<bit);
107 buf[0]&= ~(mask<<1);
108 }
109 if (bottom) /* set bottom bits to whatever odd is */
110 buf[bytes-1]|=1; 198 buf[bytes-1]|=1;
111 if (!BN_bin2bn(buf,bytes,rnd)) goto err; 199 if (!BN_bin2bn(buf,bytes,rnd)) goto err;
112 ret=1; 200 ret=1;
@@ -114,8 +202,90 @@ err:
114 if (buf != NULL) 202 if (buf != NULL)
115 { 203 {
116 memset(buf,0,bytes); 204 memset(buf,0,bytes);
117 Free(buf); 205 OPENSSL_free(buf);
118 } 206 }
119 return(ret); 207 return(ret);
120 } 208 }
121 209
210int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
211 {
212 return bnrand(0, rnd, bits, top, bottom);
213 }
214
215int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
216 {
217 return bnrand(1, rnd, bits, top, bottom);
218 }
219
220#if 1
221int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
222 {
223 return bnrand(2, rnd, bits, top, bottom);
224 }
225#endif
226
227
228/* random number r: 0 <= r < range */
229static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
230 {
231 int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
232 int n;
233
234 if (range->neg || BN_is_zero(range))
235 {
236 BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
237 return 0;
238 }
239
240 n = BN_num_bits(range); /* n > 0 */
241
242 /* BN_is_bit_set(range, n - 1) always holds */
243
244 if (n == 1)
245 {
246 if (!BN_zero(r)) return 0;
247 }
248 else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
249 {
250 /* range = 100..._2,
251 * so 3*range (= 11..._2) is exactly one bit longer than range */
252 do
253 {
254 if (!bn_rand(r, n + 1, -1, 0)) return 0;
255 /* If r < 3*range, use r := r MOD range
256 * (which is either r, r - range, or r - 2*range).
257 * Otherwise, iterate once more.
258 * Since 3*range = 11..._2, each iteration succeeds with
259 * probability >= .75. */
260 if (BN_cmp(r ,range) >= 0)
261 {
262 if (!BN_sub(r, r, range)) return 0;
263 if (BN_cmp(r, range) >= 0)
264 if (!BN_sub(r, r, range)) return 0;
265 }
266 }
267 while (BN_cmp(r, range) >= 0);
268 }
269 else
270 {
271 do
272 {
273 /* range = 11..._2 or range = 101..._2 */
274 if (!bn_rand(r, n, -1, 0)) return 0;
275 }
276 while (BN_cmp(r, range) >= 0);
277 }
278
279 return 1;
280 }
281
282
283int BN_rand_range(BIGNUM *r, BIGNUM *range)
284 {
285 return bn_rand_range(0, r, range);
286 }
287
288int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range)
289 {
290 return bn_rand_range(1, r, range);
291 }
diff --git a/src/lib/libcrypto/bn/bn_recp.c b/src/lib/libcrypto/bn/bn_recp.c
index 72cd69d3fc..ef5fdd4708 100644
--- a/src/lib/libcrypto/bn/bn_recp.c
+++ b/src/lib/libcrypto/bn/bn_recp.c
@@ -60,66 +60,171 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63int BN_mod_mul_reciprocal(r, x, y, m, i, nb, ctx) 63void BN_RECP_CTX_init(BN_RECP_CTX *recp)
64BIGNUM *r;
65BIGNUM *x;
66BIGNUM *y;
67BIGNUM *m;
68BIGNUM *i;
69int nb;
70BN_CTX *ctx;
71 { 64 {
72 int ret=0,j; 65 BN_init(&(recp->N));
73 BIGNUM *a,*b,*c,*d; 66 BN_init(&(recp->Nr));
67 recp->num_bits=0;
68 recp->flags=0;
69 }
70
71BN_RECP_CTX *BN_RECP_CTX_new(void)
72 {
73 BN_RECP_CTX *ret;
74
75 if ((ret=(BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL)
76 return(NULL);
77
78 BN_RECP_CTX_init(ret);
79 ret->flags=BN_FLG_MALLOCED;
80 return(ret);
81 }
82
83void BN_RECP_CTX_free(BN_RECP_CTX *recp)
84 {
85 if(recp == NULL)
86 return;
87
88 BN_free(&(recp->N));
89 BN_free(&(recp->Nr));
90 if (recp->flags & BN_FLG_MALLOCED)
91 OPENSSL_free(recp);
92 }
74 93
75 a=ctx->bn[ctx->tos++]; 94int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
76 b=ctx->bn[ctx->tos++]; 95 {
77 c=ctx->bn[ctx->tos++]; 96 if (!BN_copy(&(recp->N),d)) return 0;
78 d=ctx->bn[ctx->tos++]; 97 if (!BN_zero(&(recp->Nr))) return 0;
98 recp->num_bits=BN_num_bits(d);
99 recp->shift=0;
100 return(1);
101 }
102
103int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
104 BN_RECP_CTX *recp, BN_CTX *ctx)
105 {
106 int ret=0;
107 BIGNUM *a;
108 const BIGNUM *ca;
79 109
80 if (x == y) 110 BN_CTX_start(ctx);
81 { if (!BN_sqr(a,x,ctx)) goto err; } 111 if ((a = BN_CTX_get(ctx)) == NULL) goto err;
112 if (y != NULL)
113 {
114 if (x == y)
115 { if (!BN_sqr(a,x,ctx)) goto err; }
116 else
117 { if (!BN_mul(a,x,y,ctx)) goto err; }
118 ca = a;
119 }
82 else 120 else
83 { if (!BN_mul(a,x,y)) goto err; } 121 ca=x; /* Just do the mod */
84 if (!BN_rshift(d,a,nb)) goto err; 122
85 if (!BN_mul(b,d,i)) goto err; 123 ret = BN_div_recp(NULL,r,ca,recp,ctx);
86 if (!BN_rshift(c,b,nb)) goto err; 124err:
87 if (!BN_mul(b,m,c)) goto err; 125 BN_CTX_end(ctx);
88 if (!BN_sub(r,a,b)) goto err; 126 return(ret);
127 }
128
129int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
130 BN_RECP_CTX *recp, BN_CTX *ctx)
131 {
132 int i,j,ret=0;
133 BIGNUM *a,*b,*d,*r;
134
135 BN_CTX_start(ctx);
136 a=BN_CTX_get(ctx);
137 b=BN_CTX_get(ctx);
138 if (dv != NULL)
139 d=dv;
140 else
141 d=BN_CTX_get(ctx);
142 if (rem != NULL)
143 r=rem;
144 else
145 r=BN_CTX_get(ctx);
146 if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
147
148 if (BN_ucmp(m,&(recp->N)) < 0)
149 {
150 if (!BN_zero(d)) return 0;
151 if (!BN_copy(r,m)) return 0;
152 BN_CTX_end(ctx);
153 return(1);
154 }
155
156 /* We want the remainder
157 * Given input of ABCDEF / ab
158 * we need multiply ABCDEF by 3 digests of the reciprocal of ab
159 *
160 */
161
162 /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
163 i=BN_num_bits(m);
164 j=recp->num_bits<<1;
165 if (j>i) i=j;
166
167 /* Nr := round(2^i / N) */
168 if (i != recp->shift)
169 recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
170 i,ctx); /* BN_reciprocal returns i, or -1 for an error */
171 if (recp->shift == -1) goto err;
172
173 /* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
174 * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
175 * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
176 * = |m/N|
177 */
178 if (!BN_rshift(a,m,recp->num_bits)) goto err;
179 if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
180 if (!BN_rshift(d,b,i-recp->num_bits)) goto err;
181 d->neg=0;
182
183 if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
184 if (!BN_usub(r,m,b)) goto err;
185 r->neg=0;
186
187#if 1
89 j=0; 188 j=0;
90 while (BN_cmp(r,m) >= 0) 189 while (BN_ucmp(r,&(recp->N)) >= 0)
91 { 190 {
92 if (j++ > 2) 191 if (j++ > 2)
93 { 192 {
94 BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL); 193 BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL);
95 goto err; 194 goto err;
96 } 195 }
97 if (!BN_sub(r,r,m)) goto err; 196 if (!BN_usub(r,r,&(recp->N))) goto err;
197 if (!BN_add_word(d,1)) goto err;
98 } 198 }
199#endif
99 200
201 r->neg=BN_is_zero(r)?0:m->neg;
202 d->neg=m->neg^recp->N.neg;
100 ret=1; 203 ret=1;
101err: 204err:
102 ctx->tos-=4; 205 BN_CTX_end(ctx);
103 return(ret); 206 return(ret);
104 } 207 }
105 208
106int BN_reciprocal(r, m,ctx) 209/* len is the expected size of the result
107BIGNUM *r; 210 * We actually calculate with an extra word of precision, so
108BIGNUM *m; 211 * we can do faster division if the remainder is not required.
109BN_CTX *ctx; 212 */
213/* r := 2^len / m */
214int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
110 { 215 {
111 int nm,ret= -1; 216 int ret= -1;
112 BIGNUM *t; 217 BIGNUM t;
113 218
114 t=ctx->bn[ctx->tos++]; 219 BN_init(&t);
115 220
116 nm=BN_num_bits(m); 221 if (!BN_zero(&t)) goto err;
117 if (!BN_lshift(t,BN_value_one(),nm*2)) goto err; 222 if (!BN_set_bit(&t,len)) goto err;
118 223
119 if (!BN_div(r,NULL,t,m,ctx)) goto err; 224 if (!BN_div(r,NULL,&t,m,ctx)) goto err;
120 ret=nm; 225
226 ret=len;
121err: 227err:
122 ctx->tos--; 228 BN_free(&t);
123 return(ret); 229 return(ret);
124 } 230 }
125
diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c
index 944bf1794b..70f785ea18 100644
--- a/src/lib/libcrypto/bn/bn_shift.c
+++ b/src/lib/libcrypto/bn/bn_shift.c
@@ -60,9 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63int BN_lshift1(r, a) 63int BN_lshift1(BIGNUM *r, const BIGNUM *a)
64BIGNUM *r;
65BIGNUM *a;
66 { 64 {
67 register BN_ULONG *ap,*rp,t,c; 65 register BN_ULONG *ap,*rp,t,c;
68 int i; 66 int i;
@@ -94,9 +92,7 @@ BIGNUM *a;
94 return(1); 92 return(1);
95 } 93 }
96 94
97int BN_rshift1(r, a) 95int BN_rshift1(BIGNUM *r, const BIGNUM *a)
98BIGNUM *r;
99BIGNUM *a;
100 { 96 {
101 BN_ULONG *ap,*rp,t,c; 97 BN_ULONG *ap,*rp,t,c;
102 int i; 98 int i;
@@ -125,18 +121,15 @@ BIGNUM *a;
125 return(1); 121 return(1);
126 } 122 }
127 123
128int BN_lshift(r, a, n) 124int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
129BIGNUM *r;
130BIGNUM *a;
131int n;
132 { 125 {
133 int i,nw,lb,rb; 126 int i,nw,lb,rb;
134 BN_ULONG *t,*f; 127 BN_ULONG *t,*f;
135 BN_ULONG l; 128 BN_ULONG l;
136 129
137 r->neg=a->neg; 130 r->neg=a->neg;
138 if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
139 nw=n/BN_BITS2; 131 nw=n/BN_BITS2;
132 if (bn_wexpand(r,a->top+nw+1) == NULL) return(0);
140 lb=n%BN_BITS2; 133 lb=n%BN_BITS2;
141 rb=BN_BITS2-lb; 134 rb=BN_BITS2-lb;
142 f=a->d; 135 f=a->d;
@@ -160,10 +153,7 @@ int n;
160 return(1); 153 return(1);
161 } 154 }
162 155
163int BN_rshift(r, a, n) 156int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
164BIGNUM *r;
165BIGNUM *a;
166int n;
167 { 157 {
168 int i,j,nw,lb,rb; 158 int i,j,nw,lb,rb;
169 BN_ULONG *t,*f; 159 BN_ULONG *t,*f;
@@ -172,7 +162,7 @@ int n;
172 nw=n/BN_BITS2; 162 nw=n/BN_BITS2;
173 rb=n%BN_BITS2; 163 rb=n%BN_BITS2;
174 lb=BN_BITS2-rb; 164 lb=BN_BITS2-rb;
175 if (nw > a->top) 165 if (nw > a->top || a->top == 0)
176 { 166 {
177 BN_zero(r); 167 BN_zero(r);
178 return(1); 168 return(1);
@@ -182,6 +172,11 @@ int n;
182 r->neg=a->neg; 172 r->neg=a->neg;
183 if (bn_wexpand(r,a->top-nw+1) == NULL) return(0); 173 if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
184 } 174 }
175 else
176 {
177 if (n == 0)
178 return 1; /* or the copying loop will go berserk */
179 }
185 180
186 f= &(a->d[nw]); 181 f= &(a->d[nw]);
187 t=r->d; 182 t=r->d;
diff --git a/src/lib/libcrypto/bn/bn_sqr.c b/src/lib/libcrypto/bn/bn_sqr.c
index a8464610e5..c1d0cca438 100644
--- a/src/lib/libcrypto/bn/bn_sqr.c
+++ b/src/lib/libcrypto/bn/bn_sqr.c
@@ -62,35 +62,105 @@
62 62
63/* r must not be a */ 63/* r must not be a */
64/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */ 64/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
65int BN_sqr(r, a, ctx) 65int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
66BIGNUM *r;
67BIGNUM *a;
68BN_CTX *ctx;
69 { 66 {
70 int i,j,max,al; 67 int max,al;
71 BIGNUM *tmp; 68 int ret = 0;
72 BN_ULONG *ap,*rp; 69 BIGNUM *tmp,*rr;
73 70
74 tmp=ctx->bn[ctx->tos]; 71#ifdef BN_COUNT
72 fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
73#endif
74 bn_check_top(a);
75 75
76 al=a->top; 76 al=a->top;
77 if (al == 0) 77 if (al <= 0)
78 { 78 {
79 r->top=0; 79 r->top=0;
80 return(1); 80 return(1);
81 } 81 }
82 82
83 max=(al*2); 83 BN_CTX_start(ctx);
84 if (bn_wexpand(r,1+max) == NULL) return(0); 84 rr=(a != r) ? r : BN_CTX_get(ctx);
85 if (bn_wexpand(tmp,1+max) == NULL) return(0); 85 tmp=BN_CTX_get(ctx);
86 if (tmp == NULL) goto err;
86 87
87 r->neg=0; 88 max=(al+al);
89 if (bn_wexpand(rr,max+1) == NULL) goto err;
88 90
89 ap=a->d; 91 if (al == 4)
90 rp=r->d; 92 {
93#ifndef BN_SQR_COMBA
94 BN_ULONG t[8];
95 bn_sqr_normal(rr->d,a->d,4,t);
96#else
97 bn_sqr_comba4(rr->d,a->d);
98#endif
99 }
100 else if (al == 8)
101 {
102#ifndef BN_SQR_COMBA
103 BN_ULONG t[16];
104 bn_sqr_normal(rr->d,a->d,8,t);
105#else
106 bn_sqr_comba8(rr->d,a->d);
107#endif
108 }
109 else
110 {
111#if defined(BN_RECURSION)
112 if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
113 {
114 BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
115 bn_sqr_normal(rr->d,a->d,al,t);
116 }
117 else
118 {
119 int j,k;
120
121 j=BN_num_bits_word((BN_ULONG)al);
122 j=1<<(j-1);
123 k=j+j;
124 if (al == j)
125 {
126 if (bn_wexpand(tmp,k*2) == NULL) goto err;
127 bn_sqr_recursive(rr->d,a->d,al,tmp->d);
128 }
129 else
130 {
131 if (bn_wexpand(tmp,max) == NULL) goto err;
132 bn_sqr_normal(rr->d,a->d,al,tmp->d);
133 }
134 }
135#else
136 if (bn_wexpand(tmp,max) == NULL) goto err;
137 bn_sqr_normal(rr->d,a->d,al,tmp->d);
138#endif
139 }
140
141 rr->top=max;
142 rr->neg=0;
143 if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
144 if (rr != r) BN_copy(r,rr);
145 ret = 1;
146 err:
147 BN_CTX_end(ctx);
148 return(ret);
149 }
150
151/* tmp must have 2*n words */
152void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
153 {
154 int i,j,max;
155 const BN_ULONG *ap;
156 BN_ULONG *rp;
157
158 max=n*2;
159 ap=a;
160 rp=r;
91 rp[0]=rp[max-1]=0; 161 rp[0]=rp[max-1]=0;
92 rp++; 162 rp++;
93 j=al; 163 j=n;
94 164
95 if (--j > 0) 165 if (--j > 0)
96 { 166 {
@@ -99,7 +169,7 @@ BN_CTX *ctx;
99 rp+=2; 169 rp+=2;
100 } 170 }
101 171
102 for (i=2; i<al; i++) 172 for (i=n-2; i>0; i--)
103 { 173 {
104 j--; 174 j--;
105 ap++; 175 ap++;
@@ -107,16 +177,112 @@ BN_CTX *ctx;
107 rp+=2; 177 rp+=2;
108 } 178 }
109 179
110 bn_add_words(r->d,r->d,r->d,max); 180 bn_add_words(r,r,r,max);
111 181
112 /* There will not be a carry */ 182 /* There will not be a carry */
113 183
114 bn_sqr_words(tmp->d,a->d,al); 184 bn_sqr_words(tmp,a,n);
115 185
116 bn_add_words(r->d,r->d,tmp->d,max); 186 bn_add_words(r,r,tmp,max);
117
118 r->top=max;
119 if (r->d[max-1] == 0) r->top--;
120 return(1);
121 } 187 }
122 188
189#ifdef BN_RECURSION
190/* r is 2*n words in size,
191 * a and b are both n words in size. (There's not actually a 'b' here ...)
192 * n must be a power of 2.
193 * We multiply and return the result.
194 * t must be 2*n words in size
195 * We calculate
196 * a[0]*b[0]
197 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
198 * a[1]*b[1]
199 */
200void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
201 {
202 int n=n2/2;
203 int zero,c1;
204 BN_ULONG ln,lo,*p;
205
206#ifdef BN_COUNT
207 fprintf(stderr," bn_sqr_recursive %d * %d\n",n2,n2);
208#endif
209 if (n2 == 4)
210 {
211#ifndef BN_SQR_COMBA
212 bn_sqr_normal(r,a,4,t);
213#else
214 bn_sqr_comba4(r,a);
215#endif
216 return;
217 }
218 else if (n2 == 8)
219 {
220#ifndef BN_SQR_COMBA
221 bn_sqr_normal(r,a,8,t);
222#else
223 bn_sqr_comba8(r,a);
224#endif
225 return;
226 }
227 if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
228 {
229 bn_sqr_normal(r,a,n2,t);
230 return;
231 }
232 /* r=(a[0]-a[1])*(a[1]-a[0]) */
233 c1=bn_cmp_words(a,&(a[n]),n);
234 zero=0;
235 if (c1 > 0)
236 bn_sub_words(t,a,&(a[n]),n);
237 else if (c1 < 0)
238 bn_sub_words(t,&(a[n]),a,n);
239 else
240 zero=1;
241
242 /* The result will always be negative unless it is zero */
243 p= &(t[n2*2]);
244
245 if (!zero)
246 bn_sqr_recursive(&(t[n2]),t,n,p);
247 else
248 memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
249 bn_sqr_recursive(r,a,n,p);
250 bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
251
252 /* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
253 * r[10] holds (a[0]*b[0])
254 * r[32] holds (b[1]*b[1])
255 */
256
257 c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
258
259 /* t[32] is negative */
260 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
261
262 /* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
263 * r[10] holds (a[0]*a[0])
264 * r[32] holds (a[1]*a[1])
265 * c1 holds the carry bits
266 */
267 c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
268 if (c1)
269 {
270 p= &(r[n+n2]);
271 lo= *p;
272 ln=(lo+c1)&BN_MASK2;
273 *p=ln;
274
275 /* The overflow will stop before we over write
276 * words we should not overwrite */
277 if (ln < (BN_ULONG)c1)
278 {
279 do {
280 p++;
281 lo= *p;
282 ln=(lo+1)&BN_MASK2;
283 *p=ln;
284 } while (ln == 0);
285 }
286 }
287 }
288#endif
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index 4b3d0f011d..cd59baa2c4 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -60,9 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63BN_ULONG BN_mod_word(a, w) 63BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
64BIGNUM *a;
65unsigned long w;
66 { 64 {
67#ifndef BN_LLONG 65#ifndef BN_LLONG
68 BN_ULONG ret=0; 66 BN_ULONG ret=0;
@@ -75,8 +73,8 @@ unsigned long w;
75 for (i=a->top-1; i>=0; i--) 73 for (i=a->top-1; i>=0; i--)
76 { 74 {
77#ifndef BN_LLONG 75#ifndef BN_LLONG
78 ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%(unsigned long)w; 76 ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
79 ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%(unsigned long)w; 77 ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
80#else 78#else
81 ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])% 79 ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
82 (BN_ULLONG)w); 80 (BN_ULLONG)w);
@@ -85,9 +83,7 @@ unsigned long w;
85 return((BN_ULONG)ret); 83 return((BN_ULONG)ret);
86 } 84 }
87 85
88BN_ULONG BN_div_word(a, w) 86BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
89BIGNUM *a;
90unsigned long w;
91 { 87 {
92 BN_ULONG ret; 88 BN_ULONG ret;
93 int i; 89 int i;
@@ -100,18 +96,16 @@ unsigned long w;
100 BN_ULONG l,d; 96 BN_ULONG l,d;
101 97
102 l=a->d[i]; 98 l=a->d[i];
103 d=bn_div64(ret,l,w); 99 d=bn_div_words(ret,l,w);
104 ret=(l-((d*w)&BN_MASK2))&BN_MASK2; 100 ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
105 a->d[i]=d; 101 a->d[i]=d;
106 } 102 }
107 if (a->d[a->top-1] == 0) 103 if ((a->top > 0) && (a->d[a->top-1] == 0))
108 a->top--; 104 a->top--;
109 return(ret); 105 return(ret);
110 } 106 }
111 107
112int BN_add_word(a, w) 108int BN_add_word(BIGNUM *a, BN_ULONG w)
113BIGNUM *a;
114unsigned long w;
115 { 109 {
116 BN_ULONG l; 110 BN_ULONG l;
117 int i; 111 int i;
@@ -121,7 +115,7 @@ unsigned long w;
121 a->neg=0; 115 a->neg=0;
122 i=BN_sub_word(a,w); 116 i=BN_sub_word(a,w);
123 if (!BN_is_zero(a)) 117 if (!BN_is_zero(a))
124 a->neg=1; 118 a->neg=!(a->neg);
125 return(i); 119 return(i);
126 } 120 }
127 w&=BN_MASK2; 121 w&=BN_MASK2;
@@ -142,13 +136,11 @@ unsigned long w;
142 return(1); 136 return(1);
143 } 137 }
144 138
145int BN_sub_word(a, w) 139int BN_sub_word(BIGNUM *a, BN_ULONG w)
146BIGNUM *a;
147unsigned long w;
148 { 140 {
149 int i; 141 int i;
150 142
151 if (a->neg) 143 if (BN_is_zero(a) || a->neg)
152 { 144 {
153 a->neg=0; 145 a->neg=0;
154 i=BN_add_word(a,w); 146 i=BN_add_word(a,w);
@@ -183,22 +175,25 @@ unsigned long w;
183 return(1); 175 return(1);
184 } 176 }
185 177
186int BN_mul_word(a,w) 178int BN_mul_word(BIGNUM *a, BN_ULONG w)
187BIGNUM *a;
188unsigned long w;
189 { 179 {
190 BN_ULONG ll; 180 BN_ULONG ll;
191 181
192 w&=BN_MASK2; 182 w&=BN_MASK2;
193 if (a->top) 183 if (a->top)
194 { 184 {
195 ll=bn_mul_words(a->d,a->d,a->top,w); 185 if (w == 0)
196 if (ll) 186 BN_zero(a);
187 else
197 { 188 {
198 if (bn_wexpand(a,a->top+1) == NULL) return(0); 189 ll=bn_mul_words(a->d,a->d,a->top,w);
199 a->d[a->top++]=ll; 190 if (ll)
191 {
192 if (bn_wexpand(a,a->top+1) == NULL) return(0);
193 a->d[a->top++]=ll;
194 }
200 } 195 }
201 } 196 }
202 return(0); 197 return(1);
203 } 198 }
204 199