diff options
| author | djm <> | 2008-09-06 12:17:54 +0000 |
|---|---|---|
| committer | djm <> | 2008-09-06 12:17:54 +0000 |
| commit | 6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda (patch) | |
| tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/bn | |
| parent | 89181603212b41e95cde36b1be5a146ce8fb2935 (diff) | |
| download | openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.gz openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.bz2 openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.zip | |
resolve conflicts
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 | } |
