diff options
Diffstat (limited to 'src/lib/libcrypto/bn')
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; | ||
9 | for (@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 |
172 | bn_add_words: | 172 | bn_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 |
225 | bn_sub_words: | 225 | bn_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 |
284 | bn_mul_words: | 284 | bn_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 |
398 | bn_mul_add_words: | 398 | bn_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 |
467 | bn_sqr_words: | 466 | bn_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 |
546 | bn_sqr_comba8: | 545 | bn_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 |
618 | bn_mul_comba8: | 616 | bn_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 |
1176 | bn_sqr_comba4: | 1173 | bn_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 |
1209 | bn_mul_comba4: | 1205 | bn_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 |
1412 | bn_div_words: | 1407 | bn_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 |
68 | extern "C" { | 82 | extern "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 | ||
245 | typedef struct bignum_st | 277 | /* Already declared in ossl_typ.h */ |
278 | #if 0 | ||
279 | typedef struct bignum_st BIGNUM; | ||
280 | /* Used for temp variables (declaration hidden in bn_lcl.h) */ | ||
281 | typedef struct bignum_ctx BN_CTX; | ||
282 | typedef struct bn_blinding_st BN_BLINDING; | ||
283 | typedef struct bn_mont_ctx_st BN_MONT_CTX; | ||
284 | typedef struct bn_recp_ctx_st BN_RECP_CTX; | ||
285 | typedef struct bn_gencb_st BN_GENCB; | ||
286 | #endif | ||
287 | |||
288 | struct 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) */ | ||
256 | typedef struct bignum_ctx BN_CTX; | ||
257 | |||
258 | typedef 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 */ |
269 | typedef struct bn_mont_ctx_st | 299 | struct 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 | */ |
283 | typedef struct bn_recp_ctx_st | 318 | struct 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. */ | ||
328 | struct 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, */ | ||
341 | int 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 | ||
329 | const BIGNUM *BN_value_one(void); | 399 | const BIGNUM *BN_value_one(void); |
330 | char * BN_options(void); | 400 | char * BN_options(void); |
331 | BN_CTX *BN_CTX_new(void); | 401 | BN_CTX *BN_CTX_new(void); |
402 | #ifndef OPENSSL_NO_DEPRECATED | ||
332 | void BN_CTX_init(BN_CTX *c); | 403 | void BN_CTX_init(BN_CTX *c); |
404 | #endif | ||
333 | void BN_CTX_free(BN_CTX *c); | 405 | void BN_CTX_free(BN_CTX *c); |
334 | void BN_CTX_start(BN_CTX *ctx); | 406 | void BN_CTX_start(BN_CTX *ctx); |
335 | BIGNUM *BN_CTX_get(BN_CTX *ctx); | 407 | BIGNUM *BN_CTX_get(BN_CTX *ctx); |
@@ -355,6 +427,16 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | |||
355 | int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | 427 | int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); |
356 | int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); | 428 | int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); |
357 | int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx); | 429 | int 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 | */ | ||
434 | void 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 | ||
359 | int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, | 441 | int 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); |
429 | BIGNUM *BN_mod_sqrt(BIGNUM *ret, | 511 | BIGNUM *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 | ||
431 | BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, | 516 | BIGNUM *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, | |||
437 | int BN_is_prime_fasttest(const BIGNUM *p,int nchecks, | 522 | int 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 */ |
442 | int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, | 528 | int 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, | 530 | int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb); |
445 | const BIGNUM *e, BN_CTX *ctx); | 531 | int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, |
446 | int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); | 532 | int do_trial_division, BN_GENCB *cb); |
447 | int 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 | ||
454 | BN_MONT_CTX *BN_MONT_CTX_new(void ); | 534 | BN_MONT_CTX *BN_MONT_CTX_new(void ); |
455 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx); | 535 | void 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); | |||
465 | BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, | 545 | BN_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 | ||
468 | BN_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 | |||
552 | BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod); | ||
469 | void BN_BLINDING_free(BN_BLINDING *b); | 553 | void BN_BLINDING_free(BN_BLINDING *b); |
470 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); | 554 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); |
471 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx); | 555 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); |
472 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); | 556 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); |
473 | 557 | int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); | |
558 | int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); | ||
559 | unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); | ||
560 | void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); | ||
561 | unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); | ||
562 | void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); | ||
563 | BN_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 | ||
474 | void BN_set_params(int mul,int high,int low,int mont); | 570 | void BN_set_params(int mul,int high,int low,int mont); |
475 | int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ | 571 | int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ |
572 | #endif | ||
476 | 573 | ||
477 | void BN_RECP_CTX_init(BN_RECP_CTX *recp); | 574 | void BN_RECP_CTX_init(BN_RECP_CTX *recp); |
478 | BN_RECP_CTX *BN_RECP_CTX_new(void); | 575 | BN_RECP_CTX *BN_RECP_CTX_new(void); |
@@ -485,15 +582,162 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
485 | int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, | 582 | int 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 | |||
594 | int 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) | ||
596 | int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/ | ||
597 | int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | ||
598 | const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */ | ||
599 | int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
600 | BN_CTX *ctx); /* r = (a * a) mod p */ | ||
601 | int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, | ||
602 | BN_CTX *ctx); /* r = (1 / b) mod p */ | ||
603 | int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | ||
604 | const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */ | ||
605 | int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | ||
606 | const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */ | ||
607 | int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
608 | BN_CTX *ctx); /* r = sqrt(a) mod p */ | ||
609 | int 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 | */ | ||
617 | int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]); | ||
618 | /* r = a mod p */ | ||
619 | int 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 */ | ||
621 | int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], | ||
622 | BN_CTX *ctx); /* r = (a * a) mod p */ | ||
623 | int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[], | ||
624 | BN_CTX *ctx); /* r = (1 / b) mod p */ | ||
625 | int 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 */ | ||
627 | int 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 */ | ||
629 | int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, | ||
630 | const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ | ||
631 | int 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 */ | ||
633 | int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max); | ||
634 | int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a); | ||
635 | |||
636 | /* faster mod functions for the 'NIST primes' | ||
637 | * 0 <= a < p^2 */ | ||
638 | int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); | ||
639 | int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); | ||
640 | int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); | ||
641 | int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); | ||
642 | int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); | ||
643 | |||
644 | const BIGNUM *BN_get0_nist_prime_192(void); | ||
645 | const BIGNUM *BN_get0_nist_prime_224(void); | ||
646 | const BIGNUM *BN_get0_nist_prime_256(void); | ||
647 | const BIGNUM *BN_get0_nist_prime_384(void); | ||
648 | const 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))) |
493 | BIGNUM *bn_expand2(BIGNUM *a, int words); | 655 | BIGNUM *bn_expand2(BIGNUM *a, int words); |
494 | BIGNUM *bn_dup_expand(const BIGNUM *a, int words); | 656 | #ifndef OPENSSL_NO_DEPRECATED |
657 | BIGNUM *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 | ||
696 | int 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 | ||
506 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); | 751 | BN_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); | |||
510 | BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); | 755 | BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); |
511 | BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); | 756 | BN_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 */ |
514 | void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n); | 759 | BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); |
515 | # define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ | 760 | BIGNUM *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 | 763 | BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); |
519 | # define bn_print(a) | 764 | BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); |
520 | # define bn_dump(a,b) | 765 | BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); |
521 | #endif | 766 | BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); |
767 | BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); | ||
768 | BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); | ||
522 | 769 | ||
523 | int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom); | 770 | int 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 @@ | |||
64 | int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 64 | int 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 */ |
107 | int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 105 | int 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. */ |
168 | int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 166 | int 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 | ||
63 | BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) | 116 | #define BN_BLINDING_COUNTER 32 |
117 | |||
118 | struct 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 | |||
134 | BN_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); |
82 | err: | 162 | err: |
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; |
111 | err: | 203 | err: |
204 | if (b->counter == 0) | ||
205 | b->counter = BN_BLINDING_COUNTER; | ||
112 | return(ret); | 206 | return(ret); |
113 | } | 207 | } |
114 | 208 | ||
115 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) | 209 | int 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 | |||
214 | int 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 | ||
127 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) | 236 | int 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 | |||
241 | int 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 | ||
266 | unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) | ||
267 | { | ||
268 | return b->thread_id; | ||
269 | } | ||
270 | |||
271 | void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) | ||
272 | { | ||
273 | b->thread_id = n; | ||
274 | } | ||
275 | |||
276 | unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) | ||
277 | { | ||
278 | return b->flags; | ||
279 | } | ||
280 | |||
281 | void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) | ||
282 | { | ||
283 | b->flags = flags; | ||
284 | } | ||
285 | |||
286 | BN_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; | ||
357 | err: | ||
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 | ||
69 | BN_CTX *BN_CTX_new(void) | 86 | /***********/ |
87 | /* BN_POOL */ | ||
88 | /***********/ | ||
89 | |||
90 | /* A bundle of bignums that can be linked with other bundles */ | ||
91 | typedef 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 */ | ||
99 | typedef 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; | ||
106 | static void BN_POOL_init(BN_POOL *); | ||
107 | static void BN_POOL_finish(BN_POOL *); | ||
108 | #ifndef OPENSSL_NO_DEPRECATED | ||
109 | static void BN_POOL_reset(BN_POOL *); | ||
110 | #endif | ||
111 | static BIGNUM * BN_POOL_get(BN_POOL *); | ||
112 | static void BN_POOL_release(BN_POOL *, unsigned int); | ||
113 | |||
114 | /************/ | ||
115 | /* BN_STACK */ | ||
116 | /************/ | ||
117 | |||
118 | /* A wrapper to manage the "stack frames" */ | ||
119 | typedef 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; | ||
126 | static void BN_STACK_init(BN_STACK *); | ||
127 | static void BN_STACK_finish(BN_STACK *); | ||
128 | #ifndef OPENSSL_NO_DEPRECATED | ||
129 | static void BN_STACK_reset(BN_STACK *); | ||
130 | #endif | ||
131 | static int BN_STACK_push(BN_STACK *, unsigned int); | ||
132 | static unsigned int BN_STACK_pop(BN_STACK *); | ||
133 | |||
134 | /**********/ | ||
135 | /* BN_CTX */ | ||
136 | /**********/ | ||
137 | |||
138 | /* The opaque BN_CTX type */ | ||
139 | struct 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 |
155 | static const char *ctxdbg_cur = NULL; | ||
156 | static 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 | ||
85 | void BN_CTX_init(BN_CTX *ctx) | 200 | void 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 | |||
214 | BN_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 | ||
100 | void BN_CTX_free(BN_CTX *ctx) | 231 | void 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 | ||
113 | void BN_CTX_start(BN_CTX *ctx) | 255 | void 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 | ||
270 | void 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 | ||
121 | BIGNUM *BN_CTX_get(BN_CTX *ctx) | 288 | BIGNUM *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 | |||
312 | static void BN_STACK_init(BN_STACK *st) | ||
313 | { | ||
314 | st->indexes = NULL; | ||
315 | st->depth = st->size = 0; | ||
316 | } | ||
317 | |||
318 | static void BN_STACK_finish(BN_STACK *st) | ||
319 | { | ||
320 | if(st->size) OPENSSL_free(st->indexes); | ||
321 | } | ||
322 | |||
323 | #ifndef OPENSSL_NO_DEPRECATED | ||
324 | static void BN_STACK_reset(BN_STACK *st) | ||
325 | { | ||
326 | st->depth = 0; | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | static 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 | |||
351 | static unsigned int BN_STACK_pop(BN_STACK *st) | ||
352 | { | ||
353 | return st->indexes[--(st->depth)]; | ||
354 | } | ||
355 | |||
356 | /***********/ | ||
357 | /* BN_POOL */ | ||
358 | /***********/ | ||
359 | |||
360 | static void BN_POOL_init(BN_POOL *p) | ||
361 | { | ||
362 | p->head = p->current = p->tail = NULL; | ||
363 | p->used = p->size = 0; | ||
364 | } | ||
365 | |||
366 | static 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 | ||
141 | void BN_CTX_end(BN_CTX *ctx) | 383 | #ifndef OPENSSL_NO_DEPRECATED |
384 | static 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; | 403 | static 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 | |||
438 | static 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 | */ |
179 | static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, | ||
180 | const BIGNUM *divisor, BN_CTX *ctx); | ||
179 | int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, | 181 | int 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); | ||
401 | err: | ||
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 | */ | ||
411 | static 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\ | ||
528 | X) -> 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\ | ||
557 | X) -> 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); |
382 | err: | 626 | err: |
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 | ||
71 | static ERR_STRING_DATA BN_str_functs[]= | 71 | static 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 | ||
126 | void ERR_load_BN_strings(void) | 140 | void 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) | |||
155 | err: | 155 | err: |
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; |
360 | err: | 363 | err: |
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, | |||
508 | err: | 511 | err: |
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, | |||
863 | err: | 866 | err: |
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 :-) */ |
871 | int BN_mod_exp_simple(BIGNUM *r, | 875 | int 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; |
981 | err: | 985 | err: |
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, | |||
305 | err: | 306 | err: |
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; |
141 | err: | 141 | err: |
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); |
198 | err: | 200 | err: |
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) */ |
206 | static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | ||
207 | const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); | ||
204 | BIGNUM *BN_mod_inverse(BIGNUM *in, | 208 | BIGNUM *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, | |||
486 | err: | 495 | err: |
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 | */ | ||
506 | static 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; | ||
649 | err: | ||
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 | 178 | end: | |
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 | ||
125 | struct 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); | |||
472 | int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n); | 467 | int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n); |
473 | int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, | 468 | int 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 | 470 | void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, |
476 | void 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); | 472 | void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, |
478 | void 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); | 474 | void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t); |
475 | void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n); | ||
480 | void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, | 476 | void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, |
481 | BN_ULONG *t); | 477 | BN_ULONG *t); |
482 | void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2, | 478 | void 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); |
484 | void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t); | 480 | BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, |
485 | #endif | 481 | int cl, int dl); |
486 | void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n); | 482 | BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, |
483 | int cl, int dl); | ||
484 | int 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 | ||
70 | const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT; | 70 | const 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 | ||
131 | const BIGNUM *BN_value_one(void) | 134 | const 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 | ||
245 | int BN_num_bits(const BIGNUM *a) | 248 | int 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 | ||
259 | void BN_clear_free(BIGNUM *a) | 257 | void 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) | |||
276 | void BN_free(BIGNUM *a) | 275 | void 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 | ||
286 | void BN_init(BIGNUM *a) | 292 | void 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 | ||
291 | BIGNUM *BN_new(void) | 298 | BIGNUM *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 | ||
396 | BIGNUM *bn_dup_expand(const BIGNUM *b, int words) | 394 | BIGNUM *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 | ||
442 | BIGNUM *bn_expand2(BIGNUM *b, int words) | 445 | BIGNUM *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 | ||
461 | BIGNUM *BN_dup(const BIGNUM *a) | 479 | BIGNUM *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 | ||
478 | BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) | 497 | BIGNUM *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 | |||
546 | void BN_clear(BIGNUM *a) | 567 | void 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 | ||
554 | BN_ULONG BN_get_word(const BIGNUM *a) | 576 | BN_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 | ||
575 | int BN_set_word(BIGNUM *a, BN_ULONG w) | 586 | int 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 | ||
759 | int BN_mask_bits(BIGNUM *a, int n) | 769 | int 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 | ||
790 | void 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 | |||
777 | int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) | 798 | int 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 */ |
150 | int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) | 150 | int 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; |
196 | err: | 197 | err: |
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) | |||
210 | int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | 211 | int 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) | |||
219 | int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) | 221 | int 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 | ||
140 | static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); | ||
141 | #endif | ||
142 | |||
143 | |||
144 | |||
72 | int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | 145 | int 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; |
94 | err: | 191 | err: |
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 | ||
197 | static 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 | |||
325 | int 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 | |||
99 | int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, | 340 | int 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 | ||
289 | BN_MONT_CTX *BN_MONT_CTX_new(void) | 534 | BN_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 | ||
322 | int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) | 572 | int 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; |
386 | err: | 679 | err: |
387 | return(0); | 680 | BN_CTX_end(ctx); |
681 | return ret; | ||
388 | } | 682 | } |
389 | 683 | ||
390 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) | 684 | BN_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 | ||
402 | BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, | 701 | BN_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 | |||
80 | BN_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 | |||
207 | BN_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 */ | ||
77 | void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, | 393 | void 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 */ |
223 | void 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) | 550 | void 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 | ||
611 | int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | 946 | int 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) |
736 | end: | 1096 | end: |
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; |
741 | err: | 1101 | err: |
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) | |||
782 | void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | 1149 | void 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, | |||
129 | static int probable_prime_dh_safe(BIGNUM *rnd, int bits, | 134 | static 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 | ||
132 | BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, | 137 | int 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 | |||
159 | int 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; | ||
152 | loop: | 173 | loop: |
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; |
204 | err: | 228 | err: |
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 | ||
211 | int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *), | 238 | int 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 | ||
217 | int BN_is_prime_fasttest(const BIGNUM *a, int checks, | 243 | int 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; |
314 | err: | 339 | err: |
@@ -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 | ||
351 | static int probable_prime(BIGNUM *rnd, int bits) | 377 | static 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 | ||
357 | again: | 383 | again: |
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; |
414 | err: | 438 | err: |
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; |
465 | err: | 490 | err: |
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 |
61 | typedef unsigned short prime_t; | ||
61 | #else | 62 | #else |
62 | #define NUMPRIMES 54 | 63 | #define NUMPRIMES 54 |
64 | typedef unsigned char prime_t; | ||
63 | #endif | 65 | #endif |
64 | static const unsigned int primes[NUMPRIMES]= | 66 | static 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 | ||
102 | printf "#ifndef EIGHT_BIT\n"; | 102 | printf "#ifndef EIGHT_BIT\n"; |
103 | printf "#define NUMPRIMES %d\n",$num; | 103 | printf "#define NUMPRIMES %d\n",$num; |
104 | printf "typedef unsigned short prime_t;\n"; | ||
104 | printf "#else\n"; | 105 | printf "#else\n"; |
105 | printf "#define NUMPRIMES %d\n",$eight; | 106 | printf "#define NUMPRIMES %d\n",$eight; |
107 | printf "typedef unsigned char prime_t;\n"; | ||
106 | printf "#endif\n"; | 108 | printf "#endif\n"; |
107 | print "static const unsigned int primes[NUMPRIMES]=\n\t{\n\t"; | 109 | print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t"; |
108 | $init=0; | 110 | $init=0; |
109 | for ($i=0; $i <= $#primes; $i++) | 111 | for ($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 | ||
65 | static const char *Hex="0123456789ABCDEF"; | 65 | static const char Hex[]="0123456789ABCDEF"; |
66 | 66 | ||
67 | /* Must 'OPENSSL_free' the returned data */ | 67 | /* Must 'OPENSSL_free' the returned data */ |
68 | char *BN_bn2hex(const BIGNUM *a) | 68 | char *BN_bn2hex(const BIGNUM *a) |
@@ -102,14 +102,19 @@ err: | |||
102 | /* Must 'OPENSSL_free' the returned data */ | 102 | /* Must 'OPENSSL_free' the returned data */ |
103 | char *BN_bn2dec(const BIGNUM *a) | 103 | char *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; | ||
152 | err: | 160 | err: |
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); |
219 | err: | 234 | err: |
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); |
276 | err: | 292 | err: |
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 | ||
325 | void 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) | |||
94 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) | 94 | int 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); |
124 | err: | 124 | err: |
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; |
204 | err: | 205 | err: |
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: | |||
214 | int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) | 217 | int 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; |
227 | err: | 230 | err: |
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 | ||
86 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) | 90 | BN_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_); | |||
79 | int test_rshift1(BIO *bp); | 98 | int test_rshift1(BIO *bp); |
80 | int test_rshift(BIO *bp,BN_CTX *ctx); | 99 | int test_rshift(BIO *bp,BN_CTX *ctx); |
81 | int test_div(BIO *bp,BN_CTX *ctx); | 100 | int test_div(BIO *bp,BN_CTX *ctx); |
101 | int test_div_word(BIO *bp); | ||
82 | int test_div_recp(BIO *bp,BN_CTX *ctx); | 102 | int test_div_recp(BIO *bp,BN_CTX *ctx); |
83 | int test_mul(BIO *bp); | 103 | int test_mul(BIO *bp); |
84 | int test_sqr(BIO *bp,BN_CTX *ctx); | 104 | int test_sqr(BIO *bp,BN_CTX *ctx); |
@@ -88,6 +108,15 @@ int test_mod_mul(BIO *bp,BN_CTX *ctx); | |||
88 | int test_mod_exp(BIO *bp,BN_CTX *ctx); | 108 | int test_mod_exp(BIO *bp,BN_CTX *ctx); |
89 | int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx); | 109 | int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx); |
90 | int test_exp(BIO *bp,BN_CTX *ctx); | 110 | int test_exp(BIO *bp,BN_CTX *ctx); |
111 | int test_gf2m_add(BIO *bp); | ||
112 | int test_gf2m_mod(BIO *bp); | ||
113 | int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx); | ||
114 | int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx); | ||
115 | int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx); | ||
116 | int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx); | ||
117 | int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx); | ||
118 | int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx); | ||
119 | int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx); | ||
91 | int test_kron(BIO *bp,BN_CTX *ctx); | 120 | int test_kron(BIO *bp,BN_CTX *ctx); |
92 | int test_sqrt(BIO *bp,BN_CTX *ctx); | 121 | int test_sqrt(BIO *bp,BN_CTX *ctx); |
93 | int rand_neg(void); | 122 | int 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); |
238 | err: | 307 | err: |
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 | ||
476 | static 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 | |||
492 | int 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 | |||
407 | int test_div_recp(BIO *bp, BN_CTX *ctx) | 548 | int 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 | ||
922 | static void genprime_cb(int p, int n, void *arg) | 1063 | int 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 | |||
1115 | int 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 | |||
1173 | int 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 | |||
1244 | int 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 | |||
1303 | int 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 | |||
1358 | int 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 | |||
1421 | int 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 | |||
1492 | int 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 | |||
1551 | int 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 | |||
1638 | static 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 | ||
936 | int test_kron(BIO *bp, BN_CTX *ctx) | 1651 | int 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 | ||
1024 | int test_sqrt(BIO *bp, BN_CTX *ctx) | 1742 | int 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[]) | |||
195 | err: | 195 | err: |
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 | } |