summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn')
-rw-r--r--src/lib/libcrypto/bn/asm/bn-586.pl86
-rw-r--r--src/lib/libcrypto/bn/asm/ia64.S35
-rw-r--r--src/lib/libcrypto/bn/bn.h399
-rw-r--r--src/lib/libcrypto/bn/bn_add.c96
-rw-r--r--src/lib/libcrypto/bn/bn_asm.c28
-rw-r--r--src/lib/libcrypto/bn/bn_blind.c249
-rw-r--r--src/lib/libcrypto/bn/bn_ctx.c417
-rw-r--r--src/lib/libcrypto/bn/bn_div.c299
-rw-r--r--src/lib/libcrypto/bn/bn_err.c29
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c133
-rw-r--r--src/lib/libcrypto/bn/bn_exp2.c56
-rw-r--r--src/lib/libcrypto/bn/bn_gcd.c164
-rw-r--r--src/lib/libcrypto/bn/bn_kron.c8
-rw-r--r--src/lib/libcrypto/bn/bn_lcl.h114
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c225
-rw-r--r--src/lib/libcrypto/bn/bn_mod.c7
-rw-r--r--src/lib/libcrypto/bn/bn_mont.c377
-rw-r--r--src/lib/libcrypto/bn/bn_mpi.c1
-rw-r--r--src/lib/libcrypto/bn/bn_mul.c539
-rw-r--r--src/lib/libcrypto/bn/bn_prime.c114
-rw-r--r--src/lib/libcrypto/bn/bn_prime.h4
-rw-r--r--src/lib/libcrypto/bn/bn_prime.pl6
-rw-r--r--src/lib/libcrypto/bn/bn_print.c41
-rw-r--r--src/lib/libcrypto/bn/bn_rand.c24
-rw-r--r--src/lib/libcrypto/bn/bn_recp.c22
-rw-r--r--src/lib/libcrypto/bn/bn_shift.c27
-rw-r--r--src/lib/libcrypto/bn/bn_sqr.c18
-rw-r--r--src/lib/libcrypto/bn/bn_sqrt.c76
-rw-r--r--src/lib/libcrypto/bn/bn_word.c67
-rw-r--r--src/lib/libcrypto/bn/bntest.c775
-rw-r--r--src/lib/libcrypto/bn/exptest.c3
31 files changed, 3649 insertions, 790 deletions
diff --git a/src/lib/libcrypto/bn/asm/bn-586.pl b/src/lib/libcrypto/bn/asm/bn-586.pl
index c4de4a2bee..26c2685a72 100644
--- a/src/lib/libcrypto/bn/asm/bn-586.pl
+++ b/src/lib/libcrypto/bn/asm/bn-586.pl
@@ -5,13 +5,18 @@ require "x86asm.pl";
5 5
6&asm_init($ARGV[0],$0); 6&asm_init($ARGV[0],$0);
7 7
8$sse2=0;
9for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
10
11&external_label("OPENSSL_ia32cap_P") if ($sse2);
12
8&bn_mul_add_words("bn_mul_add_words"); 13&bn_mul_add_words("bn_mul_add_words");
9&bn_mul_words("bn_mul_words"); 14&bn_mul_words("bn_mul_words");
10&bn_sqr_words("bn_sqr_words"); 15&bn_sqr_words("bn_sqr_words");
11&bn_div_words("bn_div_words"); 16&bn_div_words("bn_div_words");
12&bn_add_words("bn_add_words"); 17&bn_add_words("bn_add_words");
13&bn_sub_words("bn_sub_words"); 18&bn_sub_words("bn_sub_words");
14#&bn_sub_part_words("bn_sub_part_words"); 19&bn_sub_part_words("bn_sub_part_words");
15 20
16&asm_finish(); 21&asm_finish();
17 22
@@ -19,7 +24,7 @@ sub bn_mul_add_words
19 { 24 {
20 local($name)=@_; 25 local($name)=@_;
21 26
22 &function_begin($name,""); 27 &function_begin($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
23 28
24 &comment(""); 29 &comment("");
25 $Low="eax"; 30 $Low="eax";
@@ -42,6 +47,83 @@ sub bn_mul_add_words
42 47
43 &jz(&label("maw_finish")); 48 &jz(&label("maw_finish"));
44 49
50 if ($sse2) {
51 &picmeup("eax","OPENSSL_ia32cap_P");
52 &bt(&DWP(0,"eax"),26);
53 &jnc(&label("maw_loop"));
54
55 &movd("mm0",$w); # mm0 = w
56 &pxor("mm1","mm1"); # mm1 = carry_in
57
58 &set_label("maw_sse2_loop",0);
59 &movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0]
60 &paddq("mm1","mm3"); # mm1 = carry_in + r[0]
61 &movd("mm2",&DWP(0,$a,"",0)); # mm2 = a[0]
62 &pmuludq("mm2","mm0"); # mm2 = w*a[0]
63 &movd("mm4",&DWP(4,$a,"",0)); # mm4 = a[1]
64 &pmuludq("mm4","mm0"); # mm4 = w*a[1]
65 &movd("mm6",&DWP(8,$a,"",0)); # mm6 = a[2]
66 &pmuludq("mm6","mm0"); # mm6 = w*a[2]
67 &movd("mm7",&DWP(12,$a,"",0)); # mm7 = a[3]
68 &pmuludq("mm7","mm0"); # mm7 = w*a[3]
69 &paddq("mm1","mm2"); # mm1 = carry_in + r[0] + w*a[0]
70 &movd("mm3",&DWP(4,$r,"",0)); # mm3 = r[1]
71 &paddq("mm3","mm4"); # mm3 = r[1] + w*a[1]
72 &movd("mm5",&DWP(8,$r,"",0)); # mm5 = r[2]
73 &paddq("mm5","mm6"); # mm5 = r[2] + w*a[2]
74 &movd("mm4",&DWP(12,$r,"",0)); # mm4 = r[3]
75 &paddq("mm7","mm4"); # mm7 = r[3] + w*a[3]
76 &movd(&DWP(0,$r,"",0),"mm1");
77 &movd("mm2",&DWP(16,$a,"",0)); # mm2 = a[4]
78 &pmuludq("mm2","mm0"); # mm2 = w*a[4]
79 &psrlq("mm1",32); # mm1 = carry0
80 &movd("mm4",&DWP(20,$a,"",0)); # mm4 = a[5]
81 &pmuludq("mm4","mm0"); # mm4 = w*a[5]
82 &paddq("mm1","mm3"); # mm1 = carry0 + r[1] + w*a[1]
83 &movd("mm6",&DWP(24,$a,"",0)); # mm6 = a[6]
84 &pmuludq("mm6","mm0"); # mm6 = w*a[6]
85 &movd(&DWP(4,$r,"",0),"mm1");
86 &psrlq("mm1",32); # mm1 = carry1
87 &movd("mm3",&DWP(28,$a,"",0)); # mm3 = a[7]
88 &add($a,32);
89 &pmuludq("mm3","mm0"); # mm3 = w*a[7]
90 &paddq("mm1","mm5"); # mm1 = carry1 + r[2] + w*a[2]
91 &movd("mm5",&DWP(16,$r,"",0)); # mm5 = r[4]
92 &paddq("mm2","mm5"); # mm2 = r[4] + w*a[4]
93 &movd(&DWP(8,$r,"",0),"mm1");
94 &psrlq("mm1",32); # mm1 = carry2
95 &paddq("mm1","mm7"); # mm1 = carry2 + r[3] + w*a[3]
96 &movd("mm5",&DWP(20,$r,"",0)); # mm5 = r[5]
97 &paddq("mm4","mm5"); # mm4 = r[5] + w*a[5]
98 &movd(&DWP(12,$r,"",0),"mm1");
99 &psrlq("mm1",32); # mm1 = carry3
100 &paddq("mm1","mm2"); # mm1 = carry3 + r[4] + w*a[4]
101 &movd("mm5",&DWP(24,$r,"",0)); # mm5 = r[6]
102 &paddq("mm6","mm5"); # mm6 = r[6] + w*a[6]
103 &movd(&DWP(16,$r,"",0),"mm1");
104 &psrlq("mm1",32); # mm1 = carry4
105 &paddq("mm1","mm4"); # mm1 = carry4 + r[5] + w*a[5]
106 &movd("mm5",&DWP(28,$r,"",0)); # mm5 = r[7]
107 &paddq("mm3","mm5"); # mm3 = r[7] + w*a[7]
108 &movd(&DWP(20,$r,"",0),"mm1");
109 &psrlq("mm1",32); # mm1 = carry5
110 &paddq("mm1","mm6"); # mm1 = carry5 + r[6] + w*a[6]
111 &movd(&DWP(24,$r,"",0),"mm1");
112 &psrlq("mm1",32); # mm1 = carry6
113 &paddq("mm1","mm3"); # mm1 = carry6 + r[7] + w*a[7]
114 &movd(&DWP(28,$r,"",0),"mm1");
115 &add($r,32);
116 &psrlq("mm1",32); # mm1 = carry_out
117
118 &sub("ecx",8);
119 &jnz(&label("maw_sse2_loop"));
120
121 &movd($c,"mm1"); # c = carry_out
122 &emms();
123
124 &jmp(&label("maw_finish"));
125 }
126
45 &set_label("maw_loop",0); 127 &set_label("maw_loop",0);
46 128
47 &mov(&swtmp(0),"ecx"); # 129 &mov(&swtmp(0),"ecx"); #
diff --git a/src/lib/libcrypto/bn/asm/ia64.S b/src/lib/libcrypto/bn/asm/ia64.S
index 7b82b820e6..951abc53ea 100644
--- a/src/lib/libcrypto/bn/asm/ia64.S
+++ b/src/lib/libcrypto/bn/asm/ia64.S
@@ -171,21 +171,21 @@
171.skip 32 // makes the loop body aligned at 64-byte boundary 171.skip 32 // makes the loop body aligned at 64-byte boundary
172bn_add_words: 172bn_add_words:
173 .prologue 173 .prologue
174 .fframe 0
175 .save ar.pfs,r2 174 .save ar.pfs,r2
176{ .mii; alloc r2=ar.pfs,4,12,0,16 175{ .mii; alloc r2=ar.pfs,4,12,0,16
177 cmp4.le p6,p0=r35,r0 };; 176 cmp4.le p6,p0=r35,r0 };;
178{ .mfb; mov r8=r0 // return value 177{ .mfb; mov r8=r0 // return value
179(p6) br.ret.spnt.many b0 };; 178(p6) br.ret.spnt.many b0 };;
180 179
181 .save ar.lc,r3
182{ .mib; sub r10=r35,r0,1 180{ .mib; sub r10=r35,r0,1
181 .save ar.lc,r3
183 mov r3=ar.lc 182 mov r3=ar.lc
184 brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16 183 brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16
185 } 184 }
186 .body
187{ .mib; ADDP r14=0,r32 // rp 185{ .mib; ADDP r14=0,r32 // rp
186 .save pr,r9
188 mov r9=pr };; 187 mov r9=pr };;
188 .body
189{ .mii; ADDP r15=0,r33 // ap 189{ .mii; ADDP r15=0,r33 // ap
190 mov ar.lc=r10 190 mov ar.lc=r10
191 mov ar.ec=6 } 191 mov ar.ec=6 }
@@ -224,21 +224,21 @@ bn_add_words:
224.skip 32 // makes the loop body aligned at 64-byte boundary 224.skip 32 // makes the loop body aligned at 64-byte boundary
225bn_sub_words: 225bn_sub_words:
226 .prologue 226 .prologue
227 .fframe 0
228 .save ar.pfs,r2 227 .save ar.pfs,r2
229{ .mii; alloc r2=ar.pfs,4,12,0,16 228{ .mii; alloc r2=ar.pfs,4,12,0,16
230 cmp4.le p6,p0=r35,r0 };; 229 cmp4.le p6,p0=r35,r0 };;
231{ .mfb; mov r8=r0 // return value 230{ .mfb; mov r8=r0 // return value
232(p6) br.ret.spnt.many b0 };; 231(p6) br.ret.spnt.many b0 };;
233 232
234 .save ar.lc,r3
235{ .mib; sub r10=r35,r0,1 233{ .mib; sub r10=r35,r0,1
234 .save ar.lc,r3
236 mov r3=ar.lc 235 mov r3=ar.lc
237 brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16 236 brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16
238 } 237 }
239 .body
240{ .mib; ADDP r14=0,r32 // rp 238{ .mib; ADDP r14=0,r32 // rp
239 .save pr,r9
241 mov r9=pr };; 240 mov r9=pr };;
241 .body
242{ .mii; ADDP r15=0,r33 // ap 242{ .mii; ADDP r15=0,r33 // ap
243 mov ar.lc=r10 243 mov ar.lc=r10
244 mov ar.ec=6 } 244 mov ar.ec=6 }
@@ -283,7 +283,6 @@ bn_sub_words:
283.skip 32 // makes the loop body aligned at 64-byte boundary 283.skip 32 // makes the loop body aligned at 64-byte boundary
284bn_mul_words: 284bn_mul_words:
285 .prologue 285 .prologue
286 .fframe 0
287 .save ar.pfs,r2 286 .save ar.pfs,r2
288#ifdef XMA_TEMPTATION 287#ifdef XMA_TEMPTATION
289{ .mfi; alloc r2=ar.pfs,4,0,0,0 };; 288{ .mfi; alloc r2=ar.pfs,4,0,0,0 };;
@@ -294,9 +293,10 @@ bn_mul_words:
294 cmp4.le p6,p0=r34,r0 293 cmp4.le p6,p0=r34,r0
295(p6) br.ret.spnt.many b0 };; 294(p6) br.ret.spnt.many b0 };;
296 295
297 .save ar.lc,r3
298{ .mii; sub r10=r34,r0,1 296{ .mii; sub r10=r34,r0,1
297 .save ar.lc,r3
299 mov r3=ar.lc 298 mov r3=ar.lc
299 .save pr,r9
300 mov r9=pr };; 300 mov r9=pr };;
301 301
302 .body 302 .body
@@ -397,22 +397,21 @@ bn_mul_words:
397.skip 48 // makes the loop body aligned at 64-byte boundary 397.skip 48 // makes the loop body aligned at 64-byte boundary
398bn_mul_add_words: 398bn_mul_add_words:
399 .prologue 399 .prologue
400 .fframe 0
401 .save ar.pfs,r2 400 .save ar.pfs,r2
402 .save ar.lc,r3
403 .save pr,r9
404{ .mmi; alloc r2=ar.pfs,4,4,0,8 401{ .mmi; alloc r2=ar.pfs,4,4,0,8
405 cmp4.le p6,p0=r34,r0 402 cmp4.le p6,p0=r34,r0
403 .save ar.lc,r3
406 mov r3=ar.lc };; 404 mov r3=ar.lc };;
407{ .mib; mov r8=r0 // return value 405{ .mib; mov r8=r0 // return value
408 sub r10=r34,r0,1 406 sub r10=r34,r0,1
409(p6) br.ret.spnt.many b0 };; 407(p6) br.ret.spnt.many b0 };;
410 408
411 .body
412{ .mib; setf.sig f8=r35 // w 409{ .mib; setf.sig f8=r35 // w
410 .save pr,r9
413 mov r9=pr 411 mov r9=pr
414 brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16 412 brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16
415 } 413 }
414 .body
416{ .mmi; ADDP r14=0,r32 // rp 415{ .mmi; ADDP r14=0,r32 // rp
417 ADDP r15=0,r33 // ap 416 ADDP r15=0,r33 // ap
418 mov ar.lc=r10 } 417 mov ar.lc=r10 }
@@ -466,7 +465,6 @@ bn_mul_add_words:
466.skip 32 // makes the loop body aligned at 64-byte boundary 465.skip 32 // makes the loop body aligned at 64-byte boundary
467bn_sqr_words: 466bn_sqr_words:
468 .prologue 467 .prologue
469 .fframe 0
470 .save ar.pfs,r2 468 .save ar.pfs,r2
471{ .mii; alloc r2=ar.pfs,3,0,0,0 469{ .mii; alloc r2=ar.pfs,3,0,0,0
472 sxt4 r34=r34 };; 470 sxt4 r34=r34 };;
@@ -476,9 +474,10 @@ bn_sqr_words:
476 nop.f 0x0 474 nop.f 0x0
477(p6) br.ret.spnt.many b0 };; 475(p6) br.ret.spnt.many b0 };;
478 476
479 .save ar.lc,r3
480{ .mii; sub r10=r34,r0,1 477{ .mii; sub r10=r34,r0,1
478 .save ar.lc,r3
481 mov r3=ar.lc 479 mov r3=ar.lc
480 .save pr,r9
482 mov r9=pr };; 481 mov r9=pr };;
483 482
484 .body 483 .body
@@ -545,7 +544,6 @@ bn_sqr_words:
545.align 64 544.align 64
546bn_sqr_comba8: 545bn_sqr_comba8:
547 .prologue 546 .prologue
548 .fframe 0
549 .save ar.pfs,r2 547 .save ar.pfs,r2
550#if defined(_HPUX_SOURCE) && !defined(_LP64) 548#if defined(_HPUX_SOURCE) && !defined(_LP64)
551{ .mii; alloc r2=ar.pfs,2,1,0,0 549{ .mii; alloc r2=ar.pfs,2,1,0,0
@@ -617,7 +615,6 @@ bn_sqr_comba8:
617.align 64 615.align 64
618bn_mul_comba8: 616bn_mul_comba8:
619 .prologue 617 .prologue
620 .fframe 0
621 .save ar.pfs,r2 618 .save ar.pfs,r2
622#if defined(_HPUX_SOURCE) && !defined(_LP64) 619#if defined(_HPUX_SOURCE) && !defined(_LP64)
623{ .mii; alloc r2=ar.pfs,3,0,0,0 620{ .mii; alloc r2=ar.pfs,3,0,0,0
@@ -1175,7 +1172,6 @@ bn_mul_comba8:
1175.align 64 1172.align 64
1176bn_sqr_comba4: 1173bn_sqr_comba4:
1177 .prologue 1174 .prologue
1178 .fframe 0
1179 .save ar.pfs,r2 1175 .save ar.pfs,r2
1180#if defined(_HPUX_SOURCE) && !defined(_LP64) 1176#if defined(_HPUX_SOURCE) && !defined(_LP64)
1181{ .mii; alloc r2=ar.pfs,2,1,0,0 1177{ .mii; alloc r2=ar.pfs,2,1,0,0
@@ -1208,7 +1204,6 @@ bn_sqr_comba4:
1208.align 64 1204.align 64
1209bn_mul_comba4: 1205bn_mul_comba4:
1210 .prologue 1206 .prologue
1211 .fframe 0
1212 .save ar.pfs,r2 1207 .save ar.pfs,r2
1213#if defined(_HPUX_SOURCE) && !defined(_LP64) 1208#if defined(_HPUX_SOURCE) && !defined(_LP64)
1214{ .mii; alloc r2=ar.pfs,3,0,0,0 1209{ .mii; alloc r2=ar.pfs,3,0,0,0
@@ -1411,11 +1406,11 @@ equ=p24
1411.align 64 1406.align 64
1412bn_div_words: 1407bn_div_words:
1413 .prologue 1408 .prologue
1414 .fframe 0
1415 .save ar.pfs,r2 1409 .save ar.pfs,r2
1416 .save b0,r3
1417{ .mii; alloc r2=ar.pfs,3,5,0,8 1410{ .mii; alloc r2=ar.pfs,3,5,0,8
1411 .save b0,r3
1418 mov r3=b0 1412 mov r3=b0
1413 .save pr,r10
1419 mov r10=pr };; 1414 mov r10=pr };;
1420{ .mmb; cmp.eq p6,p0=r34,r0 1415{ .mmb; cmp.eq p6,p0=r34,r0
1421 mov r8=-1 1416 mov r8=-1
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h
index 1251521c54..6d754d5547 100644
--- a/src/lib/libcrypto/bn/bn.h
+++ b/src/lib/libcrypto/bn/bn.h
@@ -55,6 +55,19 @@
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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the Eric Young open source
65 * license provided above.
66 *
67 * The binary polynomial arithmetic software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
58 71
59#ifndef HEADER_BN_H 72#ifndef HEADER_BN_H
60#define HEADER_BN_H 73#define HEADER_BN_H
@@ -63,14 +76,23 @@
63#ifndef OPENSSL_NO_FP_API 76#ifndef OPENSSL_NO_FP_API
64#include <stdio.h> /* FILE */ 77#include <stdio.h> /* FILE */
65#endif 78#endif
79#include <openssl/ossl_typ.h>
66 80
67#ifdef __cplusplus 81#ifdef __cplusplus
68extern "C" { 82extern "C" {
69#endif 83#endif
70 84
71#ifdef OPENSSL_SYS_VMS 85/* These preprocessor symbols control various aspects of the bignum headers and
72#undef BN_LLONG /* experimental, so far... */ 86 * library code. They're not defined by any "normal" configuration, as they are
73#endif 87 * intended for development and testing purposes. NB: defining all three can be
88 * useful for debugging application code as well as openssl itself.
89 *
90 * BN_DEBUG - turn on various debugging alterations to the bignum code
91 * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
92 * mismanagement of bignum internals. You must also define BN_DEBUG.
93 */
94/* #define BN_DEBUG */
95/* #define BN_DEBUG_RAND */
74 96
75#define BN_MUL_COMBA 97#define BN_MUL_COMBA
76#define BN_SQR_COMBA 98#define BN_SQR_COMBA
@@ -143,10 +165,12 @@ extern "C" {
143#endif 165#endif
144 166
145#ifdef THIRTY_TWO_BIT 167#ifdef THIRTY_TWO_BIT
146#if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) 168#ifdef BN_LLONG
147#define BN_ULLONG unsigned _int64 169# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
148#else 170# define BN_ULLONG unsigned __int64
149#define BN_ULLONG unsigned long long 171# else
172# define BN_ULLONG unsigned long long
173# endif
150#endif 174#endif
151#define BN_ULONG unsigned long 175#define BN_ULONG unsigned long
152#define BN_LONG long 176#define BN_LONG long
@@ -219,15 +243,23 @@ extern "C" {
219 243
220#define BN_DEFAULT_BITS 1280 244#define BN_DEFAULT_BITS 1280
221 245
222#ifdef BIGNUM
223#undef BIGNUM
224#endif
225
226#define BN_FLG_MALLOCED 0x01 246#define BN_FLG_MALLOCED 0x01
227#define BN_FLG_STATIC_DATA 0x02 247#define BN_FLG_STATIC_DATA 0x02
228#define BN_FLG_EXP_CONSTTIME 0x04 /* avoid leaking exponent information through timings 248#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing,
229 * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ 249 * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
250 * BN_div() will call BN_div_no_branch,
251 * BN_mod_inverse() will call BN_mod_inverse_no_branch.
252 */
253
254#ifndef OPENSSL_NO_DEPRECATED
255#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
256 /* avoid leaking exponent information through timings
257 * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
258#endif
259
260#ifndef OPENSSL_NO_DEPRECATED
230#define BN_FLG_FREE 0x8000 /* used for debuging */ 261#define BN_FLG_FREE 0x8000 /* used for debuging */
262#endif
231#define BN_set_flags(b,n) ((b)->flags|=(n)) 263#define BN_set_flags(b,n) ((b)->flags|=(n))
232#define BN_get_flags(b,n) ((b)->flags&(n)) 264#define BN_get_flags(b,n) ((b)->flags&(n))
233 265
@@ -242,7 +274,18 @@ extern "C" {
242 | BN_FLG_STATIC_DATA \ 274 | BN_FLG_STATIC_DATA \
243 | (n))) 275 | (n)))
244 276
245typedef struct bignum_st 277/* Already declared in ossl_typ.h */
278#if 0
279typedef struct bignum_st BIGNUM;
280/* Used for temp variables (declaration hidden in bn_lcl.h) */
281typedef struct bignum_ctx BN_CTX;
282typedef struct bn_blinding_st BN_BLINDING;
283typedef struct bn_mont_ctx_st BN_MONT_CTX;
284typedef struct bn_recp_ctx_st BN_RECP_CTX;
285typedef struct bn_gencb_st BN_GENCB;
286#endif
287
288struct bignum_st
246 { 289 {
247 BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ 290 BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
248 int top; /* Index of last used d +1. */ 291 int top; /* Index of last used d +1. */
@@ -250,44 +293,64 @@ typedef struct bignum_st
250 int dmax; /* Size of the d array. */ 293 int dmax; /* Size of the d array. */
251 int neg; /* one if the number is negative */ 294 int neg; /* one if the number is negative */
252 int flags; 295 int flags;
253 } BIGNUM; 296 };
254
255/* Used for temp variables (declaration hidden in bn_lcl.h) */
256typedef struct bignum_ctx BN_CTX;
257
258typedef struct bn_blinding_st
259 {
260 int init;
261 BIGNUM *A;
262 BIGNUM *Ai;
263 BIGNUM *mod; /* just a reference */
264 unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
265 * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
266 } BN_BLINDING;
267 297
268/* Used for montgomery multiplication */ 298/* Used for montgomery multiplication */
269typedef struct bn_mont_ctx_st 299struct bn_mont_ctx_st
270 { 300 {
271 int ri; /* number of bits in R */ 301 int ri; /* number of bits in R */
272 BIGNUM RR; /* used to convert to montgomery form */ 302 BIGNUM RR; /* used to convert to montgomery form */
273 BIGNUM N; /* The modulus */ 303 BIGNUM N; /* The modulus */
274 BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 304 BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
275 * (Ni is only stored for bignum algorithm) */ 305 * (Ni is only stored for bignum algorithm) */
306#if 0
307 /* OpenSSL 0.9.9 preview: */
308 BN_ULONG n0[2];/* least significant word(s) of Ni */
309#else
276 BN_ULONG n0; /* least significant word of Ni */ 310 BN_ULONG n0; /* least significant word of Ni */
311#endif
277 int flags; 312 int flags;
278 } BN_MONT_CTX; 313 };
279 314
280/* Used for reciprocal division/mod functions 315/* Used for reciprocal division/mod functions
281 * It cannot be shared between threads 316 * It cannot be shared between threads
282 */ 317 */
283typedef struct bn_recp_ctx_st 318struct bn_recp_ctx_st
284 { 319 {
285 BIGNUM N; /* the divisor */ 320 BIGNUM N; /* the divisor */
286 BIGNUM Nr; /* the reciprocal */ 321 BIGNUM Nr; /* the reciprocal */
287 int num_bits; 322 int num_bits;
288 int shift; 323 int shift;
289 int flags; 324 int flags;
290 } BN_RECP_CTX; 325 };
326
327/* Used for slow "generation" functions. */
328struct bn_gencb_st
329 {
330 unsigned int ver; /* To handle binary (in)compatibility */
331 void *arg; /* callback-specific data */
332 union
333 {
334 /* if(ver==1) - handles old style callbacks */
335 void (*cb_1)(int, int, void *);
336 /* if(ver==2) - new callback style */
337 int (*cb_2)(int, int, BN_GENCB *);
338 } cb;
339 };
340/* Wrapper function to make using BN_GENCB easier, */
341int BN_GENCB_call(BN_GENCB *cb, int a, int b);
342/* Macro to populate a BN_GENCB structure with an "old"-style callback */
343#define BN_GENCB_set_old(gencb, callback, cb_arg) { \
344 BN_GENCB *tmp_gencb = (gencb); \
345 tmp_gencb->ver = 1; \
346 tmp_gencb->arg = (cb_arg); \
347 tmp_gencb->cb.cb_1 = (callback); }
348/* Macro to populate a BN_GENCB structure with a "new"-style callback */
349#define BN_GENCB_set(gencb, callback, cb_arg) { \
350 BN_GENCB *tmp_gencb = (gencb); \
351 tmp_gencb->ver = 2; \
352 tmp_gencb->arg = (cb_arg); \
353 tmp_gencb->cb.cb_2 = (callback); }
291 354
292#define BN_prime_checks 0 /* default: select number of iterations 355#define BN_prime_checks 0 /* default: select number of iterations
293 based on the size of the number */ 356 based on the size of the number */
@@ -312,24 +375,33 @@ typedef struct bn_recp_ctx_st
312 375
313#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) 376#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
314 377
315/* Note that BN_abs_is_word does not work reliably for w == 0 */ 378/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
316#define BN_abs_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) 379#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
317#define BN_is_zero(a) (((a)->top == 0) || BN_abs_is_word(a,0)) 380 (((w) == 0) && ((a)->top == 0)))
381#define BN_is_zero(a) ((a)->top == 0)
318#define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) 382#define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg)
319#define BN_is_word(a,w) ((w) ? BN_abs_is_word((a),(w)) && !(a)->neg : \ 383#define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
320 BN_is_zero((a)))
321#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) 384#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
322 385
323#define BN_one(a) (BN_set_word((a),1)) 386#define BN_one(a) (BN_set_word((a),1))
387#define BN_zero_ex(a) \
388 do { \
389 BIGNUM *_tmp_bn = (a); \
390 _tmp_bn->top = 0; \
391 _tmp_bn->neg = 0; \
392 } while(0)
393#ifdef OPENSSL_NO_DEPRECATED
394#define BN_zero(a) BN_zero_ex(a)
395#else
324#define BN_zero(a) (BN_set_word((a),0)) 396#define BN_zero(a) (BN_set_word((a),0))
325 397#endif
326/*#define BN_ascii2bn(a) BN_hex2bn(a) */
327/*#define BN_bn2ascii(a) BN_bn2hex(a) */
328 398
329const BIGNUM *BN_value_one(void); 399const BIGNUM *BN_value_one(void);
330char * BN_options(void); 400char * BN_options(void);
331BN_CTX *BN_CTX_new(void); 401BN_CTX *BN_CTX_new(void);
402#ifndef OPENSSL_NO_DEPRECATED
332void BN_CTX_init(BN_CTX *c); 403void BN_CTX_init(BN_CTX *c);
404#endif
333void BN_CTX_free(BN_CTX *c); 405void BN_CTX_free(BN_CTX *c);
334void BN_CTX_start(BN_CTX *ctx); 406void BN_CTX_start(BN_CTX *ctx);
335BIGNUM *BN_CTX_get(BN_CTX *ctx); 407BIGNUM *BN_CTX_get(BN_CTX *ctx);
@@ -355,6 +427,16 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
355int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); 427int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
356int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); 428int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
357int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx); 429int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
430/** BN_set_negative sets sign of a BIGNUM
431 * \param b pointer to the BIGNUM object
432 * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise
433 */
434void BN_set_negative(BIGNUM *b, int n);
435/** BN_is_negative returns 1 if the BIGNUM is negative
436 * \param a pointer to the BIGNUM object
437 * \return 1 if a < 0 and 0 otherwise
438 */
439#define BN_is_negative(a) ((a)->neg != 0)
358 440
359int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, 441int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
360 BN_CTX *ctx); 442 BN_CTX *ctx);
@@ -428,6 +510,9 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret,
428 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); 510 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
429BIGNUM *BN_mod_sqrt(BIGNUM *ret, 511BIGNUM *BN_mod_sqrt(BIGNUM *ret,
430 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); 512 const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
513
514/* Deprecated versions */
515#ifndef OPENSSL_NO_DEPRECATED
431BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, 516BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
432 const BIGNUM *add, const BIGNUM *rem, 517 const BIGNUM *add, const BIGNUM *rem,
433 void (*callback)(int,int,void *),void *cb_arg); 518 void (*callback)(int,int,void *),void *cb_arg);
@@ -437,19 +522,14 @@ int BN_is_prime(const BIGNUM *p,int nchecks,
437int BN_is_prime_fasttest(const BIGNUM *p,int nchecks, 522int BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
438 void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg, 523 void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
439 int do_trial_division); 524 int do_trial_division);
525#endif /* !defined(OPENSSL_NO_DEPRECATED) */
440 526
441#ifdef OPENSSL_FIPS 527/* Newer versions */
442int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, 528int BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add,
443 void (*cb)(int, int, void *), void *cb_arg, 529 const BIGNUM *rem, BN_GENCB *cb);
444 const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, 530int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
445 const BIGNUM *e, BN_CTX *ctx); 531int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
446int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); 532 int do_trial_division, BN_GENCB *cb);
447int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
448 BIGNUM *Xp1, BIGNUM *Xp2,
449 const BIGNUM *Xp,
450 const BIGNUM *e, BN_CTX *ctx,
451 void (*cb)(int, int, void *), void *cb_arg);
452#endif
453 533
454BN_MONT_CTX *BN_MONT_CTX_new(void ); 534BN_MONT_CTX *BN_MONT_CTX_new(void );
455void BN_MONT_CTX_init(BN_MONT_CTX *ctx); 535void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
@@ -465,14 +545,31 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
465BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, 545BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
466 const BIGNUM *mod, BN_CTX *ctx); 546 const BIGNUM *mod, BN_CTX *ctx);
467 547
468BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod); 548/* BN_BLINDING flags */
549#define BN_BLINDING_NO_UPDATE 0x00000001
550#define BN_BLINDING_NO_RECREATE 0x00000002
551
552BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
469void BN_BLINDING_free(BN_BLINDING *b); 553void BN_BLINDING_free(BN_BLINDING *b);
470int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); 554int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
471int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx); 555int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
472int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); 556int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
473 557int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
558int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
559unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
560void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
561unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
562void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
563BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
564 const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
565 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
566 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
567 BN_MONT_CTX *m_ctx);
568
569#ifndef OPENSSL_NO_DEPRECATED
474void BN_set_params(int mul,int high,int low,int mont); 570void BN_set_params(int mul,int high,int low,int mont);
475int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ 571int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
572#endif
476 573
477void BN_RECP_CTX_init(BN_RECP_CTX *recp); 574void BN_RECP_CTX_init(BN_RECP_CTX *recp);
478BN_RECP_CTX *BN_RECP_CTX_new(void); 575BN_RECP_CTX *BN_RECP_CTX_new(void);
@@ -485,15 +582,162 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
485int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, 582int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
486 BN_RECP_CTX *recp, BN_CTX *ctx); 583 BN_RECP_CTX *recp, BN_CTX *ctx);
487 584
585/* Functions for arithmetic over binary polynomials represented by BIGNUMs.
586 *
587 * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
588 * ignored.
589 *
590 * Note that input arguments are not const so that their bit arrays can
591 * be expanded to the appropriate size if needed.
592 */
593
594int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
595#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
596int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
597int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
598 const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
599int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
600 BN_CTX *ctx); /* r = (a * a) mod p */
601int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
602 BN_CTX *ctx); /* r = (1 / b) mod p */
603int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
604 const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
605int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
606 const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
607int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
608 BN_CTX *ctx); /* r = sqrt(a) mod p */
609int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
610 BN_CTX *ctx); /* r^2 + r = a mod p */
611#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
612/* Some functions allow for representation of the irreducible polynomials
613 * as an unsigned int[], say p. The irreducible f(t) is then of the form:
614 * t^p[0] + t^p[1] + ... + t^p[k]
615 * where m = p[0] > p[1] > ... > p[k] = 0.
616 */
617int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
618 /* r = a mod p */
619int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
620 const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
621int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
622 BN_CTX *ctx); /* r = (a * a) mod p */
623int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
624 BN_CTX *ctx); /* r = (1 / b) mod p */
625int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
626 const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
627int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
628 const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
629int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
630 const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
631int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
632 const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
633int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
634int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
635
636/* faster mod functions for the 'NIST primes'
637 * 0 <= a < p^2 */
638int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
639int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
640int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
641int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
642int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
643
644const BIGNUM *BN_get0_nist_prime_192(void);
645const BIGNUM *BN_get0_nist_prime_224(void);
646const BIGNUM *BN_get0_nist_prime_256(void);
647const BIGNUM *BN_get0_nist_prime_384(void);
648const BIGNUM *BN_get0_nist_prime_521(void);
649
488/* library internal functions */ 650/* library internal functions */
489 651
490#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ 652#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
491 (a):bn_expand2((a),(bits)/BN_BITS2+1)) 653 (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
492#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) 654#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
493BIGNUM *bn_expand2(BIGNUM *a, int words); 655BIGNUM *bn_expand2(BIGNUM *a, int words);
494BIGNUM *bn_dup_expand(const BIGNUM *a, int words); 656#ifndef OPENSSL_NO_DEPRECATED
657BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
658#endif
659
660/* Bignum consistency macros
661 * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
662 * bignum data after direct manipulations on the data. There is also an
663 * "internal" macro, bn_check_top(), for verifying that there are no leading
664 * zeroes. Unfortunately, some auditing is required due to the fact that
665 * bn_fix_top() has become an overabused duct-tape because bignum data is
666 * occasionally passed around in an inconsistent state. So the following
667 * changes have been made to sort this out;
668 * - bn_fix_top()s implementation has been moved to bn_correct_top()
669 * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
670 * bn_check_top() is as before.
671 * - if BN_DEBUG *is* defined;
672 * - bn_check_top() tries to pollute unused words even if the bignum 'top' is
673 * consistent. (ed: only if BN_DEBUG_RAND is defined)
674 * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
675 * The idea is to have debug builds flag up inconsistent bignums when they
676 * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
677 * the use of bn_fix_top() was appropriate (ie. it follows directly after code
678 * that manipulates the bignum) it is converted to bn_correct_top(), and if it
679 * was not appropriate, we convert it permanently to bn_check_top() and track
680 * down the cause of the bug. Eventually, no internal code should be using the
681 * bn_fix_top() macro. External applications and libraries should try this with
682 * their own code too, both in terms of building against the openssl headers
683 * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
684 * defined. This not only improves external code, it provides more test
685 * coverage for openssl's own code.
686 */
687
688#ifdef BN_DEBUG
495 689
496#define bn_fix_top(a) \ 690/* We only need assert() when debugging */
691#include <assert.h>
692
693#ifdef BN_DEBUG_RAND
694/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
695#ifndef RAND_pseudo_bytes
696int RAND_pseudo_bytes(unsigned char *buf,int num);
697#define BN_DEBUG_TRIX
698#endif
699#define bn_pollute(a) \
700 do { \
701 const BIGNUM *_bnum1 = (a); \
702 if(_bnum1->top < _bnum1->dmax) { \
703 unsigned char _tmp_char; \
704 /* We cast away const without the compiler knowing, any \
705 * *genuinely* constant variables that aren't mutable \
706 * wouldn't be constructed with top!=dmax. */ \
707 BN_ULONG *_not_const; \
708 memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
709 RAND_pseudo_bytes(&_tmp_char, 1); \
710 memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
711 (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
712 } \
713 } while(0)
714#ifdef BN_DEBUG_TRIX
715#undef RAND_pseudo_bytes
716#endif
717#else
718#define bn_pollute(a)
719#endif
720#define bn_check_top(a) \
721 do { \
722 const BIGNUM *_bnum2 = (a); \
723 if (_bnum2 != NULL) { \
724 assert((_bnum2->top == 0) || \
725 (_bnum2->d[_bnum2->top - 1] != 0)); \
726 bn_pollute(_bnum2); \
727 } \
728 } while(0)
729
730#define bn_fix_top(a) bn_check_top(a)
731
732#else /* !BN_DEBUG */
733
734#define bn_pollute(a)
735#define bn_check_top(a)
736#define bn_fix_top(a) bn_correct_top(a)
737
738#endif
739
740#define bn_correct_top(a) \
497 { \ 741 { \
498 BN_ULONG *ftl; \ 742 BN_ULONG *ftl; \
499 if ((a)->top > 0) \ 743 if ((a)->top > 0) \
@@ -501,6 +745,7 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
501 for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ 745 for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
502 if (*(ftl--)) break; \ 746 if (*(ftl--)) break; \
503 } \ 747 } \
748 bn_pollute(a); \
504 } 749 }
505 750
506BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); 751BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
@@ -510,15 +755,17 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
510BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); 755BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
511BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); 756BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
512 757
513#ifdef BN_DEBUG 758/* Primes from RFC 2409 */
514void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n); 759BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
515# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ 760BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
516 fprintf(stderr,"\n");} 761
517# define bn_dump(a,n) bn_dump1(stderr,#a,a,n); 762/* Primes from RFC 3526 */
518#else 763BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
519# define bn_print(a) 764BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
520# define bn_dump(a,b) 765BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
521#endif 766BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
767BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
768BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
522 769
523int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom); 770int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
524 771
@@ -531,18 +778,30 @@ void ERR_load_BN_strings(void);
531/* Error codes for the BN functions. */ 778/* Error codes for the BN functions. */
532 779
533/* Function codes. */ 780/* Function codes. */
534#define BN_F_BN_BLINDING_CONVERT 100 781#define BN_F_BNRAND 127
535#define BN_F_BN_BLINDING_INVERT 101 782#define BN_F_BN_BLINDING_CONVERT_EX 100
783#define BN_F_BN_BLINDING_CREATE_PARAM 128
784#define BN_F_BN_BLINDING_INVERT_EX 101
536#define BN_F_BN_BLINDING_NEW 102 785#define BN_F_BN_BLINDING_NEW 102
537#define BN_F_BN_BLINDING_UPDATE 103 786#define BN_F_BN_BLINDING_UPDATE 103
538#define BN_F_BN_BN2DEC 104 787#define BN_F_BN_BN2DEC 104
539#define BN_F_BN_BN2HEX 105 788#define BN_F_BN_BN2HEX 105
540#define BN_F_BN_CTX_GET 116 789#define BN_F_BN_CTX_GET 116
541#define BN_F_BN_CTX_NEW 106 790#define BN_F_BN_CTX_NEW 106
791#define BN_F_BN_CTX_START 129
542#define BN_F_BN_DIV 107 792#define BN_F_BN_DIV 107
793#define BN_F_BN_DIV_NO_BRANCH 138
794#define BN_F_BN_DIV_RECP 130
543#define BN_F_BN_EXP 123 795#define BN_F_BN_EXP 123
544#define BN_F_BN_EXPAND2 108 796#define BN_F_BN_EXPAND2 108
545#define BN_F_BN_EXPAND_INTERNAL 120 797#define BN_F_BN_EXPAND_INTERNAL 120
798#define BN_F_BN_GF2M_MOD 131
799#define BN_F_BN_GF2M_MOD_EXP 132
800#define BN_F_BN_GF2M_MOD_MUL 133
801#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134
802#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135
803#define BN_F_BN_GF2M_MOD_SQR 136
804#define BN_F_BN_GF2M_MOD_SQRT 137
546#define BN_F_BN_MOD_EXP2_MONT 118 805#define BN_F_BN_MOD_EXP2_MONT 118
547#define BN_F_BN_MOD_EXP_MONT 109 806#define BN_F_BN_MOD_EXP_MONT 109
548#define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 807#define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124
@@ -550,6 +809,7 @@ void ERR_load_BN_strings(void);
550#define BN_F_BN_MOD_EXP_RECP 125 809#define BN_F_BN_MOD_EXP_RECP 125
551#define BN_F_BN_MOD_EXP_SIMPLE 126 810#define BN_F_BN_MOD_EXP_SIMPLE 126
552#define BN_F_BN_MOD_INVERSE 110 811#define BN_F_BN_MOD_INVERSE 110
812#define BN_F_BN_MOD_INVERSE_NO_BRANCH 139
553#define BN_F_BN_MOD_LSHIFT_QUICK 119 813#define BN_F_BN_MOD_LSHIFT_QUICK 119
554#define BN_F_BN_MOD_MUL_RECIPROCAL 111 814#define BN_F_BN_MOD_MUL_RECIPROCAL 111
555#define BN_F_BN_MOD_SQRT 121 815#define BN_F_BN_MOD_SQRT 121
@@ -573,6 +833,7 @@ void ERR_load_BN_strings(void);
573#define BN_R_NOT_A_SQUARE 111 833#define BN_R_NOT_A_SQUARE 111
574#define BN_R_NOT_INITIALIZED 107 834#define BN_R_NOT_INITIALIZED 107
575#define BN_R_NO_INVERSE 108 835#define BN_R_NO_INVERSE 108
836#define BN_R_NO_SOLUTION 116
576#define BN_R_P_IS_NOT_PRIME 112 837#define BN_R_P_IS_NOT_PRIME 112
577#define BN_R_TOO_MANY_ITERATIONS 113 838#define BN_R_TOO_MANY_ITERATIONS 113
578#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 839#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c
index 6cba07e9f6..9405163706 100644
--- a/src/lib/libcrypto/bn/bn_add.c
+++ b/src/lib/libcrypto/bn/bn_add.c
@@ -64,7 +64,7 @@
64int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 64int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
65 { 65 {
66 const BIGNUM *tmp; 66 const BIGNUM *tmp;
67 int a_neg = a->neg; 67 int a_neg = a->neg, ret;
68 68
69 bn_check_top(a); 69 bn_check_top(a);
70 bn_check_top(b); 70 bn_check_top(b);
@@ -95,20 +95,17 @@ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
95 return(1); 95 return(1);
96 } 96 }
97 97
98 if (!BN_uadd(r,a,b)) return(0); 98 ret = BN_uadd(r,a,b);
99 if (a_neg) /* both are neg */ 99 r->neg = a_neg;
100 r->neg=1; 100 bn_check_top(r);
101 else 101 return ret;
102 r->neg=0;
103 return(1);
104 } 102 }
105 103
106/* unsigned add of b to a, r must be large enough */ 104/* unsigned add of b to a */
107int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 105int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
108 { 106 {
109 register int i; 107 int max,min,dif;
110 int max,min; 108 BN_ULONG *ap,*bp,*rp,carry,t1,t2;
111 BN_ULONG *ap,*bp,*rp,carry,t1;
112 const BIGNUM *tmp; 109 const BIGNUM *tmp;
113 110
114 bn_check_top(a); 111 bn_check_top(a);
@@ -116,11 +113,12 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
116 113
117 if (a->top < b->top) 114 if (a->top < b->top)
118 { tmp=a; a=b; b=tmp; } 115 { tmp=a; a=b; b=tmp; }
119 max=a->top; 116 max = a->top;
120 min=b->top; 117 min = b->top;
118 dif = max - min;
121 119
122 if (bn_wexpand(r,max+1) == NULL) 120 if (bn_wexpand(r,max+1) == NULL)
123 return(0); 121 return 0;
124 122
125 r->top=max; 123 r->top=max;
126 124
@@ -128,46 +126,46 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
128 ap=a->d; 126 ap=a->d;
129 bp=b->d; 127 bp=b->d;
130 rp=r->d; 128 rp=r->d;
131 carry=0;
132 129
133 carry=bn_add_words(rp,ap,bp,min); 130 carry=bn_add_words(rp,ap,bp,min);
134 rp+=min; 131 rp+=min;
135 ap+=min; 132 ap+=min;
136 bp+=min; 133 bp+=min;
137 i=min;
138 134
139 if (carry) 135 if (carry)
140 { 136 {
141 while (i < max) 137 while (dif)
142 { 138 {
143 i++; 139 dif--;
144 t1= *(ap++); 140 t1 = *(ap++);
145 if ((*(rp++)=(t1+1)&BN_MASK2) >= t1) 141 t2 = (t1+1) & BN_MASK2;
142 *(rp++) = t2;
143 if (t2)
146 { 144 {
147 carry=0; 145 carry=0;
148 break; 146 break;
149 } 147 }
150 } 148 }
151 if ((i >= max) && carry) 149 if (carry)
152 { 150 {
153 *(rp++)=1; 151 /* carry != 0 => dif == 0 */
152 *rp = 1;
154 r->top++; 153 r->top++;
155 } 154 }
156 } 155 }
157 if (rp != ap) 156 if (dif && rp != ap)
158 { 157 while (dif--)
159 for (; i<max; i++) 158 /* copy remaining words if ap != rp */
160 *(rp++)= *(ap++); 159 *(rp++) = *(ap++);
161 }
162 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
163 r->neg = 0; 160 r->neg = 0;
164 return(1); 161 bn_check_top(r);
162 return 1;
165 } 163 }
166 164
167/* unsigned subtraction of b from a, a must be larger than b. */ 165/* unsigned subtraction of b from a, a must be larger than b. */
168int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 166int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
169 { 167 {
170 int max,min; 168 int max,min,dif;
171 register BN_ULONG t1,t2,*ap,*bp,*rp; 169 register BN_ULONG t1,t2,*ap,*bp,*rp;
172 int i,carry; 170 int i,carry;
173#if defined(IRIX_CC_BUG) && !defined(LINT) 171#if defined(IRIX_CC_BUG) && !defined(LINT)
@@ -177,14 +175,16 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
177 bn_check_top(a); 175 bn_check_top(a);
178 bn_check_top(b); 176 bn_check_top(b);
179 177
180 if (a->top < b->top) /* hmm... should not be happening */ 178 max = a->top;
179 min = b->top;
180 dif = max - min;
181
182 if (dif < 0) /* hmm... should not be happening */
181 { 183 {
182 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3); 184 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
183 return(0); 185 return(0);
184 } 186 }
185 187
186 max=a->top;
187 min=b->top;
188 if (bn_wexpand(r,max) == NULL) return(0); 188 if (bn_wexpand(r,max) == NULL) return(0);
189 189
190 ap=a->d; 190 ap=a->d;
@@ -193,7 +193,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
193 193
194#if 1 194#if 1
195 carry=0; 195 carry=0;
196 for (i=0; i<min; i++) 196 for (i = min; i != 0; i--)
197 { 197 {
198 t1= *(ap++); 198 t1= *(ap++);
199 t2= *(bp++); 199 t2= *(bp++);
@@ -217,17 +217,20 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
217 ap+=min; 217 ap+=min;
218 bp+=min; 218 bp+=min;
219 rp+=min; 219 rp+=min;
220 i=min;
221#endif 220#endif
222 if (carry) /* subtracted */ 221 if (carry) /* subtracted */
223 { 222 {
224 while (i < max) 223 if (!dif)
224 /* error: a < b */
225 return 0;
226 while (dif)
225 { 227 {
226 i++; 228 dif--;
227 t1= *(ap++); 229 t1 = *(ap++);
228 t2=(t1-1)&BN_MASK2; 230 t2 = (t1-1)&BN_MASK2;
229 *(rp++)=t2; 231 *(rp++) = t2;
230 if (t1 > t2) break; 232 if (t1)
233 break;
231 } 234 }
232 } 235 }
233#if 0 236#if 0
@@ -237,13 +240,13 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
237 { 240 {
238 for (;;) 241 for (;;)
239 { 242 {
240 if (i++ >= max) break; 243 if (!dif--) break;
241 rp[0]=ap[0]; 244 rp[0]=ap[0];
242 if (i++ >= max) break; 245 if (!dif--) break;
243 rp[1]=ap[1]; 246 rp[1]=ap[1];
244 if (i++ >= max) break; 247 if (!dif--) break;
245 rp[2]=ap[2]; 248 rp[2]=ap[2];
246 if (i++ >= max) break; 249 if (!dif--) break;
247 rp[3]=ap[3]; 250 rp[3]=ap[3];
248 rp+=4; 251 rp+=4;
249 ap+=4; 252 ap+=4;
@@ -253,7 +256,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
253 256
254 r->top=max; 257 r->top=max;
255 r->neg=0; 258 r->neg=0;
256 bn_fix_top(r); 259 bn_correct_top(r);
257 return(1); 260 return(1);
258 } 261 }
259 262
@@ -304,6 +307,7 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
304 if (!BN_usub(r,a,b)) return(0); 307 if (!BN_usub(r,a,b)) return(0);
305 r->neg=0; 308 r->neg=0;
306 } 309 }
310 bn_check_top(r);
307 return(1); 311 return(1);
308 } 312 }
309 313
diff --git a/src/lib/libcrypto/bn/bn_asm.c b/src/lib/libcrypto/bn/bn_asm.c
index 19978085b2..99bc2de491 100644
--- a/src/lib/libcrypto/bn/bn_asm.c
+++ b/src/lib/libcrypto/bn/bn_asm.c
@@ -459,6 +459,34 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
459#define sqr_add_c2(a,i,j,c0,c1,c2) \ 459#define sqr_add_c2(a,i,j,c0,c1,c2) \
460 mul_add_c2((a)[i],(a)[j],c0,c1,c2) 460 mul_add_c2((a)[i],(a)[j],c0,c1,c2)
461 461
462#elif defined(BN_UMULT_LOHI)
463
464#define mul_add_c(a,b,c0,c1,c2) { \
465 BN_ULONG ta=(a),tb=(b); \
466 BN_UMULT_LOHI(t1,t2,ta,tb); \
467 c0 += t1; t2 += (c0<t1)?1:0; \
468 c1 += t2; c2 += (c1<t2)?1:0; \
469 }
470
471#define mul_add_c2(a,b,c0,c1,c2) { \
472 BN_ULONG ta=(a),tb=(b),t0; \
473 BN_UMULT_LOHI(t0,t1,ta,tb); \
474 t2 = t1+t1; c2 += (t2<t1)?1:0; \
475 t1 = t0+t0; t2 += (t1<t0)?1:0; \
476 c0 += t1; t2 += (c0<t1)?1:0; \
477 c1 += t2; c2 += (c1<t2)?1:0; \
478 }
479
480#define sqr_add_c(a,i,c0,c1,c2) { \
481 BN_ULONG ta=(a)[i]; \
482 BN_UMULT_LOHI(t1,t2,ta,ta); \
483 c0 += t1; t2 += (c0<t1)?1:0; \
484 c1 += t2; c2 += (c1<t2)?1:0; \
485 }
486
487#define sqr_add_c2(a,i,j,c0,c1,c2) \
488 mul_add_c2((a)[i],(a)[j],c0,c1,c2)
489
462#elif defined(BN_UMULT_HIGH) 490#elif defined(BN_UMULT_HIGH)
463 491
464#define mul_add_c(a,b,c0,c1,c2) { \ 492#define mul_add_c(a,b,c0,c1,c2) { \
diff --git a/src/lib/libcrypto/bn/bn_blind.c b/src/lib/libcrypto/bn/bn_blind.c
index 2d287e6d1b..c11fb4ccc2 100644
--- a/src/lib/libcrypto/bn/bn_blind.c
+++ b/src/lib/libcrypto/bn/bn_blind.c
@@ -1,4 +1,57 @@
1/* crypto/bn/bn_blind.c */ 1/* crypto/bn/bn_blind.c */
2/* ====================================================================
3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
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 *
54 */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 55/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 56 * All rights reserved.
4 * 57 *
@@ -60,11 +113,28 @@
60#include "cryptlib.h" 113#include "cryptlib.h"
61#include "bn_lcl.h" 114#include "bn_lcl.h"
62 115
63BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) 116#define BN_BLINDING_COUNTER 32
117
118struct bn_blinding_st
119 {
120 BIGNUM *A;
121 BIGNUM *Ai;
122 BIGNUM *e;
123 BIGNUM *mod; /* just a reference */
124 unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
125 * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
126 unsigned int counter;
127 unsigned long flags;
128 BN_MONT_CTX *m_ctx;
129 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
130 const BIGNUM *m, BN_CTX *ctx,
131 BN_MONT_CTX *m_ctx);
132 };
133
134BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod)
64 { 135 {
65 BN_BLINDING *ret=NULL; 136 BN_BLINDING *ret=NULL;
66 137
67 bn_check_top(Ai);
68 bn_check_top(mod); 138 bn_check_top(mod);
69 139
70 if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) 140 if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL)
@@ -73,11 +143,21 @@ BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod)
73 return(NULL); 143 return(NULL);
74 } 144 }
75 memset(ret,0,sizeof(BN_BLINDING)); 145 memset(ret,0,sizeof(BN_BLINDING));
76 if ((ret->A=BN_new()) == NULL) goto err; 146 if (A != NULL)
77 if ((ret->Ai=BN_new()) == NULL) goto err; 147 {
78 if (!BN_copy(ret->A,A)) goto err; 148 if ((ret->A = BN_dup(A)) == NULL) goto err;
79 if (!BN_copy(ret->Ai,Ai)) goto err; 149 }
80 ret->mod=mod; 150 if (Ai != NULL)
151 {
152 if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
153 }
154
155 /* save a copy of mod in the BN_BLINDING structure */
156 if ((ret->mod = BN_dup(mod)) == NULL) goto err;
157 if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
158 BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
159
160 ret->counter = BN_BLINDING_COUNTER;
81 return(ret); 161 return(ret);
82err: 162err:
83 if (ret != NULL) BN_BLINDING_free(ret); 163 if (ret != NULL) BN_BLINDING_free(ret);
@@ -91,6 +171,8 @@ void BN_BLINDING_free(BN_BLINDING *r)
91 171
92 if (r->A != NULL) BN_free(r->A ); 172 if (r->A != NULL) BN_free(r->A );
93 if (r->Ai != NULL) BN_free(r->Ai); 173 if (r->Ai != NULL) BN_free(r->Ai);
174 if (r->e != NULL) BN_free(r->e );
175 if (r->mod != NULL) BN_free(r->mod);
94 OPENSSL_free(r); 176 OPENSSL_free(r);
95 } 177 }
96 178
@@ -103,42 +185,181 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
103 BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED); 185 BNerr(BN_F_BN_BLINDING_UPDATE,BN_R_NOT_INITIALIZED);
104 goto err; 186 goto err;
105 } 187 }
106 188
107 if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err; 189 if (--(b->counter) == 0 && b->e != NULL &&
108 if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err; 190 !(b->flags & BN_BLINDING_NO_RECREATE))
191 {
192 /* re-create blinding parameters */
193 if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
194 goto err;
195 }
196 else if (!(b->flags & BN_BLINDING_NO_UPDATE))
197 {
198 if (!BN_mod_mul(b->A,b->A,b->A,b->mod,ctx)) goto err;
199 if (!BN_mod_mul(b->Ai,b->Ai,b->Ai,b->mod,ctx)) goto err;
200 }
109 201
110 ret=1; 202 ret=1;
111err: 203err:
204 if (b->counter == 0)
205 b->counter = BN_BLINDING_COUNTER;
112 return(ret); 206 return(ret);
113 } 207 }
114 208
115int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 209int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
116 { 210 {
211 return BN_BLINDING_convert_ex(n, NULL, b, ctx);
212 }
213
214int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
215 {
216 int ret = 1;
217
117 bn_check_top(n); 218 bn_check_top(n);
118 219
119 if ((b->A == NULL) || (b->Ai == NULL)) 220 if ((b->A == NULL) || (b->Ai == NULL))
120 { 221 {
121 BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITIALIZED); 222 BNerr(BN_F_BN_BLINDING_CONVERT_EX,BN_R_NOT_INITIALIZED);
122 return(0); 223 return(0);
123 } 224 }
124 return(BN_mod_mul(n,n,b->A,b->mod,ctx)); 225
226 if (r != NULL)
227 {
228 if (!BN_copy(r, b->Ai)) ret=0;
229 }
230
231 if (!BN_mod_mul(n,n,b->A,b->mod,ctx)) ret=0;
232
233 return ret;
125 } 234 }
126 235
127int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) 236int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
128 { 237 {
238 return BN_BLINDING_invert_ex(n, NULL, b, ctx);
239 }
240
241int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
242 {
129 int ret; 243 int ret;
130 244
131 bn_check_top(n); 245 bn_check_top(n);
132 if ((b->A == NULL) || (b->Ai == NULL)) 246 if ((b->A == NULL) || (b->Ai == NULL))
133 { 247 {
134 BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITIALIZED); 248 BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED);
135 return(0); 249 return(0);
136 } 250 }
137 if ((ret=BN_mod_mul(n,n,b->Ai,b->mod,ctx)) >= 0) 251
252 if (r != NULL)
253 ret = BN_mod_mul(n, n, r, b->mod, ctx);
254 else
255 ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
256
257 if (ret >= 0)
138 { 258 {
139 if (!BN_BLINDING_update(b,ctx)) 259 if (!BN_BLINDING_update(b,ctx))
140 return(0); 260 return(0);
141 } 261 }
262 bn_check_top(n);
142 return(ret); 263 return(ret);
143 } 264 }
144 265
266unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
267 {
268 return b->thread_id;
269 }
270
271void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
272 {
273 b->thread_id = n;
274 }
275
276unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
277 {
278 return b->flags;
279 }
280
281void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
282 {
283 b->flags = flags;
284 }
285
286BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
287 const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
288 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
289 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
290 BN_MONT_CTX *m_ctx)
291{
292 int retry_counter = 32;
293 BN_BLINDING *ret = NULL;
294
295 if (b == NULL)
296 ret = BN_BLINDING_new(NULL, NULL, m);
297 else
298 ret = b;
299
300 if (ret == NULL)
301 goto err;
302
303 if (ret->A == NULL && (ret->A = BN_new()) == NULL)
304 goto err;
305 if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
306 goto err;
307
308 if (e != NULL)
309 {
310 if (ret->e != NULL)
311 BN_free(ret->e);
312 ret->e = BN_dup(e);
313 }
314 if (ret->e == NULL)
315 goto err;
316
317 if (bn_mod_exp != NULL)
318 ret->bn_mod_exp = bn_mod_exp;
319 if (m_ctx != NULL)
320 ret->m_ctx = m_ctx;
321
322 do {
323 if (!BN_rand_range(ret->A, ret->mod)) goto err;
324 if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL)
325 {
326 /* this should almost never happen for good RSA keys */
327 unsigned long error = ERR_peek_last_error();
328 if (ERR_GET_REASON(error) == BN_R_NO_INVERSE)
329 {
330 if (retry_counter-- == 0)
331 {
332 BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
333 BN_R_TOO_MANY_ITERATIONS);
334 goto err;
335 }
336 ERR_clear_error();
337 }
338 else
339 goto err;
340 }
341 else
342 break;
343 } while (1);
344
345 if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL)
346 {
347 if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
348 goto err;
349 }
350 else
351 {
352 if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
353 goto err;
354 }
355
356 return ret;
357err:
358 if (b == NULL && ret != NULL)
359 {
360 BN_BLINDING_free(ret);
361 ret = NULL;
362 }
363
364 return ret;
365}
diff --git a/src/lib/libcrypto/bn/bn_ctx.c b/src/lib/libcrypto/bn/bn_ctx.c
index 7daf19eb84..b3452f1a91 100644
--- a/src/lib/libcrypto/bn/bn_ctx.c
+++ b/src/lib/libcrypto/bn/bn_ctx.c
@@ -1,7 +1,7 @@
1/* crypto/bn/bn_ctx.c */ 1/* crypto/bn/bn_ctx.c */
2/* Written by Ulf Moeller for the OpenSSL project. */ 2/* Written by Ulf Moeller for the OpenSSL project. */
3/* ==================================================================== 3/* ====================================================================
4 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 4 * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -54,9 +54,10 @@
54 * 54 *
55 */ 55 */
56 56
57#ifndef BN_CTX_DEBUG 57#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
58# undef NDEBUG /* avoid conflicting definitions */ 58#ifndef NDEBUG
59# define NDEBUG 59#define NDEBUG
60#endif
60#endif 61#endif
61 62
62#include <stdio.h> 63#include <stdio.h>
@@ -65,91 +66,389 @@
65#include "cryptlib.h" 66#include "cryptlib.h"
66#include "bn_lcl.h" 67#include "bn_lcl.h"
67 68
69/* TODO list
70 *
71 * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
72 * check they can be safely removed.
73 * - Check +1 and other ugliness in BN_from_montgomery()
74 *
75 * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
76 * appropriate 'block' size that will be honoured by bn_expand_internal() to
77 * prevent piddly little reallocations. OTOH, profiling bignum expansions in
78 * BN_CTX doesn't show this to be a big issue.
79 */
80
81/* How many bignums are in each "pool item"; */
82#define BN_CTX_POOL_SIZE 16
83/* The stack frame info is resizing, set a first-time expansion size; */
84#define BN_CTX_START_FRAMES 32
68 85
69BN_CTX *BN_CTX_new(void) 86/***********/
87/* BN_POOL */
88/***********/
89
90/* A bundle of bignums that can be linked with other bundles */
91typedef struct bignum_pool_item
92 {
93 /* The bignum values */
94 BIGNUM vals[BN_CTX_POOL_SIZE];
95 /* Linked-list admin */
96 struct bignum_pool_item *prev, *next;
97 } BN_POOL_ITEM;
98/* A linked-list of bignums grouped in bundles */
99typedef struct bignum_pool
100 {
101 /* Linked-list admin */
102 BN_POOL_ITEM *head, *current, *tail;
103 /* Stack depth and allocation size */
104 unsigned used, size;
105 } BN_POOL;
106static void BN_POOL_init(BN_POOL *);
107static void BN_POOL_finish(BN_POOL *);
108#ifndef OPENSSL_NO_DEPRECATED
109static void BN_POOL_reset(BN_POOL *);
110#endif
111static BIGNUM * BN_POOL_get(BN_POOL *);
112static void BN_POOL_release(BN_POOL *, unsigned int);
113
114/************/
115/* BN_STACK */
116/************/
117
118/* A wrapper to manage the "stack frames" */
119typedef struct bignum_ctx_stack
70 { 120 {
71 BN_CTX *ret; 121 /* Array of indexes into the bignum stack */
122 unsigned int *indexes;
123 /* Number of stack frames, and the size of the allocated array */
124 unsigned int depth, size;
125 } BN_STACK;
126static void BN_STACK_init(BN_STACK *);
127static void BN_STACK_finish(BN_STACK *);
128#ifndef OPENSSL_NO_DEPRECATED
129static void BN_STACK_reset(BN_STACK *);
130#endif
131static int BN_STACK_push(BN_STACK *, unsigned int);
132static unsigned int BN_STACK_pop(BN_STACK *);
133
134/**********/
135/* BN_CTX */
136/**********/
137
138/* The opaque BN_CTX type */
139struct bignum_ctx
140 {
141 /* The bignum bundles */
142 BN_POOL pool;
143 /* The "stack frames", if you will */
144 BN_STACK stack;
145 /* The number of bignums currently assigned */
146 unsigned int used;
147 /* Depth of stack overflow */
148 int err_stack;
149 /* Block "gets" until an "end" (compatibility behaviour) */
150 int too_many;
151 };
72 152
73 ret=(BN_CTX *)OPENSSL_malloc(sizeof(BN_CTX)); 153/* Enable this to find BN_CTX bugs */
74 if (ret == NULL) 154#ifdef BN_CTX_DEBUG
155static const char *ctxdbg_cur = NULL;
156static void ctxdbg(BN_CTX *ctx)
157 {
158 unsigned int bnidx = 0, fpidx = 0;
159 BN_POOL_ITEM *item = ctx->pool.head;
160 BN_STACK *stack = &ctx->stack;
161 fprintf(stderr,"(%08x): ", (unsigned int)ctx);
162 while(bnidx < ctx->used)
75 { 163 {
76 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); 164 fprintf(stderr,"%02x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
77 return(NULL); 165 if(!(bnidx % BN_CTX_POOL_SIZE))
166 item = item->next;
78 } 167 }
79 168 fprintf(stderr,"\n");
80 BN_CTX_init(ret); 169 bnidx = 0;
81 ret->flags=BN_FLG_MALLOCED; 170 fprintf(stderr," : ");
82 return(ret); 171 while(fpidx < stack->depth)
172 {
173 while(bnidx++ < stack->indexes[fpidx])
174 fprintf(stderr," ");
175 fprintf(stderr,"^^ ");
176 bnidx++;
177 fpidx++;
178 }
179 fprintf(stderr,"\n");
83 } 180 }
181#define CTXDBG_ENTRY(str, ctx) do { \
182 ctxdbg_cur = (str); \
183 fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
184 ctxdbg(ctx); \
185 } while(0)
186#define CTXDBG_EXIT(ctx) do { \
187 fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
188 ctxdbg(ctx); \
189 } while(0)
190#define CTXDBG_RET(ctx,ret)
191#else
192#define CTXDBG_ENTRY(str, ctx)
193#define CTXDBG_EXIT(ctx)
194#define CTXDBG_RET(ctx,ret)
195#endif
84 196
197/* This function is an evil legacy and should not be used. This implementation
198 * is WYSIWYG, though I've done my best. */
199#ifndef OPENSSL_NO_DEPRECATED
85void BN_CTX_init(BN_CTX *ctx) 200void BN_CTX_init(BN_CTX *ctx)
86 { 201 {
87#if 0 /* explicit version */ 202 /* Assume the caller obtained the context via BN_CTX_new() and so is
88 int i; 203 * trying to reset it for use. Nothing else makes sense, least of all
89 ctx->tos = 0; 204 * binary compatibility from a time when they could declare a static
90 ctx->flags = 0; 205 * variable. */
91 ctx->depth = 0; 206 BN_POOL_reset(&ctx->pool);
207 BN_STACK_reset(&ctx->stack);
208 ctx->used = 0;
209 ctx->err_stack = 0;
92 ctx->too_many = 0; 210 ctx->too_many = 0;
93 for (i = 0; i < BN_CTX_NUM; i++) 211 }
94 BN_init(&(ctx->bn[i]));
95#else
96 memset(ctx, 0, sizeof *ctx);
97#endif 212#endif
213
214BN_CTX *BN_CTX_new(void)
215 {
216 BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
217 if(!ret)
218 {
219 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
220 return NULL;
221 }
222 /* Initialise the structure */
223 BN_POOL_init(&ret->pool);
224 BN_STACK_init(&ret->stack);
225 ret->used = 0;
226 ret->err_stack = 0;
227 ret->too_many = 0;
228 return ret;
98 } 229 }
99 230
100void BN_CTX_free(BN_CTX *ctx) 231void BN_CTX_free(BN_CTX *ctx)
101 { 232 {
102 int i; 233 if (ctx == NULL)
103 234 return;
104 if (ctx == NULL) return; 235#ifdef BN_CTX_DEBUG
105 assert(ctx->depth == 0); 236 {
106 237 BN_POOL_ITEM *pool = ctx->pool.head;
107 for (i=0; i < BN_CTX_NUM; i++) 238 fprintf(stderr,"BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
108 BN_clear_free(&(ctx->bn[i])); 239 ctx->stack.size, ctx->pool.size);
109 if (ctx->flags & BN_FLG_MALLOCED) 240 fprintf(stderr,"dmaxs: ");
110 OPENSSL_free(ctx); 241 while(pool) {
242 unsigned loop = 0;
243 while(loop < BN_CTX_POOL_SIZE)
244 fprintf(stderr,"%02x ", pool->vals[loop++].dmax);
245 pool = pool->next;
246 }
247 fprintf(stderr,"\n");
248 }
249#endif
250 BN_STACK_finish(&ctx->stack);
251 BN_POOL_finish(&ctx->pool);
252 OPENSSL_free(ctx);
111 } 253 }
112 254
113void BN_CTX_start(BN_CTX *ctx) 255void BN_CTX_start(BN_CTX *ctx)
114 { 256 {
115 if (ctx->depth < BN_CTX_NUM_POS) 257 CTXDBG_ENTRY("BN_CTX_start", ctx);
116 ctx->pos[ctx->depth] = ctx->tos; 258 /* If we're already overflowing ... */
117 ctx->depth++; 259 if(ctx->err_stack || ctx->too_many)
260 ctx->err_stack++;
261 /* (Try to) get a new frame pointer */
262 else if(!BN_STACK_push(&ctx->stack, ctx->used))
263 {
264 BNerr(BN_F_BN_CTX_START,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
265 ctx->err_stack++;
266 }
267 CTXDBG_EXIT(ctx);
118 } 268 }
119 269
270void BN_CTX_end(BN_CTX *ctx)
271 {
272 CTXDBG_ENTRY("BN_CTX_end", ctx);
273 if(ctx->err_stack)
274 ctx->err_stack--;
275 else
276 {
277 unsigned int fp = BN_STACK_pop(&ctx->stack);
278 /* Does this stack frame have anything to release? */
279 if(fp < ctx->used)
280 BN_POOL_release(&ctx->pool, ctx->used - fp);
281 ctx->used = fp;
282 /* Unjam "too_many" in case "get" had failed */
283 ctx->too_many = 0;
284 }
285 CTXDBG_EXIT(ctx);
286 }
120 287
121BIGNUM *BN_CTX_get(BN_CTX *ctx) 288BIGNUM *BN_CTX_get(BN_CTX *ctx)
122 { 289 {
123 /* Note: If BN_CTX_get is ever changed to allocate BIGNUMs dynamically, 290 BIGNUM *ret;
124 * make sure that if BN_CTX_get fails once it will return NULL again 291 CTXDBG_ENTRY("BN_CTX_get", ctx);
125 * until BN_CTX_end is called. (This is so that callers have to check 292 if(ctx->err_stack || ctx->too_many) return NULL;
126 * only the last return value.) 293 if((ret = BN_POOL_get(&ctx->pool)) == NULL)
127 */ 294 {
128 if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM) 295 /* Setting too_many prevents repeated "get" attempts from
296 * cluttering the error stack. */
297 ctx->too_many = 1;
298 BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
299 return NULL;
300 }
301 /* OK, make sure the returned bignum is "zero" */
302 BN_zero(ret);
303 ctx->used++;
304 CTXDBG_RET(ctx, ret);
305 return ret;
306 }
307
308/************/
309/* BN_STACK */
310/************/
311
312static void BN_STACK_init(BN_STACK *st)
313 {
314 st->indexes = NULL;
315 st->depth = st->size = 0;
316 }
317
318static void BN_STACK_finish(BN_STACK *st)
319 {
320 if(st->size) OPENSSL_free(st->indexes);
321 }
322
323#ifndef OPENSSL_NO_DEPRECATED
324static void BN_STACK_reset(BN_STACK *st)
325 {
326 st->depth = 0;
327 }
328#endif
329
330static int BN_STACK_push(BN_STACK *st, unsigned int idx)
331 {
332 if(st->depth == st->size)
333 /* Need to expand */
334 {
335 unsigned int newsize = (st->size ?
336 (st->size * 3 / 2) : BN_CTX_START_FRAMES);
337 unsigned int *newitems = OPENSSL_malloc(newsize *
338 sizeof(unsigned int));
339 if(!newitems) return 0;
340 if(st->depth)
341 memcpy(newitems, st->indexes, st->depth *
342 sizeof(unsigned int));
343 if(st->size) OPENSSL_free(st->indexes);
344 st->indexes = newitems;
345 st->size = newsize;
346 }
347 st->indexes[(st->depth)++] = idx;
348 return 1;
349 }
350
351static unsigned int BN_STACK_pop(BN_STACK *st)
352 {
353 return st->indexes[--(st->depth)];
354 }
355
356/***********/
357/* BN_POOL */
358/***********/
359
360static void BN_POOL_init(BN_POOL *p)
361 {
362 p->head = p->current = p->tail = NULL;
363 p->used = p->size = 0;
364 }
365
366static void BN_POOL_finish(BN_POOL *p)
367 {
368 while(p->head)
129 { 369 {
130 if (!ctx->too_many) 370 unsigned int loop = 0;
371 BIGNUM *bn = p->head->vals;
372 while(loop++ < BN_CTX_POOL_SIZE)
131 { 373 {
132 BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES); 374 if(bn->d) BN_clear_free(bn);
133 /* disable error code until BN_CTX_end is called: */ 375 bn++;
134 ctx->too_many = 1;
135 } 376 }
136 return NULL; 377 p->current = p->head->next;
378 OPENSSL_free(p->head);
379 p->head = p->current;
137 } 380 }
138 return (&(ctx->bn[ctx->tos++]));
139 } 381 }
140 382
141void BN_CTX_end(BN_CTX *ctx) 383#ifndef OPENSSL_NO_DEPRECATED
384static void BN_POOL_reset(BN_POOL *p)
142 { 385 {
143 if (ctx == NULL) return; 386 BN_POOL_ITEM *item = p->head;
144 assert(ctx->depth > 0); 387 while(item)
145 if (ctx->depth == 0) 388 {
146 /* should never happen, but we can tolerate it if not in 389 unsigned int loop = 0;
147 * debug mode (could be a 'goto err' in the calling function 390 BIGNUM *bn = item->vals;
148 * before BN_CTX_start was reached) */ 391 while(loop++ < BN_CTX_POOL_SIZE)
149 BN_CTX_start(ctx); 392 {
393 if(bn->d) BN_clear(bn);
394 bn++;
395 }
396 item = item->next;
397 }
398 p->current = p->head;
399 p->used = 0;
400 }
401#endif
150 402
151 ctx->too_many = 0; 403static BIGNUM *BN_POOL_get(BN_POOL *p)
152 ctx->depth--; 404 {
153 if (ctx->depth < BN_CTX_NUM_POS) 405 if(p->used == p->size)
154 ctx->tos = ctx->pos[ctx->depth]; 406 {
407 BIGNUM *bn;
408 unsigned int loop = 0;
409 BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
410 if(!item) return NULL;
411 /* Initialise the structure */
412 bn = item->vals;
413 while(loop++ < BN_CTX_POOL_SIZE)
414 BN_init(bn++);
415 item->prev = p->tail;
416 item->next = NULL;
417 /* Link it in */
418 if(!p->head)
419 p->head = p->current = p->tail = item;
420 else
421 {
422 p->tail->next = item;
423 p->tail = item;
424 p->current = item;
425 }
426 p->size += BN_CTX_POOL_SIZE;
427 p->used++;
428 /* Return the first bignum from the new pool */
429 return item->vals;
430 }
431 if(!p->used)
432 p->current = p->head;
433 else if((p->used % BN_CTX_POOL_SIZE) == 0)
434 p->current = p->current->next;
435 return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
436 }
437
438static void BN_POOL_release(BN_POOL *p, unsigned int num)
439 {
440 unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
441 p->used -= num;
442 while(num--)
443 {
444 bn_check_top(p->current->vals + offset);
445 if(!offset)
446 {
447 offset = BN_CTX_POOL_SIZE - 1;
448 p->current = p->current->prev;
449 }
450 else
451 offset--;
452 }
155 } 453 }
454
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index 580d1201bc..8655eb118e 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -169,22 +169,31 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
169#endif /* OPENSSL_NO_ASM */ 169#endif /* OPENSSL_NO_ASM */
170 170
171 171
172/* BN_div computes dv := num / divisor, rounding towards zero, and sets up 172/* BN_div[_no_branch] computes dv := num / divisor, rounding towards
173 * rm such that dv*divisor + rm = num holds. 173 * zero, and sets up rm such that dv*divisor + rm = num holds.
174 * Thus: 174 * Thus:
175 * dv->neg == num->neg ^ divisor->neg (unless the result is zero) 175 * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
176 * rm->neg == num->neg (unless the remainder is zero) 176 * rm->neg == num->neg (unless the remainder is zero)
177 * If 'dv' or 'rm' is NULL, the respective value is not returned. 177 * If 'dv' or 'rm' is NULL, the respective value is not returned.
178 */ 178 */
179static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
180 const BIGNUM *divisor, BN_CTX *ctx);
179int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, 181int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
180 BN_CTX *ctx) 182 BN_CTX *ctx)
181 { 183 {
182 int norm_shift,i,j,loop; 184 int norm_shift,i,loop;
183 BIGNUM *tmp,wnum,*snum,*sdiv,*res; 185 BIGNUM *tmp,wnum,*snum,*sdiv,*res;
184 BN_ULONG *resp,*wnump; 186 BN_ULONG *resp,*wnump;
185 BN_ULONG d0,d1; 187 BN_ULONG d0,d1;
186 int num_n,div_n; 188 int num_n,div_n;
187 189
190 if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
191 {
192 return BN_div_no_branch(dv, rm, num, divisor, ctx);
193 }
194
195 bn_check_top(dv);
196 bn_check_top(rm);
188 bn_check_top(num); 197 bn_check_top(num);
189 bn_check_top(divisor); 198 bn_check_top(divisor);
190 199
@@ -210,7 +219,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
210 res=BN_CTX_get(ctx); 219 res=BN_CTX_get(ctx);
211 else res=dv; 220 else res=dv;
212 if (sdiv == NULL || res == NULL) goto err; 221 if (sdiv == NULL || res == NULL) goto err;
213 tmp->neg=0;
214 222
215 /* First we normalise the numbers */ 223 /* First we normalise the numbers */
216 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); 224 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
@@ -222,17 +230,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
222 div_n=sdiv->top; 230 div_n=sdiv->top;
223 num_n=snum->top; 231 num_n=snum->top;
224 loop=num_n-div_n; 232 loop=num_n-div_n;
225
226 /* Lets setup a 'window' into snum 233 /* Lets setup a 'window' into snum
227 * This is the part that corresponds to the current 234 * This is the part that corresponds to the current
228 * 'area' being divided */ 235 * 'area' being divided */
229 BN_init(&wnum); 236 wnum.neg = 0;
230 wnum.d= &(snum->d[loop]); 237 wnum.d = &(snum->d[loop]);
231 wnum.top= div_n; 238 wnum.top = div_n;
232 wnum.dmax= snum->dmax+1; /* a bit of a lie */ 239 /* only needed when BN_ucmp messes up the values between top and max */
240 wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
233 241
234 /* Get the top 2 words of sdiv */ 242 /* Get the top 2 words of sdiv */
235 /* i=sdiv->top; */ 243 /* div_n=sdiv->top; */
236 d0=sdiv->d[div_n-1]; 244 d0=sdiv->d[div_n-1];
237 d1=(div_n == 1)?0:sdiv->d[div_n-2]; 245 d1=(div_n == 1)?0:sdiv->d[div_n-2];
238 246
@@ -250,19 +258,28 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
250 258
251 if (BN_ucmp(&wnum,sdiv) >= 0) 259 if (BN_ucmp(&wnum,sdiv) >= 0)
252 { 260 {
253 if (!BN_usub(&wnum,&wnum,sdiv)) goto err; 261 /* If BN_DEBUG_RAND is defined BN_ucmp changes (via
262 * bn_pollute) the const bignum arguments =>
263 * clean the values between top and max again */
264 bn_clear_top2max(&wnum);
265 bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
254 *resp=1; 266 *resp=1;
255 res->d[res->top-1]=1;
256 } 267 }
257 else 268 else
258 res->top--; 269 res->top--;
270 /* if res->top == 0 then clear the neg value otherwise decrease
271 * the resp pointer */
259 if (res->top == 0) 272 if (res->top == 0)
260 res->neg = 0; 273 res->neg = 0;
261 resp--; 274 else
275 resp--;
262 276
263 for (i=0; i<loop-1; i++) 277 for (i=0; i<loop-1; i++, wnump--, resp--)
264 { 278 {
265 BN_ULONG q,l0; 279 BN_ULONG q,l0;
280 /* the first part of the loop uses the top two words of
281 * snum and sdiv to calculate a BN_ULONG q such that
282 * | wnum - sdiv * q | < sdiv */
266#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM) 283#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
267 BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG); 284 BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
268 q=bn_div_3_words(wnump,d1,d0); 285 q=bn_div_3_words(wnump,d1,d0);
@@ -346,27 +363,252 @@ X) -> 0x%08X\n",
346#endif /* !BN_DIV3W */ 363#endif /* !BN_DIV3W */
347 364
348 l0=bn_mul_words(tmp->d,sdiv->d,div_n,q); 365 l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
349 wnum.d--; wnum.top++;
350 tmp->d[div_n]=l0; 366 tmp->d[div_n]=l0;
351 for (j=div_n+1; j>0; j--) 367 wnum.d--;
352 if (tmp->d[j-1]) break; 368 /* ingore top values of the bignums just sub the two
353 tmp->top=j; 369 * BN_ULONG arrays with bn_sub_words */
370 if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
371 {
372 /* Note: As we have considered only the leading
373 * two BN_ULONGs in the calculation of q, sdiv * q
374 * might be greater than wnum (but then (q-1) * sdiv
375 * is less or equal than wnum)
376 */
377 q--;
378 if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
379 /* we can't have an overflow here (assuming
380 * that q != 0, but if q == 0 then tmp is
381 * zero anyway) */
382 (*wnump)++;
383 }
384 /* store part of the result */
385 *resp = q;
386 }
387 bn_correct_top(snum);
388 if (rm != NULL)
389 {
390 /* Keep a copy of the neg flag in num because if rm==num
391 * BN_rshift() will overwrite it.
392 */
393 int neg = num->neg;
394 BN_rshift(rm,snum,norm_shift);
395 if (!BN_is_zero(rm))
396 rm->neg = neg;
397 bn_check_top(rm);
398 }
399 BN_CTX_end(ctx);
400 return(1);
401err:
402 bn_check_top(rm);
403 BN_CTX_end(ctx);
404 return(0);
405 }
406
407
408/* BN_div_no_branch is a special version of BN_div. It does not contain
409 * branches that may leak sensitive information.
410 */
411static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
412 const BIGNUM *divisor, BN_CTX *ctx)
413 {
414 int norm_shift,i,loop;
415 BIGNUM *tmp,wnum,*snum,*sdiv,*res;
416 BN_ULONG *resp,*wnump;
417 BN_ULONG d0,d1;
418 int num_n,div_n;
419
420 bn_check_top(dv);
421 bn_check_top(rm);
422 bn_check_top(num);
423 bn_check_top(divisor);
424
425 if (BN_is_zero(divisor))
426 {
427 BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO);
428 return(0);
429 }
430
431 BN_CTX_start(ctx);
432 tmp=BN_CTX_get(ctx);
433 snum=BN_CTX_get(ctx);
434 sdiv=BN_CTX_get(ctx);
435 if (dv == NULL)
436 res=BN_CTX_get(ctx);
437 else res=dv;
438 if (sdiv == NULL || res == NULL) goto err;
439
440 /* First we normalise the numbers */
441 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
442 if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
443 sdiv->neg=0;
444 norm_shift+=BN_BITS2;
445 if (!(BN_lshift(snum,num,norm_shift))) goto err;
446 snum->neg=0;
447
448 /* Since we don't know whether snum is larger than sdiv,
449 * we pad snum with enough zeroes without changing its
450 * value.
451 */
452 if (snum->top <= sdiv->top+1)
453 {
454 if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
455 for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
456 snum->top = sdiv->top + 2;
457 }
458 else
459 {
460 if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
461 snum->d[snum->top] = 0;
462 snum->top ++;
463 }
464
465 div_n=sdiv->top;
466 num_n=snum->top;
467 loop=num_n-div_n;
468 /* Lets setup a 'window' into snum
469 * This is the part that corresponds to the current
470 * 'area' being divided */
471 wnum.neg = 0;
472 wnum.d = &(snum->d[loop]);
473 wnum.top = div_n;
474 /* only needed when BN_ucmp messes up the values between top and max */
475 wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
476
477 /* Get the top 2 words of sdiv */
478 /* div_n=sdiv->top; */
479 d0=sdiv->d[div_n-1];
480 d1=(div_n == 1)?0:sdiv->d[div_n-2];
481
482 /* pointer to the 'top' of snum */
483 wnump= &(snum->d[num_n-1]);
484
485 /* Setup to 'res' */
486 res->neg= (num->neg^divisor->neg);
487 if (!bn_wexpand(res,(loop+1))) goto err;
488 res->top=loop-1;
489 resp= &(res->d[loop-1]);
490
491 /* space for temp */
492 if (!bn_wexpand(tmp,(div_n+1))) goto err;
493
494 /* if res->top == 0 then clear the neg value otherwise decrease
495 * the resp pointer */
496 if (res->top == 0)
497 res->neg = 0;
498 else
499 resp--;
500
501 for (i=0; i<loop-1; i++, wnump--, resp--)
502 {
503 BN_ULONG q,l0;
504 /* the first part of the loop uses the top two words of
505 * snum and sdiv to calculate a BN_ULONG q such that
506 * | wnum - sdiv * q | < sdiv */
507#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
508 BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
509 q=bn_div_3_words(wnump,d1,d0);
510#else
511 BN_ULONG n0,n1,rem=0;
512
513 n0=wnump[0];
514 n1=wnump[-1];
515 if (n0 == d0)
516 q=BN_MASK2;
517 else /* n0 < d0 */
518 {
519#ifdef BN_LLONG
520 BN_ULLONG t2;
521
522#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
523 q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
524#else
525 q=bn_div_words(n0,n1,d0);
526#ifdef BN_DEBUG_LEVITTE
527 fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
528X) -> 0x%08X\n",
529 n0, n1, d0, q);
530#endif
531#endif
532
533#ifndef REMAINDER_IS_ALREADY_CALCULATED
534 /*
535 * rem doesn't have to be BN_ULLONG. The least we
536 * know it's less that d0, isn't it?
537 */
538 rem=(n1-q*d0)&BN_MASK2;
539#endif
540 t2=(BN_ULLONG)d1*q;
541
542 for (;;)
543 {
544 if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
545 break;
546 q--;
547 rem += d0;
548 if (rem < d0) break; /* don't let rem overflow */
549 t2 -= d1;
550 }
551#else /* !BN_LLONG */
552 BN_ULONG t2l,t2h,ql,qh;
553
554 q=bn_div_words(n0,n1,d0);
555#ifdef BN_DEBUG_LEVITTE
556 fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
557X) -> 0x%08X\n",
558 n0, n1, d0, q);
559#endif
560#ifndef REMAINDER_IS_ALREADY_CALCULATED
561 rem=(n1-q*d0)&BN_MASK2;
562#endif
354 563
355 j=wnum.top; 564#if defined(BN_UMULT_LOHI)
356 if (!BN_sub(&wnum,&wnum,tmp)) goto err; 565 BN_UMULT_LOHI(t2l,t2h,d1,q);
566#elif defined(BN_UMULT_HIGH)
567 t2l = d1 * q;
568 t2h = BN_UMULT_HIGH(d1,q);
569#else
570 t2l=LBITS(d1); t2h=HBITS(d1);
571 ql =LBITS(q); qh =HBITS(q);
572 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
573#endif
357 574
358 snum->top=snum->top+wnum.top-j; 575 for (;;)
576 {
577 if ((t2h < rem) ||
578 ((t2h == rem) && (t2l <= wnump[-2])))
579 break;
580 q--;
581 rem += d0;
582 if (rem < d0) break; /* don't let rem overflow */
583 if (t2l < d1) t2h--; t2l -= d1;
584 }
585#endif /* !BN_LLONG */
586 }
587#endif /* !BN_DIV3W */
359 588
360 if (wnum.neg) 589 l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
590 tmp->d[div_n]=l0;
591 wnum.d--;
592 /* ingore top values of the bignums just sub the two
593 * BN_ULONG arrays with bn_sub_words */
594 if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
361 { 595 {
596 /* Note: As we have considered only the leading
597 * two BN_ULONGs in the calculation of q, sdiv * q
598 * might be greater than wnum (but then (q-1) * sdiv
599 * is less or equal than wnum)
600 */
362 q--; 601 q--;
363 j=wnum.top; 602 if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
364 if (!BN_add(&wnum,&wnum,sdiv)) goto err; 603 /* we can't have an overflow here (assuming
365 snum->top+=wnum.top-j; 604 * that q != 0, but if q == 0 then tmp is
605 * zero anyway) */
606 (*wnump)++;
366 } 607 }
367 *(resp--)=q; 608 /* store part of the result */
368 wnump--; 609 *resp = q;
369 } 610 }
611 bn_correct_top(snum);
370 if (rm != NULL) 612 if (rm != NULL)
371 { 613 {
372 /* Keep a copy of the neg flag in num because if rm==num 614 /* Keep a copy of the neg flag in num because if rm==num
@@ -376,10 +618,13 @@ X) -> 0x%08X\n",
376 BN_rshift(rm,snum,norm_shift); 618 BN_rshift(rm,snum,norm_shift);
377 if (!BN_is_zero(rm)) 619 if (!BN_is_zero(rm))
378 rm->neg = neg; 620 rm->neg = neg;
621 bn_check_top(rm);
379 } 622 }
623 bn_correct_top(res);
380 BN_CTX_end(ctx); 624 BN_CTX_end(ctx);
381 return(1); 625 return(1);
382err: 626err:
627 bn_check_top(rm);
383 BN_CTX_end(ctx); 628 BN_CTX_end(ctx);
384 return(0); 629 return(0);
385 } 630 }
diff --git a/src/lib/libcrypto/bn/bn_err.c b/src/lib/libcrypto/bn/bn_err.c
index 5dfac00c88..cfe2eb94a0 100644
--- a/src/lib/libcrypto/bn/bn_err.c
+++ b/src/lib/libcrypto/bn/bn_err.c
@@ -1,6 +1,6 @@
1/* crypto/bn/bn_err.c */ 1/* crypto/bn/bn_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,18 +70,30 @@
70 70
71static ERR_STRING_DATA BN_str_functs[]= 71static ERR_STRING_DATA BN_str_functs[]=
72 { 72 {
73{ERR_FUNC(BN_F_BN_BLINDING_CONVERT), "BN_BLINDING_convert"}, 73{ERR_FUNC(BN_F_BNRAND), "BNRAND"},
74{ERR_FUNC(BN_F_BN_BLINDING_INVERT), "BN_BLINDING_invert"}, 74{ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"},
75{ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"},
76{ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"},
75{ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"}, 77{ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"},
76{ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"}, 78{ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"},
77{ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"}, 79{ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"},
78{ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"}, 80{ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"},
79{ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"}, 81{ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"},
80{ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, 82{ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"},
83{ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"},
81{ERR_FUNC(BN_F_BN_DIV), "BN_div"}, 84{ERR_FUNC(BN_F_BN_DIV), "BN_div"},
85{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"},
86{ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"},
82{ERR_FUNC(BN_F_BN_EXP), "BN_exp"}, 87{ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
83{ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"}, 88{ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"},
84{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"}, 89{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"},
90{ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
91{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
92{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
93{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"},
94{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
95{ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
96{ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
85{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"}, 97{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
86{ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"}, 98{ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
87{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"}, 99{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
@@ -89,6 +101,7 @@ static ERR_STRING_DATA BN_str_functs[]=
89{ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"}, 101{ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"},
90{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"}, 102{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"},
91{ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"}, 103{ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"},
104{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"},
92{ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"}, 105{ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"},
93{ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"}, 106{ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"},
94{ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"}, 107{ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"},
@@ -115,6 +128,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
115{ERR_REASON(BN_R_NOT_A_SQUARE) ,"not a square"}, 128{ERR_REASON(BN_R_NOT_A_SQUARE) ,"not a square"},
116{ERR_REASON(BN_R_NOT_INITIALIZED) ,"not initialized"}, 129{ERR_REASON(BN_R_NOT_INITIALIZED) ,"not initialized"},
117{ERR_REASON(BN_R_NO_INVERSE) ,"no inverse"}, 130{ERR_REASON(BN_R_NO_INVERSE) ,"no inverse"},
131{ERR_REASON(BN_R_NO_SOLUTION) ,"no solution"},
118{ERR_REASON(BN_R_P_IS_NOT_PRIME) ,"p is not prime"}, 132{ERR_REASON(BN_R_P_IS_NOT_PRIME) ,"p is not prime"},
119{ERR_REASON(BN_R_TOO_MANY_ITERATIONS) ,"too many iterations"}, 133{ERR_REASON(BN_R_TOO_MANY_ITERATIONS) ,"too many iterations"},
120{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),"too many temporary variables"}, 134{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),"too many temporary variables"},
@@ -125,15 +139,12 @@ static ERR_STRING_DATA BN_str_reasons[]=
125 139
126void ERR_load_BN_strings(void) 140void ERR_load_BN_strings(void)
127 { 141 {
128 static int init=1; 142#ifndef OPENSSL_NO_ERR
129 143
130 if (init) 144 if (ERR_func_error_string(BN_str_functs[0].error) == NULL)
131 { 145 {
132 init=0;
133#ifndef OPENSSL_NO_ERR
134 ERR_load_strings(0,BN_str_functs); 146 ERR_load_strings(0,BN_str_functs);
135 ERR_load_strings(0,BN_str_reasons); 147 ERR_load_strings(0,BN_str_reasons);
136#endif
137
138 } 148 }
149#endif
139 } 150 }
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index 9e1e88abe8..70a33f0d93 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -122,9 +122,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
122 int i,bits,ret=0; 122 int i,bits,ret=0;
123 BIGNUM *v,*rr; 123 BIGNUM *v,*rr;
124 124
125 if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) 125 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
126 { 126 {
127 /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ 127 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
128 BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 128 BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
129 return -1; 129 return -1;
130 } 130 }
@@ -155,6 +155,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
155err: 155err:
156 if (r != rr) BN_copy(r,rr); 156 if (r != rr) BN_copy(r,rr);
157 BN_CTX_end(ctx); 157 BN_CTX_end(ctx);
158 bn_check_top(r);
158 return(ret); 159 return(ret);
159 } 160 }
160 161
@@ -212,7 +213,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
212 if (BN_is_odd(m)) 213 if (BN_is_odd(m))
213 { 214 {
214# ifdef MONT_EXP_WORD 215# ifdef MONT_EXP_WORD
215 if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0)) 216 if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
216 { 217 {
217 BN_ULONG A = a->d[0]; 218 BN_ULONG A = a->d[0];
218 ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL); 219 ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
@@ -229,6 +230,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
229 { ret=BN_mod_exp_simple(r,a,p,m,ctx); } 230 { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
230#endif 231#endif
231 232
233 bn_check_top(r);
232 return(ret); 234 return(ret);
233 } 235 }
234 236
@@ -237,14 +239,15 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
237 const BIGNUM *m, BN_CTX *ctx) 239 const BIGNUM *m, BN_CTX *ctx)
238 { 240 {
239 int i,j,bits,ret=0,wstart,wend,window,wvalue; 241 int i,j,bits,ret=0,wstart,wend,window,wvalue;
240 int start=1,ts=0; 242 int start=1;
241 BIGNUM *aa; 243 BIGNUM *aa;
242 BIGNUM val[TABLE_SIZE]; 244 /* Table of variables obtained from 'ctx' */
245 BIGNUM *val[TABLE_SIZE];
243 BN_RECP_CTX recp; 246 BN_RECP_CTX recp;
244 247
245 if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) 248 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
246 { 249 {
247 /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ 250 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
248 BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 251 BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
249 return -1; 252 return -1;
250 } 253 }
@@ -258,7 +261,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
258 } 261 }
259 262
260 BN_CTX_start(ctx); 263 BN_CTX_start(ctx);
261 if ((aa = BN_CTX_get(ctx)) == NULL) goto err; 264 aa = BN_CTX_get(ctx);
265 val[0] = BN_CTX_get(ctx);
266 if(!aa || !val[0]) goto err;
262 267
263 BN_RECP_CTX_init(&recp); 268 BN_RECP_CTX_init(&recp);
264 if (m->neg) 269 if (m->neg)
@@ -273,29 +278,27 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
273 if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; 278 if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
274 } 279 }
275 280
276 BN_init(&(val[0])); 281 if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */
277 ts=1; 282 if (BN_is_zero(val[0]))
278
279 if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */
280 if (BN_is_zero(&(val[0])))
281 { 283 {
282 ret = BN_zero(r); 284 BN_zero(r);
285 ret = 1;
283 goto err; 286 goto err;
284 } 287 }
285 288
286 window = BN_window_bits_for_exponent_size(bits); 289 window = BN_window_bits_for_exponent_size(bits);
287 if (window > 1) 290 if (window > 1)
288 { 291 {
289 if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx)) 292 if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
290 goto err; /* 2 */ 293 goto err; /* 2 */
291 j=1<<(window-1); 294 j=1<<(window-1);
292 for (i=1; i<j; i++) 295 for (i=1; i<j; i++)
293 { 296 {
294 BN_init(&val[i]); 297 if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
295 if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx)) 298 !BN_mod_mul_reciprocal(val[i],val[i-1],
299 aa,&recp,ctx))
296 goto err; 300 goto err;
297 } 301 }
298 ts=i;
299 } 302 }
300 303
301 start=1; /* This is used to avoid multiplication etc 304 start=1; /* This is used to avoid multiplication etc
@@ -347,7 +350,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
347 } 350 }
348 351
349 /* wvalue will be an odd number < 2^window */ 352 /* wvalue will be an odd number < 2^window */
350 if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx)) 353 if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx))
351 goto err; 354 goto err;
352 355
353 /* move the 'window' down further */ 356 /* move the 'window' down further */
@@ -359,9 +362,8 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
359 ret=1; 362 ret=1;
360err: 363err:
361 BN_CTX_end(ctx); 364 BN_CTX_end(ctx);
362 for (i=0; i<ts; i++)
363 BN_clear_free(&(val[i]));
364 BN_RECP_CTX_free(&recp); 365 BN_RECP_CTX_free(&recp);
366 bn_check_top(r);
365 return(ret); 367 return(ret);
366 } 368 }
367 369
@@ -370,13 +372,14 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
370 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 372 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
371 { 373 {
372 int i,j,bits,ret=0,wstart,wend,window,wvalue; 374 int i,j,bits,ret=0,wstart,wend,window,wvalue;
373 int start=1,ts=0; 375 int start=1;
374 BIGNUM *d,*r; 376 BIGNUM *d,*r;
375 const BIGNUM *aa; 377 const BIGNUM *aa;
376 BIGNUM val[TABLE_SIZE]; 378 /* Table of variables obtained from 'ctx' */
379 BIGNUM *val[TABLE_SIZE];
377 BN_MONT_CTX *mont=NULL; 380 BN_MONT_CTX *mont=NULL;
378 381
379 if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) 382 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
380 { 383 {
381 return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); 384 return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
382 } 385 }
@@ -385,7 +388,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
385 bn_check_top(p); 388 bn_check_top(p);
386 bn_check_top(m); 389 bn_check_top(m);
387 390
388 if (!(m->d[0] & 1)) 391 if (!BN_is_odd(m))
389 { 392 {
390 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); 393 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
391 return(0); 394 return(0);
@@ -400,7 +403,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
400 BN_CTX_start(ctx); 403 BN_CTX_start(ctx);
401 d = BN_CTX_get(ctx); 404 d = BN_CTX_get(ctx);
402 r = BN_CTX_get(ctx); 405 r = BN_CTX_get(ctx);
403 if (d == NULL || r == NULL) goto err; 406 val[0] = BN_CTX_get(ctx);
407 if (!d || !r || !val[0]) goto err;
404 408
405 /* If this is not done, things will break in the montgomery 409 /* If this is not done, things will break in the montgomery
406 * part */ 410 * part */
@@ -413,35 +417,34 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
413 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 417 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
414 } 418 }
415 419
416 BN_init(&val[0]);
417 ts=1;
418 if (a->neg || BN_ucmp(a,m) >= 0) 420 if (a->neg || BN_ucmp(a,m) >= 0)
419 { 421 {
420 if (!BN_nnmod(&(val[0]),a,m,ctx)) 422 if (!BN_nnmod(val[0],a,m,ctx))
421 goto err; 423 goto err;
422 aa= &(val[0]); 424 aa= val[0];
423 } 425 }
424 else 426 else
425 aa=a; 427 aa=a;
426 if (BN_is_zero(aa)) 428 if (BN_is_zero(aa))
427 { 429 {
428 ret = BN_zero(rr); 430 BN_zero(rr);
431 ret = 1;
429 goto err; 432 goto err;
430 } 433 }
431 if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */ 434 if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
432 435
433 window = BN_window_bits_for_exponent_size(bits); 436 window = BN_window_bits_for_exponent_size(bits);
434 if (window > 1) 437 if (window > 1)
435 { 438 {
436 if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */ 439 if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */
437 j=1<<(window-1); 440 j=1<<(window-1);
438 for (i=1; i<j; i++) 441 for (i=1; i<j; i++)
439 { 442 {
440 BN_init(&(val[i])); 443 if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
441 if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx)) 444 !BN_mod_mul_montgomery(val[i],val[i-1],
445 d,mont,ctx))
442 goto err; 446 goto err;
443 } 447 }
444 ts=i;
445 } 448 }
446 449
447 start=1; /* This is used to avoid multiplication etc 450 start=1; /* This is used to avoid multiplication etc
@@ -494,7 +497,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
494 } 497 }
495 498
496 /* wvalue will be an odd number < 2^window */ 499 /* wvalue will be an odd number < 2^window */
497 if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx)) 500 if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx))
498 goto err; 501 goto err;
499 502
500 /* move the 'window' down further */ 503 /* move the 'window' down further */
@@ -508,8 +511,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
508err: 511err:
509 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 512 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
510 BN_CTX_end(ctx); 513 BN_CTX_end(ctx);
511 for (i=0; i<ts; i++) 514 bn_check_top(rr);
512 BN_clear_free(&(val[i]));
513 return(ret); 515 return(ret);
514 } 516 }
515 517
@@ -535,7 +537,7 @@ static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf,
535 buf[j] = ((unsigned char*)b->d)[i]; 537 buf[j] = ((unsigned char*)b->d)[i];
536 } 538 }
537 539
538 bn_fix_top(b); 540 bn_correct_top(b);
539 return 1; 541 return 1;
540 } 542 }
541 543
@@ -552,7 +554,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf
552 } 554 }
553 555
554 b->top = top; 556 b->top = top;
555 bn_fix_top(b); 557 bn_correct_top(b);
556 return 1; 558 return 1;
557 } 559 }
558 560
@@ -743,9 +745,9 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
743#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ 745#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
744 (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) 746 (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
745 747
746 if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) 748 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
747 { 749 {
748 /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ 750 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
749 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 751 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
750 return -1; 752 return -1;
751 } 753 }
@@ -753,7 +755,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
753 bn_check_top(p); 755 bn_check_top(p);
754 bn_check_top(m); 756 bn_check_top(m);
755 757
756 if (m->top == 0 || !(m->d[0] & 1)) 758 if (!BN_is_odd(m))
757 { 759 {
758 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS); 760 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
759 return(0); 761 return(0);
@@ -769,7 +771,8 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
769 } 771 }
770 if (a == 0) 772 if (a == 0)
771 { 773 {
772 ret = BN_zero(rr); 774 BN_zero(rr);
775 ret = 1;
773 return ret; 776 return ret;
774 } 777 }
775 778
@@ -863,23 +866,24 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
863err: 866err:
864 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 867 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
865 BN_CTX_end(ctx); 868 BN_CTX_end(ctx);
869 bn_check_top(rr);
866 return(ret); 870 return(ret);
867 } 871 }
868 872
869 873
870/* The old fallback, simple version :-) */ 874/* The old fallback, simple version :-) */
871int BN_mod_exp_simple(BIGNUM *r, 875int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
872 const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, 876 const BIGNUM *m, BN_CTX *ctx)
873 BN_CTX *ctx)
874 { 877 {
875 int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0; 878 int i,j,bits,ret=0,wstart,wend,window,wvalue;
876 int start=1; 879 int start=1;
877 BIGNUM *d; 880 BIGNUM *d;
878 BIGNUM val[TABLE_SIZE]; 881 /* Table of variables obtained from 'ctx' */
882 BIGNUM *val[TABLE_SIZE];
879 883
880 if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) 884 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
881 { 885 {
882 /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ 886 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
883 BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 887 BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
884 return -1; 888 return -1;
885 } 889 }
@@ -893,30 +897,30 @@ int BN_mod_exp_simple(BIGNUM *r,
893 } 897 }
894 898
895 BN_CTX_start(ctx); 899 BN_CTX_start(ctx);
896 if ((d = BN_CTX_get(ctx)) == NULL) goto err; 900 d = BN_CTX_get(ctx);
901 val[0] = BN_CTX_get(ctx);
902 if(!d || !val[0]) goto err;
897 903
898 BN_init(&(val[0])); 904 if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */
899 ts=1; 905 if (BN_is_zero(val[0]))
900 if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err; /* 1 */
901 if (BN_is_zero(&(val[0])))
902 { 906 {
903 ret = BN_zero(r); 907 BN_zero(r);
908 ret = 1;
904 goto err; 909 goto err;
905 } 910 }
906 911
907 window = BN_window_bits_for_exponent_size(bits); 912 window = BN_window_bits_for_exponent_size(bits);
908 if (window > 1) 913 if (window > 1)
909 { 914 {
910 if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx)) 915 if (!BN_mod_mul(d,val[0],val[0],m,ctx))
911 goto err; /* 2 */ 916 goto err; /* 2 */
912 j=1<<(window-1); 917 j=1<<(window-1);
913 for (i=1; i<j; i++) 918 for (i=1; i<j; i++)
914 { 919 {
915 BN_init(&(val[i])); 920 if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
916 if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx)) 921 !BN_mod_mul(val[i],val[i-1],d,m,ctx))
917 goto err; 922 goto err;
918 } 923 }
919 ts=i;
920 } 924 }
921 925
922 start=1; /* This is used to avoid multiplication etc 926 start=1; /* This is used to avoid multiplication etc
@@ -968,7 +972,7 @@ int BN_mod_exp_simple(BIGNUM *r,
968 } 972 }
969 973
970 /* wvalue will be an odd number < 2^window */ 974 /* wvalue will be an odd number < 2^window */
971 if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx)) 975 if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx))
972 goto err; 976 goto err;
973 977
974 /* move the 'window' down further */ 978 /* move the 'window' down further */
@@ -980,8 +984,7 @@ int BN_mod_exp_simple(BIGNUM *r,
980 ret=1; 984 ret=1;
981err: 985err:
982 BN_CTX_end(ctx); 986 BN_CTX_end(ctx);
983 for (i=0; i<ts; i++) 987 bn_check_top(r);
984 BN_clear_free(&(val[i]));
985 return(ret); 988 return(ret);
986 } 989 }
987 990
diff --git a/src/lib/libcrypto/bn/bn_exp2.c b/src/lib/libcrypto/bn/bn_exp2.c
index 73ccd58a83..b3f43cec8c 100644
--- a/src/lib/libcrypto/bn/bn_exp2.c
+++ b/src/lib/libcrypto/bn/bn_exp2.c
@@ -120,10 +120,11 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
120 BN_CTX *ctx, BN_MONT_CTX *in_mont) 120 BN_CTX *ctx, BN_MONT_CTX *in_mont)
121 { 121 {
122 int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2; 122 int i,j,bits,b,bits1,bits2,ret=0,wpos1,wpos2,window1,window2,wvalue1,wvalue2;
123 int r_is_one=1,ts1=0,ts2=0; 123 int r_is_one=1;
124 BIGNUM *d,*r; 124 BIGNUM *d,*r;
125 const BIGNUM *a_mod_m; 125 const BIGNUM *a_mod_m;
126 BIGNUM val1[TABLE_SIZE], val2[TABLE_SIZE]; 126 /* Tables of variables obtained from 'ctx' */
127 BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
127 BN_MONT_CTX *mont=NULL; 128 BN_MONT_CTX *mont=NULL;
128 129
129 bn_check_top(a1); 130 bn_check_top(a1);
@@ -150,7 +151,9 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
150 BN_CTX_start(ctx); 151 BN_CTX_start(ctx);
151 d = BN_CTX_get(ctx); 152 d = BN_CTX_get(ctx);
152 r = BN_CTX_get(ctx); 153 r = BN_CTX_get(ctx);
153 if (d == NULL || r == NULL) goto err; 154 val1[0] = BN_CTX_get(ctx);
155 val2[0] = BN_CTX_get(ctx);
156 if(!d || !r || !val1[0] || !val2[0]) goto err;
154 157
155 if (in_mont != NULL) 158 if (in_mont != NULL)
156 mont=in_mont; 159 mont=in_mont;
@@ -166,69 +169,67 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
166 /* 169 /*
167 * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1) 170 * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1)
168 */ 171 */
169 BN_init(&val1[0]);
170 ts1=1;
171 if (a1->neg || BN_ucmp(a1,m) >= 0) 172 if (a1->neg || BN_ucmp(a1,m) >= 0)
172 { 173 {
173 if (!BN_mod(&(val1[0]),a1,m,ctx)) 174 if (!BN_mod(val1[0],a1,m,ctx))
174 goto err; 175 goto err;
175 a_mod_m = &(val1[0]); 176 a_mod_m = val1[0];
176 } 177 }
177 else 178 else
178 a_mod_m = a1; 179 a_mod_m = a1;
179 if (BN_is_zero(a_mod_m)) 180 if (BN_is_zero(a_mod_m))
180 { 181 {
181 ret = BN_zero(rr); 182 BN_zero(rr);
183 ret = 1;
182 goto err; 184 goto err;
183 } 185 }
184 186
185 if (!BN_to_montgomery(&(val1[0]),a_mod_m,mont,ctx)) goto err; 187 if (!BN_to_montgomery(val1[0],a_mod_m,mont,ctx)) goto err;
186 if (window1 > 1) 188 if (window1 > 1)
187 { 189 {
188 if (!BN_mod_mul_montgomery(d,&(val1[0]),&(val1[0]),mont,ctx)) goto err; 190 if (!BN_mod_mul_montgomery(d,val1[0],val1[0],mont,ctx)) goto err;
189 191
190 j=1<<(window1-1); 192 j=1<<(window1-1);
191 for (i=1; i<j; i++) 193 for (i=1; i<j; i++)
192 { 194 {
193 BN_init(&(val1[i])); 195 if(((val1[i] = BN_CTX_get(ctx)) == NULL) ||
194 if (!BN_mod_mul_montgomery(&(val1[i]),&(val1[i-1]),d,mont,ctx)) 196 !BN_mod_mul_montgomery(val1[i],val1[i-1],
197 d,mont,ctx))
195 goto err; 198 goto err;
196 } 199 }
197 ts1=i;
198 } 200 }
199 201
200 202
201 /* 203 /*
202 * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1) 204 * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1)
203 */ 205 */
204 BN_init(&val2[0]);
205 ts2=1;
206 if (a2->neg || BN_ucmp(a2,m) >= 0) 206 if (a2->neg || BN_ucmp(a2,m) >= 0)
207 { 207 {
208 if (!BN_mod(&(val2[0]),a2,m,ctx)) 208 if (!BN_mod(val2[0],a2,m,ctx))
209 goto err; 209 goto err;
210 a_mod_m = &(val2[0]); 210 a_mod_m = val2[0];
211 } 211 }
212 else 212 else
213 a_mod_m = a2; 213 a_mod_m = a2;
214 if (BN_is_zero(a_mod_m)) 214 if (BN_is_zero(a_mod_m))
215 { 215 {
216 ret = BN_zero(rr); 216 BN_zero(rr);
217 ret = 1;
217 goto err; 218 goto err;
218 } 219 }
219 if (!BN_to_montgomery(&(val2[0]),a_mod_m,mont,ctx)) goto err; 220 if (!BN_to_montgomery(val2[0],a_mod_m,mont,ctx)) goto err;
220 if (window2 > 1) 221 if (window2 > 1)
221 { 222 {
222 if (!BN_mod_mul_montgomery(d,&(val2[0]),&(val2[0]),mont,ctx)) goto err; 223 if (!BN_mod_mul_montgomery(d,val2[0],val2[0],mont,ctx)) goto err;
223 224
224 j=1<<(window2-1); 225 j=1<<(window2-1);
225 for (i=1; i<j; i++) 226 for (i=1; i<j; i++)
226 { 227 {
227 BN_init(&(val2[i])); 228 if(((val2[i] = BN_CTX_get(ctx)) == NULL) ||
228 if (!BN_mod_mul_montgomery(&(val2[i]),&(val2[i-1]),d,mont,ctx)) 229 !BN_mod_mul_montgomery(val2[i],val2[i-1],
230 d,mont,ctx))
229 goto err; 231 goto err;
230 } 232 }
231 ts2=i;
232 } 233 }
233 234
234 235
@@ -285,7 +286,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
285 if (wvalue1 && b == wpos1) 286 if (wvalue1 && b == wpos1)
286 { 287 {
287 /* wvalue1 is odd and < 2^window1 */ 288 /* wvalue1 is odd and < 2^window1 */
288 if (!BN_mod_mul_montgomery(r,r,&(val1[wvalue1>>1]),mont,ctx)) 289 if (!BN_mod_mul_montgomery(r,r,val1[wvalue1>>1],mont,ctx))
289 goto err; 290 goto err;
290 wvalue1 = 0; 291 wvalue1 = 0;
291 r_is_one = 0; 292 r_is_one = 0;
@@ -294,7 +295,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
294 if (wvalue2 && b == wpos2) 295 if (wvalue2 && b == wpos2)
295 { 296 {
296 /* wvalue2 is odd and < 2^window2 */ 297 /* wvalue2 is odd and < 2^window2 */
297 if (!BN_mod_mul_montgomery(r,r,&(val2[wvalue2>>1]),mont,ctx)) 298 if (!BN_mod_mul_montgomery(r,r,val2[wvalue2>>1],mont,ctx))
298 goto err; 299 goto err;
299 wvalue2 = 0; 300 wvalue2 = 0;
300 r_is_one = 0; 301 r_is_one = 0;
@@ -305,9 +306,6 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
305err: 306err:
306 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 307 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
307 BN_CTX_end(ctx); 308 BN_CTX_end(ctx);
308 for (i=0; i<ts1; i++) 309 bn_check_top(rr);
309 BN_clear_free(&(val1[i]));
310 for (i=0; i<ts2; i++)
311 BN_clear_free(&(val2[i]));
312 return(ret); 310 return(ret);
313 } 311 }
diff --git a/src/lib/libcrypto/bn/bn_gcd.c b/src/lib/libcrypto/bn/bn_gcd.c
index 7649f63fd2..4a352119ba 100644
--- a/src/lib/libcrypto/bn/bn_gcd.c
+++ b/src/lib/libcrypto/bn/bn_gcd.c
@@ -140,6 +140,7 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
140 ret=1; 140 ret=1;
141err: 141err:
142 BN_CTX_end(ctx); 142 BN_CTX_end(ctx);
143 bn_check_top(r);
143 return(ret); 144 return(ret);
144 } 145 }
145 146
@@ -194,6 +195,7 @@ static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
194 { 195 {
195 if (!BN_lshift(a,a,shifts)) goto err; 196 if (!BN_lshift(a,a,shifts)) goto err;
196 } 197 }
198 bn_check_top(a);
197 return(a); 199 return(a);
198err: 200err:
199 return(NULL); 201 return(NULL);
@@ -201,6 +203,8 @@ err:
201 203
202 204
203/* solves ax == 1 (mod n) */ 205/* solves ax == 1 (mod n) */
206static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
207 const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
204BIGNUM *BN_mod_inverse(BIGNUM *in, 208BIGNUM *BN_mod_inverse(BIGNUM *in,
205 const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) 209 const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
206 { 210 {
@@ -208,6 +212,11 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
208 BIGNUM *ret=NULL; 212 BIGNUM *ret=NULL;
209 int sign; 213 int sign;
210 214
215 if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
216 {
217 return BN_mod_inverse_no_branch(in, a, n, ctx);
218 }
219
211 bn_check_top(a); 220 bn_check_top(a);
212 bn_check_top(n); 221 bn_check_top(n);
213 222
@@ -486,5 +495,160 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
486err: 495err:
487 if ((ret == NULL) && (in == NULL)) BN_free(R); 496 if ((ret == NULL) && (in == NULL)) BN_free(R);
488 BN_CTX_end(ctx); 497 BN_CTX_end(ctx);
498 bn_check_top(ret);
499 return(ret);
500 }
501
502
503/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
504 * It does not contain branches that may leak sensitive information.
505 */
506static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
507 const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
508 {
509 BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
510 BIGNUM local_A, local_B;
511 BIGNUM *pA, *pB;
512 BIGNUM *ret=NULL;
513 int sign;
514
515 bn_check_top(a);
516 bn_check_top(n);
517
518 BN_CTX_start(ctx);
519 A = BN_CTX_get(ctx);
520 B = BN_CTX_get(ctx);
521 X = BN_CTX_get(ctx);
522 D = BN_CTX_get(ctx);
523 M = BN_CTX_get(ctx);
524 Y = BN_CTX_get(ctx);
525 T = BN_CTX_get(ctx);
526 if (T == NULL) goto err;
527
528 if (in == NULL)
529 R=BN_new();
530 else
531 R=in;
532 if (R == NULL) goto err;
533
534 BN_one(X);
535 BN_zero(Y);
536 if (BN_copy(B,a) == NULL) goto err;
537 if (BN_copy(A,n) == NULL) goto err;
538 A->neg = 0;
539
540 if (B->neg || (BN_ucmp(B, A) >= 0))
541 {
542 /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
543 * BN_div_no_branch will be called eventually.
544 */
545 pB = &local_B;
546 BN_with_flags(pB, B, BN_FLG_CONSTTIME);
547 if (!BN_nnmod(B, pB, A, ctx)) goto err;
548 }
549 sign = -1;
550 /* From B = a mod |n|, A = |n| it follows that
551 *
552 * 0 <= B < A,
553 * -sign*X*a == B (mod |n|),
554 * sign*Y*a == A (mod |n|).
555 */
556
557 while (!BN_is_zero(B))
558 {
559 BIGNUM *tmp;
560
561 /*
562 * 0 < B < A,
563 * (*) -sign*X*a == B (mod |n|),
564 * sign*Y*a == A (mod |n|)
565 */
566
567 /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
568 * BN_div_no_branch will be called eventually.
569 */
570 pA = &local_A;
571 BN_with_flags(pA, A, BN_FLG_CONSTTIME);
572
573 /* (D, M) := (A/B, A%B) ... */
574 if (!BN_div(D,M,pA,B,ctx)) goto err;
575
576 /* Now
577 * A = D*B + M;
578 * thus we have
579 * (**) sign*Y*a == D*B + M (mod |n|).
580 */
581
582 tmp=A; /* keep the BIGNUM object, the value does not matter */
583
584 /* (A, B) := (B, A mod B) ... */
585 A=B;
586 B=M;
587 /* ... so we have 0 <= B < A again */
588
589 /* Since the former M is now B and the former B is now A,
590 * (**) translates into
591 * sign*Y*a == D*A + B (mod |n|),
592 * i.e.
593 * sign*Y*a - D*A == B (mod |n|).
594 * Similarly, (*) translates into
595 * -sign*X*a == A (mod |n|).
596 *
597 * Thus,
598 * sign*Y*a + D*sign*X*a == B (mod |n|),
599 * i.e.
600 * sign*(Y + D*X)*a == B (mod |n|).
601 *
602 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
603 * -sign*X*a == B (mod |n|),
604 * sign*Y*a == A (mod |n|).
605 * Note that X and Y stay non-negative all the time.
606 */
607
608 if (!BN_mul(tmp,D,X,ctx)) goto err;
609 if (!BN_add(tmp,tmp,Y)) goto err;
610
611 M=Y; /* keep the BIGNUM object, the value does not matter */
612 Y=X;
613 X=tmp;
614 sign = -sign;
615 }
616
617 /*
618 * The while loop (Euclid's algorithm) ends when
619 * A == gcd(a,n);
620 * we have
621 * sign*Y*a == A (mod |n|),
622 * where Y is non-negative.
623 */
624
625 if (sign < 0)
626 {
627 if (!BN_sub(Y,n,Y)) goto err;
628 }
629 /* Now Y*a == A (mod |n|). */
630
631 if (BN_is_one(A))
632 {
633 /* Y*a == 1 (mod |n|) */
634 if (!Y->neg && BN_ucmp(Y,n) < 0)
635 {
636 if (!BN_copy(R,Y)) goto err;
637 }
638 else
639 {
640 if (!BN_nnmod(R,Y,n,ctx)) goto err;
641 }
642 }
643 else
644 {
645 BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
646 goto err;
647 }
648 ret=R;
649err:
650 if ((ret == NULL) && (in == NULL)) BN_free(R);
651 BN_CTX_end(ctx);
652 bn_check_top(ret);
489 return(ret); 653 return(ret);
490 } 654 }
diff --git a/src/lib/libcrypto/bn/bn_kron.c b/src/lib/libcrypto/bn/bn_kron.c
index 49f75594ae..740359b752 100644
--- a/src/lib/libcrypto/bn/bn_kron.c
+++ b/src/lib/libcrypto/bn/bn_kron.c
@@ -53,9 +53,9 @@
53 * 53 *
54 */ 54 */
55 55
56#include "cryptlib.h"
56#include "bn_lcl.h" 57#include "bn_lcl.h"
57 58
58
59/* least significant word */ 59/* least significant word */
60#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) 60#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
61 61
@@ -74,6 +74,9 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
74 */ 74 */
75 static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1}; 75 static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
76 76
77 bn_check_top(a);
78 bn_check_top(b);
79
77 BN_CTX_start(ctx); 80 BN_CTX_start(ctx);
78 A = BN_CTX_get(ctx); 81 A = BN_CTX_get(ctx);
79 B = BN_CTX_get(ctx); 82 B = BN_CTX_get(ctx);
@@ -172,8 +175,7 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
172 tmp = A; A = B; B = tmp; 175 tmp = A; A = B; B = tmp;
173 tmp->neg = 0; 176 tmp->neg = 0;
174 } 177 }
175 178end:
176 end:
177 BN_CTX_end(ctx); 179 BN_CTX_end(ctx);
178 if (err) 180 if (err)
179 return -2; 181 return -2;
diff --git a/src/lib/libcrypto/bn/bn_lcl.h b/src/lib/libcrypto/bn/bn_lcl.h
index a84998f2bd..27ac4397a1 100644
--- a/src/lib/libcrypto/bn/bn_lcl.h
+++ b/src/lib/libcrypto/bn/bn_lcl.h
@@ -119,20 +119,6 @@ extern "C" {
119#endif 119#endif
120 120
121 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/* 122/*
137 * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions 123 * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
138 * 124 *
@@ -284,6 +270,15 @@ struct bignum_ctx
284 : "a"(a),"g"(b) \ 270 : "a"(a),"g"(b) \
285 : "cc"); 271 : "cc");
286# endif 272# endif
273# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
274# if defined(_MSC_VER) && _MSC_VER>=1400
275 unsigned __int64 __umulh (unsigned __int64 a,unsigned __int64 b);
276 unsigned __int64 _umul128 (unsigned __int64 a,unsigned __int64 b,
277 unsigned __int64 *h);
278# pragma intrinsic(__umulh,_umul128)
279# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
280# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
281# endif
287# endif /* cpu */ 282# endif /* cpu */
288#endif /* OPENSSL_NO_ASM */ 283#endif /* OPENSSL_NO_ASM */
289 284
@@ -293,44 +288,17 @@ struct bignum_ctx
293#define Lw(t) (((BN_ULONG)(t))&BN_MASK2) 288#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
294#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) 289#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
295 290
296/* This is used for internal error checking and is not normally used */ 291#ifdef BN_DEBUG_RAND
297#ifdef BN_DEBUG 292#define bn_clear_top2max(a) \
298# include <assert.h>
299# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
300#else
301# define bn_check_top(a)
302#endif
303
304/* This macro is to add extra stuff for development checking */
305#ifdef BN_DEBUG
306#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
307#else
308#define bn_set_max(r)
309#endif
310
311/* These macros are used to 'take' a section of a bignum for read only use */
312#define bn_set_low(r,a,n) \
313 { \
314 (r)->top=((a)->top > (n))?(n):(a)->top; \
315 (r)->d=(a)->d; \
316 (r)->neg=(a)->neg; \
317 (r)->flags|=BN_FLG_STATIC_DATA; \
318 bn_set_max(r); \
319 }
320
321#define bn_set_high(r,a,n) \
322 { \ 293 { \
323 if ((a)->top > (n)) \ 294 int ind = (a)->dmax - (a)->top; \
324 { \ 295 BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
325 (r)->top=(a)->top-n; \ 296 for (; ind != 0; ind--) \
326 (r)->d= &((a)->d[n]); \ 297 *(++ftl) = 0x0; \
327 } \
328 else \
329 (r)->top=0; \
330 (r)->neg=(a)->neg; \
331 (r)->flags|=BN_FLG_STATIC_DATA; \
332 bn_set_max(r); \
333 } 298 }
299#else
300#define bn_clear_top2max(a)
301#endif
334 302
335#ifdef BN_LLONG 303#ifdef BN_LLONG
336#define mul_add(r,a,w,c) { \ 304#define mul_add(r,a,w,c) { \
@@ -354,6 +322,33 @@ struct bignum_ctx
354 (r1)=Hw(t); \ 322 (r1)=Hw(t); \
355 } 323 }
356 324
325#elif defined(BN_UMULT_LOHI)
326#define mul_add(r,a,w,c) { \
327 BN_ULONG high,low,ret,tmp=(a); \
328 ret = (r); \
329 BN_UMULT_LOHI(low,high,w,tmp); \
330 ret += (c); \
331 (c) = (ret<(c))?1:0; \
332 (c) += high; \
333 ret += low; \
334 (c) += (ret<low)?1:0; \
335 (r) = ret; \
336 }
337
338#define mul(r,a,w,c) { \
339 BN_ULONG high,low,ret,ta=(a); \
340 BN_UMULT_LOHI(low,high,w,ta); \
341 ret = low + (c); \
342 (c) = high; \
343 (c) += (ret<low)?1:0; \
344 (r) = ret; \
345 }
346
347#define sqr(r0,r1,a) { \
348 BN_ULONG tmp=(a); \
349 BN_UMULT_LOHI(r0,r1,tmp,tmp); \
350 }
351
357#elif defined(BN_UMULT_HIGH) 352#elif defined(BN_UMULT_HIGH)
358#define mul_add(r,a,w,c) { \ 353#define mul_add(r,a,w,c) { \
359 BN_ULONG high,low,ret,tmp=(a); \ 354 BN_ULONG high,low,ret,tmp=(a); \
@@ -472,18 +467,21 @@ void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
472int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n); 467int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
473int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, 468int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
474 int cl, int dl); 469 int cl, int dl);
475#ifdef BN_RECURSION 470void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
476void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, 471 int dna,int dnb,BN_ULONG *t);
477 BN_ULONG *t); 472void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
478void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn, 473 int n,int tna,int tnb,BN_ULONG *t);
479 int n, BN_ULONG *t); 474void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t);
475void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
480void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, 476void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
481 BN_ULONG *t); 477 BN_ULONG *t);
482void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2, 478void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
483 BN_ULONG *t); 479 BN_ULONG *t);
484void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t); 480BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
485#endif 481 int cl, int dl);
486void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n); 482BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
483 int cl, int dl);
484int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
487 485
488#ifdef __cplusplus 486#ifdef __cplusplus
489} 487}
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index e1660450bc..2649b8c538 100644
--- a/src/lib/libcrypto/bn/bn_lib.c
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -67,8 +67,10 @@
67#include "cryptlib.h" 67#include "cryptlib.h"
68#include "bn_lcl.h" 68#include "bn_lcl.h"
69 69
70const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT; 70const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
71 71
72/* This stuff appears to be completely unused, so is deprecated */
73#ifndef OPENSSL_NO_DEPRECATED
72/* For a 32 bit machine 74/* For a 32 bit machine
73 * 2 - 4 == 128 75 * 2 - 4 == 128
74 * 3 - 8 == 256 76 * 3 - 8 == 256
@@ -91,28 +93,28 @@ void BN_set_params(int mult, int high, int low, int mont)
91 { 93 {
92 if (mult >= 0) 94 if (mult >= 0)
93 { 95 {
94 if (mult > (sizeof(int)*8)-1) 96 if (mult > (int)(sizeof(int)*8)-1)
95 mult=sizeof(int)*8-1; 97 mult=sizeof(int)*8-1;
96 bn_limit_bits=mult; 98 bn_limit_bits=mult;
97 bn_limit_num=1<<mult; 99 bn_limit_num=1<<mult;
98 } 100 }
99 if (high >= 0) 101 if (high >= 0)
100 { 102 {
101 if (high > (sizeof(int)*8)-1) 103 if (high > (int)(sizeof(int)*8)-1)
102 high=sizeof(int)*8-1; 104 high=sizeof(int)*8-1;
103 bn_limit_bits_high=high; 105 bn_limit_bits_high=high;
104 bn_limit_num_high=1<<high; 106 bn_limit_num_high=1<<high;
105 } 107 }
106 if (low >= 0) 108 if (low >= 0)
107 { 109 {
108 if (low > (sizeof(int)*8)-1) 110 if (low > (int)(sizeof(int)*8)-1)
109 low=sizeof(int)*8-1; 111 low=sizeof(int)*8-1;
110 bn_limit_bits_low=low; 112 bn_limit_bits_low=low;
111 bn_limit_num_low=1<<low; 113 bn_limit_num_low=1<<low;
112 } 114 }
113 if (mont >= 0) 115 if (mont >= 0)
114 { 116 {
115 if (mont > (sizeof(int)*8)-1) 117 if (mont > (int)(sizeof(int)*8)-1)
116 mont=sizeof(int)*8-1; 118 mont=sizeof(int)*8-1;
117 bn_limit_bits_mont=mont; 119 bn_limit_bits_mont=mont;
118 bn_limit_num_mont=1<<mont; 120 bn_limit_num_mont=1<<mont;
@@ -127,11 +129,12 @@ int BN_get_params(int which)
127 else if (which == 3) return(bn_limit_bits_mont); 129 else if (which == 3) return(bn_limit_bits_mont);
128 else return(0); 130 else return(0);
129 } 131 }
132#endif
130 133
131const BIGNUM *BN_value_one(void) 134const BIGNUM *BN_value_one(void)
132 { 135 {
133 static BN_ULONG data_one=1L; 136 static BN_ULONG data_one=1L;
134 static BIGNUM const_one={&data_one,1,1,0}; 137 static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
135 138
136 return(&const_one); 139 return(&const_one);
137 } 140 }
@@ -244,16 +247,11 @@ int BN_num_bits_word(BN_ULONG l)
244 247
245int BN_num_bits(const BIGNUM *a) 248int BN_num_bits(const BIGNUM *a)
246 { 249 {
247 BN_ULONG l; 250 int i = a->top - 1;
248 int i;
249
250 bn_check_top(a); 251 bn_check_top(a);
251 252
252 if (a->top == 0) return(0); 253 if (BN_is_zero(a)) return 0;
253 l=a->d[a->top-1]; 254 return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
254 assert(l != 0);
255 i=(a->top-1)*BN_BITS2;
256 return(i+BN_num_bits_word(l));
257 } 255 }
258 256
259void BN_clear_free(BIGNUM *a) 257void BN_clear_free(BIGNUM *a)
@@ -261,6 +259,7 @@ void BN_clear_free(BIGNUM *a)
261 int i; 259 int i;
262 260
263 if (a == NULL) return; 261 if (a == NULL) return;
262 bn_check_top(a);
264 if (a->d != NULL) 263 if (a->d != NULL)
265 { 264 {
266 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0])); 265 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
@@ -276,16 +275,24 @@ void BN_clear_free(BIGNUM *a)
276void BN_free(BIGNUM *a) 275void BN_free(BIGNUM *a)
277 { 276 {
278 if (a == NULL) return; 277 if (a == NULL) return;
278 bn_check_top(a);
279 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA))) 279 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
280 OPENSSL_free(a->d); 280 OPENSSL_free(a->d);
281 a->flags|=BN_FLG_FREE; /* REMOVE? */
282 if (a->flags & BN_FLG_MALLOCED) 281 if (a->flags & BN_FLG_MALLOCED)
283 OPENSSL_free(a); 282 OPENSSL_free(a);
283 else
284 {
285#ifndef OPENSSL_NO_DEPRECATED
286 a->flags|=BN_FLG_FREE;
287#endif
288 a->d = NULL;
289 }
284 } 290 }
285 291
286void BN_init(BIGNUM *a) 292void BN_init(BIGNUM *a)
287 { 293 {
288 memset(a,0,sizeof(BIGNUM)); 294 memset(a,0,sizeof(BIGNUM));
295 bn_check_top(a);
289 } 296 }
290 297
291BIGNUM *BN_new(void) 298BIGNUM *BN_new(void)
@@ -302,6 +309,7 @@ BIGNUM *BN_new(void)
302 ret->neg=0; 309 ret->neg=0;
303 ret->dmax=0; 310 ret->dmax=0;
304 ret->d=NULL; 311 ret->d=NULL;
312 bn_check_top(ret);
305 return(ret); 313 return(ret);
306 } 314 }
307 315
@@ -313,19 +321,19 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
313 const BN_ULONG *B; 321 const BN_ULONG *B;
314 int i; 322 int i;
315 323
324 bn_check_top(b);
325
316 if (words > (INT_MAX/(4*BN_BITS2))) 326 if (words > (INT_MAX/(4*BN_BITS2)))
317 { 327 {
318 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG); 328 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
319 return NULL; 329 return NULL;
320 } 330 }
321
322 bn_check_top(b);
323 if (BN_get_flags(b,BN_FLG_STATIC_DATA)) 331 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
324 { 332 {
325 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); 333 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
326 return(NULL); 334 return(NULL);
327 } 335 }
328 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1)); 336 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
329 if (A == NULL) 337 if (A == NULL)
330 { 338 {
331 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE); 339 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
@@ -363,19 +371,8 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
363 } 371 }
364 } 372 }
365 373
366 /* Now need to zero any data between b->top and b->max */
367 /* XXX Why? */
368
369 A= &(a[b->top]);
370 for (i=(words - b->top)>>3; i>0; i--,A+=8)
371 {
372 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
373 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
374 }
375 for (i=(words - b->top)&7; i>0; i--,A++)
376 A[0]=0;
377#else 374#else
378 memset(A,0,sizeof(BN_ULONG)*(words+1)); 375 memset(A,0,sizeof(BN_ULONG)*words);
379 memcpy(A,b->d,sizeof(b->d[0])*b->top); 376 memcpy(A,b->d,sizeof(b->d[0])*b->top);
380#endif 377#endif
381 378
@@ -393,16 +390,19 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
393 * while bn_dup_expand() makes sure allocation is made only once. 390 * while bn_dup_expand() makes sure allocation is made only once.
394 */ 391 */
395 392
393#ifndef OPENSSL_NO_DEPRECATED
396BIGNUM *bn_dup_expand(const BIGNUM *b, int words) 394BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
397 { 395 {
398 BIGNUM *r = NULL; 396 BIGNUM *r = NULL;
399 397
398 bn_check_top(b);
399
400 /* This function does not work if 400 /* This function does not work if
401 * words <= b->dmax && top < words 401 * words <= b->dmax && top < words
402 * because BN_dup() does not preserve 'dmax'! 402 * because BN_dup() does not preserve 'dmax'!
403 * (But bn_dup_expand() is not used anywhere yet.) 403 * (But bn_dup_expand() is not used anywhere yet.)
404 */ 404 */
405 405
406 if (words > b->dmax) 406 if (words > b->dmax)
407 { 407 {
408 BN_ULONG *a = bn_expand_internal(b, words); 408 BN_ULONG *a = bn_expand_internal(b, words);
@@ -431,48 +431,67 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
431 r = BN_dup(b); 431 r = BN_dup(b);
432 } 432 }
433 433
434 bn_check_top(r);
434 return r; 435 return r;
435 } 436 }
437#endif
436 438
437/* This is an internal function that should not be used in applications. 439/* This is an internal function that should not be used in applications.
438 * It ensures that 'b' has enough room for a 'words' word number number. 440 * It ensures that 'b' has enough room for a 'words' word number
441 * and initialises any unused part of b->d with leading zeros.
439 * It is mostly used by the various BIGNUM routines. If there is an error, 442 * It is mostly used by the various BIGNUM routines. If there is an error,
440 * NULL is returned. If not, 'b' is returned. */ 443 * NULL is returned. If not, 'b' is returned. */
441 444
442BIGNUM *bn_expand2(BIGNUM *b, int words) 445BIGNUM *bn_expand2(BIGNUM *b, int words)
443 { 446 {
447 bn_check_top(b);
448
444 if (words > b->dmax) 449 if (words > b->dmax)
445 { 450 {
446 BN_ULONG *a = bn_expand_internal(b, words); 451 BN_ULONG *a = bn_expand_internal(b, words);
452 if(!a) return NULL;
453 if(b->d) OPENSSL_free(b->d);
454 b->d=a;
455 b->dmax=words;
456 }
447 457
448 if (a) 458/* None of this should be necessary because of what b->top means! */
459#if 0
460 /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
461 if (b->top < b->dmax)
462 {
463 int i;
464 BN_ULONG *A = &(b->d[b->top]);
465 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
449 { 466 {
450 if (b->d) 467 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
451 OPENSSL_free(b->d); 468 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
452 b->d=a;
453 b->dmax=words;
454 } 469 }
455 else 470 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
456 b = NULL; 471 A[0]=0;
472 assert(A == &(b->d[b->dmax]));
457 } 473 }
474#endif
475 bn_check_top(b);
458 return b; 476 return b;
459 } 477 }
460 478
461BIGNUM *BN_dup(const BIGNUM *a) 479BIGNUM *BN_dup(const BIGNUM *a)
462 { 480 {
463 BIGNUM *r, *t; 481 BIGNUM *t;
464 482
465 if (a == NULL) return NULL; 483 if (a == NULL) return NULL;
466
467 bn_check_top(a); 484 bn_check_top(a);
468 485
469 t = BN_new(); 486 t = BN_new();
470 if (t == NULL) return(NULL); 487 if (t == NULL) return NULL;
471 r = BN_copy(t, a); 488 if(!BN_copy(t, a))
472 /* now r == t || r == NULL */ 489 {
473 if (r == NULL)
474 BN_free(t); 490 BN_free(t);
475 return r; 491 return NULL;
492 }
493 bn_check_top(t);
494 return t;
476 } 495 }
477 496
478BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) 497BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
@@ -506,11 +525,9 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
506 memcpy(a->d,b->d,sizeof(b->d[0])*b->top); 525 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
507#endif 526#endif
508 527
509/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
510 a->top=b->top; 528 a->top=b->top;
511 if ((a->top == 0) && (a->d != NULL))
512 a->d[0]=0;
513 a->neg=b->neg; 529 a->neg=b->neg;
530 bn_check_top(a);
514 return(a); 531 return(a);
515 } 532 }
516 533
@@ -520,6 +537,9 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
520 BN_ULONG *tmp_d; 537 BN_ULONG *tmp_d;
521 int tmp_top, tmp_dmax, tmp_neg; 538 int tmp_top, tmp_dmax, tmp_neg;
522 539
540 bn_check_top(a);
541 bn_check_top(b);
542
523 flags_old_a = a->flags; 543 flags_old_a = a->flags;
524 flags_old_b = b->flags; 544 flags_old_b = b->flags;
525 545
@@ -540,11 +560,13 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
540 560
541 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA); 561 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
542 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA); 562 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
563 bn_check_top(a);
564 bn_check_top(b);
543 } 565 }
544 566
545
546void BN_clear(BIGNUM *a) 567void BN_clear(BIGNUM *a)
547 { 568 {
569 bn_check_top(a);
548 if (a->d != NULL) 570 if (a->d != NULL)
549 memset(a->d,0,a->dmax*sizeof(a->d[0])); 571 memset(a->d,0,a->dmax*sizeof(a->d[0]));
550 a->top=0; 572 a->top=0;
@@ -553,49 +575,22 @@ void BN_clear(BIGNUM *a)
553 575
554BN_ULONG BN_get_word(const BIGNUM *a) 576BN_ULONG BN_get_word(const BIGNUM *a)
555 { 577 {
556 int i,n; 578 if (a->top > 1)
557 BN_ULONG ret=0; 579 return BN_MASK2;
558 580 else if (a->top == 1)
559 n=BN_num_bytes(a); 581 return a->d[0];
560 if (n > sizeof(BN_ULONG)) 582 /* a->top == 0 */
561 return(BN_MASK2); 583 return 0;
562 for (i=a->top-1; i>=0; i--)
563 {
564#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
565 ret<<=BN_BITS4; /* stops the compiler complaining */
566 ret<<=BN_BITS4;
567#else
568 ret=0;
569#endif
570 ret|=a->d[i];
571 }
572 return(ret);
573 } 584 }
574 585
575int BN_set_word(BIGNUM *a, BN_ULONG w) 586int BN_set_word(BIGNUM *a, BN_ULONG w)
576 { 587 {
577 int i,n; 588 bn_check_top(a);
578 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0); 589 if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
579 590 a->neg = 0;
580 n=sizeof(BN_ULONG)/BN_BYTES; 591 a->d[0] = w;
581 a->neg=0; 592 a->top = (w ? 1 : 0);
582 a->top=0; 593 bn_check_top(a);
583 a->d[0]=(BN_ULONG)w&BN_MASK2;
584 if (a->d[0] != 0) a->top=1;
585 for (i=1; i<n; i++)
586 {
587 /* the following is done instead of
588 * w>>=BN_BITS2 so compilers don't complain
589 * on builds where sizeof(long) == BN_TYPES */
590#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
591 w>>=BN_BITS4;
592 w>>=BN_BITS4;
593#else
594 w=0;
595#endif
596 a->d[i]=(BN_ULONG)w&BN_MASK2;
597 if (a->d[i] != 0) a->top=i+1;
598 }
599 return(1); 594 return(1);
600 } 595 }
601 596
@@ -604,9 +599,12 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
604 unsigned int i,m; 599 unsigned int i,m;
605 unsigned int n; 600 unsigned int n;
606 BN_ULONG l; 601 BN_ULONG l;
602 BIGNUM *bn = NULL;
607 603
608 if (ret == NULL) ret=BN_new(); 604 if (ret == NULL)
605 ret = bn = BN_new();
609 if (ret == NULL) return(NULL); 606 if (ret == NULL) return(NULL);
607 bn_check_top(ret);
610 l=0; 608 l=0;
611 n=len; 609 n=len;
612 if (n == 0) 610 if (n == 0)
@@ -614,13 +612,16 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
614 ret->top=0; 612 ret->top=0;
615 return(ret); 613 return(ret);
616 } 614 }
617 if (bn_expand(ret,(int)(n+2)*8) == NULL)
618 return(NULL);
619 i=((n-1)/BN_BYTES)+1; 615 i=((n-1)/BN_BYTES)+1;
620 m=((n-1)%(BN_BYTES)); 616 m=((n-1)%(BN_BYTES));
617 if (bn_wexpand(ret, (int)i) == NULL)
618 {
619 if (bn) BN_free(bn);
620 return NULL;
621 }
621 ret->top=i; 622 ret->top=i;
622 ret->neg=0; 623 ret->neg=0;
623 while (n-- > 0) 624 while (n--)
624 { 625 {
625 l=(l<<8L)| *(s++); 626 l=(l<<8L)| *(s++);
626 if (m-- == 0) 627 if (m-- == 0)
@@ -632,7 +633,7 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
632 } 633 }
633 /* need to call this due to clear byte at top if avoiding 634 /* need to call this due to clear byte at top if avoiding
634 * having the top bit set (-ve number) */ 635 * having the top bit set (-ve number) */
635 bn_fix_top(ret); 636 bn_correct_top(ret);
636 return(ret); 637 return(ret);
637 } 638 }
638 639
@@ -642,8 +643,9 @@ int BN_bn2bin(const BIGNUM *a, unsigned char *to)
642 int n,i; 643 int n,i;
643 BN_ULONG l; 644 BN_ULONG l;
644 645
646 bn_check_top(a);
645 n=i=BN_num_bytes(a); 647 n=i=BN_num_bytes(a);
646 while (i-- > 0) 648 while (i--)
647 { 649 {
648 l=a->d[i/BN_BYTES]; 650 l=a->d[i/BN_BYTES];
649 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff; 651 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
@@ -668,7 +670,7 @@ int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
668 t1= ap[i]; 670 t1= ap[i];
669 t2= bp[i]; 671 t2= bp[i];
670 if (t1 != t2) 672 if (t1 != t2)
671 return(t1 > t2?1:-1); 673 return((t1 > t2) ? 1 : -1);
672 } 674 }
673 return(0); 675 return(0);
674 } 676 }
@@ -718,6 +720,9 @@ int BN_set_bit(BIGNUM *a, int n)
718 { 720 {
719 int i,j,k; 721 int i,j,k;
720 722
723 if (n < 0)
724 return 0;
725
721 i=n/BN_BITS2; 726 i=n/BN_BITS2;
722 j=n%BN_BITS2; 727 j=n%BN_BITS2;
723 if (a->top <= i) 728 if (a->top <= i)
@@ -729,6 +734,7 @@ int BN_set_bit(BIGNUM *a, int n)
729 } 734 }
730 735
731 a->d[i]|=(((BN_ULONG)1)<<j); 736 a->d[i]|=(((BN_ULONG)1)<<j);
737 bn_check_top(a);
732 return(1); 738 return(1);
733 } 739 }
734 740
@@ -736,12 +742,15 @@ int BN_clear_bit(BIGNUM *a, int n)
736 { 742 {
737 int i,j; 743 int i,j;
738 744
745 bn_check_top(a);
746 if (n < 0) return 0;
747
739 i=n/BN_BITS2; 748 i=n/BN_BITS2;
740 j=n%BN_BITS2; 749 j=n%BN_BITS2;
741 if (a->top <= i) return(0); 750 if (a->top <= i) return(0);
742 751
743 a->d[i]&=(~(((BN_ULONG)1)<<j)); 752 a->d[i]&=(~(((BN_ULONG)1)<<j));
744 bn_fix_top(a); 753 bn_correct_top(a);
745 return(1); 754 return(1);
746 } 755 }
747 756
@@ -749,20 +758,24 @@ int BN_is_bit_set(const BIGNUM *a, int n)
749 { 758 {
750 int i,j; 759 int i,j;
751 760
752 if (n < 0) return(0); 761 bn_check_top(a);
762 if (n < 0) return 0;
753 i=n/BN_BITS2; 763 i=n/BN_BITS2;
754 j=n%BN_BITS2; 764 j=n%BN_BITS2;
755 if (a->top <= i) return(0); 765 if (a->top <= i) return 0;
756 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0); 766 return(((a->d[i])>>j)&((BN_ULONG)1));
757 } 767 }
758 768
759int BN_mask_bits(BIGNUM *a, int n) 769int BN_mask_bits(BIGNUM *a, int n)
760 { 770 {
761 int b,w; 771 int b,w;
762 772
773 bn_check_top(a);
774 if (n < 0) return 0;
775
763 w=n/BN_BITS2; 776 w=n/BN_BITS2;
764 b=n%BN_BITS2; 777 b=n%BN_BITS2;
765 if (w >= a->top) return(0); 778 if (w >= a->top) return 0;
766 if (b == 0) 779 if (b == 0)
767 a->top=w; 780 a->top=w;
768 else 781 else
@@ -770,10 +783,18 @@ int BN_mask_bits(BIGNUM *a, int n)
770 a->top=w+1; 783 a->top=w+1;
771 a->d[w]&= ~(BN_MASK2<<b); 784 a->d[w]&= ~(BN_MASK2<<b);
772 } 785 }
773 bn_fix_top(a); 786 bn_correct_top(a);
774 return(1); 787 return(1);
775 } 788 }
776 789
790void BN_set_negative(BIGNUM *a, int b)
791 {
792 if (b && !BN_is_zero(a))
793 a->neg = 1;
794 else
795 a->neg = 0;
796 }
797
777int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) 798int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
778 { 799 {
779 int i; 800 int i;
diff --git a/src/lib/libcrypto/bn/bn_mod.c b/src/lib/libcrypto/bn/bn_mod.c
index 5cf82480d7..77d6ddb91a 100644
--- a/src/lib/libcrypto/bn/bn_mod.c
+++ b/src/lib/libcrypto/bn/bn_mod.c
@@ -149,7 +149,7 @@ int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_
149 * and less than m */ 149 * and less than m */
150int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) 150int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
151 { 151 {
152 if (!BN_add(r, a, b)) return 0; 152 if (!BN_uadd(r, a, b)) return 0;
153 if (BN_ucmp(r, m) >= 0) 153 if (BN_ucmp(r, m) >= 0)
154 return BN_usub(r, r, m); 154 return BN_usub(r, r, m);
155 return 1; 155 return 1;
@@ -192,6 +192,7 @@ int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
192 else 192 else
193 { if (!BN_mul(t,a,b,ctx)) goto err; } 193 { if (!BN_mul(t,a,b,ctx)) goto err; }
194 if (!BN_nnmod(r,t,m,ctx)) goto err; 194 if (!BN_nnmod(r,t,m,ctx)) goto err;
195 bn_check_top(r);
195 ret=1; 196 ret=1;
196err: 197err:
197 BN_CTX_end(ctx); 198 BN_CTX_end(ctx);
@@ -210,6 +211,7 @@ int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
210int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) 211int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
211 { 212 {
212 if (!BN_lshift1(r, a)) return 0; 213 if (!BN_lshift1(r, a)) return 0;
214 bn_check_top(r);
213 return BN_nnmod(r, r, m, ctx); 215 return BN_nnmod(r, r, m, ctx);
214 } 216 }
215 217
@@ -219,6 +221,7 @@ int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
219int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) 221int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
220 { 222 {
221 if (!BN_lshift1(r, a)) return 0; 223 if (!BN_lshift1(r, a)) return 0;
224 bn_check_top(r);
222 if (BN_cmp(r, m) >= 0) 225 if (BN_cmp(r, m) >= 0)
223 return BN_sub(r, r, m); 226 return BN_sub(r, r, m);
224 return 1; 227 return 1;
@@ -240,6 +243,7 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ct
240 } 243 }
241 244
242 ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); 245 ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
246 bn_check_top(r);
243 247
244 if (abs_m) 248 if (abs_m)
245 BN_free(abs_m); 249 BN_free(abs_m);
@@ -291,6 +295,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
291 if (!BN_sub(r, r, m)) return 0; 295 if (!BN_sub(r, r, m)) return 0;
292 } 296 }
293 } 297 }
298 bn_check_top(r);
294 299
295 return 1; 300 return 1;
296 } 301 }
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c
index 726d5f2b1b..4799b152dd 100644
--- a/src/lib/libcrypto/bn/bn_mont.c
+++ b/src/lib/libcrypto/bn/bn_mont.c
@@ -55,6 +55,59 @@
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-2006 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/* 112/*
60 * Details about Montgomery multiplication algorithms can be found at 113 * Details about Montgomery multiplication algorithms can be found at
@@ -69,11 +122,50 @@
69 122
70#define MONT_WORD /* use the faster word-based algorithm */ 123#define MONT_WORD /* use the faster word-based algorithm */
71 124
125#if defined(MONT_WORD) && defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
126/* This condition means we have a specific non-default build:
127 * In the 0.9.8 branch, OPENSSL_BN_ASM_MONT is normally not set for any
128 * BN_BITS2<=32 platform; an explicit "enable-montasm" is required.
129 * I.e., if we are here, the user intentionally deviates from the
130 * normal stable build to get better Montgomery performance from
131 * the 0.9.9-dev backport.
132 *
133 * In this case only, we also enable BN_from_montgomery_word()
134 * (another non-stable feature from 0.9.9-dev).
135 */
136#define MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
137#endif
138
139#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
140static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
141#endif
142
143
144
72int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 145int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
73 BN_MONT_CTX *mont, BN_CTX *ctx) 146 BN_MONT_CTX *mont, BN_CTX *ctx)
74 { 147 {
75 BIGNUM *tmp; 148 BIGNUM *tmp;
76 int ret=0; 149 int ret=0;
150#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
151 int num = mont->N.top;
152
153 if (num>1 && a->top==num && b->top==num)
154 {
155 if (bn_wexpand(r,num) == NULL) return(0);
156#if 0 /* for OpenSSL 0.9.9 mont->n0 */
157 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
158#else
159 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,&mont->n0,num))
160#endif
161 {
162 r->neg = a->neg^b->neg;
163 r->top = num;
164 bn_correct_top(r);
165 return(1);
166 }
167 }
168#endif
77 169
78 BN_CTX_start(ctx); 170 BN_CTX_start(ctx);
79 tmp = BN_CTX_get(ctx); 171 tmp = BN_CTX_get(ctx);
@@ -89,13 +181,162 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
89 if (!BN_mul(tmp,a,b,ctx)) goto err; 181 if (!BN_mul(tmp,a,b,ctx)) goto err;
90 } 182 }
91 /* reduce from aRR to aR */ 183 /* reduce from aRR to aR */
184#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
185 if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
186#else
92 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; 187 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
188#endif
189 bn_check_top(r);
93 ret=1; 190 ret=1;
94err: 191err:
95 BN_CTX_end(ctx); 192 BN_CTX_end(ctx);
96 return(ret); 193 return(ret);
97 } 194 }
98 195
196#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
197static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
198 {
199 BIGNUM *n;
200 BN_ULONG *ap,*np,*rp,n0,v,*nrp;
201 int al,nl,max,i,x,ri;
202
203 n= &(mont->N);
204 /* mont->ri is the size of mont->N in bits (rounded up
205 to the word size) */
206 al=ri=mont->ri/BN_BITS2;
207
208 nl=n->top;
209 if ((al == 0) || (nl == 0)) { ret->top=0; return(1); }
210
211 max=(nl+al+1); /* allow for overflow (no?) XXX */
212 if (bn_wexpand(r,max) == NULL) return(0);
213
214 r->neg^=n->neg;
215 np=n->d;
216 rp=r->d;
217 nrp= &(r->d[nl]);
218
219 /* clear the top words of T */
220 for (i=r->top; i<max; i++) /* memset? XXX */
221 r->d[i]=0;
222
223 r->top=max;
224#if 0 /* for OpenSSL 0.9.9 mont->n0 */
225 n0=mont->n0[0];
226#else
227 n0=mont->n0;
228#endif
229
230#ifdef BN_COUNT
231 fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
232#endif
233 for (i=0; i<nl; i++)
234 {
235#ifdef __TANDEM
236 {
237 long long t1;
238 long long t2;
239 long long t3;
240 t1 = rp[0] * (n0 & 0177777);
241 t2 = 037777600000l;
242 t2 = n0 & t2;
243 t3 = rp[0] & 0177777;
244 t2 = (t3 * t2) & BN_MASK2;
245 t1 = t1 + t2;
246 v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
247 }
248#else
249 v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
250#endif
251 nrp++;
252 rp++;
253 if (((nrp[-1]+=v)&BN_MASK2) >= v)
254 continue;
255 else
256 {
257 if (((++nrp[0])&BN_MASK2) != 0) continue;
258 if (((++nrp[1])&BN_MASK2) != 0) continue;
259 for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
260 }
261 }
262 bn_correct_top(r);
263
264 /* mont->ri will be a multiple of the word size and below code
265 * is kind of BN_rshift(ret,r,mont->ri) equivalent */
266 if (r->top <= ri)
267 {
268 ret->top=0;
269 return(1);
270 }
271 al=r->top-ri;
272
273 if (bn_wexpand(ret,ri) == NULL) return(0);
274 x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
275 ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
276 ret->neg=r->neg;
277
278 rp=ret->d;
279 ap=&(r->d[ri]);
280
281 {
282 size_t m1,m2;
283
284 v=bn_sub_words(rp,ap,np,ri);
285 /* this ----------------^^ works even in al<ri case
286 * thanks to zealous zeroing of top of the vector in the
287 * beginning. */
288
289 /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
290 /* in other words if subtraction result is real, then
291 * trick unconditional memcpy below to perform in-place
292 * "refresh" instead of actual copy. */
293 m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al<ri */
294 m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1); /* al>ri */
295 m1|=m2; /* (al!=ri) */
296 m1|=(0-(size_t)v); /* (al!=ri || v) */
297 m1&=~m2; /* (al!=ri || v) && !al>ri */
298 nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
299 }
300
301 /* 'i<ri' is chosen to eliminate dependency on input data, even
302 * though it results in redundant copy in al<ri case. */
303 for (i=0,ri-=4; i<ri; i+=4)
304 {
305 BN_ULONG t1,t2,t3,t4;
306
307 t1=nrp[i+0];
308 t2=nrp[i+1];
309 t3=nrp[i+2]; ap[i+0]=0;
310 t4=nrp[i+3]; ap[i+1]=0;
311 rp[i+0]=t1; ap[i+2]=0;
312 rp[i+1]=t2; ap[i+3]=0;
313 rp[i+2]=t3;
314 rp[i+3]=t4;
315 }
316 for (ri+=4; i<ri; i++)
317 rp[i]=nrp[i], ap[i]=0;
318 bn_correct_top(r);
319 bn_correct_top(ret);
320 bn_check_top(ret);
321
322 return(1);
323 }
324
325int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
326 BN_CTX *ctx)
327 {
328 int retn=0;
329 BIGNUM *t;
330
331 BN_CTX_start(ctx);
332 if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
333 retn = BN_from_montgomery_word(ret,t,mont);
334 BN_CTX_end(ctx);
335 return retn;
336 }
337
338#else /* !MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
339
99int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, 340int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
100 BN_CTX *ctx) 341 BN_CTX *ctx)
101 { 342 {
@@ -171,7 +412,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
171 for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; 412 for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
172 } 413 }
173 } 414 }
174 bn_fix_top(r); 415 bn_correct_top(r);
175 416
176 /* mont->ri will be a multiple of the word size and below code 417 /* mont->ri will be a multiple of the word size and below code
177 * is kind of BN_rshift(ret,r,mont->ri) equivalent */ 418 * is kind of BN_rshift(ret,r,mont->ri) equivalent */
@@ -230,6 +471,8 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
230 } 471 }
231 for (ri+=4; i<ri; i++) 472 for (ri+=4; i<ri; i++)
232 rp[i]=nrp[i], ap[i]=0; 473 rp[i]=nrp[i], ap[i]=0;
474 bn_correct_top(r);
475 bn_correct_top(ret);
233# else 476# else
234 if (bn_wexpand(ret,al) == NULL) goto err; 477 if (bn_wexpand(ret,al) == NULL) goto err;
235 ret->top=al; 478 ret->top=al;
@@ -281,10 +524,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
281 } 524 }
282#endif 525#endif
283 retn=1; 526 retn=1;
527 bn_check_top(ret);
284 err: 528 err:
285 BN_CTX_end(ctx); 529 BN_CTX_end(ctx);
286 return(retn); 530 return(retn);
287 } 531 }
532#endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
288 533
289BN_MONT_CTX *BN_MONT_CTX_new(void) 534BN_MONT_CTX *BN_MONT_CTX_new(void)
290 { 535 {
@@ -304,6 +549,11 @@ void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
304 BN_init(&(ctx->RR)); 549 BN_init(&(ctx->RR));
305 BN_init(&(ctx->N)); 550 BN_init(&(ctx->N));
306 BN_init(&(ctx->Ni)); 551 BN_init(&(ctx->Ni));
552#if 0 /* for OpenSSL 0.9.9 mont->n0 */
553 ctx->n0[0] = ctx->n0[1] = 0;
554#else
555 ctx->n0 = 0;
556#endif
307 ctx->flags=0; 557 ctx->flags=0;
308 } 558 }
309 559
@@ -321,9 +571,11 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont)
321 571
322int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) 572int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
323 { 573 {
324 BIGNUM Ri,*R; 574 int ret = 0;
575 BIGNUM *Ri,*R;
325 576
326 BN_init(&Ri); 577 BN_CTX_start(ctx);
578 if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
327 R= &(mont->RR); /* grab RR as a temp */ 579 R= &(mont->RR); /* grab RR as a temp */
328 if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */ 580 if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */
329 mont->N.neg = 0; 581 mont->N.neg = 0;
@@ -334,57 +586,99 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
334 BN_ULONG buf[2]; 586 BN_ULONG buf[2];
335 587
336 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; 588 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
337 if (!(BN_zero(R))) goto err; 589 BN_zero(R);
590#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)",
591 only certain BN_BITS2<=32 platforms actually need this */
592 if (!(BN_set_bit(R,2*BN_BITS2))) goto err; /* R */
593#else
338 if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ 594 if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
595#endif
339 596
340 buf[0]=mod->d[0]; /* tmod = N mod word size */ 597 buf[0]=mod->d[0]; /* tmod = N mod word size */
341 buf[1]=0; 598 buf[1]=0;
599
600 BN_init(&tmod);
342 tmod.d=buf; 601 tmod.d=buf;
343 tmod.top=1; 602 tmod.top = buf[0] != 0 ? 1 : 0;
344 tmod.dmax=2; 603 tmod.dmax=2;
345 tmod.neg=0; 604 tmod.neg=0;
605
606#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)";
607 only certain BN_BITS2<=32 platforms actually need this */
608 tmod.top=0;
609 if ((buf[0] = mod->d[0])) tmod.top=1;
610 if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2;
611
612 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
613 goto err;
614 if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */
615 if (!BN_is_zero(Ri))
616 {
617 if (!BN_sub_word(Ri,1)) goto err;
618 }
619 else /* if N mod word size == 1 */
620 {
621 if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL)
622 goto err;
623 /* Ri-- (mod double word size) */
624 Ri->neg=0;
625 Ri->d[0]=BN_MASK2;
626 Ri->d[1]=BN_MASK2;
627 Ri->top=2;
628 }
629 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
630 /* Ni = (R*Ri-1)/N,
631 * keep only couple of least significant words: */
632 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
633 mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
634#else
346 /* Ri = R^-1 mod N*/ 635 /* Ri = R^-1 mod N*/
347 if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) 636 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
348 goto err; 637 goto err;
349 if (!BN_lshift(&Ri,&Ri,BN_BITS2)) goto err; /* R*Ri */ 638 if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
350 if (!BN_is_zero(&Ri)) 639 if (!BN_is_zero(Ri))
351 { 640 {
352 if (!BN_sub_word(&Ri,1)) goto err; 641 if (!BN_sub_word(Ri,1)) goto err;
353 } 642 }
354 else /* if N mod word size == 1 */ 643 else /* if N mod word size == 1 */
355 { 644 {
356 if (!BN_set_word(&Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */ 645 if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */
357 } 646 }
358 if (!BN_div(&Ri,NULL,&Ri,&tmod,ctx)) goto err; 647 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
359 /* Ni = (R*Ri-1)/N, 648 /* Ni = (R*Ri-1)/N,
360 * keep only least significant word: */ 649 * keep only least significant word: */
361 mont->n0 = (Ri.top > 0) ? Ri.d[0] : 0; 650# if 0 /* for OpenSSL 0.9.9 mont->n0 */
362 BN_free(&Ri); 651 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
652 mont->n0[1] = 0;
653# else
654 mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
655# endif
656#endif
363 } 657 }
364#else /* !MONT_WORD */ 658#else /* !MONT_WORD */
365 { /* bignum version */ 659 { /* bignum version */
366 mont->ri=BN_num_bits(&mont->N); 660 mont->ri=BN_num_bits(&mont->N);
367 if (!BN_zero(R)) goto err; 661 BN_zero(R);
368 if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */ 662 if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */
369 /* Ri = R^-1 mod N*/ 663 /* Ri = R^-1 mod N*/
370 if ((BN_mod_inverse(&Ri,R,&mont->N,ctx)) == NULL) 664 if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
371 goto err; 665 goto err;
372 if (!BN_lshift(&Ri,&Ri,mont->ri)) goto err; /* R*Ri */ 666 if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
373 if (!BN_sub_word(&Ri,1)) goto err; 667 if (!BN_sub_word(Ri,1)) goto err;
374 /* Ni = (R*Ri-1) / N */ 668 /* Ni = (R*Ri-1) / N */
375 if (!BN_div(&(mont->Ni),NULL,&Ri,&mont->N,ctx)) goto err; 669 if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
376 BN_free(&Ri);
377 } 670 }
378#endif 671#endif
379 672
380 /* setup RR for conversions */ 673 /* setup RR for conversions */
381 if (!BN_zero(&(mont->RR))) goto err; 674 BN_zero(&(mont->RR));
382 if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err; 675 if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
383 if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err; 676 if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
384 677
385 return(1); 678 ret = 1;
386err: 679err:
387 return(0); 680 BN_CTX_end(ctx);
681 return ret;
388 } 682 }
389 683
390BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) 684BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
@@ -395,27 +689,44 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
395 if (!BN_copy(&(to->N),&(from->N))) return NULL; 689 if (!BN_copy(&(to->N),&(from->N))) return NULL;
396 if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL; 690 if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
397 to->ri=from->ri; 691 to->ri=from->ri;
692#if 0 /* for OpenSSL 0.9.9 mont->n0 */
693 to->n0[0]=from->n0[0];
694 to->n0[1]=from->n0[1];
695#else
398 to->n0=from->n0; 696 to->n0=from->n0;
697#endif
399 return(to); 698 return(to);
400 } 699 }
401 700
402BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, 701BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
403 const BIGNUM *mod, BN_CTX *ctx) 702 const BIGNUM *mod, BN_CTX *ctx)
404 { 703 {
405 if (*pmont) 704 int got_write_lock = 0;
406 return *pmont; 705 BN_MONT_CTX *ret;
407 CRYPTO_w_lock(lock); 706
707 CRYPTO_r_lock(lock);
408 if (!*pmont) 708 if (!*pmont)
409 { 709 {
410 *pmont = BN_MONT_CTX_new(); 710 CRYPTO_r_unlock(lock);
411 if (*pmont && !BN_MONT_CTX_set(*pmont, mod, ctx)) 711 CRYPTO_w_lock(lock);
712 got_write_lock = 1;
713
714 if (!*pmont)
412 { 715 {
413 BN_MONT_CTX_free(*pmont); 716 ret = BN_MONT_CTX_new();
414 *pmont = NULL; 717 if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
718 BN_MONT_CTX_free(ret);
719 else
720 *pmont = ret;
415 } 721 }
416 } 722 }
417 CRYPTO_w_unlock(lock); 723
418 return *pmont; 724 ret = *pmont;
419 } 725
726 if (got_write_lock)
727 CRYPTO_w_unlock(lock);
728 else
729 CRYPTO_r_unlock(lock);
420 730
421 731 return ret;
732 }
diff --git a/src/lib/libcrypto/bn/bn_mpi.c b/src/lib/libcrypto/bn/bn_mpi.c
index 05fa9d1e9a..a054d21aed 100644
--- a/src/lib/libcrypto/bn/bn_mpi.c
+++ b/src/lib/libcrypto/bn/bn_mpi.c
@@ -124,6 +124,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
124 { 124 {
125 BN_clear_bit(a,BN_num_bits(a)-1); 125 BN_clear_bit(a,BN_num_bits(a)-1);
126 } 126 }
127 bn_check_top(a);
127 return(a); 128 return(a);
128 } 129 }
129 130
diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c
index 3ae3822bc2..b848c8cc60 100644
--- a/src/lib/libcrypto/bn/bn_mul.c
+++ b/src/lib/libcrypto/bn/bn_mul.c
@@ -56,10 +56,325 @@
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
69#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
70/* Here follows specialised variants of bn_add_words() and
71 bn_sub_words(). They have the property performing operations on
72 arrays of different sizes. The sizes of those arrays is expressed through
73 cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
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)
83 {
84 BN_ULONG c, t;
85
86 assert(cl >= 0);
87 c = bn_sub_words(r, a, b, cl);
88
89 if (dl == 0)
90 return c;
91
92 r += cl;
93 a += cl;
94 b += cl;
95
96 if (dl < 0)
97 {
98#ifdef BN_COUNT
99 fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
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;
117
118 t = b[3];
119 r[3] = (0-t-c)&BN_MASK2;
120 if (t != 0) c=1;
121 if (++dl >= 0) break;
122
123 b += 4;
124 r += 4;
125 }
126 }
127 else
128 {
129 int save_dl = dl;
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 }
202 }
203 return c;
204 }
205#endif
206
207BN_ULONG bn_add_part_words(BN_ULONG *r,
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;
245
246 l=(c+b[3])&BN_MASK2;
247 c=(l < c);
248 r[3]=l;
249 if (++dl >= 0) break;
250
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
63#ifdef BN_RECURSION 378#ifdef BN_RECURSION
64/* Karatsuba recursive multiplication algorithm 379/* Karatsuba recursive multiplication algorithm
65 * (cf. Knuth, The Art of Computer Programming, Vol. 2) */ 380 * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
@@ -74,15 +389,17 @@
74 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) 389 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
75 * a[1]*b[1] 390 * a[1]*b[1]
76 */ 391 */
392/* dnX may not be positive, but n2/2+dnX has to be */
77void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, 393void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
78 BN_ULONG *t) 394 int dna, int dnb, BN_ULONG *t)
79 { 395 {
80 int n=n2/2,c1,c2; 396 int n=n2/2,c1,c2;
397 int tna=n+dna, tnb=n+dnb;
81 unsigned int neg,zero; 398 unsigned int neg,zero;
82 BN_ULONG ln,lo,*p; 399 BN_ULONG ln,lo,*p;
83 400
84# ifdef BN_COUNT 401# ifdef BN_COUNT
85 printf(" bn_mul_recursive %d * %d\n",n2,n2); 402 fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
86# endif 403# endif
87# ifdef BN_MUL_COMBA 404# ifdef BN_MUL_COMBA
88# if 0 405# if 0
@@ -92,34 +409,40 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
92 return; 409 return;
93 } 410 }
94# endif 411# endif
95 if (n2 == 8) 412 /* Only call bn_mul_comba 8 if n2 == 8 and the
413 * two arrays are complete [steve]
414 */
415 if (n2 == 8 && dna == 0 && dnb == 0)
96 { 416 {
97 bn_mul_comba8(r,a,b); 417 bn_mul_comba8(r,a,b);
98 return; 418 return;
99 } 419 }
100# endif /* BN_MUL_COMBA */ 420# endif /* BN_MUL_COMBA */
421 /* Else do normal multiply */
101 if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) 422 if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
102 { 423 {
103 /* This should not happen */ 424 bn_mul_normal(r,a,n2+dna,b,n2+dnb);
104 bn_mul_normal(r,a,n2,b,n2); 425 if ((dna + dnb) < 0)
426 memset(&r[2*n2 + dna + dnb], 0,
427 sizeof(BN_ULONG) * -(dna + dnb));
105 return; 428 return;
106 } 429 }
107 /* r=(a[0]-a[1])*(b[1]-b[0]) */ 430 /* r=(a[0]-a[1])*(b[1]-b[0]) */
108 c1=bn_cmp_words(a,&(a[n]),n); 431 c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
109 c2=bn_cmp_words(&(b[n]),b,n); 432 c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
110 zero=neg=0; 433 zero=neg=0;
111 switch (c1*3+c2) 434 switch (c1*3+c2)
112 { 435 {
113 case -4: 436 case -4:
114 bn_sub_words(t, &(a[n]),a, n); /* - */ 437 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
115 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 438 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
116 break; 439 break;
117 case -3: 440 case -3:
118 zero=1; 441 zero=1;
119 break; 442 break;
120 case -2: 443 case -2:
121 bn_sub_words(t, &(a[n]),a, n); /* - */ 444 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
122 bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ 445 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
123 neg=1; 446 neg=1;
124 break; 447 break;
125 case -1: 448 case -1:
@@ -128,21 +451,22 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
128 zero=1; 451 zero=1;
129 break; 452 break;
130 case 2: 453 case 2:
131 bn_sub_words(t, a, &(a[n]),n); /* + */ 454 bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
132 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 455 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
133 neg=1; 456 neg=1;
134 break; 457 break;
135 case 3: 458 case 3:
136 zero=1; 459 zero=1;
137 break; 460 break;
138 case 4: 461 case 4:
139 bn_sub_words(t, a, &(a[n]),n); 462 bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
140 bn_sub_words(&(t[n]),&(b[n]),b, n); 463 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
141 break; 464 break;
142 } 465 }
143 466
144# ifdef BN_MUL_COMBA 467# ifdef BN_MUL_COMBA
145 if (n == 4) 468 if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
469 extra args to do this well */
146 { 470 {
147 if (!zero) 471 if (!zero)
148 bn_mul_comba4(&(t[n2]),t,&(t[n])); 472 bn_mul_comba4(&(t[n2]),t,&(t[n]));
@@ -152,7 +476,9 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
152 bn_mul_comba4(r,a,b); 476 bn_mul_comba4(r,a,b);
153 bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n])); 477 bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
154 } 478 }
155 else if (n == 8) 479 else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
480 take extra args to do this
481 well */
156 { 482 {
157 if (!zero) 483 if (!zero)
158 bn_mul_comba8(&(t[n2]),t,&(t[n])); 484 bn_mul_comba8(&(t[n2]),t,&(t[n]));
@@ -167,11 +493,11 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
167 { 493 {
168 p= &(t[n2*2]); 494 p= &(t[n2*2]);
169 if (!zero) 495 if (!zero)
170 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); 496 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
171 else 497 else
172 memset(&(t[n2]),0,n2*sizeof(BN_ULONG)); 498 memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
173 bn_mul_recursive(r,a,b,n,p); 499 bn_mul_recursive(r,a,b,n,0,0,p);
174 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p); 500 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
175 } 501 }
176 502
177 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign 503 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
@@ -220,39 +546,40 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
220 546
221/* n+tn is the word length 547/* n+tn is the word length
222 * t needs to be n*4 is size, as does r */ 548 * t needs to be n*4 is size, as does r */
223void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn, 549/* tnX may not be negative but less than n */
224 int n, BN_ULONG *t) 550void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
551 int tna, int tnb, BN_ULONG *t)
225 { 552 {
226 int i,j,n2=n*2; 553 int i,j,n2=n*2;
227 int c1,c2,neg,zero; 554 int c1,c2,neg,zero;
228 BN_ULONG ln,lo,*p; 555 BN_ULONG ln,lo,*p;
229 556
230# ifdef BN_COUNT 557# ifdef BN_COUNT
231 printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n); 558 fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
559 n, tna, n, tnb);
232# endif 560# endif
233 if (n < 8) 561 if (n < 8)
234 { 562 {
235 i=tn+n; 563 bn_mul_normal(r,a,n+tna,b,n+tnb);
236 bn_mul_normal(r,a,i,b,i);
237 return; 564 return;
238 } 565 }
239 566
240 /* r=(a[0]-a[1])*(b[1]-b[0]) */ 567 /* r=(a[0]-a[1])*(b[1]-b[0]) */
241 c1=bn_cmp_words(a,&(a[n]),n); 568 c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
242 c2=bn_cmp_words(&(b[n]),b,n); 569 c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
243 zero=neg=0; 570 zero=neg=0;
244 switch (c1*3+c2) 571 switch (c1*3+c2)
245 { 572 {
246 case -4: 573 case -4:
247 bn_sub_words(t, &(a[n]),a, n); /* - */ 574 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
248 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 575 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
249 break; 576 break;
250 case -3: 577 case -3:
251 zero=1; 578 zero=1;
252 /* break; */ 579 /* break; */
253 case -2: 580 case -2:
254 bn_sub_words(t, &(a[n]),a, n); /* - */ 581 bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
255 bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ 582 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
256 neg=1; 583 neg=1;
257 break; 584 break;
258 case -1: 585 case -1:
@@ -261,16 +588,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
261 zero=1; 588 zero=1;
262 /* break; */ 589 /* break; */
263 case 2: 590 case 2:
264 bn_sub_words(t, a, &(a[n]),n); /* + */ 591 bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
265 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 592 bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
266 neg=1; 593 neg=1;
267 break; 594 break;
268 case 3: 595 case 3:
269 zero=1; 596 zero=1;
270 /* break; */ 597 /* break; */
271 case 4: 598 case 4:
272 bn_sub_words(t, a, &(a[n]),n); 599 bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
273 bn_sub_words(&(t[n]),&(b[n]),b, n); 600 bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
274 break; 601 break;
275 } 602 }
276 /* The zero case isn't yet implemented here. The speedup 603 /* The zero case isn't yet implemented here. The speedup
@@ -289,54 +616,62 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
289 { 616 {
290 bn_mul_comba8(&(t[n2]),t,&(t[n])); 617 bn_mul_comba8(&(t[n2]),t,&(t[n]));
291 bn_mul_comba8(r,a,b); 618 bn_mul_comba8(r,a,b);
292 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); 619 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
293 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); 620 memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
294 } 621 }
295 else 622 else
296 { 623 {
297 p= &(t[n2*2]); 624 p= &(t[n2*2]);
298 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); 625 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
299 bn_mul_recursive(r,a,b,n,p); 626 bn_mul_recursive(r,a,b,n,0,0,p);
300 i=n/2; 627 i=n/2;
301 /* If there is only a bottom half to the number, 628 /* If there is only a bottom half to the number,
302 * just do it */ 629 * just do it */
303 j=tn-i; 630 if (tna > tnb)
631 j = tna - i;
632 else
633 j = tnb - i;
304 if (j == 0) 634 if (j == 0)
305 { 635 {
306 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p); 636 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
637 i,tna-i,tnb-i,p);
307 memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2)); 638 memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
308 } 639 }
309 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */ 640 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
310 { 641 {
311 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]), 642 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
312 j,i,p); 643 i,tna-i,tnb-i,p);
313 memset(&(r[n2+tn*2]),0, 644 memset(&(r[n2+tna+tnb]),0,
314 sizeof(BN_ULONG)*(n2-tn*2)); 645 sizeof(BN_ULONG)*(n2-tna-tnb));
315 } 646 }
316 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ 647 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
317 { 648 {
318 memset(&(r[n2]),0,sizeof(BN_ULONG)*n2); 649 memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
319 if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL) 650 if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
651 && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
320 { 652 {
321 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); 653 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
322 } 654 }
323 else 655 else
324 { 656 {
325 for (;;) 657 for (;;)
326 { 658 {
327 i/=2; 659 i/=2;
328 if (i < tn) 660 /* these simplified conditions work
661 * exclusively because difference
662 * between tna and tnb is 1 or 0 */
663 if (i < tna || i < tnb)
329 { 664 {
330 bn_mul_part_recursive(&(r[n2]), 665 bn_mul_part_recursive(&(r[n2]),
331 &(a[n]),&(b[n]), 666 &(a[n]),&(b[n]),
332 tn-i,i,p); 667 i,tna-i,tnb-i,p);
333 break; 668 break;
334 } 669 }
335 else if (i == tn) 670 else if (i == tna || i == tnb)
336 { 671 {
337 bn_mul_recursive(&(r[n2]), 672 bn_mul_recursive(&(r[n2]),
338 &(a[n]),&(b[n]), 673 &(a[n]),&(b[n]),
339 i,p); 674 i,tna-i,tnb-i,p);
340 break; 675 break;
341 } 676 }
342 } 677 }
@@ -397,10 +732,10 @@ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
397 int n=n2/2; 732 int n=n2/2;
398 733
399# ifdef BN_COUNT 734# ifdef BN_COUNT
400 printf(" bn_mul_low_recursive %d * %d\n",n2,n2); 735 fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
401# endif 736# endif
402 737
403 bn_mul_recursive(r,a,b,n,&(t[0])); 738 bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
404 if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) 739 if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
405 { 740 {
406 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2])); 741 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
@@ -431,7 +766,7 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
431 BN_ULONG ll,lc,*lp,*mp; 766 BN_ULONG ll,lc,*lp,*mp;
432 767
433# ifdef BN_COUNT 768# ifdef BN_COUNT
434 printf(" bn_mul_high %d * %d\n",n2,n2); 769 fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
435# endif 770# endif
436 n=n2/2; 771 n=n2/2;
437 772
@@ -484,8 +819,8 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
484 else 819 else
485# endif 820# endif
486 { 821 {
487 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2])); 822 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
488 bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2])); 823 bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
489 } 824 }
490 825
491 /* s0 == low(al*bl) 826 /* s0 == low(al*bl)
@@ -610,19 +945,19 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
610 945
611int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 946int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
612 { 947 {
948 int ret=0;
613 int top,al,bl; 949 int top,al,bl;
614 BIGNUM *rr; 950 BIGNUM *rr;
615 int ret = 0;
616#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) 951#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
617 int i; 952 int i;
618#endif 953#endif
619#ifdef BN_RECURSION 954#ifdef BN_RECURSION
620 BIGNUM *t; 955 BIGNUM *t=NULL;
621 int j,k; 956 int j=0,k;
622#endif 957#endif
623 958
624#ifdef BN_COUNT 959#ifdef BN_COUNT
625 printf("BN_mul %d * %d\n",a->top,b->top); 960 fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
626#endif 961#endif
627 962
628 bn_check_top(a); 963 bn_check_top(a);
@@ -634,7 +969,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
634 969
635 if ((al == 0) || (bl == 0)) 970 if ((al == 0) || (bl == 0))
636 { 971 {
637 if (!BN_zero(r)) goto err; 972 BN_zero(r);
638 return(1); 973 return(1);
639 } 974 }
640 top=al+bl; 975 top=al+bl;
@@ -675,21 +1010,55 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
675#ifdef BN_RECURSION 1010#ifdef BN_RECURSION
676 if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) 1011 if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
677 { 1012 {
678 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA) && bl<b->dmax) 1013 if (i >= -1 && i <= 1)
679 { 1014 {
680#if 0 /* tribute to const-ification, bl<b->dmax above covers for this */ 1015 int sav_j =0;
681 if (bn_wexpand(b,al) == NULL) goto err; 1016 /* Find out the power of two lower or equal
682#endif 1017 to the longest of the two numbers */
683 b->d[bl]=0; 1018 if (i >= 0)
1019 {
1020 j = BN_num_bits_word((BN_ULONG)al);
1021 }
1022 if (i == -1)
1023 {
1024 j = BN_num_bits_word((BN_ULONG)bl);
1025 }
1026 sav_j = j;
1027 j = 1<<(j-1);
1028 assert(j <= al || j <= bl);
1029 k = j+j;
1030 t = BN_CTX_get(ctx);
1031 if (al > j || bl > j)
1032 {
1033 bn_wexpand(t,k*4);
1034 bn_wexpand(rr,k*4);
1035 bn_mul_part_recursive(rr->d,a->d,b->d,
1036 j,al-j,bl-j,t->d);
1037 }
1038 else /* al <= j || bl <= j */
1039 {
1040 bn_wexpand(t,k*2);
1041 bn_wexpand(rr,k*2);
1042 bn_mul_recursive(rr->d,a->d,b->d,
1043 j,al-j,bl-j,t->d);
1044 }
1045 rr->top=top;
1046 goto end;
1047 }
1048#if 0
1049 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
1050 {
1051 BIGNUM *tmp_bn = (BIGNUM *)b;
1052 if (bn_wexpand(tmp_bn,al) == NULL) goto err;
1053 tmp_bn->d[bl]=0;
684 bl++; 1054 bl++;
685 i--; 1055 i--;
686 } 1056 }
687 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA) && al<a->dmax) 1057 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
688 { 1058 {
689#if 0 /* tribute to const-ification, al<a->dmax above covers for this */ 1059 BIGNUM *tmp_bn = (BIGNUM *)a;
690 if (bn_wexpand(a,bl) == NULL) goto err; 1060 if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
691#endif 1061 tmp_bn->d[al]=0;
692 a->d[al]=0;
693 al++; 1062 al++;
694 i++; 1063 i++;
695 } 1064 }
@@ -706,26 +1075,17 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
706 if (bn_wexpand(t,k*2) == NULL) goto err; 1075 if (bn_wexpand(t,k*2) == NULL) goto err;
707 if (bn_wexpand(rr,k*2) == NULL) goto err; 1076 if (bn_wexpand(rr,k*2) == NULL) goto err;
708 bn_mul_recursive(rr->d,a->d,b->d,al,t->d); 1077 bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
709 rr->top=top;
710 goto end;
711 } 1078 }
712#if 0 /* tribute to const-ification, rsa/dsa performance is not affected */
713 else 1079 else
714 { 1080 {
715 if (bn_wexpand(a,k) == NULL ) goto err; 1081 if (bn_wexpand(t,k*4) == NULL) goto err;
716 if (bn_wexpand(b,k) == NULL ) goto err; 1082 if (bn_wexpand(rr,k*4) == NULL) goto err;
717 if (bn_wexpand(t,k*4) == NULL ) goto err;
718 if (bn_wexpand(rr,k*4) == NULL ) goto err;
719 for (i=a->top; i<k; i++)
720 a->d[i]=0;
721 for (i=b->top; i<k; i++)
722 b->d[i]=0;
723 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); 1083 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
724 } 1084 }
725 rr->top=top; 1085 rr->top=top;
726 goto end; 1086 goto end;
727#endif
728 } 1087 }
1088#endif
729 } 1089 }
730#endif /* BN_RECURSION */ 1090#endif /* BN_RECURSION */
731 if (bn_wexpand(rr,top) == NULL) goto err; 1091 if (bn_wexpand(rr,top) == NULL) goto err;
@@ -735,10 +1095,11 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
735#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) 1095#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
736end: 1096end:
737#endif 1097#endif
738 bn_fix_top(rr); 1098 bn_correct_top(rr);
739 if (r != rr) BN_copy(r,rr); 1099 if (r != rr) BN_copy(r,rr);
740 ret=1; 1100 ret=1;
741err: 1101err:
1102 bn_check_top(r);
742 BN_CTX_end(ctx); 1103 BN_CTX_end(ctx);
743 return(ret); 1104 return(ret);
744 } 1105 }
@@ -748,7 +1109,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
748 BN_ULONG *rr; 1109 BN_ULONG *rr;
749 1110
750#ifdef BN_COUNT 1111#ifdef BN_COUNT
751 printf(" bn_mul_normal %d * %d\n",na,nb); 1112 fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
752#endif 1113#endif
753 1114
754 if (na < nb) 1115 if (na < nb)
@@ -761,7 +1122,13 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
761 1122
762 } 1123 }
763 rr= &(r[na]); 1124 rr= &(r[na]);
764 rr[0]=bn_mul_words(r,a,na,b[0]); 1125 if (nb <= 0)
1126 {
1127 (void)bn_mul_words(r,a,na,0);
1128 return;
1129 }
1130 else
1131 rr[0]=bn_mul_words(r,a,na,b[0]);
765 1132
766 for (;;) 1133 for (;;)
767 { 1134 {
@@ -782,7 +1149,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
782void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 1149void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
783 { 1150 {
784#ifdef BN_COUNT 1151#ifdef BN_COUNT
785 printf(" bn_mul_low_normal %d * %d\n",n,n); 1152 fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
786#endif 1153#endif
787 bn_mul_words(r,a,n,b[0]); 1154 bn_mul_words(r,a,n,b[0]);
788 1155
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c
index f422172f16..7b25979dd1 100644
--- a/src/lib/libcrypto/bn/bn_prime.c
+++ b/src/lib/libcrypto/bn/bn_prime.c
@@ -115,6 +115,11 @@
115#include "bn_lcl.h" 115#include "bn_lcl.h"
116#include <openssl/rand.h> 116#include <openssl/rand.h>
117 117
118/* NB: these functions have been "upgraded", the deprecated versions (which are
119 * compatibility wrappers using these functions) are in bn_depr.c.
120 * - Geoff
121 */
122
118/* The quick sieve algorithm approach to weeding out primes is 123/* The quick sieve algorithm approach to weeding out primes is
119 * Philip Zimmermann's, as implemented in PGP. I have had a read of 124 * Philip Zimmermann's, as implemented in PGP. I have had a read of
120 * his comments and implemented my own version. 125 * his comments and implemented my own version.
@@ -129,51 +134,69 @@ static int probable_prime_dh(BIGNUM *rnd, int bits,
129static int probable_prime_dh_safe(BIGNUM *rnd, int bits, 134static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
130 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); 135 const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
131 136
132BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, 137int BN_GENCB_call(BN_GENCB *cb, int a, int b)
133 const BIGNUM *add, const BIGNUM *rem, 138 {
134 void (*callback)(int,int,void *), void *cb_arg) 139 /* No callback means continue */
140 if(!cb) return 1;
141 switch(cb->ver)
142 {
143 case 1:
144 /* Deprecated-style callbacks */
145 if(!cb->cb.cb_1)
146 return 1;
147 cb->cb.cb_1(a, b, cb->arg);
148 return 1;
149 case 2:
150 /* New-style callbacks */
151 return cb->cb.cb_2(a, b, cb);
152 default:
153 break;
154 }
155 /* Unrecognised callback type */
156 return 0;
157 }
158
159int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
160 const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
135 { 161 {
136 BIGNUM *rnd=NULL; 162 BIGNUM *t;
137 BIGNUM t;
138 int found=0; 163 int found=0;
139 int i,j,c1=0; 164 int i,j,c1=0;
140 BN_CTX *ctx; 165 BN_CTX *ctx;
141 int checks = BN_prime_checks_for_size(bits); 166 int checks = BN_prime_checks_for_size(bits);
142 167
143 BN_init(&t);
144 ctx=BN_CTX_new(); 168 ctx=BN_CTX_new();
145 if (ctx == NULL) goto err; 169 if (ctx == NULL) goto err;
146 if (ret == NULL) 170 BN_CTX_start(ctx);
147 { 171 t = BN_CTX_get(ctx);
148 if ((rnd=BN_new()) == NULL) goto err; 172 if(!t) goto err;
149 }
150 else
151 rnd=ret;
152loop: 173loop:
153 /* make a random number and set the top and bottom bits */ 174 /* make a random number and set the top and bottom bits */
154 if (add == NULL) 175 if (add == NULL)
155 { 176 {
156 if (!probable_prime(rnd,bits)) goto err; 177 if (!probable_prime(ret,bits)) goto err;
157 } 178 }
158 else 179 else
159 { 180 {
160 if (safe) 181 if (safe)
161 { 182 {
162 if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx)) 183 if (!probable_prime_dh_safe(ret,bits,add,rem,ctx))
163 goto err; 184 goto err;
164 } 185 }
165 else 186 else
166 { 187 {
167 if (!probable_prime_dh(rnd,bits,add,rem,ctx)) 188 if (!probable_prime_dh(ret,bits,add,rem,ctx))
168 goto err; 189 goto err;
169 } 190 }
170 } 191 }
171 /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ 192 /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
172 if (callback != NULL) callback(0,c1++,cb_arg); 193 if(!BN_GENCB_call(cb, 0, c1++))
194 /* aborted */
195 goto err;
173 196
174 if (!safe) 197 if (!safe)
175 { 198 {
176 i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0); 199 i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb);
177 if (i == -1) goto err; 200 if (i == -1) goto err;
178 if (i == 0) goto loop; 201 if (i == 0) goto loop;
179 } 202 }
@@ -183,41 +206,42 @@ loop:
183 * check that (p-1)/2 is prime. 206 * check that (p-1)/2 is prime.
184 * Since a prime is odd, We just 207 * Since a prime is odd, We just
185 * need to divide by 2 */ 208 * need to divide by 2 */
186 if (!BN_rshift1(&t,rnd)) goto err; 209 if (!BN_rshift1(t,ret)) goto err;
187 210
188 for (i=0; i<checks; i++) 211 for (i=0; i<checks; i++)
189 { 212 {
190 j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0); 213 j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb);
191 if (j == -1) goto err; 214 if (j == -1) goto err;
192 if (j == 0) goto loop; 215 if (j == 0) goto loop;
193 216
194 j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0); 217 j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb);
195 if (j == -1) goto err; 218 if (j == -1) goto err;
196 if (j == 0) goto loop; 219 if (j == 0) goto loop;
197 220
198 if (callback != NULL) callback(2,c1-1,cb_arg); 221 if(!BN_GENCB_call(cb, 2, c1-1))
222 goto err;
199 /* We have a safe prime test pass */ 223 /* We have a safe prime test pass */
200 } 224 }
201 } 225 }
202 /* we have a prime :-) */ 226 /* we have a prime :-) */
203 found = 1; 227 found = 1;
204err: 228err:
205 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); 229 if (ctx != NULL)
206 BN_free(&t); 230 {
207 if (ctx != NULL) BN_CTX_free(ctx); 231 BN_CTX_end(ctx);
208 return(found ? rnd : NULL); 232 BN_CTX_free(ctx);
233 }
234 bn_check_top(ret);
235 return found;
209 } 236 }
210 237
211int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *), 238int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
212 BN_CTX *ctx_passed, void *cb_arg)
213 { 239 {
214 return BN_is_prime_fasttest(a, checks, callback, ctx_passed, cb_arg, 0); 240 return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
215 } 241 }
216 242
217int BN_is_prime_fasttest(const BIGNUM *a, int checks, 243int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
218 void (*callback)(int,int,void *), 244 int do_trial_division, BN_GENCB *cb)
219 BN_CTX *ctx_passed, void *cb_arg,
220 int do_trial_division)
221 { 245 {
222 int i, j, ret = -1; 246 int i, j, ret = -1;
223 int k; 247 int k;
@@ -236,13 +260,13 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
236 if (!BN_is_odd(a)) 260 if (!BN_is_odd(a))
237 /* a is even => a is prime if and only if a == 2 */ 261 /* a is even => a is prime if and only if a == 2 */
238 return BN_is_word(a, 2); 262 return BN_is_word(a, 2);
239
240 if (do_trial_division) 263 if (do_trial_division)
241 { 264 {
242 for (i = 1; i < NUMPRIMES; i++) 265 for (i = 1; i < NUMPRIMES; i++)
243 if (BN_mod_word(a, primes[i]) == 0) 266 if (BN_mod_word(a, primes[i]) == 0)
244 return 0; 267 return 0;
245 if (callback != NULL) callback(1, -1, cb_arg); 268 if(!BN_GENCB_call(cb, 1, -1))
269 goto err;
246 } 270 }
247 271
248 if (ctx_passed != NULL) 272 if (ctx_passed != NULL)
@@ -308,7 +332,8 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks,
308 ret=0; 332 ret=0;
309 goto err; 333 goto err;
310 } 334 }
311 if (callback != NULL) callback(1,i,cb_arg); 335 if(!BN_GENCB_call(cb, 1, i))
336 goto err;
312 } 337 }
313 ret=1; 338 ret=1;
314err: 339err:
@@ -345,20 +370,22 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
345 } 370 }
346 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', 371 /* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
347 * and it is neither -1 nor +1 -- so 'a' cannot be prime */ 372 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
373 bn_check_top(w);
348 return 1; 374 return 1;
349 } 375 }
350 376
351static int probable_prime(BIGNUM *rnd, int bits) 377static int probable_prime(BIGNUM *rnd, int bits)
352 { 378 {
353 int i; 379 int i;
354 BN_ULONG mods[NUMPRIMES]; 380 prime_t mods[NUMPRIMES];
355 BN_ULONG delta,d; 381 BN_ULONG delta,maxdelta;
356 382
357again: 383again:
358 if (!BN_rand(rnd,bits,1,1)) return(0); 384 if (!BN_rand(rnd,bits,1,1)) return(0);
359 /* we now have a random number 'rand' to test. */ 385 /* we now have a random number 'rand' to test. */
360 for (i=1; i<NUMPRIMES; i++) 386 for (i=1; i<NUMPRIMES; i++)
361 mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]); 387 mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
388 maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
362 delta=0; 389 delta=0;
363 loop: for (i=1; i<NUMPRIMES; i++) 390 loop: for (i=1; i<NUMPRIMES; i++)
364 { 391 {
@@ -366,16 +393,13 @@ again:
366 * that gcd(rnd-1,primes) == 1 (except for 2) */ 393 * that gcd(rnd-1,primes) == 1 (except for 2) */
367 if (((mods[i]+delta)%primes[i]) <= 1) 394 if (((mods[i]+delta)%primes[i]) <= 1)
368 { 395 {
369 d=delta;
370 delta+=2; 396 delta+=2;
371 /* perhaps need to check for overflow of 397 if (delta > maxdelta) goto again;
372 * delta (but delta can be up to 2^32)
373 * 21-May-98 eay - added overflow check */
374 if (delta < d) goto again;
375 goto loop; 398 goto loop;
376 } 399 }
377 } 400 }
378 if (!BN_add_word(rnd,delta)) return(0); 401 if (!BN_add_word(rnd,delta)) return(0);
402 bn_check_top(rnd);
379 return(1); 403 return(1);
380 } 404 }
381 405
@@ -413,6 +437,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits,
413 ret=1; 437 ret=1;
414err: 438err:
415 BN_CTX_end(ctx); 439 BN_CTX_end(ctx);
440 bn_check_top(rnd);
416 return(ret); 441 return(ret);
417 } 442 }
418 443
@@ -464,5 +489,6 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
464 ret=1; 489 ret=1;
465err: 490err:
466 BN_CTX_end(ctx); 491 BN_CTX_end(ctx);
492 bn_check_top(p);
467 return(ret); 493 return(ret);
468 } 494 }
diff --git a/src/lib/libcrypto/bn/bn_prime.h b/src/lib/libcrypto/bn/bn_prime.h
index b7cf9a9bfe..51d2194feb 100644
--- a/src/lib/libcrypto/bn/bn_prime.h
+++ b/src/lib/libcrypto/bn/bn_prime.h
@@ -58,10 +58,12 @@
58 58
59#ifndef EIGHT_BIT 59#ifndef EIGHT_BIT
60#define NUMPRIMES 2048 60#define NUMPRIMES 2048
61typedef unsigned short prime_t;
61#else 62#else
62#define NUMPRIMES 54 63#define NUMPRIMES 54
64typedef unsigned char prime_t;
63#endif 65#endif
64static const unsigned int primes[NUMPRIMES]= 66static const prime_t primes[NUMPRIMES]=
65 { 67 {
66 2, 3, 5, 7, 11, 13, 17, 19, 68 2, 3, 5, 7, 11, 13, 17, 19,
67 23, 29, 31, 37, 41, 43, 47, 53, 69 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 9fc3765486..3fafb6f3e9 100644
--- a/src/lib/libcrypto/bn/bn_prime.pl
+++ b/src/lib/libcrypto/bn/bn_prime.pl
@@ -11,7 +11,7 @@ loop: while ($#primes < $num-1)
11 $p+=2; 11 $p+=2;
12 $s=int(sqrt($p)); 12 $s=int(sqrt($p));
13 13
14 for ($i=0; $primes[$i]<=$s; $i++) 14 for ($i=0; defined($primes[$i]) && $primes[$i]<=$s; $i++)
15 { 15 {
16 next loop if (($p%$primes[$i]) == 0); 16 next loop if (($p%$primes[$i]) == 0);
17 } 17 }
@@ -101,10 +101,12 @@ for ($i=0; $i <= $#primes; $i++)
101 101
102printf "#ifndef EIGHT_BIT\n"; 102printf "#ifndef EIGHT_BIT\n";
103printf "#define NUMPRIMES %d\n",$num; 103printf "#define NUMPRIMES %d\n",$num;
104printf "typedef unsigned short prime_t;\n";
104printf "#else\n"; 105printf "#else\n";
105printf "#define NUMPRIMES %d\n",$eight; 106printf "#define NUMPRIMES %d\n",$eight;
107printf "typedef unsigned char prime_t;\n";
106printf "#endif\n"; 108printf "#endif\n";
107print "static const unsigned int primes[NUMPRIMES]=\n\t{\n\t"; 109print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t";
108$init=0; 110$init=0;
109for ($i=0; $i <= $#primes; $i++) 111for ($i=0; $i <= $#primes; $i++)
110 { 112 {
diff --git a/src/lib/libcrypto/bn/bn_print.c b/src/lib/libcrypto/bn/bn_print.c
index acba7ed7ee..810dde34e1 100644
--- a/src/lib/libcrypto/bn/bn_print.c
+++ b/src/lib/libcrypto/bn/bn_print.c
@@ -62,7 +62,7 @@
62#include <openssl/buffer.h> 62#include <openssl/buffer.h>
63#include "bn_lcl.h" 63#include "bn_lcl.h"
64 64
65static const char *Hex="0123456789ABCDEF"; 65static const char Hex[]="0123456789ABCDEF";
66 66
67/* Must 'OPENSSL_free' the returned data */ 67/* Must 'OPENSSL_free' the returned data */
68char *BN_bn2hex(const BIGNUM *a) 68char *BN_bn2hex(const BIGNUM *a)
@@ -102,14 +102,19 @@ err:
102/* Must 'OPENSSL_free' the returned data */ 102/* Must 'OPENSSL_free' the returned data */
103char *BN_bn2dec(const BIGNUM *a) 103char *BN_bn2dec(const BIGNUM *a)
104 { 104 {
105 int i=0,num; 105 int i=0,num, ok = 0;
106 char *buf=NULL; 106 char *buf=NULL;
107 char *p; 107 char *p;
108 BIGNUM *t=NULL; 108 BIGNUM *t=NULL;
109 BN_ULONG *bn_data=NULL,*lp; 109 BN_ULONG *bn_data=NULL,*lp;
110 110
111 /* get an upper bound for the length of the decimal integer
112 * num <= (BN_num_bits(a) + 1) * log(2)
113 * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
114 * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
115 */
111 i=BN_num_bits(a)*3; 116 i=BN_num_bits(a)*3;
112 num=(i/10+i/1000+3)+1; 117 num=(i/10+i/1000+1)+1;
113 bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG)); 118 bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
114 buf=(char *)OPENSSL_malloc(num+3); 119 buf=(char *)OPENSSL_malloc(num+3);
115 if ((buf == NULL) || (bn_data == NULL)) 120 if ((buf == NULL) || (bn_data == NULL))
@@ -122,7 +127,6 @@ char *BN_bn2dec(const BIGNUM *a)
122#define BUF_REMAIN (num+3 - (size_t)(p - buf)) 127#define BUF_REMAIN (num+3 - (size_t)(p - buf))
123 p=buf; 128 p=buf;
124 lp=bn_data; 129 lp=bn_data;
125 if (t->neg) *(p++)='-';
126 if (BN_is_zero(t)) 130 if (BN_is_zero(t))
127 { 131 {
128 *(p++)='0'; 132 *(p++)='0';
@@ -130,6 +134,9 @@ char *BN_bn2dec(const BIGNUM *a)
130 } 134 }
131 else 135 else
132 { 136 {
137 if (BN_is_negative(t))
138 *p++ = '-';
139
133 i=0; 140 i=0;
134 while (!BN_is_zero(t)) 141 while (!BN_is_zero(t))
135 { 142 {
@@ -149,9 +156,16 @@ char *BN_bn2dec(const BIGNUM *a)
149 while (*p) p++; 156 while (*p) p++;
150 } 157 }
151 } 158 }
159 ok = 1;
152err: 160err:
153 if (bn_data != NULL) OPENSSL_free(bn_data); 161 if (bn_data != NULL) OPENSSL_free(bn_data);
154 if (t != NULL) BN_free(t); 162 if (t != NULL) BN_free(t);
163 if (!ok && buf)
164 {
165 OPENSSL_free(buf);
166 buf = NULL;
167 }
168
155 return(buf); 169 return(buf);
156 } 170 }
157 171
@@ -211,10 +225,11 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
211 j-=(BN_BYTES*2); 225 j-=(BN_BYTES*2);
212 } 226 }
213 ret->top=h; 227 ret->top=h;
214 bn_fix_top(ret); 228 bn_correct_top(ret);
215 ret->neg=neg; 229 ret->neg=neg;
216 230
217 *bn=ret; 231 *bn=ret;
232 bn_check_top(ret);
218 return(num); 233 return(num);
219err: 234err:
220 if (*bn == NULL) BN_free(ret); 235 if (*bn == NULL) BN_free(ret);
@@ -270,8 +285,9 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
270 } 285 }
271 ret->neg=neg; 286 ret->neg=neg;
272 287
273 bn_fix_top(ret); 288 bn_correct_top(ret);
274 *bn=ret; 289 *bn=ret;
290 bn_check_top(ret);
275 return(num); 291 return(num);
276err: 292err:
277 if (*bn == NULL) BN_free(ret); 293 if (*bn == NULL) BN_free(ret);
@@ -300,7 +316,7 @@ int BN_print(BIO *bp, const BIGNUM *a)
300 int ret=0; 316 int ret=0;
301 317
302 if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end; 318 if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
303 if ((BN_is_zero(a)) && (BIO_write(bp,"0",1) != 1)) goto end; 319 if (BN_is_zero(a) && (BIO_write(bp,"0",1) != 1)) goto end;
304 for (i=a->top-1; i >=0; i--) 320 for (i=a->top-1; i >=0; i--)
305 { 321 {
306 for (j=BN_BITS2-4; j >= 0; j-=4) 322 for (j=BN_BITS2-4; j >= 0; j-=4)
@@ -320,14 +336,3 @@ end:
320 return(ret); 336 return(ret);
321 } 337 }
322#endif 338#endif
323
324#ifdef BN_DEBUG
325void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n)
326 {
327 int i;
328 fprintf(o, "%s=", a);
329 for (i=n-1;i>=0;i--)
330 fprintf(o, "%08lX", b[i]); /* assumes 32-bit BN_ULONG */
331 fprintf(o, "\n");
332 }
333#endif
diff --git a/src/lib/libcrypto/bn/bn_rand.c b/src/lib/libcrypto/bn/bn_rand.c
index 893c9d2af9..f51830b12b 100644
--- a/src/lib/libcrypto/bn/bn_rand.c
+++ b/src/lib/libcrypto/bn/bn_rand.c
@@ -134,13 +134,13 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
134 buf=(unsigned char *)OPENSSL_malloc(bytes); 134 buf=(unsigned char *)OPENSSL_malloc(bytes);
135 if (buf == NULL) 135 if (buf == NULL)
136 { 136 {
137 BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE); 137 BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE);
138 goto err; 138 goto err;
139 } 139 }
140 140
141 /* make a random number and set the top and bottom bits */ 141 /* make a random number and set the top and bottom bits */
142 time(&tim); 142 time(&tim);
143 RAND_add(&tim,sizeof(tim),0); 143 RAND_add(&tim,sizeof(tim),0.0);
144 144
145 if (pseudorand) 145 if (pseudorand)
146 { 146 {
@@ -204,6 +204,7 @@ err:
204 OPENSSL_cleanse(buf,bytes); 204 OPENSSL_cleanse(buf,bytes);
205 OPENSSL_free(buf); 205 OPENSSL_free(buf);
206 } 206 }
207 bn_check_top(rnd);
207 return(ret); 208 return(ret);
208 } 209 }
209 210
@@ -230,6 +231,7 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
230 { 231 {
231 int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; 232 int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
232 int n; 233 int n;
234 int count = 100;
233 235
234 if (range->neg || BN_is_zero(range)) 236 if (range->neg || BN_is_zero(range))
235 { 237 {
@@ -242,9 +244,7 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
242 /* BN_is_bit_set(range, n - 1) always holds */ 244 /* BN_is_bit_set(range, n - 1) always holds */
243 245
244 if (n == 1) 246 if (n == 1)
245 { 247 BN_zero(r);
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)) 248 else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
249 { 249 {
250 /* range = 100..._2, 250 /* range = 100..._2,
@@ -263,6 +263,13 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
263 if (BN_cmp(r, range) >= 0) 263 if (BN_cmp(r, range) >= 0)
264 if (!BN_sub(r, r, range)) return 0; 264 if (!BN_sub(r, r, range)) return 0;
265 } 265 }
266
267 if (!--count)
268 {
269 BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
270 return 0;
271 }
272
266 } 273 }
267 while (BN_cmp(r, range) >= 0); 274 while (BN_cmp(r, range) >= 0);
268 } 275 }
@@ -272,10 +279,17 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
272 { 279 {
273 /* range = 11..._2 or range = 101..._2 */ 280 /* range = 11..._2 or range = 101..._2 */
274 if (!bn_rand(r, n, -1, 0)) return 0; 281 if (!bn_rand(r, n, -1, 0)) return 0;
282
283 if (!--count)
284 {
285 BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
286 return 0;
287 }
275 } 288 }
276 while (BN_cmp(r, range) >= 0); 289 while (BN_cmp(r, range) >= 0);
277 } 290 }
278 291
292 bn_check_top(r);
279 return 1; 293 return 1;
280 } 294 }
281 295
diff --git a/src/lib/libcrypto/bn/bn_recp.c b/src/lib/libcrypto/bn/bn_recp.c
index ef5fdd4708..2e8efb8dae 100644
--- a/src/lib/libcrypto/bn/bn_recp.c
+++ b/src/lib/libcrypto/bn/bn_recp.c
@@ -94,7 +94,7 @@ void BN_RECP_CTX_free(BN_RECP_CTX *recp)
94int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) 94int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
95 { 95 {
96 if (!BN_copy(&(recp->N),d)) return 0; 96 if (!BN_copy(&(recp->N),d)) return 0;
97 if (!BN_zero(&(recp->Nr))) return 0; 97 BN_zero(&(recp->Nr));
98 recp->num_bits=BN_num_bits(d); 98 recp->num_bits=BN_num_bits(d);
99 recp->shift=0; 99 recp->shift=0;
100 return(1); 100 return(1);
@@ -123,6 +123,7 @@ int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
123 ret = BN_div_recp(NULL,r,ca,recp,ctx); 123 ret = BN_div_recp(NULL,r,ca,recp,ctx);
124err: 124err:
125 BN_CTX_end(ctx); 125 BN_CTX_end(ctx);
126 bn_check_top(r);
126 return(ret); 127 return(ret);
127 } 128 }
128 129
@@ -147,7 +148,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
147 148
148 if (BN_ucmp(m,&(recp->N)) < 0) 149 if (BN_ucmp(m,&(recp->N)) < 0)
149 { 150 {
150 if (!BN_zero(d)) return 0; 151 BN_zero(d);
151 if (!BN_copy(r,m)) return 0; 152 if (!BN_copy(r,m)) return 0;
152 BN_CTX_end(ctx); 153 BN_CTX_end(ctx);
153 return(1); 154 return(1);
@@ -190,7 +191,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
190 { 191 {
191 if (j++ > 2) 192 if (j++ > 2)
192 { 193 {
193 BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL); 194 BNerr(BN_F_BN_DIV_RECP,BN_R_BAD_RECIPROCAL);
194 goto err; 195 goto err;
195 } 196 }
196 if (!BN_usub(r,r,&(recp->N))) goto err; 197 if (!BN_usub(r,r,&(recp->N))) goto err;
@@ -203,6 +204,8 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
203 ret=1; 204 ret=1;
204err: 205err:
205 BN_CTX_end(ctx); 206 BN_CTX_end(ctx);
207 bn_check_top(dv);
208 bn_check_top(rem);
206 return(ret); 209 return(ret);
207 } 210 }
208 211
@@ -214,17 +217,18 @@ err:
214int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) 217int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
215 { 218 {
216 int ret= -1; 219 int ret= -1;
217 BIGNUM t; 220 BIGNUM *t;
218 221
219 BN_init(&t); 222 BN_CTX_start(ctx);
223 if((t = BN_CTX_get(ctx)) == NULL) goto err;
220 224
221 if (!BN_zero(&t)) goto err; 225 if (!BN_set_bit(t,len)) goto err;
222 if (!BN_set_bit(&t,len)) goto err;
223 226
224 if (!BN_div(r,NULL,&t,m,ctx)) goto err; 227 if (!BN_div(r,NULL,t,m,ctx)) goto err;
225 228
226 ret=len; 229 ret=len;
227err: 230err:
228 BN_free(&t); 231 bn_check_top(r);
232 BN_CTX_end(ctx);
229 return(ret); 233 return(ret);
230 } 234 }
diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c
index 70f785ea18..de9312dce2 100644
--- a/src/lib/libcrypto/bn/bn_shift.c
+++ b/src/lib/libcrypto/bn/bn_shift.c
@@ -65,6 +65,9 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
65 register BN_ULONG *ap,*rp,t,c; 65 register BN_ULONG *ap,*rp,t,c;
66 int i; 66 int i;
67 67
68 bn_check_top(r);
69 bn_check_top(a);
70
68 if (r != a) 71 if (r != a)
69 { 72 {
70 r->neg=a->neg; 73 r->neg=a->neg;
@@ -89,6 +92,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
89 *rp=1; 92 *rp=1;
90 r->top++; 93 r->top++;
91 } 94 }
95 bn_check_top(r);
92 return(1); 96 return(1);
93 } 97 }
94 98
@@ -97,6 +101,9 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
97 BN_ULONG *ap,*rp,t,c; 101 BN_ULONG *ap,*rp,t,c;
98 int i; 102 int i;
99 103
104 bn_check_top(r);
105 bn_check_top(a);
106
100 if (BN_is_zero(a)) 107 if (BN_is_zero(a))
101 { 108 {
102 BN_zero(r); 109 BN_zero(r);
@@ -117,7 +124,8 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
117 rp[i]=((t>>1)&BN_MASK2)|c; 124 rp[i]=((t>>1)&BN_MASK2)|c;
118 c=(t&1)?BN_TBIT:0; 125 c=(t&1)?BN_TBIT:0;
119 } 126 }
120 bn_fix_top(r); 127 bn_correct_top(r);
128 bn_check_top(r);
121 return(1); 129 return(1);
122 } 130 }
123 131
@@ -127,6 +135,9 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
127 BN_ULONG *t,*f; 135 BN_ULONG *t,*f;
128 BN_ULONG l; 136 BN_ULONG l;
129 137
138 bn_check_top(r);
139 bn_check_top(a);
140
130 r->neg=a->neg; 141 r->neg=a->neg;
131 nw=n/BN_BITS2; 142 nw=n/BN_BITS2;
132 if (bn_wexpand(r,a->top+nw+1) == NULL) return(0); 143 if (bn_wexpand(r,a->top+nw+1) == NULL) return(0);
@@ -149,7 +160,8 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
149/* for (i=0; i<nw; i++) 160/* for (i=0; i<nw; i++)
150 t[i]=0;*/ 161 t[i]=0;*/
151 r->top=a->top+nw+1; 162 r->top=a->top+nw+1;
152 bn_fix_top(r); 163 bn_correct_top(r);
164 bn_check_top(r);
153 return(1); 165 return(1);
154 } 166 }
155 167
@@ -159,6 +171,9 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
159 BN_ULONG *t,*f; 171 BN_ULONG *t,*f;
160 BN_ULONG l,tmp; 172 BN_ULONG l,tmp;
161 173
174 bn_check_top(r);
175 bn_check_top(a);
176
162 nw=n/BN_BITS2; 177 nw=n/BN_BITS2;
163 rb=n%BN_BITS2; 178 rb=n%BN_BITS2;
164 lb=BN_BITS2-rb; 179 lb=BN_BITS2-rb;
@@ -185,13 +200,13 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
185 200
186 if (rb == 0) 201 if (rb == 0)
187 { 202 {
188 for (i=j+1; i > 0; i--) 203 for (i=j; i != 0; i--)
189 *(t++)= *(f++); 204 *(t++)= *(f++);
190 } 205 }
191 else 206 else
192 { 207 {
193 l= *(f++); 208 l= *(f++);
194 for (i=1; i<j; i++) 209 for (i=j-1; i != 0; i--)
195 { 210 {
196 tmp =(l>>rb)&BN_MASK2; 211 tmp =(l>>rb)&BN_MASK2;
197 l= *(f++); 212 l= *(f++);
@@ -199,7 +214,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
199 } 214 }
200 *(t++) =(l>>rb)&BN_MASK2; 215 *(t++) =(l>>rb)&BN_MASK2;
201 } 216 }
202 *t=0; 217 bn_correct_top(r);
203 bn_fix_top(r); 218 bn_check_top(r);
204 return(1); 219 return(1);
205 } 220 }
diff --git a/src/lib/libcrypto/bn/bn_sqr.c b/src/lib/libcrypto/bn/bn_sqr.c
index c1d0cca438..270d0cd348 100644
--- a/src/lib/libcrypto/bn/bn_sqr.c
+++ b/src/lib/libcrypto/bn/bn_sqr.c
@@ -77,16 +77,16 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
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 BN_CTX_start(ctx); 83 BN_CTX_start(ctx);
84 rr=(a != r) ? r : BN_CTX_get(ctx); 84 rr=(a != r) ? r : BN_CTX_get(ctx);
85 tmp=BN_CTX_get(ctx); 85 tmp=BN_CTX_get(ctx);
86 if (tmp == NULL) goto err; 86 if (!rr || !tmp) goto err;
87 87
88 max=(al+al); 88 max = 2 * al; /* Non-zero (from above) */
89 if (bn_wexpand(rr,max+1) == NULL) goto err; 89 if (bn_wexpand(rr,max) == NULL) goto err;
90 90
91 if (al == 4) 91 if (al == 4)
92 { 92 {
@@ -138,12 +138,18 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
138#endif 138#endif
139 } 139 }
140 140
141 rr->top=max;
142 rr->neg=0; 141 rr->neg=0;
143 if ((max > 0) && (rr->d[max-1] == 0)) rr->top--; 142 /* If the most-significant half of the top word of 'a' is zero, then
143 * the square of 'a' will max-1 words. */
144 if(a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
145 rr->top = max - 1;
146 else
147 rr->top = max;
144 if (rr != r) BN_copy(r,rr); 148 if (rr != r) BN_copy(r,rr);
145 ret = 1; 149 ret = 1;
146 err: 150 err:
151 bn_check_top(rr);
152 bn_check_top(tmp);
147 BN_CTX_end(ctx); 153 BN_CTX_end(ctx);
148 return(ret); 154 return(ret);
149 } 155 }
diff --git a/src/lib/libcrypto/bn/bn_sqrt.c b/src/lib/libcrypto/bn/bn_sqrt.c
index e2a1105dc8..6beaf9e5e5 100644
--- a/src/lib/libcrypto/bn/bn_sqrt.c
+++ b/src/lib/libcrypto/bn/bn_sqrt.c
@@ -1,4 +1,4 @@
1/* crypto/bn/bn_mod.c */ 1/* crypto/bn/bn_sqrt.c */
2/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * and Bodo Moeller for the OpenSSL project. */ 3 * and Bodo Moeller for the OpenSSL project. */
4/* ==================================================================== 4/* ====================================================================
@@ -65,14 +65,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
65 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course 65 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
66 * in Algebraic Computational Number Theory", algorithm 1.5.1). 66 * in Algebraic Computational Number Theory", algorithm 1.5.1).
67 * 'p' must be prime! 67 * 'p' must be prime!
68 * If 'a' is not a square, this is not necessarily detected by
69 * the algorithms; a bogus result must be expected in this case.
70 */ 68 */
71 { 69 {
72 BIGNUM *ret = in; 70 BIGNUM *ret = in;
73 int err = 1; 71 int err = 1;
74 int r; 72 int r;
75 BIGNUM *b, *q, *t, *x, *y; 73 BIGNUM *A, *b, *q, *t, *x, *y;
76 int e, i, j; 74 int e, i, j;
77 75
78 if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) 76 if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
@@ -85,9 +83,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
85 goto end; 83 goto end;
86 if (!BN_set_word(ret, BN_is_bit_set(a, 0))) 84 if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
87 { 85 {
88 BN_free(ret); 86 if (ret != in)
87 BN_free(ret);
89 return NULL; 88 return NULL;
90 } 89 }
90 bn_check_top(ret);
91 return ret; 91 return ret;
92 } 92 }
93 93
@@ -103,23 +103,16 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
103 goto end; 103 goto end;
104 if (!BN_set_word(ret, BN_is_one(a))) 104 if (!BN_set_word(ret, BN_is_one(a)))
105 { 105 {
106 BN_free(ret); 106 if (ret != in)
107 BN_free(ret);
107 return NULL; 108 return NULL;
108 } 109 }
110 bn_check_top(ret);
109 return ret; 111 return ret;
110 } 112 }
111 113
112#if 0 /* if BN_mod_sqrt is used with correct input, this just wastes time */
113 r = BN_kronecker(a, p, ctx);
114 if (r < -1) return NULL;
115 if (r == -1)
116 {
117 BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
118 return(NULL);
119 }
120#endif
121
122 BN_CTX_start(ctx); 114 BN_CTX_start(ctx);
115 A = BN_CTX_get(ctx);
123 b = BN_CTX_get(ctx); 116 b = BN_CTX_get(ctx);
124 q = BN_CTX_get(ctx); 117 q = BN_CTX_get(ctx);
125 t = BN_CTX_get(ctx); 118 t = BN_CTX_get(ctx);
@@ -131,6 +124,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
131 ret = BN_new(); 124 ret = BN_new();
132 if (ret == NULL) goto end; 125 if (ret == NULL) goto end;
133 126
127 /* A = a mod p */
128 if (!BN_nnmod(A, a, p, ctx)) goto end;
129
134 /* now write |p| - 1 as 2^e*q where q is odd */ 130 /* now write |p| - 1 as 2^e*q where q is odd */
135 e = 1; 131 e = 1;
136 while (!BN_is_bit_set(p, e)) 132 while (!BN_is_bit_set(p, e))
@@ -149,9 +145,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
149 if (!BN_rshift(q, p, 2)) goto end; 145 if (!BN_rshift(q, p, 2)) goto end;
150 q->neg = 0; 146 q->neg = 0;
151 if (!BN_add_word(q, 1)) goto end; 147 if (!BN_add_word(q, 1)) goto end;
152 if (!BN_mod_exp(ret, a, q, p, ctx)) goto end; 148 if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
153 err = 0; 149 err = 0;
154 goto end; 150 goto vrfy;
155 } 151 }
156 152
157 if (e == 2) 153 if (e == 2)
@@ -182,15 +178,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
182 * November 1992.) 178 * November 1992.)
183 */ 179 */
184 180
185 /* make sure that a is reduced modulo p */
186 if (a->neg || BN_ucmp(a, p) >= 0)
187 {
188 if (!BN_nnmod(x, a, p, ctx)) goto end;
189 a = x; /* use x as temporary variable */
190 }
191
192 /* t := 2*a */ 181 /* t := 2*a */
193 if (!BN_mod_lshift1_quick(t, a, p)) goto end; 182 if (!BN_mod_lshift1_quick(t, A, p)) goto end;
194 183
195 /* b := (2*a)^((|p|-5)/8) */ 184 /* b := (2*a)^((|p|-5)/8) */
196 if (!BN_rshift(q, p, 3)) goto end; 185 if (!BN_rshift(q, p, 3)) goto end;
@@ -205,12 +194,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
205 if (!BN_sub_word(t, 1)) goto end; 194 if (!BN_sub_word(t, 1)) goto end;
206 195
207 /* x = a*b*t */ 196 /* x = a*b*t */
208 if (!BN_mod_mul(x, a, b, p, ctx)) goto end; 197 if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
209 if (!BN_mod_mul(x, x, t, p, ctx)) goto end; 198 if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
210 199
211 if (!BN_copy(ret, x)) goto end; 200 if (!BN_copy(ret, x)) goto end;
212 err = 0; 201 err = 0;
213 goto end; 202 goto vrfy;
214 } 203 }
215 204
216 /* e > 2, so we really have to use the Tonelli/Shanks algorithm. 205 /* e > 2, so we really have to use the Tonelli/Shanks algorithm.
@@ -297,11 +286,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
297 /* x := a^((q-1)/2) */ 286 /* x := a^((q-1)/2) */
298 if (BN_is_zero(t)) /* special case: p = 2^e + 1 */ 287 if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
299 { 288 {
300 if (!BN_nnmod(t, a, p, ctx)) goto end; 289 if (!BN_nnmod(t, A, p, ctx)) goto end;
301 if (BN_is_zero(t)) 290 if (BN_is_zero(t))
302 { 291 {
303 /* special case: a == 0 (mod p) */ 292 /* special case: a == 0 (mod p) */
304 if (!BN_zero(ret)) goto end; 293 BN_zero(ret);
305 err = 0; 294 err = 0;
306 goto end; 295 goto end;
307 } 296 }
@@ -310,11 +299,11 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
310 } 299 }
311 else 300 else
312 { 301 {
313 if (!BN_mod_exp(x, a, t, p, ctx)) goto end; 302 if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
314 if (BN_is_zero(x)) 303 if (BN_is_zero(x))
315 { 304 {
316 /* special case: a == 0 (mod p) */ 305 /* special case: a == 0 (mod p) */
317 if (!BN_zero(ret)) goto end; 306 BN_zero(ret);
318 err = 0; 307 err = 0;
319 goto end; 308 goto end;
320 } 309 }
@@ -322,10 +311,10 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
322 311
323 /* b := a*x^2 (= a^q) */ 312 /* b := a*x^2 (= a^q) */
324 if (!BN_mod_sqr(b, x, p, ctx)) goto end; 313 if (!BN_mod_sqr(b, x, p, ctx)) goto end;
325 if (!BN_mod_mul(b, b, a, p, ctx)) goto end; 314 if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
326 315
327 /* x := a*x (= a^((q+1)/2)) */ 316 /* x := a*x (= a^((q+1)/2)) */
328 if (!BN_mod_mul(x, x, a, p, ctx)) goto end; 317 if (!BN_mod_mul(x, x, A, p, ctx)) goto end;
329 318
330 while (1) 319 while (1)
331 { 320 {
@@ -342,7 +331,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
342 { 331 {
343 if (!BN_copy(ret, x)) goto end; 332 if (!BN_copy(ret, x)) goto end;
344 err = 0; 333 err = 0;
345 goto end; 334 goto vrfy;
346 } 335 }
347 336
348 337
@@ -373,6 +362,22 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
373 e = i; 362 e = i;
374 } 363 }
375 364
365 vrfy:
366 if (!err)
367 {
368 /* verify the result -- the input might have been not a square
369 * (test added in 0.9.8) */
370
371 if (!BN_mod_sqr(x, ret, p, ctx))
372 err = 1;
373
374 if (!err && 0 != BN_cmp(x, A))
375 {
376 BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
377 err = 1;
378 }
379 }
380
376 end: 381 end:
377 if (err) 382 if (err)
378 { 383 {
@@ -383,5 +388,6 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
383 ret = NULL; 388 ret = NULL;
384 } 389 }
385 BN_CTX_end(ctx); 390 BN_CTX_end(ctx);
391 bn_check_top(ret);
386 return ret; 392 return ret;
387 } 393 }
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index de610ce54c..ee7b87c45c 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -69,6 +69,10 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
69#endif 69#endif
70 int i; 70 int i;
71 71
72 if (w == 0)
73 return (BN_ULONG)-1;
74
75 bn_check_top(a);
72 w&=BN_MASK2; 76 w&=BN_MASK2;
73 for (i=a->top-1; i>=0; i--) 77 for (i=a->top-1; i>=0; i--)
74 { 78 {
@@ -85,12 +89,24 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
85 89
86BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) 90BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
87 { 91 {
88 BN_ULONG ret; 92 BN_ULONG ret = 0;
89 int i; 93 int i, j;
94
95 bn_check_top(a);
96 w &= BN_MASK2;
97
98 if (!w)
99 /* actually this an error (division by zero) */
100 return (BN_ULONG)-1;
101 if (a->top == 0)
102 return 0;
103
104 /* normalize input (so bn_div_words doesn't complain) */
105 j = BN_BITS2 - BN_num_bits_word(w);
106 w <<= j;
107 if (!BN_lshift(a, a, j))
108 return (BN_ULONG)-1;
90 109
91 if (a->top == 0) return(0);
92 ret=0;
93 w&=BN_MASK2;
94 for (i=a->top-1; i>=0; i--) 110 for (i=a->top-1; i>=0; i--)
95 { 111 {
96 BN_ULONG l,d; 112 BN_ULONG l,d;
@@ -102,6 +118,8 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
102 } 118 }
103 if ((a->top > 0) && (a->d[a->top-1] == 0)) 119 if ((a->top > 0) && (a->d[a->top-1] == 0))
104 a->top--; 120 a->top--;
121 ret >>= j;
122 bn_check_top(a);
105 return(ret); 123 return(ret);
106 } 124 }
107 125
@@ -110,9 +128,14 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
110 BN_ULONG l; 128 BN_ULONG l;
111 int i; 129 int i;
112 130
113 if ((w & BN_MASK2) == 0) 131 bn_check_top(a);
114 return(1); 132 w &= BN_MASK2;
115 133
134 /* degenerate case: w is zero */
135 if (!w) return 1;
136 /* degenerate case: a is zero */
137 if(BN_is_zero(a)) return BN_set_word(a, w);
138 /* handle 'a' when negative */
116 if (a->neg) 139 if (a->neg)
117 { 140 {
118 a->neg=0; 141 a->neg=0;
@@ -121,15 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
121 a->neg=!(a->neg); 144 a->neg=!(a->neg);
122 return(i); 145 return(i);
123 } 146 }
124 w&=BN_MASK2; 147 /* Only expand (and risk failing) if it's possibly necessary */
125 if (bn_wexpand(a,a->top+1) == NULL) return(0); 148 if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
149 (bn_wexpand(a,a->top+1) == NULL))
150 return(0);
126 i=0; 151 i=0;
127 for (;;) 152 for (;;)
128 { 153 {
129 if (i >= a->top) 154 if (i >= a->top)
130 l=w; 155 l=w;
131 else 156 else
132 l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; 157 l=(a->d[i]+w)&BN_MASK2;
133 a->d[i]=l; 158 a->d[i]=l;
134 if (w > l) 159 if (w > l)
135 w=1; 160 w=1;
@@ -139,6 +164,7 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
139 } 164 }
140 if (i >= a->top) 165 if (i >= a->top)
141 a->top++; 166 a->top++;
167 bn_check_top(a);
142 return(1); 168 return(1);
143 } 169 }
144 170
@@ -146,10 +172,21 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
146 { 172 {
147 int i; 173 int i;
148 174
149 if ((w & BN_MASK2) == 0) 175 bn_check_top(a);
150 return(1); 176 w &= BN_MASK2;
151 177
152 if (BN_is_zero(a) || a->neg) 178 /* degenerate case: w is zero */
179 if (!w) return 1;
180 /* degenerate case: a is zero */
181 if(BN_is_zero(a))
182 {
183 i = BN_set_word(a,w);
184 if (i != 0)
185 BN_set_negative(a, 1);
186 return i;
187 }
188 /* handle 'a' when negative */
189 if (a->neg)
153 { 190 {
154 a->neg=0; 191 a->neg=0;
155 i=BN_add_word(a,w); 192 i=BN_add_word(a,w);
@@ -157,7 +194,6 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
157 return(i); 194 return(i);
158 } 195 }
159 196
160 w&=BN_MASK2;
161 if ((a->top == 1) && (a->d[0] < w)) 197 if ((a->top == 1) && (a->d[0] < w))
162 { 198 {
163 a->d[0]=w-a->d[0]; 199 a->d[0]=w-a->d[0];
@@ -181,6 +217,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
181 } 217 }
182 if ((a->d[i] == 0) && (i == (a->top-1))) 218 if ((a->d[i] == 0) && (i == (a->top-1)))
183 a->top--; 219 a->top--;
220 bn_check_top(a);
184 return(1); 221 return(1);
185 } 222 }
186 223
@@ -188,6 +225,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
188 { 225 {
189 BN_ULONG ll; 226 BN_ULONG ll;
190 227
228 bn_check_top(a);
191 w&=BN_MASK2; 229 w&=BN_MASK2;
192 if (a->top) 230 if (a->top)
193 { 231 {
@@ -203,6 +241,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
203 } 241 }
204 } 242 }
205 } 243 }
244 bn_check_top(a);
206 return(1); 245 return(1);
207 } 246 }
208 247
diff --git a/src/lib/libcrypto/bn/bntest.c b/src/lib/libcrypto/bn/bntest.c
index 792a75ff4f..cf190380f5 100644
--- a/src/lib/libcrypto/bn/bntest.c
+++ b/src/lib/libcrypto/bn/bntest.c
@@ -55,6 +55,25 @@
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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the Eric Young open source
65 * license provided above.
66 *
67 * The binary polynomial arithmetic software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71
72/* Until the key-gen callbacks are modified to use newer prototypes, we allow
73 * deprecated functions for openssl-internal code */
74#ifdef OPENSSL_NO_DEPRECATED
75#undef OPENSSL_NO_DEPRECATED
76#endif
58 77
59#include <stdio.h> 78#include <stdio.h>
60#include <stdlib.h> 79#include <stdlib.h>
@@ -79,6 +98,7 @@ int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
79int test_rshift1(BIO *bp); 98int test_rshift1(BIO *bp);
80int test_rshift(BIO *bp,BN_CTX *ctx); 99int test_rshift(BIO *bp,BN_CTX *ctx);
81int test_div(BIO *bp,BN_CTX *ctx); 100int test_div(BIO *bp,BN_CTX *ctx);
101int test_div_word(BIO *bp);
82int test_div_recp(BIO *bp,BN_CTX *ctx); 102int test_div_recp(BIO *bp,BN_CTX *ctx);
83int test_mul(BIO *bp); 103int test_mul(BIO *bp);
84int test_sqr(BIO *bp,BN_CTX *ctx); 104int test_sqr(BIO *bp,BN_CTX *ctx);
@@ -88,6 +108,15 @@ int test_mod_mul(BIO *bp,BN_CTX *ctx);
88int test_mod_exp(BIO *bp,BN_CTX *ctx); 108int test_mod_exp(BIO *bp,BN_CTX *ctx);
89int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx); 109int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
90int test_exp(BIO *bp,BN_CTX *ctx); 110int test_exp(BIO *bp,BN_CTX *ctx);
111int test_gf2m_add(BIO *bp);
112int test_gf2m_mod(BIO *bp);
113int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
114int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
115int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
116int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
117int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
118int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
119int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
91int test_kron(BIO *bp,BN_CTX *ctx); 120int test_kron(BIO *bp,BN_CTX *ctx);
92int test_sqrt(BIO *bp,BN_CTX *ctx); 121int test_sqrt(BIO *bp,BN_CTX *ctx);
93int rand_neg(void); 122int rand_neg(void);
@@ -155,80 +184,120 @@ int main(int argc, char *argv[])
155 184
156 message(out,"BN_add"); 185 message(out,"BN_add");
157 if (!test_add(out)) goto err; 186 if (!test_add(out)) goto err;
158 BIO_flush(out); 187 (void)BIO_flush(out);
159 188
160 message(out,"BN_sub"); 189 message(out,"BN_sub");
161 if (!test_sub(out)) goto err; 190 if (!test_sub(out)) goto err;
162 BIO_flush(out); 191 (void)BIO_flush(out);
163 192
164 message(out,"BN_lshift1"); 193 message(out,"BN_lshift1");
165 if (!test_lshift1(out)) goto err; 194 if (!test_lshift1(out)) goto err;
166 BIO_flush(out); 195 (void)BIO_flush(out);
167 196
168 message(out,"BN_lshift (fixed)"); 197 message(out,"BN_lshift (fixed)");
169 if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL))) 198 if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
170 goto err; 199 goto err;
171 BIO_flush(out); 200 (void)BIO_flush(out);
172 201
173 message(out,"BN_lshift"); 202 message(out,"BN_lshift");
174 if (!test_lshift(out,ctx,NULL)) goto err; 203 if (!test_lshift(out,ctx,NULL)) goto err;
175 BIO_flush(out); 204 (void)BIO_flush(out);
176 205
177 message(out,"BN_rshift1"); 206 message(out,"BN_rshift1");
178 if (!test_rshift1(out)) goto err; 207 if (!test_rshift1(out)) goto err;
179 BIO_flush(out); 208 (void)BIO_flush(out);
180 209
181 message(out,"BN_rshift"); 210 message(out,"BN_rshift");
182 if (!test_rshift(out,ctx)) goto err; 211 if (!test_rshift(out,ctx)) goto err;
183 BIO_flush(out); 212 (void)BIO_flush(out);
184 213
185 message(out,"BN_sqr"); 214 message(out,"BN_sqr");
186 if (!test_sqr(out,ctx)) goto err; 215 if (!test_sqr(out,ctx)) goto err;
187 BIO_flush(out); 216 (void)BIO_flush(out);
188 217
189 message(out,"BN_mul"); 218 message(out,"BN_mul");
190 if (!test_mul(out)) goto err; 219 if (!test_mul(out)) goto err;
191 BIO_flush(out); 220 (void)BIO_flush(out);
192 221
193 message(out,"BN_div"); 222 message(out,"BN_div");
194 if (!test_div(out,ctx)) goto err; 223 if (!test_div(out,ctx)) goto err;
195 BIO_flush(out); 224 (void)BIO_flush(out);
225
226 message(out,"BN_div_word");
227 if (!test_div_word(out)) goto err;
228 (void)BIO_flush(out);
196 229
197 message(out,"BN_div_recp"); 230 message(out,"BN_div_recp");
198 if (!test_div_recp(out,ctx)) goto err; 231 if (!test_div_recp(out,ctx)) goto err;
199 BIO_flush(out); 232 (void)BIO_flush(out);
200 233
201 message(out,"BN_mod"); 234 message(out,"BN_mod");
202 if (!test_mod(out,ctx)) goto err; 235 if (!test_mod(out,ctx)) goto err;
203 BIO_flush(out); 236 (void)BIO_flush(out);
204 237
205 message(out,"BN_mod_mul"); 238 message(out,"BN_mod_mul");
206 if (!test_mod_mul(out,ctx)) goto err; 239 if (!test_mod_mul(out,ctx)) goto err;
207 BIO_flush(out); 240 (void)BIO_flush(out);
208 241
209 message(out,"BN_mont"); 242 message(out,"BN_mont");
210 if (!test_mont(out,ctx)) goto err; 243 if (!test_mont(out,ctx)) goto err;
211 BIO_flush(out); 244 (void)BIO_flush(out);
212 245
213 message(out,"BN_mod_exp"); 246 message(out,"BN_mod_exp");
214 if (!test_mod_exp(out,ctx)) goto err; 247 if (!test_mod_exp(out,ctx)) goto err;
215 BIO_flush(out); 248 (void)BIO_flush(out);
216 249
217 message(out,"BN_mod_exp_mont_consttime"); 250 message(out,"BN_mod_exp_mont_consttime");
218 if (!test_mod_exp_mont_consttime(out,ctx)) goto err; 251 if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
219 BIO_flush(out); 252 (void)BIO_flush(out);
220 253
221 message(out,"BN_exp"); 254 message(out,"BN_exp");
222 if (!test_exp(out,ctx)) goto err; 255 if (!test_exp(out,ctx)) goto err;
223 BIO_flush(out); 256 (void)BIO_flush(out);
224 257
225 message(out,"BN_kronecker"); 258 message(out,"BN_kronecker");
226 if (!test_kron(out,ctx)) goto err; 259 if (!test_kron(out,ctx)) goto err;
227 BIO_flush(out); 260 (void)BIO_flush(out);
228 261
229 message(out,"BN_mod_sqrt"); 262 message(out,"BN_mod_sqrt");
230 if (!test_sqrt(out,ctx)) goto err; 263 if (!test_sqrt(out,ctx)) goto err;
231 BIO_flush(out); 264 (void)BIO_flush(out);
265
266 message(out,"BN_GF2m_add");
267 if (!test_gf2m_add(out)) goto err;
268 (void)BIO_flush(out);
269
270 message(out,"BN_GF2m_mod");
271 if (!test_gf2m_mod(out)) goto err;
272 (void)BIO_flush(out);
273
274 message(out,"BN_GF2m_mod_mul");
275 if (!test_gf2m_mod_mul(out,ctx)) goto err;
276 (void)BIO_flush(out);
277
278 message(out,"BN_GF2m_mod_sqr");
279 if (!test_gf2m_mod_sqr(out,ctx)) goto err;
280 (void)BIO_flush(out);
281
282 message(out,"BN_GF2m_mod_inv");
283 if (!test_gf2m_mod_inv(out,ctx)) goto err;
284 (void)BIO_flush(out);
285
286 message(out,"BN_GF2m_mod_div");
287 if (!test_gf2m_mod_div(out,ctx)) goto err;
288 (void)BIO_flush(out);
289
290 message(out,"BN_GF2m_mod_exp");
291 if (!test_gf2m_mod_exp(out,ctx)) goto err;
292 (void)BIO_flush(out);
293
294 message(out,"BN_GF2m_mod_sqrt");
295 if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
296 (void)BIO_flush(out);
297
298 message(out,"BN_GF2m_mod_solve_quad");
299 if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
300 (void)BIO_flush(out);
232 301
233 BN_CTX_free(ctx); 302 BN_CTX_free(ctx);
234 BIO_free(out); 303 BIO_free(out);
@@ -237,8 +306,8 @@ int main(int argc, char *argv[])
237 EXIT(0); 306 EXIT(0);
238err: 307err:
239 BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices 308 BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
240 * the failure, see test_bn in test/Makefile */ 309 * the failure, see test_bn in test/Makefile.ssl*/
241 BIO_flush(out); 310 (void)BIO_flush(out);
242 ERR_load_crypto_strings(); 311 ERR_load_crypto_strings();
243 ERR_print_errors_fp(stderr); 312 ERR_print_errors_fp(stderr);
244 EXIT(1); 313 EXIT(1);
@@ -404,6 +473,78 @@ int test_div(BIO *bp, BN_CTX *ctx)
404 return(1); 473 return(1);
405 } 474 }
406 475
476static void print_word(BIO *bp,BN_ULONG w)
477 {
478#ifdef SIXTY_FOUR_BIT
479 if (sizeof(w) > sizeof(unsigned long))
480 {
481 unsigned long h=(unsigned long)(w>>32),
482 l=(unsigned long)(w);
483
484 if (h) BIO_printf(bp,"%lX%08lX",h,l);
485 else BIO_printf(bp,"%lX",l);
486 return;
487 }
488#endif
489 BIO_printf(bp,"%lX",w);
490 }
491
492int test_div_word(BIO *bp)
493 {
494 BIGNUM a,b;
495 BN_ULONG r,s;
496 int i;
497
498 BN_init(&a);
499 BN_init(&b);
500
501 for (i=0; i<num0; i++)
502 {
503 do {
504 BN_bntest_rand(&a,512,-1,0);
505 BN_bntest_rand(&b,BN_BITS2,-1,0);
506 s = b.d[0];
507 } while (!s);
508
509 BN_copy(&b, &a);
510 r = BN_div_word(&b, s);
511
512 if (bp != NULL)
513 {
514 if (!results)
515 {
516 BN_print(bp,&a);
517 BIO_puts(bp," / ");
518 print_word(bp,s);
519 BIO_puts(bp," - ");
520 }
521 BN_print(bp,&b);
522 BIO_puts(bp,"\n");
523
524 if (!results)
525 {
526 BN_print(bp,&a);
527 BIO_puts(bp," % ");
528 print_word(bp,s);
529 BIO_puts(bp," - ");
530 }
531 print_word(bp,r);
532 BIO_puts(bp,"\n");
533 }
534 BN_mul_word(&b,s);
535 BN_add_word(&b,r);
536 BN_sub(&b,&a,&b);
537 if(!BN_is_zero(&b))
538 {
539 fprintf(stderr,"Division (word) test failed!\n");
540 return 0;
541 }
542 }
543 BN_free(&a);
544 BN_free(&b);
545 return(1);
546 }
547
407int test_div_recp(BIO *bp, BN_CTX *ctx) 548int test_div_recp(BIO *bp, BN_CTX *ctx)
408 { 549 {
409 BIGNUM a,b,c,d,e; 550 BIGNUM a,b,c,d,e;
@@ -919,7 +1060,582 @@ int test_exp(BIO *bp, BN_CTX *ctx)
919 return(1); 1060 return(1);
920 } 1061 }
921 1062
922static void genprime_cb(int p, int n, void *arg) 1063int test_gf2m_add(BIO *bp)
1064 {
1065 BIGNUM a,b,c;
1066 int i, ret = 0;
1067
1068 BN_init(&a);
1069 BN_init(&b);
1070 BN_init(&c);
1071
1072 for (i=0; i<num0; i++)
1073 {
1074 BN_rand(&a,512,0,0);
1075 BN_copy(&b, BN_value_one());
1076 a.neg=rand_neg();
1077 b.neg=rand_neg();
1078 BN_GF2m_add(&c,&a,&b);
1079#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1080 if (bp != NULL)
1081 {
1082 if (!results)
1083 {
1084 BN_print(bp,&a);
1085 BIO_puts(bp," ^ ");
1086 BN_print(bp,&b);
1087 BIO_puts(bp," = ");
1088 }
1089 BN_print(bp,&c);
1090 BIO_puts(bp,"\n");
1091 }
1092#endif
1093 /* Test that two added values have the correct parity. */
1094 if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
1095 {
1096 fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
1097 goto err;
1098 }
1099 BN_GF2m_add(&c,&c,&c);
1100 /* Test that c + c = 0. */
1101 if(!BN_is_zero(&c))
1102 {
1103 fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
1104 goto err;
1105 }
1106 }
1107 ret = 1;
1108 err:
1109 BN_free(&a);
1110 BN_free(&b);
1111 BN_free(&c);
1112 return ret;
1113 }
1114
1115int test_gf2m_mod(BIO *bp)
1116 {
1117 BIGNUM *a,*b[2],*c,*d,*e;
1118 int i, j, ret = 0;
1119 unsigned int p0[] = {163,7,6,3,0};
1120 unsigned int p1[] = {193,15,0};
1121
1122 a=BN_new();
1123 b[0]=BN_new();
1124 b[1]=BN_new();
1125 c=BN_new();
1126 d=BN_new();
1127 e=BN_new();
1128
1129 BN_GF2m_arr2poly(p0, b[0]);
1130 BN_GF2m_arr2poly(p1, b[1]);
1131
1132 for (i=0; i<num0; i++)
1133 {
1134 BN_bntest_rand(a, 1024, 0, 0);
1135 for (j=0; j < 2; j++)
1136 {
1137 BN_GF2m_mod(c, a, b[j]);
1138#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1139 if (bp != NULL)
1140 {
1141 if (!results)
1142 {
1143 BN_print(bp,a);
1144 BIO_puts(bp," % ");
1145 BN_print(bp,b[j]);
1146 BIO_puts(bp," - ");
1147 BN_print(bp,c);
1148 BIO_puts(bp,"\n");
1149 }
1150 }
1151#endif
1152 BN_GF2m_add(d, a, c);
1153 BN_GF2m_mod(e, d, b[j]);
1154 /* Test that a + (a mod p) mod p == 0. */
1155 if(!BN_is_zero(e))
1156 {
1157 fprintf(stderr,"GF(2^m) modulo test failed!\n");
1158 goto err;
1159 }
1160 }
1161 }
1162 ret = 1;
1163 err:
1164 BN_free(a);
1165 BN_free(b[0]);
1166 BN_free(b[1]);
1167 BN_free(c);
1168 BN_free(d);
1169 BN_free(e);
1170 return ret;
1171 }
1172
1173int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
1174 {
1175 BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
1176 int i, j, ret = 0;
1177 unsigned int p0[] = {163,7,6,3,0};
1178 unsigned int p1[] = {193,15,0};
1179
1180 a=BN_new();
1181 b[0]=BN_new();
1182 b[1]=BN_new();
1183 c=BN_new();
1184 d=BN_new();
1185 e=BN_new();
1186 f=BN_new();
1187 g=BN_new();
1188 h=BN_new();
1189
1190 BN_GF2m_arr2poly(p0, b[0]);
1191 BN_GF2m_arr2poly(p1, b[1]);
1192
1193 for (i=0; i<num0; i++)
1194 {
1195 BN_bntest_rand(a, 1024, 0, 0);
1196 BN_bntest_rand(c, 1024, 0, 0);
1197 BN_bntest_rand(d, 1024, 0, 0);
1198 for (j=0; j < 2; j++)
1199 {
1200 BN_GF2m_mod_mul(e, a, c, b[j], ctx);
1201#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1202 if (bp != NULL)
1203 {
1204 if (!results)
1205 {
1206 BN_print(bp,a);
1207 BIO_puts(bp," * ");
1208 BN_print(bp,c);
1209 BIO_puts(bp," % ");
1210 BN_print(bp,b[j]);
1211 BIO_puts(bp," - ");
1212 BN_print(bp,e);
1213 BIO_puts(bp,"\n");
1214 }
1215 }
1216#endif
1217 BN_GF2m_add(f, a, d);
1218 BN_GF2m_mod_mul(g, f, c, b[j], ctx);
1219 BN_GF2m_mod_mul(h, d, c, b[j], ctx);
1220 BN_GF2m_add(f, e, g);
1221 BN_GF2m_add(f, f, h);
1222 /* Test that (a+d)*c = a*c + d*c. */
1223 if(!BN_is_zero(f))
1224 {
1225 fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
1226 goto err;
1227 }
1228 }
1229 }
1230 ret = 1;
1231 err:
1232 BN_free(a);
1233 BN_free(b[0]);
1234 BN_free(b[1]);
1235 BN_free(c);
1236 BN_free(d);
1237 BN_free(e);
1238 BN_free(f);
1239 BN_free(g);
1240 BN_free(h);
1241 return ret;
1242 }
1243
1244int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
1245 {
1246 BIGNUM *a,*b[2],*c,*d;
1247 int i, j, ret = 0;
1248 unsigned int p0[] = {163,7,6,3,0};
1249 unsigned int p1[] = {193,15,0};
1250
1251 a=BN_new();
1252 b[0]=BN_new();
1253 b[1]=BN_new();
1254 c=BN_new();
1255 d=BN_new();
1256
1257 BN_GF2m_arr2poly(p0, b[0]);
1258 BN_GF2m_arr2poly(p1, b[1]);
1259
1260 for (i=0; i<num0; i++)
1261 {
1262 BN_bntest_rand(a, 1024, 0, 0);
1263 for (j=0; j < 2; j++)
1264 {
1265 BN_GF2m_mod_sqr(c, a, b[j], ctx);
1266 BN_copy(d, a);
1267 BN_GF2m_mod_mul(d, a, d, b[j], ctx);
1268#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1269 if (bp != NULL)
1270 {
1271 if (!results)
1272 {
1273 BN_print(bp,a);
1274 BIO_puts(bp," ^ 2 % ");
1275 BN_print(bp,b[j]);
1276 BIO_puts(bp, " = ");
1277 BN_print(bp,c);
1278 BIO_puts(bp,"; a * a = ");
1279 BN_print(bp,d);
1280 BIO_puts(bp,"\n");
1281 }
1282 }
1283#endif
1284 BN_GF2m_add(d, c, d);
1285 /* Test that a*a = a^2. */
1286 if(!BN_is_zero(d))
1287 {
1288 fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
1289 goto err;
1290 }
1291 }
1292 }
1293 ret = 1;
1294 err:
1295 BN_free(a);
1296 BN_free(b[0]);
1297 BN_free(b[1]);
1298 BN_free(c);
1299 BN_free(d);
1300 return ret;
1301 }
1302
1303int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
1304 {
1305 BIGNUM *a,*b[2],*c,*d;
1306 int i, j, ret = 0;
1307 unsigned int p0[] = {163,7,6,3,0};
1308 unsigned int p1[] = {193,15,0};
1309
1310 a=BN_new();
1311 b[0]=BN_new();
1312 b[1]=BN_new();
1313 c=BN_new();
1314 d=BN_new();
1315
1316 BN_GF2m_arr2poly(p0, b[0]);
1317 BN_GF2m_arr2poly(p1, b[1]);
1318
1319 for (i=0; i<num0; i++)
1320 {
1321 BN_bntest_rand(a, 512, 0, 0);
1322 for (j=0; j < 2; j++)
1323 {
1324 BN_GF2m_mod_inv(c, a, b[j], ctx);
1325 BN_GF2m_mod_mul(d, a, c, b[j], ctx);
1326#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1327 if (bp != NULL)
1328 {
1329 if (!results)
1330 {
1331 BN_print(bp,a);
1332 BIO_puts(bp, " * ");
1333 BN_print(bp,c);
1334 BIO_puts(bp," - 1 % ");
1335 BN_print(bp,b[j]);
1336 BIO_puts(bp,"\n");
1337 }
1338 }
1339#endif
1340 /* Test that ((1/a)*a) = 1. */
1341 if(!BN_is_one(d))
1342 {
1343 fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
1344 goto err;
1345 }
1346 }
1347 }
1348 ret = 1;
1349 err:
1350 BN_free(a);
1351 BN_free(b[0]);
1352 BN_free(b[1]);
1353 BN_free(c);
1354 BN_free(d);
1355 return ret;
1356 }
1357
1358int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
1359 {
1360 BIGNUM *a,*b[2],*c,*d,*e,*f;
1361 int i, j, ret = 0;
1362 unsigned int p0[] = {163,7,6,3,0};
1363 unsigned int p1[] = {193,15,0};
1364
1365 a=BN_new();
1366 b[0]=BN_new();
1367 b[1]=BN_new();
1368 c=BN_new();
1369 d=BN_new();
1370 e=BN_new();
1371 f=BN_new();
1372
1373 BN_GF2m_arr2poly(p0, b[0]);
1374 BN_GF2m_arr2poly(p1, b[1]);
1375
1376 for (i=0; i<num0; i++)
1377 {
1378 BN_bntest_rand(a, 512, 0, 0);
1379 BN_bntest_rand(c, 512, 0, 0);
1380 for (j=0; j < 2; j++)
1381 {
1382 BN_GF2m_mod_div(d, a, c, b[j], ctx);
1383 BN_GF2m_mod_mul(e, d, c, b[j], ctx);
1384 BN_GF2m_mod_div(f, a, e, b[j], ctx);
1385#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1386 if (bp != NULL)
1387 {
1388 if (!results)
1389 {
1390 BN_print(bp,a);
1391 BIO_puts(bp, " = ");
1392 BN_print(bp,c);
1393 BIO_puts(bp," * ");
1394 BN_print(bp,d);
1395 BIO_puts(bp, " % ");
1396 BN_print(bp,b[j]);
1397 BIO_puts(bp,"\n");
1398 }
1399 }
1400#endif
1401 /* Test that ((a/c)*c)/a = 1. */
1402 if(!BN_is_one(f))
1403 {
1404 fprintf(stderr,"GF(2^m) modular division test failed!\n");
1405 goto err;
1406 }
1407 }
1408 }
1409 ret = 1;
1410 err:
1411 BN_free(a);
1412 BN_free(b[0]);
1413 BN_free(b[1]);
1414 BN_free(c);
1415 BN_free(d);
1416 BN_free(e);
1417 BN_free(f);
1418 return ret;
1419 }
1420
1421int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
1422 {
1423 BIGNUM *a,*b[2],*c,*d,*e,*f;
1424 int i, j, ret = 0;
1425 unsigned int p0[] = {163,7,6,3,0};
1426 unsigned int p1[] = {193,15,0};
1427
1428 a=BN_new();
1429 b[0]=BN_new();
1430 b[1]=BN_new();
1431 c=BN_new();
1432 d=BN_new();
1433 e=BN_new();
1434 f=BN_new();
1435
1436 BN_GF2m_arr2poly(p0, b[0]);
1437 BN_GF2m_arr2poly(p1, b[1]);
1438
1439 for (i=0; i<num0; i++)
1440 {
1441 BN_bntest_rand(a, 512, 0, 0);
1442 BN_bntest_rand(c, 512, 0, 0);
1443 BN_bntest_rand(d, 512, 0, 0);
1444 for (j=0; j < 2; j++)
1445 {
1446 BN_GF2m_mod_exp(e, a, c, b[j], ctx);
1447 BN_GF2m_mod_exp(f, a, d, b[j], ctx);
1448 BN_GF2m_mod_mul(e, e, f, b[j], ctx);
1449 BN_add(f, c, d);
1450 BN_GF2m_mod_exp(f, a, f, b[j], ctx);
1451#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1452 if (bp != NULL)
1453 {
1454 if (!results)
1455 {
1456 BN_print(bp,a);
1457 BIO_puts(bp, " ^ (");
1458 BN_print(bp,c);
1459 BIO_puts(bp," + ");
1460 BN_print(bp,d);
1461 BIO_puts(bp, ") = ");
1462 BN_print(bp,e);
1463 BIO_puts(bp, "; - ");
1464 BN_print(bp,f);
1465 BIO_puts(bp, " % ");
1466 BN_print(bp,b[j]);
1467 BIO_puts(bp,"\n");
1468 }
1469 }
1470#endif
1471 BN_GF2m_add(f, e, f);
1472 /* Test that a^(c+d)=a^c*a^d. */
1473 if(!BN_is_zero(f))
1474 {
1475 fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
1476 goto err;
1477 }
1478 }
1479 }
1480 ret = 1;
1481 err:
1482 BN_free(a);
1483 BN_free(b[0]);
1484 BN_free(b[1]);
1485 BN_free(c);
1486 BN_free(d);
1487 BN_free(e);
1488 BN_free(f);
1489 return ret;
1490 }
1491
1492int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
1493 {
1494 BIGNUM *a,*b[2],*c,*d,*e,*f;
1495 int i, j, ret = 0;
1496 unsigned int p0[] = {163,7,6,3,0};
1497 unsigned int p1[] = {193,15,0};
1498
1499 a=BN_new();
1500 b[0]=BN_new();
1501 b[1]=BN_new();
1502 c=BN_new();
1503 d=BN_new();
1504 e=BN_new();
1505 f=BN_new();
1506
1507 BN_GF2m_arr2poly(p0, b[0]);
1508 BN_GF2m_arr2poly(p1, b[1]);
1509
1510 for (i=0; i<num0; i++)
1511 {
1512 BN_bntest_rand(a, 512, 0, 0);
1513 for (j=0; j < 2; j++)
1514 {
1515 BN_GF2m_mod(c, a, b[j]);
1516 BN_GF2m_mod_sqrt(d, a, b[j], ctx);
1517 BN_GF2m_mod_sqr(e, d, b[j], ctx);
1518#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1519 if (bp != NULL)
1520 {
1521 if (!results)
1522 {
1523 BN_print(bp,d);
1524 BIO_puts(bp, " ^ 2 - ");
1525 BN_print(bp,a);
1526 BIO_puts(bp,"\n");
1527 }
1528 }
1529#endif
1530 BN_GF2m_add(f, c, e);
1531 /* Test that d^2 = a, where d = sqrt(a). */
1532 if(!BN_is_zero(f))
1533 {
1534 fprintf(stderr,"GF(2^m) modular square root test failed!\n");
1535 goto err;
1536 }
1537 }
1538 }
1539 ret = 1;
1540 err:
1541 BN_free(a);
1542 BN_free(b[0]);
1543 BN_free(b[1]);
1544 BN_free(c);
1545 BN_free(d);
1546 BN_free(e);
1547 BN_free(f);
1548 return ret;
1549 }
1550
1551int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
1552 {
1553 BIGNUM *a,*b[2],*c,*d,*e;
1554 int i, j, s = 0, t, ret = 0;
1555 unsigned int p0[] = {163,7,6,3,0};
1556 unsigned int p1[] = {193,15,0};
1557
1558 a=BN_new();
1559 b[0]=BN_new();
1560 b[1]=BN_new();
1561 c=BN_new();
1562 d=BN_new();
1563 e=BN_new();
1564
1565 BN_GF2m_arr2poly(p0, b[0]);
1566 BN_GF2m_arr2poly(p1, b[1]);
1567
1568 for (i=0; i<num0; i++)
1569 {
1570 BN_bntest_rand(a, 512, 0, 0);
1571 for (j=0; j < 2; j++)
1572 {
1573 t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1574 if (t)
1575 {
1576 s++;
1577 BN_GF2m_mod_sqr(d, c, b[j], ctx);
1578 BN_GF2m_add(d, c, d);
1579 BN_GF2m_mod(e, a, b[j]);
1580#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1581 if (bp != NULL)
1582 {
1583 if (!results)
1584 {
1585 BN_print(bp,c);
1586 BIO_puts(bp, " is root of z^2 + z = ");
1587 BN_print(bp,a);
1588 BIO_puts(bp, " % ");
1589 BN_print(bp,b[j]);
1590 BIO_puts(bp, "\n");
1591 }
1592 }
1593#endif
1594 BN_GF2m_add(e, e, d);
1595 /* Test that solution of quadratic c satisfies c^2 + c = a. */
1596 if(!BN_is_zero(e))
1597 {
1598 fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
1599 goto err;
1600 }
1601
1602 }
1603 else
1604 {
1605#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1606 if (bp != NULL)
1607 {
1608 if (!results)
1609 {
1610 BIO_puts(bp, "There are no roots of z^2 + z = ");
1611 BN_print(bp,a);
1612 BIO_puts(bp, " % ");
1613 BN_print(bp,b[j]);
1614 BIO_puts(bp, "\n");
1615 }
1616 }
1617#endif
1618 }
1619 }
1620 }
1621 if (s == 0)
1622 {
1623 fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
1624 fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
1625 goto err;
1626 }
1627 ret = 1;
1628 err:
1629 BN_free(a);
1630 BN_free(b[0]);
1631 BN_free(b[1]);
1632 BN_free(c);
1633 BN_free(d);
1634 BN_free(e);
1635 return ret;
1636 }
1637
1638static int genprime_cb(int p, int n, BN_GENCB *arg)
923 { 1639 {
924 char c='*'; 1640 char c='*';
925 1641
@@ -929,12 +1645,12 @@ static void genprime_cb(int p, int n, void *arg)
929 if (p == 3) c='\n'; 1645 if (p == 3) c='\n';
930 putc(c, stderr); 1646 putc(c, stderr);
931 fflush(stderr); 1647 fflush(stderr);
932 (void)n; 1648 return 1;
933 (void)arg;
934 } 1649 }
935 1650
936int test_kron(BIO *bp, BN_CTX *ctx) 1651int test_kron(BIO *bp, BN_CTX *ctx)
937 { 1652 {
1653 BN_GENCB cb;
938 BIGNUM *a,*b,*r,*t; 1654 BIGNUM *a,*b,*r,*t;
939 int i; 1655 int i;
940 int legendre, kronecker; 1656 int legendre, kronecker;
@@ -945,6 +1661,8 @@ int test_kron(BIO *bp, BN_CTX *ctx)
945 r = BN_new(); 1661 r = BN_new();
946 t = BN_new(); 1662 t = BN_new();
947 if (a == NULL || b == NULL || r == NULL || t == NULL) goto err; 1663 if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
1664
1665 BN_GENCB_set(&cb, genprime_cb, NULL);
948 1666
949 /* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). 1667 /* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol).
950 * In this case we know that if b is prime, then BN_kronecker(a, b, ctx) 1668 * In this case we know that if b is prime, then BN_kronecker(a, b, ctx)
@@ -955,7 +1673,7 @@ int test_kron(BIO *bp, BN_CTX *ctx)
955 * don't want to test whether b is prime but whether BN_kronecker 1673 * don't want to test whether b is prime but whether BN_kronecker
956 * works.) */ 1674 * works.) */
957 1675
958 if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err; 1676 if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
959 b->neg = rand_neg(); 1677 b->neg = rand_neg();
960 putc('\n', stderr); 1678 putc('\n', stderr);
961 1679
@@ -1023,6 +1741,7 @@ int test_kron(BIO *bp, BN_CTX *ctx)
1023 1741
1024int test_sqrt(BIO *bp, BN_CTX *ctx) 1742int test_sqrt(BIO *bp, BN_CTX *ctx)
1025 { 1743 {
1744 BN_GENCB cb;
1026 BIGNUM *a,*p,*r; 1745 BIGNUM *a,*p,*r;
1027 int i, j; 1746 int i, j;
1028 int ret = 0; 1747 int ret = 0;
@@ -1031,7 +1750,9 @@ int test_sqrt(BIO *bp, BN_CTX *ctx)
1031 p = BN_new(); 1750 p = BN_new();
1032 r = BN_new(); 1751 r = BN_new();
1033 if (a == NULL || p == NULL || r == NULL) goto err; 1752 if (a == NULL || p == NULL || r == NULL) goto err;
1034 1753
1754 BN_GENCB_set(&cb, genprime_cb, NULL);
1755
1035 for (i = 0; i < 16; i++) 1756 for (i = 0; i < 16; i++)
1036 { 1757 {
1037 if (i < 8) 1758 if (i < 8)
@@ -1045,7 +1766,7 @@ int test_sqrt(BIO *bp, BN_CTX *ctx)
1045 if (!BN_set_word(a, 32)) goto err; 1766 if (!BN_set_word(a, 32)) goto err;
1046 if (!BN_set_word(r, 2*i + 1)) goto err; 1767 if (!BN_set_word(r, 2*i + 1)) goto err;
1047 1768
1048 if (!BN_generate_prime(p, 256, 0, a, r, genprime_cb, NULL)) goto err; 1769 if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
1049 putc('\n', stderr); 1770 putc('\n', stderr);
1050 } 1771 }
1051 p->neg = rand_neg(); 1772 p->neg = rand_neg();
diff --git a/src/lib/libcrypto/bn/exptest.c b/src/lib/libcrypto/bn/exptest.c
index 28aaac2ac1..f598a07cf5 100644
--- a/src/lib/libcrypto/bn/exptest.c
+++ b/src/lib/libcrypto/bn/exptest.c
@@ -195,6 +195,9 @@ int main(int argc, char *argv[])
195err: 195err:
196 ERR_load_crypto_strings(); 196 ERR_load_crypto_strings();
197 ERR_print_errors(out); 197 ERR_print_errors(out);
198#ifdef OPENSSL_SYS_NETWARE
199 printf("ERROR\n");
200#endif
198 EXIT(1); 201 EXIT(1);
199 return(1); 202 return(1);
200 } 203 }