summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_exp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_exp.c')
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c1146
1 files changed, 582 insertions, 564 deletions
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index 22ef643c02..0e36e8d7b5 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -5,21 +5,21 @@
5 * This package is an SSL implementation written 5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com). 6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL. 7 * The implementation was written so as to conform with Netscapes SSL.
8 * 8 *
9 * This library is free for commercial and non-commercial use as long as 9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions 10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA, 11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms 13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 * 15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed. 17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution 18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used. 19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or 20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package. 21 * in documentation (online or textual) provided with the package.
22 * 22 *
23 * Redistribution and use in source and binary forms, with or without 23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions 24 * modification, are permitted provided that the following conditions
25 * are met: 25 * are met:
@@ -34,10 +34,10 @@
34 * Eric Young (eay@cryptsoft.com)" 34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library 35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-). 36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement: 38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 * 40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,7 +49,7 @@
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE. 51 * SUCH DAMAGE.
52 * 52 *
53 * The licence and distribution terms for any publically available version or 53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
@@ -63,7 +63,7 @@
63 * are met: 63 * are met:
64 * 64 *
65 * 1. Redistributions of source code must retain the above copyright 65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer. 66 * notice, this list of conditions and the following disclaimer.
67 * 67 *
68 * 2. Redistributions in binary form must reproduce the above copyright 68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in 69 * notice, this list of conditions and the following disclaimer in
@@ -124,17 +124,17 @@
124#define TABLE_SIZE 32 124#define TABLE_SIZE 32
125 125
126/* this one works - simple but works */ 126/* this one works - simple but works */
127int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 127int
128 { 128BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
129 int i,bits,ret=0; 129{
130 BIGNUM *v,*rr; 130 int i, bits, ret = 0;
131 BIGNUM *v, *rr;
131 132
132 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) 133 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
133 {
134 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ 134 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
135 BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 135 BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
136 return -1; 136 return -1;
137 } 137 }
138 138
139 BN_CTX_start(ctx); 139 BN_CTX_start(ctx);
140 if ((r == a) || (r == p)) 140 if ((r == a) || (r == p))
@@ -142,35 +142,43 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
142 else 142 else
143 rr = r; 143 rr = r;
144 v = BN_CTX_get(ctx); 144 v = BN_CTX_get(ctx);
145 if (rr == NULL || v == NULL) goto err; 145 if (rr == NULL || v == NULL)
146 goto err;
146 147
147 if (BN_copy(v,a) == NULL) goto err; 148 if (BN_copy(v, a) == NULL)
148 bits=BN_num_bits(p); 149 goto err;
150 bits = BN_num_bits(p);
149 151
150 if (BN_is_odd(p)) 152 if (BN_is_odd(p)) {
151 { if (BN_copy(rr,a) == NULL) goto err; } 153 if (BN_copy(rr, a) == NULL)
152 else { if (!BN_one(rr)) goto err; } 154 goto err;
155 } else {
156 if (!BN_one(rr))
157 goto err;
158 }
153 159
154 for (i=1; i<bits; i++) 160 for (i = 1; i < bits; i++) {
155 { 161 if (!BN_sqr(v, v, ctx))
156 if (!BN_sqr(v,v,ctx)) goto err; 162 goto err;
157 if (BN_is_bit_set(p,i)) 163 if (BN_is_bit_set(p, i)) {
158 { 164 if (!BN_mul(rr, rr, v, ctx))
159 if (!BN_mul(rr,rr,v,ctx)) goto err; 165 goto err;
160 }
161 } 166 }
162 ret=1; 167 }
168 ret = 1;
169
163err: 170err:
164 if (r != rr) BN_copy(r,rr); 171 if (r != rr)
172 BN_copy(r, rr);
165 BN_CTX_end(ctx); 173 BN_CTX_end(ctx);
166 bn_check_top(r); 174 bn_check_top(r);
167 return(ret); 175 return (ret);
168 } 176}
169 177
170 178int
171int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, 179BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
172 BN_CTX *ctx) 180 BN_CTX *ctx)
173 { 181{
174 int ret; 182 int ret;
175 183
176 bn_check_top(a); 184 bn_check_top(a);
@@ -194,7 +202,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
194 * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] 202 * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
195 * 55 .. 77 % [UltraSparc processor, but 203 * 55 .. 77 % [UltraSparc processor, but
196 * debug-solaris-sparcv8-gcc conf.] 204 * debug-solaris-sparcv8-gcc conf.]
197 * 205 *
198 * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] 206 * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
199 * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] 207 * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
200 * 208 *
@@ -218,310 +226,305 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
218 * a >= m. eay 07-May-97 */ 226 * a >= m. eay 07-May-97 */
219/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ 227/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
220 228
221 if (BN_is_odd(m)) 229 if (BN_is_odd(m)) {
222 {
223# ifdef MONT_EXP_WORD 230# ifdef MONT_EXP_WORD
224 if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) 231 if (a->top == 1 && !a->neg &&
225 { 232 (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
226 BN_ULONG A = a->d[0]; 233 BN_ULONG A = a->d[0];
227 ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL); 234 ret = BN_mod_exp_mont_word(r, A,p, m,ctx, NULL);
228 } 235 } else
229 else
230# endif 236# endif
231 ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); 237 ret = BN_mod_exp_mont(r, a,p, m,ctx, NULL);
232 } 238 } else
233 else
234#endif 239#endif
235#ifdef RECP_MUL_MOD 240#ifdef RECP_MUL_MOD
236 { ret=BN_mod_exp_recp(r,a,p,m,ctx); } 241 {
242 ret = BN_mod_exp_recp(r, a,p, m, ctx);
243 }
237#else 244#else
238 { ret=BN_mod_exp_simple(r,a,p,m,ctx); } 245 {
246 ret = BN_mod_exp_simple(r, a,p, m, ctx);
247 }
239#endif 248#endif
240 249
241 bn_check_top(r); 250 bn_check_top(r);
242 return(ret); 251 return (ret);
243 } 252}
244 253
245 254int
246int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 255BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
247 const BIGNUM *m, BN_CTX *ctx) 256 BN_CTX *ctx)
248 { 257{
249 int i,j,bits,ret=0,wstart,wend,window,wvalue; 258 int i, j, bits, ret = 0, wstart, wend, window, wvalue;
250 int start=1; 259 int start = 1;
251 BIGNUM *aa; 260 BIGNUM *aa;
252 /* Table of variables obtained from 'ctx' */ 261 /* Table of variables obtained from 'ctx' */
253 BIGNUM *val[TABLE_SIZE]; 262 BIGNUM *val[TABLE_SIZE];
254 BN_RECP_CTX recp; 263 BN_RECP_CTX recp;
255 264
256 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) 265 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
257 {
258 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ 266 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
259 BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 267 BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
260 return -1; 268 return -1;
261 } 269 }
262 270
263 bits=BN_num_bits(p); 271 bits = BN_num_bits(p);
264 272
265 if (bits == 0) 273 if (bits == 0) {
266 {
267 ret = BN_one(r); 274 ret = BN_one(r);
268 return ret; 275 return ret;
269 } 276 }
270 277
271 BN_CTX_start(ctx); 278 BN_CTX_start(ctx);
272 aa = BN_CTX_get(ctx); 279 aa = BN_CTX_get(ctx);
273 val[0] = BN_CTX_get(ctx); 280 val[0] = BN_CTX_get(ctx);
274 if(!aa || !val[0]) goto err; 281 if (!aa || !val[0])
282 goto err;
275 283
276 BN_RECP_CTX_init(&recp); 284 BN_RECP_CTX_init(&recp);
277 if (m->neg) 285 if (m->neg) {
278 {
279 /* ignore sign of 'm' */ 286 /* ignore sign of 'm' */
280 if (!BN_copy(aa, m)) goto err; 287 if (!BN_copy(aa, m))
288 goto err;
281 aa->neg = 0; 289 aa->neg = 0;
282 if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err; 290 if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
283 } 291 goto err;
284 else 292 } else {
285 { 293 if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
286 if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; 294 goto err;
287 } 295 }
288 296
289 if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */ 297 if (!BN_nnmod(val[0], a, m, ctx))
290 if (BN_is_zero(val[0])) 298 goto err; /* 1 */
291 { 299 if (BN_is_zero(val[0])) {
292 BN_zero(r); 300 BN_zero(r);
293 ret = 1; 301 ret = 1;
294 goto err; 302 goto err;
295 } 303 }
296 304
297 window = BN_window_bits_for_exponent_size(bits); 305 window = BN_window_bits_for_exponent_size(bits);
298 if (window > 1) 306 if (window > 1) {
299 { 307 if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
300 if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
301 goto err; /* 2 */ 308 goto err; /* 2 */
302 j=1<<(window-1); 309 j = 1 << (window - 1);
303 for (i=1; i<j; i++) 310 for (i = 1; i < j; i++) {
304 { 311 if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
305 if(((val[i] = BN_CTX_get(ctx)) == NULL) || 312 !BN_mod_mul_reciprocal(val[i], val[i - 1],
306 !BN_mod_mul_reciprocal(val[i],val[i-1], 313 aa, &recp, ctx))
307 aa,&recp,ctx))
308 goto err; 314 goto err;
309 }
310 } 315 }
311 316 }
312 start=1; /* This is used to avoid multiplication etc
313 * when there is only the value '1' in the
314 * buffer. */
315 wvalue=0; /* The 'value' of the window */
316 wstart=bits-1; /* The top bit of the window */
317 wend=0; /* The bottom bit of the window */
318 317
319 if (!BN_one(r)) goto err; 318 start = 1; /* This is used to avoid multiplication etc
319 * when there is only the value '1' in the
320 * buffer. */
321 wvalue = 0; /* The 'value' of the window */
322 wstart = bits - 1; /* The top bit of the window */
323 wend = 0; /* The bottom bit of the window */
320 324
321 for (;;) 325 if (!BN_one(r))
322 { 326 goto err;
323 if (BN_is_bit_set(p,wstart) == 0) 327
324 { 328 for (;;) {
329 if (BN_is_bit_set(p, wstart) == 0) {
325 if (!start) 330 if (!start)
326 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx)) 331 if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx))
327 goto err; 332 goto err;
328 if (wstart == 0) break; 333 if (wstart == 0)
334 break;
329 wstart--; 335 wstart--;
330 continue; 336 continue;
331 } 337 }
332 /* We now have wstart on a 'set' bit, we now need to work out 338 /* We now have wstart on a 'set' bit, we now need to work out
333 * how bit a window to do. To do this we need to scan 339 * how bit a window to do. To do this we need to scan
334 * forward until the last set bit before the end of the 340 * forward until the last set bit before the end of the
335 * window */ 341 * window */
336 j=wstart; 342 j = wstart;
337 wvalue=1; 343 wvalue = 1;
338 wend=0; 344 wend = 0;
339 for (i=1; i<window; i++) 345 for (i = 1; i < window; i++) {
340 { 346 if (wstart - i < 0)
341 if (wstart-i < 0) break; 347 break;
342 if (BN_is_bit_set(p,wstart-i)) 348 if (BN_is_bit_set(p, wstart - i)) {
343 { 349 wvalue <<= (i - wend);
344 wvalue<<=(i-wend); 350 wvalue |= 1;
345 wvalue|=1; 351 wend = i;
346 wend=i;
347 }
348 } 352 }
353 }
349 354
350 /* wend is the size of the current window */ 355 /* wend is the size of the current window */
351 j=wend+1; 356 j = wend + 1;
352 /* add the 'bytes above' */ 357 /* add the 'bytes above' */
353 if (!start) 358 if (!start)
354 for (i=0; i<j; i++) 359 for (i = 0; i < j; i++) {
355 { 360 if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx))
356 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
357 goto err; 361 goto err;
358 } 362 }
359 363
360 /* wvalue will be an odd number < 2^window */ 364 /* wvalue will be an odd number < 2^window */
361 if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx)) 365 if (!BN_mod_mul_reciprocal(r, r,val[wvalue >> 1], &recp, ctx))
362 goto err; 366 goto err;
363 367
364 /* move the 'window' down further */ 368 /* move the 'window' down further */
365 wstart-=wend+1; 369 wstart -= wend + 1;
366 wvalue=0; 370 wvalue = 0;
367 start=0; 371 start = 0;
368 if (wstart < 0) break; 372 if (wstart < 0)
369 } 373 break;
370 ret=1; 374 }
375 ret = 1;
376
371err: 377err:
372 BN_CTX_end(ctx); 378 BN_CTX_end(ctx);
373 BN_RECP_CTX_free(&recp); 379 BN_RECP_CTX_free(&recp);
374 bn_check_top(r); 380 bn_check_top(r);
375 return(ret); 381 return (ret);
376 } 382}
377 383
378 384int
379int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, 385BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
380 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 386 BN_CTX *ctx, BN_MONT_CTX *in_mont)
381 { 387{
382 int i,j,bits,ret=0,wstart,wend,window,wvalue; 388 int i, j, bits, ret = 0, wstart, wend, window, wvalue;
383 int start=1; 389 int start = 1;
384 BIGNUM *d,*r; 390 BIGNUM *d, *r;
385 const BIGNUM *aa; 391 const BIGNUM *aa;
386 /* Table of variables obtained from 'ctx' */ 392 /* Table of variables obtained from 'ctx' */
387 BIGNUM *val[TABLE_SIZE]; 393 BIGNUM *val[TABLE_SIZE];
388 BN_MONT_CTX *mont=NULL; 394 BN_MONT_CTX *mont = NULL;
389 395
390 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) 396 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
391 {
392 return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); 397 return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
393 } 398 }
394 399
395 bn_check_top(a); 400 bn_check_top(a);
396 bn_check_top(p); 401 bn_check_top(p);
397 bn_check_top(m); 402 bn_check_top(m);
398 403
399 if (!BN_is_odd(m)) 404 if (!BN_is_odd(m)) {
400 { 405 BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
401 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); 406 return (0);
402 return(0); 407 }
403 } 408 bits = BN_num_bits(p);
404 bits=BN_num_bits(p); 409 if (bits == 0) {
405 if (bits == 0)
406 {
407 ret = BN_one(rr); 410 ret = BN_one(rr);
408 return ret; 411 return ret;
409 } 412 }
410 413
411 BN_CTX_start(ctx); 414 BN_CTX_start(ctx);
412 d = BN_CTX_get(ctx); 415 d = BN_CTX_get(ctx);
413 r = BN_CTX_get(ctx); 416 r = BN_CTX_get(ctx);
414 val[0] = BN_CTX_get(ctx); 417 val[0] = BN_CTX_get(ctx);
415 if (!d || !r || !val[0]) goto err; 418 if (!d || !r || !val[0])
419 goto err;
416 420
417 /* If this is not done, things will break in the montgomery 421 /* If this is not done, things will break in the montgomery
418 * part */ 422 * part */
419 423
420 if (in_mont != NULL) 424 if (in_mont != NULL)
421 mont=in_mont; 425 mont = in_mont;
422 else 426 else {
423 { 427 if ((mont = BN_MONT_CTX_new()) == NULL)
424 if ((mont=BN_MONT_CTX_new()) == NULL) goto err; 428 goto err;
425 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 429 if (!BN_MONT_CTX_set(mont, m, ctx))
426 } 430 goto err;
431 }
427 432
428 if (a->neg || BN_ucmp(a,m) >= 0) 433 if (a->neg || BN_ucmp(a, m) >= 0) {
429 { 434 if (!BN_nnmod(val[0], a,m, ctx))
430 if (!BN_nnmod(val[0],a,m,ctx))
431 goto err; 435 goto err;
432 aa= val[0]; 436 aa = val[0];
433 } 437 } else
434 else 438 aa = a;
435 aa=a; 439 if (BN_is_zero(aa)) {
436 if (BN_is_zero(aa))
437 {
438 BN_zero(rr); 440 BN_zero(rr);
439 ret = 1; 441 ret = 1;
440 goto err; 442 goto err;
441 } 443 }
442 if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */ 444 if (!BN_to_montgomery(val[0], aa, mont, ctx))
445 goto err; /* 1 */
443 446
444 window = BN_window_bits_for_exponent_size(bits); 447 window = BN_window_bits_for_exponent_size(bits);
445 if (window > 1) 448 if (window > 1) {
446 { 449 if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
447 if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */ 450 goto err; /* 2 */
448 j=1<<(window-1); 451 j = 1 << (window - 1);
449 for (i=1; i<j; i++) 452 for (i = 1; i < j; i++) {
450 { 453 if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
451 if(((val[i] = BN_CTX_get(ctx)) == NULL) || 454 !BN_mod_mul_montgomery(val[i], val[i - 1],
452 !BN_mod_mul_montgomery(val[i],val[i-1], 455 d, mont, ctx))
453 d,mont,ctx))
454 goto err; 456 goto err;
455 }
456 } 457 }
458 }
457 459
458 start=1; /* This is used to avoid multiplication etc 460 start = 1; /* This is used to avoid multiplication etc
459 * when there is only the value '1' in the 461 * when there is only the value '1' in the
460 * buffer. */ 462 * buffer. */
461 wvalue=0; /* The 'value' of the window */ 463 wvalue = 0; /* The 'value' of the window */
462 wstart=bits-1; /* The top bit of the window */ 464 wstart = bits - 1; /* The top bit of the window */
463 wend=0; /* The bottom bit of the window */ 465 wend = 0; /* The bottom bit of the window */
464 466
465 if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err; 467 if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
466 for (;;) 468 goto err;
467 { 469 for (;;) {
468 if (BN_is_bit_set(p,wstart) == 0) 470 if (BN_is_bit_set(p, wstart) == 0) {
469 { 471 if (!start) {
470 if (!start) 472 if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
471 { 473 goto err;
472 if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) 474 }
473 goto err; 475 if (wstart == 0)
474 } 476 break;
475 if (wstart == 0) break;
476 wstart--; 477 wstart--;
477 continue; 478 continue;
478 } 479 }
479 /* We now have wstart on a 'set' bit, we now need to work out 480 /* We now have wstart on a 'set' bit, we now need to work out
480 * how bit a window to do. To do this we need to scan 481 * how bit a window to do. To do this we need to scan
481 * forward until the last set bit before the end of the 482 * forward until the last set bit before the end of the
482 * window */ 483 * window */
483 j=wstart; 484 j = wstart;
484 wvalue=1; 485 wvalue = 1;
485 wend=0; 486 wend = 0;
486 for (i=1; i<window; i++) 487 for (i = 1; i < window; i++) {
487 { 488 if (wstart - i < 0)
488 if (wstart-i < 0) break; 489 break;
489 if (BN_is_bit_set(p,wstart-i)) 490 if (BN_is_bit_set(p, wstart - i)) {
490 { 491 wvalue <<= (i - wend);
491 wvalue<<=(i-wend); 492 wvalue |= 1;
492 wvalue|=1; 493 wend = i;
493 wend=i;
494 }
495 } 494 }
495 }
496 496
497 /* wend is the size of the current window */ 497 /* wend is the size of the current window */
498 j=wend+1; 498 j = wend + 1;
499 /* add the 'bytes above' */ 499 /* add the 'bytes above' */
500 if (!start) 500 if (!start)
501 for (i=0; i<j; i++) 501 for (i = 0; i < j; i++) {
502 { 502 if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
503 if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
504 goto err; 503 goto err;
505 } 504 }
506 505
507 /* wvalue will be an odd number < 2^window */ 506 /* wvalue will be an odd number < 2^window */
508 if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx)) 507 if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
509 goto err; 508 goto err;
510 509
511 /* move the 'window' down further */ 510 /* move the 'window' down further */
512 wstart-=wend+1; 511 wstart -= wend + 1;
513 wvalue=0; 512 wvalue = 0;
514 start=0; 513 start = 0;
515 if (wstart < 0) break; 514 if (wstart < 0)
516 } 515 break;
517 if (!BN_from_montgomery(rr,r,mont,ctx)) goto err; 516 }
518 ret=1; 517 if (!BN_from_montgomery(rr, r,mont, ctx))
518 goto err;
519 ret = 1;
520
519err: 521err:
520 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 522 if ((in_mont == NULL) && (mont != NULL))
523 BN_MONT_CTX_free(mont);
521 BN_CTX_end(ctx); 524 BN_CTX_end(ctx);
522 bn_check_top(rr); 525 bn_check_top(rr);
523 return(ret); 526 return (ret);
524 } 527}
525 528
526 529
527/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout 530/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
@@ -529,36 +532,38 @@ err:
529 * as cache lines are concerned. The following functions are used to transfer a BIGNUM 532 * as cache lines are concerned. The following functions are used to transfer a BIGNUM
530 * from/to that table. */ 533 * from/to that table. */
531 534
532static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, int idx, int width) 535static int
533 { 536MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf,
537 int idx, int width)
538{
534 size_t i, j; 539 size_t i, j;
535 540
536 if (top > b->top) 541 if (top > b->top)
537 top = b->top; /* this works because 'buf' is explicitly zeroed */ 542 top = b->top; /* this works because 'buf' is explicitly zeroed */
538 for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width) 543 for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
539 {
540 buf[j] = ((unsigned char*)b->d)[i]; 544 buf[j] = ((unsigned char*)b->d)[i];
541 } 545 }
542 546
543 return 1; 547 return 1;
544 } 548}
545 549
546static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width) 550static int
547 { 551MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx,
552 int width)
553{
548 size_t i, j; 554 size_t i, j;
549 555
550 if (bn_wexpand(b, top) == NULL) 556 if (bn_wexpand(b, top) == NULL)
551 return 0; 557 return 0;
552 558
553 for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width) 559 for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
554 {
555 ((unsigned char*)b->d)[i] = buf[j]; 560 ((unsigned char*)b->d)[i] = buf[j];
556 } 561 }
557 562
558 b->top = top; 563 b->top = top;
559 bn_correct_top(b); 564 bn_correct_top(b);
560 return 1; 565 return 1;
561 } 566}
562 567
563/* Given a pointer value, compute the next address that is a cache line multiple. */ 568/* Given a pointer value, compute the next address that is a cache line multiple. */
564#define MOD_EXP_CTIME_ALIGN(x_) \ 569#define MOD_EXP_CTIME_ALIGN(x_) \
@@ -570,17 +575,17 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf
570 * pointed out by Colin Percival, 575 * pointed out by Colin Percival,
571 * http://www.daemonology.net/hyperthreading-considered-harmful/) 576 * http://www.daemonology.net/hyperthreading-considered-harmful/)
572 */ 577 */
573int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, 578int
574 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 579BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
575 { 580 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
576 int i,bits,ret=0,window,wvalue; 581{
582 int i, bits, ret = 0, window, wvalue;
577 int top; 583 int top;
578 BN_MONT_CTX *mont=NULL; 584 BN_MONT_CTX *mont = NULL;
579
580 int numPowers; 585 int numPowers;
581 unsigned char *powerbufFree=NULL; 586 unsigned char *powerbufFree = NULL;
582 int powerbufLen = 0; 587 int powerbufLen = 0;
583 unsigned char *powerbuf=NULL; 588 unsigned char *powerbuf = NULL;
584 BIGNUM tmp, am; 589 BIGNUM tmp, am;
585 590
586 bn_check_top(a); 591 bn_check_top(a);
@@ -589,17 +594,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
589 594
590 top = m->top; 595 top = m->top;
591 596
592 if (!(m->d[0] & 1)) 597 if (!(m->d[0] & 1)) {
593 { 598 BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,
594 BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS); 599 BN_R_CALLED_WITH_EVEN_MODULUS);
595 return(0); 600 return (0);
596 } 601 }
597 bits=BN_num_bits(p); 602 bits = BN_num_bits(p);
598 if (bits == 0) 603 if (bits == 0) {
599 {
600 ret = BN_one(rr); 604 ret = BN_one(rr);
601 return ret; 605 return ret;
602 } 606 }
603 607
604 BN_CTX_start(ctx); 608 BN_CTX_start(ctx);
605 609
@@ -607,33 +611,37 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
607 * If this is not done, things will break in the montgomery part. 611 * If this is not done, things will break in the montgomery part.
608 */ 612 */
609 if (in_mont != NULL) 613 if (in_mont != NULL)
610 mont=in_mont; 614 mont = in_mont;
611 else 615 else {
612 { 616 if ((mont = BN_MONT_CTX_new()) == NULL)
613 if ((mont=BN_MONT_CTX_new()) == NULL) goto err; 617 goto err;
614 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 618 if (!BN_MONT_CTX_set(mont, m, ctx))
615 } 619 goto err;
620 }
616 621
617 /* Get the window size to use with size of p. */ 622 /* Get the window size to use with size of p. */
618 window = BN_window_bits_for_ctime_exponent_size(bits); 623 window = BN_window_bits_for_ctime_exponent_size(bits);
619#if defined(OPENSSL_BN_ASM_MONT5) 624#if defined(OPENSSL_BN_ASM_MONT5)
620 if (window==6 && bits<=1024) window=5; /* ~5% improvement of 2048-bit RSA sign */ 625 if (window == 6 && bits <= 1024)
626 window = 5; /* ~5% improvement of 2048-bit RSA sign */
621#endif 627#endif
622 628
623 /* Allocate a buffer large enough to hold all of the pre-computed 629 /* Allocate a buffer large enough to hold all of the pre-computed
624 * powers of am, am itself and tmp. 630 * powers of am, am itself and tmp.
625 */ 631 */
626 numPowers = 1 << window; 632 numPowers = 1 << window;
627 powerbufLen = sizeof(m->d[0])*(top*numPowers + 633 powerbufLen = sizeof(m->d[0]) * (top * numPowers +
628 ((2*top)>numPowers?(2*top):numPowers)); 634 ((2*top) > numPowers ? (2*top) : numPowers));
629#ifdef alloca 635#ifdef alloca
630 if (powerbufLen < 3072) 636 if (powerbufLen < 3072)
631 powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); 637 powerbufFree = alloca(powerbufLen +
638 MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
632 else 639 else
633#endif 640#endif
634 if ((powerbufFree=(unsigned char*)malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) 641 if ((powerbufFree = (unsigned char*)malloc(powerbufLen +
642 MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
635 goto err; 643 goto err;
636 644
637 powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); 645 powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
638 memset(powerbuf, 0, powerbufLen); 646 memset(powerbuf, 0, powerbufLen);
639 647
@@ -643,196 +651,213 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
643#endif 651#endif
644 652
645 /* lay down tmp and am right after powers table */ 653 /* lay down tmp and am right after powers table */
646 tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0])*top*numPowers); 654 tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
647 am.d = tmp.d + top; 655 am.d = tmp.d + top;
648 tmp.top = am.top = 0; 656 tmp.top = am.top = 0;
649 tmp.dmax = am.dmax = top; 657 tmp.dmax = am.dmax = top;
650 tmp.neg = am.neg = 0; 658 tmp.neg = am.neg = 0;
651 tmp.flags = am.flags = BN_FLG_STATIC_DATA; 659 tmp.flags = am.flags = BN_FLG_STATIC_DATA;
652 660
653 /* prepare a^0 in Montgomery domain */ 661 /* prepare a^0 in Montgomery domain */
654#if 1 662#if 1
655 if (!BN_to_montgomery(&tmp,BN_value_one(),mont,ctx)) goto err; 663 if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
664 goto err;
656#else 665#else
657 tmp.d[0] = (0-m->d[0])&BN_MASK2; /* 2^(top*BN_BITS2) - m */ 666 tmp.d[0] = (0 - m - >d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */
658 for (i=1;i<top;i++) 667 for (i = 1; i < top; i++)
659 tmp.d[i] = (~m->d[i])&BN_MASK2; 668 tmp.d[i] = (~m->d[i]) & BN_MASK2;
660 tmp.top = top; 669 tmp.top = top;
661#endif 670#endif
662 671
663 /* prepare a^1 in Montgomery domain */ 672 /* prepare a^1 in Montgomery domain */
664 if (a->neg || BN_ucmp(a,m) >= 0) 673 if (a->neg || BN_ucmp(a, m) >= 0) {
665 { 674 if (!BN_mod(&am, a,m, ctx))
666 if (!BN_mod(&am,a,m,ctx)) goto err; 675 goto err;
667 if (!BN_to_montgomery(&am,&am,mont,ctx)) goto err; 676 if (!BN_to_montgomery(&am, &am, mont, ctx))
668 } 677 goto err;
669 else if (!BN_to_montgomery(&am,a,mont,ctx)) goto err; 678 } else if (!BN_to_montgomery(&am, a,mont, ctx))
679 goto err;
670 680
671#if defined(OPENSSL_BN_ASM_MONT5) 681#if defined(OPENSSL_BN_ASM_MONT5)
672 /* This optimization uses ideas from http://eprint.iacr.org/2011/239, 682 /* This optimization uses ideas from http://eprint.iacr.org/2011/239,
673 * specifically optimization of cache-timing attack countermeasures 683 * specifically optimization of cache-timing attack countermeasures
674 * and pre-computation optimization. */ 684 * and pre-computation optimization. */
675 685
676 /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as 686 /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
677 * 512-bit RSA is hardly relevant, we omit it to spare size... */ 687 * 512-bit RSA is hardly relevant, we omit it to spare size... */
678 if (window==5) 688 if (window == 5) {
679 { 689 void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
680 void bn_mul_mont_gather5(BN_ULONG *rp,const BN_ULONG *ap, 690 const void *table, const BN_ULONG *np,
681 const void *table,const BN_ULONG *np, 691 const BN_ULONG *n0, int num, int power);
682 const BN_ULONG *n0,int num,int power); 692 void bn_scatter5(const BN_ULONG *inp, size_t num,
683 void bn_scatter5(const BN_ULONG *inp,size_t num, 693 void *table, size_t power);
684 void *table,size_t power); 694 void bn_gather5(BN_ULONG *out, size_t num,
685 void bn_gather5(BN_ULONG *out,size_t num, 695 void *table, size_t power);
686 void *table,size_t power); 696
687 697 BN_ULONG *np = mont->N.d, *n0 = mont->n0;
688 BN_ULONG *np=mont->N.d, *n0=mont->n0; 698
689 699 /* BN_to_montgomery can contaminate words above .top
690 /* BN_to_montgomery can contaminate words above .top 700 * [in BN_DEBUG[_DEBUG] build]... */
691 * [in BN_DEBUG[_DEBUG] build]... */ 701 for (i = am.top; i < top; i++)
692 for (i=am.top; i<top; i++) am.d[i]=0; 702 am.d[i] = 0;
693 for (i=tmp.top; i<top; i++) tmp.d[i]=0; 703 for (i = tmp.top; i < top; i++)
694 704 tmp.d[i] = 0;
695 bn_scatter5(tmp.d,top,powerbuf,0); 705
696 bn_scatter5(am.d,am.top,powerbuf,1); 706 bn_scatter5(tmp.d, top, powerbuf, 0);
697 bn_mul_mont(tmp.d,am.d,am.d,np,n0,top); 707 bn_scatter5(am.d, am.top, powerbuf, 1);
698 bn_scatter5(tmp.d,top,powerbuf,2); 708 bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
709 bn_scatter5(tmp.d, top, powerbuf, 2);
699 710
700#if 0 711#if 0
701 for (i=3; i<32; i++) 712 for (i = 3; i < 32; i++) {
702 { 713 /* Calculate a^i = a^(i-1) * a */
703 /* Calculate a^i = a^(i-1) * a */ 714 bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
704 bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1); 715 n0, top, i - 1);
705 bn_scatter5(tmp.d,top,powerbuf,i); 716 bn_scatter5(tmp.d, top, powerbuf, i);
706 } 717 }
707#else 718#else
708 /* same as above, but uses squaring for 1/2 of operations */ 719 /* same as above, but uses squaring for 1/2 of operations */
709 for (i=4; i<32; i*=2) 720 for (i = 4; i < 32; i*=2) {
710 { 721 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
711 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 722 bn_scatter5(tmp.d, top, powerbuf, i);
712 bn_scatter5(tmp.d,top,powerbuf,i);
713 } 723 }
714 for (i=3; i<8; i+=2) 724 for (i = 3; i < 8; i += 2) {
715 { 725 int j;
716 int j; 726 bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
717 bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1); 727 n0, top, i - 1);
718 bn_scatter5(tmp.d,top,powerbuf,i); 728 bn_scatter5(tmp.d, top, powerbuf, i);
719 for (j=2*i; j<32; j*=2) 729 for (j = 2 * i; j < 32; j *= 2) {
720 { 730 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
721 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 731 bn_scatter5(tmp.d, top, powerbuf, j);
722 bn_scatter5(tmp.d,top,powerbuf,j);
723 } 732 }
724 } 733 }
725 for (; i<16; i+=2) 734 for (; i < 16; i += 2) {
726 { 735 bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
727 bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1); 736 n0, top, i - 1);
728 bn_scatter5(tmp.d,top,powerbuf,i); 737 bn_scatter5(tmp.d, top, powerbuf, i);
729 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 738 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
730 bn_scatter5(tmp.d,top,powerbuf,2*i); 739 bn_scatter5(tmp.d, top, powerbuf, 2*i);
731 } 740 }
732 for (; i<32; i+=2) 741 for (; i < 32; i += 2) {
733 { 742 bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
734 bn_mul_mont_gather5(tmp.d,am.d,powerbuf,np,n0,top,i-1); 743 n0, top, i - 1);
735 bn_scatter5(tmp.d,top,powerbuf,i); 744 bn_scatter5(tmp.d, top, powerbuf, i);
736 } 745 }
737#endif 746#endif
738 bits--; 747 bits--;
739 for (wvalue=0, i=bits%5; i>=0; i--,bits--) 748 for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
740 wvalue = (wvalue<<1)+BN_is_bit_set(p,bits); 749 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
741 bn_gather5(tmp.d,top,powerbuf,wvalue); 750 bn_gather5(tmp.d, top, powerbuf, wvalue);
742 751
743 /* Scan the exponent one window at a time starting from the most 752 /* Scan the exponent one window at a time starting from the most
744 * significant bits. 753 * significant bits.
745 */ 754 */
746 while (bits >= 0) 755 while (bits >= 0) {
747 { 756 for (wvalue = 0, i = 0; i < 5; i++, bits--)
748 for (wvalue=0, i=0; i<5; i++,bits--) 757 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
749 wvalue = (wvalue<<1)+BN_is_bit_set(p,bits); 758
750 759 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
751 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 760 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
752 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 761 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
753 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 762 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
754 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 763 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
755 bn_mul_mont(tmp.d,tmp.d,tmp.d,np,n0,top); 764 bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
756 bn_mul_mont_gather5(tmp.d,tmp.d,powerbuf,np,n0,top,wvalue);
757 } 765 }
758 766
759 tmp.top=top; 767 tmp.top = top;
760 bn_correct_top(&tmp); 768 bn_correct_top(&tmp);
761 } 769 } else
762 else
763#endif 770#endif
764 { 771 {
765 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers)) goto err; 772 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0,
766 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, numPowers)) goto err; 773 numPowers))
774 goto err;
775 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1,
776 numPowers))
777 goto err;
767 778
768 /* If the window size is greater than 1, then calculate 779 /* If the window size is greater than 1, then calculate
769 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) 780 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
770 * (even powers could instead be computed as (a^(i/2))^2 781 * (even powers could instead be computed as (a^(i/2))^2
771 * to use the slight performance advantage of sqr over mul). 782 * to use the slight performance advantage of sqr over mul).
772 */ 783 */
773 if (window > 1) 784 if (window > 1) {
774 { 785 if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
775 if (!BN_mod_mul_montgomery(&tmp,&am,&am,mont,ctx)) goto err; 786 goto err;
776 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, numPowers)) goto err; 787 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf,
777 for (i=3; i<numPowers; i++) 788 2, numPowers))
778 {
779 /* Calculate a^i = a^(i-1) * a */
780 if (!BN_mod_mul_montgomery(&tmp,&am,&tmp,mont,ctx))
781 goto err; 789 goto err;
782 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, numPowers)) goto err; 790 for (i = 3; i < numPowers; i++) {
791 /* Calculate a^i = a^(i-1) * a */
792 if (!BN_mod_mul_montgomery(&tmp, &am, &tmp,
793 mont, ctx))
794 goto err;
795 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top,
796 powerbuf, i, numPowers))
797 goto err;
783 } 798 }
784 } 799 }
785 800
786 bits--; 801 bits--;
787 for (wvalue=0, i=bits%window; i>=0; i--,bits--) 802 for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
788 wvalue = (wvalue<<1)+BN_is_bit_set(p,bits); 803 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
789 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp,top,powerbuf,wvalue,numPowers)) goto err; 804 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf,
790 805 wvalue, numPowers))
791 /* Scan the exponent one window at a time starting from the most 806 goto err;
792 * significant bits. 807
793 */ 808 /* Scan the exponent one window at a time starting from the most
794 while (bits >= 0) 809 * significant bits.
795 { 810 */
796 wvalue=0; /* The 'value' of the window */ 811 while (bits >= 0) {
797 812 wvalue = 0; /* The 'value' of the window */
798 /* Scan the window, squaring the result as we go */ 813
799 for (i=0; i<window; i++,bits--) 814 /* Scan the window, squaring the result as we go */
800 { 815 for (i = 0; i < window; i++, bits--) {
801 if (!BN_mod_mul_montgomery(&tmp,&tmp,&tmp,mont,ctx)) goto err; 816 if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp,
802 wvalue = (wvalue<<1)+BN_is_bit_set(p,bits); 817 mont, ctx))
803 } 818 goto err;
804 819 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
805 /* Fetch the appropriate pre-computed value from the pre-buf */ 820 }
806 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, numPowers)) goto err; 821
807 822 /* Fetch the appropriate pre-computed value from the pre-buf */
808 /* Multiply the result into the intermediate result */ 823 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf,
809 if (!BN_mod_mul_montgomery(&tmp,&tmp,&am,mont,ctx)) goto err; 824 wvalue, numPowers))
810 } 825 goto err;
826
827 /* Multiply the result into the intermediate result */
828 if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
829 goto err;
830 }
811 } 831 }
812 832
813 /* Convert the final result from montgomery to standard format */ 833 /* Convert the final result from montgomery to standard format */
814 if (!BN_from_montgomery(rr,&tmp,mont,ctx)) goto err; 834 if (!BN_from_montgomery(rr, &tmp, mont, ctx))
815 ret=1; 835 goto err;
836 ret = 1;
837
816err: 838err:
817 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 839 if ((in_mont == NULL) && (mont != NULL))
818 if (powerbuf!=NULL) 840 BN_MONT_CTX_free(mont);
819 { 841 if (powerbuf != NULL) {
820 OPENSSL_cleanse(powerbuf,powerbufLen); 842 OPENSSL_cleanse(powerbuf, powerbufLen);
821 if (powerbufFree) free(powerbufFree); 843 if (powerbufFree)
822 } 844 free(powerbufFree);
823 BN_CTX_end(ctx);
824 return(ret);
825 } 845 }
846 BN_CTX_end(ctx);
847 return (ret);
848}
826 849
827int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, 850int
828 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 851BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m,
829 { 852 BN_CTX *ctx, BN_MONT_CTX *in_mont)
853{
830 BN_MONT_CTX *mont = NULL; 854 BN_MONT_CTX *mont = NULL;
831 int b, bits, ret=0; 855 int b, bits, ret = 0;
832 int r_is_one; 856 int r_is_one;
833 BN_ULONG w, next_w; 857 BN_ULONG w, next_w;
834 BIGNUM *d, *r, *t; 858 BIGNUM *d, *r, *t;
835 BIGNUM *swap_tmp; 859 BIGNUM *swap_tmp;
860
836#define BN_MOD_MUL_WORD(r, w, m) \ 861#define BN_MOD_MUL_WORD(r, w, m) \
837 (BN_mul_word(r, (w)) && \ 862 (BN_mul_word(r, (w)) && \
838 (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ 863 (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
@@ -848,50 +873,48 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
848#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ 873#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
849 (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) 874 (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
850 875
851 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) 876 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
852 {
853 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ 877 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
854 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 878 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,
879 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
855 return -1; 880 return -1;
856 } 881 }
857 882
858 bn_check_top(p); 883 bn_check_top(p);
859 bn_check_top(m); 884 bn_check_top(m);
860 885
861 if (!BN_is_odd(m)) 886 if (!BN_is_odd(m)) {
862 { 887 BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
863 BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS); 888 return (0);
864 return(0); 889 }
865 }
866 if (m->top == 1) 890 if (m->top == 1)
867 a %= m->d[0]; /* make sure that 'a' is reduced */ 891 a %= m->d[0]; /* make sure that 'a' is reduced */
868 892 bits = BN_num_bits(p);
869 bits = BN_num_bits(p); 893 if (bits == 0) {
870 if (bits == 0)
871 {
872 ret = BN_one(rr); 894 ret = BN_one(rr);
873 return ret; 895 return ret;
874 } 896 }
875 if (a == 0) 897 if (a == 0) {
876 {
877 BN_zero(rr); 898 BN_zero(rr);
878 ret = 1; 899 ret = 1;
879 return ret; 900 return ret;
880 } 901 }
881 902
882 BN_CTX_start(ctx); 903 BN_CTX_start(ctx);
883 d = BN_CTX_get(ctx); 904 d = BN_CTX_get(ctx);
884 r = BN_CTX_get(ctx); 905 r = BN_CTX_get(ctx);
885 t = BN_CTX_get(ctx); 906 t = BN_CTX_get(ctx);
886 if (d == NULL || r == NULL || t == NULL) goto err; 907 if (d == NULL || r == NULL || t == NULL)
908 goto err;
887 909
888 if (in_mont != NULL) 910 if (in_mont != NULL)
889 mont=in_mont; 911 mont = in_mont;
890 else 912 else {
891 { 913 if ((mont = BN_MONT_CTX_new()) == NULL)
892 if ((mont = BN_MONT_CTX_new()) == NULL) goto err; 914 goto err;
893 if (!BN_MONT_CTX_set(mont, m, ctx)) goto err; 915 if (!BN_MONT_CTX_set(mont, m, ctx))
894 } 916 goto err;
917 }
895 918
896 r_is_one = 1; /* except for Montgomery factor */ 919 r_is_one = 1; /* except for Montgomery factor */
897 920
@@ -899,194 +922,189 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
899 922
900 /* The result is accumulated in the product r*w. */ 923 /* The result is accumulated in the product r*w. */
901 w = a; /* bit 'bits-1' of 'p' is always set */ 924 w = a; /* bit 'bits-1' of 'p' is always set */
902 for (b = bits-2; b >= 0; b--) 925 for (b = bits - 2; b >= 0; b--) {
903 {
904 /* First, square r*w. */ 926 /* First, square r*w. */
905 next_w = w*w; 927 next_w = w * w;
906 if ((next_w/w) != w) /* overflow */ 928 if ((next_w / w) != w) /* overflow */
907 { 929 {
908 if (r_is_one) 930 if (r_is_one) {
909 { 931 if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
910 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err; 932 goto err;
911 r_is_one = 0; 933 r_is_one = 0;
912 } 934 } else {
913 else 935 if (!BN_MOD_MUL_WORD(r, w, m))
914 { 936 goto err;
915 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
916 }
917 next_w = 1;
918 } 937 }
938 next_w = 1;
939 }
919 w = next_w; 940 w = next_w;
920 if (!r_is_one) 941 if (!r_is_one) {
921 { 942 if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
922 if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err; 943 goto err;
923 } 944 }
924 945
925 /* Second, multiply r*w by 'a' if exponent bit is set. */ 946 /* Second, multiply r*w by 'a' if exponent bit is set. */
926 if (BN_is_bit_set(p, b)) 947 if (BN_is_bit_set(p, b)) {
948 next_w = w * a;
949 if ((next_w / a) != w) /* overflow */
927 { 950 {
928 next_w = w*a; 951 if (r_is_one) {
929 if ((next_w/a) != w) /* overflow */ 952 if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
930 { 953 goto err;
931 if (r_is_one)
932 {
933 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
934 r_is_one = 0; 954 r_is_one = 0;
935 } 955 } else {
936 else 956 if (!BN_MOD_MUL_WORD(r, w, m))
937 { 957 goto err;
938 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
939 }
940 next_w = a;
941 } 958 }
942 w = next_w; 959 next_w = a;
943 } 960 }
961 w = next_w;
944 } 962 }
963 }
945 964
946 /* Finally, set r:=r*w. */ 965 /* Finally, set r:=r*w. */
947 if (w != 1) 966 if (w != 1) {
948 { 967 if (r_is_one) {
949 if (r_is_one) 968 if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
950 { 969 goto err;
951 if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
952 r_is_one = 0; 970 r_is_one = 0;
953 } 971 } else {
954 else 972 if (!BN_MOD_MUL_WORD(r, w, m))
955 { 973 goto err;
956 if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
957 }
958 } 974 }
975 }
959 976
960 if (r_is_one) /* can happen only if a == 1*/ 977 if (r_is_one) /* can happen only if a == 1*/
961 { 978 {
962 if (!BN_one(rr)) goto err; 979 if (!BN_one(rr))
963 } 980 goto err;
964 else 981 } else {
965 { 982 if (!BN_from_montgomery(rr, r, mont, ctx))
966 if (!BN_from_montgomery(rr, r, mont, ctx)) goto err; 983 goto err;
967 } 984 }
968 ret = 1; 985 ret = 1;
986
969err: 987err:
970 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 988 if ((in_mont == NULL) && (mont != NULL))
989 BN_MONT_CTX_free(mont);
971 BN_CTX_end(ctx); 990 BN_CTX_end(ctx);
972 bn_check_top(rr); 991 bn_check_top(rr);
973 return(ret); 992 return (ret);
974 } 993}
975 994
976 995
977/* The old fallback, simple version :-) */ 996/* The old fallback, simple version :-) */
978int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 997int
979 const BIGNUM *m, BN_CTX *ctx) 998BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
980 { 999 BN_CTX *ctx)
981 int i,j,bits,ret=0,wstart,wend,window,wvalue; 1000{
982 int start=1; 1001 int i, j,bits, ret = 0, wstart, wend, window, wvalue;
1002 int start = 1;
983 BIGNUM *d; 1003 BIGNUM *d;
984 /* Table of variables obtained from 'ctx' */ 1004 /* Table of variables obtained from 'ctx' */
985 BIGNUM *val[TABLE_SIZE]; 1005 BIGNUM *val[TABLE_SIZE];
986 1006
987 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) 1007 if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
988 {
989 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ 1008 /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
990 BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1009 BNerr(BN_F_BN_MOD_EXP_SIMPLE,
1010 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
991 return -1; 1011 return -1;
992 } 1012 }
993 1013
994 bits=BN_num_bits(p); 1014 bits = BN_num_bits(p);
995 1015
996 if (bits == 0) 1016 if (bits == 0) {
997 {
998 ret = BN_one(r); 1017 ret = BN_one(r);
999 return ret; 1018 return ret;
1000 } 1019 }
1001 1020
1002 BN_CTX_start(ctx); 1021 BN_CTX_start(ctx);
1003 d = BN_CTX_get(ctx); 1022 d = BN_CTX_get(ctx);
1004 val[0] = BN_CTX_get(ctx); 1023 val[0] = BN_CTX_get(ctx);
1005 if(!d || !val[0]) goto err; 1024 if (!d || !val[0])
1025 goto err;
1006 1026
1007 if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */ 1027 if (!BN_nnmod(val[0],a,m,ctx))
1008 if (BN_is_zero(val[0])) 1028 goto err; /* 1 */
1009 { 1029 if (BN_is_zero(val[0])) {
1010 BN_zero(r); 1030 BN_zero(r);
1011 ret = 1; 1031 ret = 1;
1012 goto err; 1032 goto err;
1013 } 1033 }
1014 1034
1015 window = BN_window_bits_for_exponent_size(bits); 1035 window = BN_window_bits_for_exponent_size(bits);
1016 if (window > 1) 1036 if (window > 1) {
1017 { 1037 if (!BN_mod_mul(d, val[0], val[0], m, ctx))
1018 if (!BN_mod_mul(d,val[0],val[0],m,ctx))
1019 goto err; /* 2 */ 1038 goto err; /* 2 */
1020 j=1<<(window-1); 1039 j = 1 << (window - 1);
1021 for (i=1; i<j; i++) 1040 for (i = 1; i < j; i++) {
1022 { 1041 if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
1023 if(((val[i] = BN_CTX_get(ctx)) == NULL) || 1042 !BN_mod_mul(val[i], val[i - 1], d,m, ctx))
1024 !BN_mod_mul(val[i],val[i-1],d,m,ctx))
1025 goto err; 1043 goto err;
1026 }
1027 } 1044 }
1045 }
1028 1046
1029 start=1; /* This is used to avoid multiplication etc 1047 start = 1; /* This is used to avoid multiplication etc
1030 * when there is only the value '1' in the 1048 * when there is only the value '1' in the
1031 * buffer. */ 1049 * buffer. */
1032 wvalue=0; /* The 'value' of the window */ 1050 wvalue = 0; /* The 'value' of the window */
1033 wstart=bits-1; /* The top bit of the window */ 1051 wstart = bits - 1; /* The top bit of the window */
1034 wend=0; /* The bottom bit of the window */ 1052 wend = 0; /* The bottom bit of the window */
1035 1053
1036 if (!BN_one(r)) goto err; 1054 if (!BN_one(r))
1055 goto err;
1037 1056
1038 for (;;) 1057 for (;;) {
1039 { 1058 if (BN_is_bit_set(p, wstart) == 0) {
1040 if (BN_is_bit_set(p,wstart) == 0)
1041 {
1042 if (!start) 1059 if (!start)
1043 if (!BN_mod_mul(r,r,r,m,ctx)) 1060 if (!BN_mod_mul(r, r, r, m, ctx))
1044 goto err; 1061 goto err;
1045 if (wstart == 0) break; 1062 if (wstart == 0)
1063 break;
1046 wstart--; 1064 wstart--;
1047 continue; 1065 continue;
1048 } 1066 }
1049 /* We now have wstart on a 'set' bit, we now need to work out 1067 /* We now have wstart on a 'set' bit, we now need to work out
1050 * how bit a window to do. To do this we need to scan 1068 * how bit a window to do. To do this we need to scan
1051 * forward until the last set bit before the end of the 1069 * forward until the last set bit before the end of the
1052 * window */ 1070 * window */
1053 j=wstart; 1071 j = wstart;
1054 wvalue=1; 1072 wvalue = 1;
1055 wend=0; 1073 wend = 0;
1056 for (i=1; i<window; i++) 1074 for (i = 1; i < window; i++) {
1057 { 1075 if (wstart - i < 0)
1058 if (wstart-i < 0) break; 1076 break;
1059 if (BN_is_bit_set(p,wstart-i)) 1077 if (BN_is_bit_set(p, wstart - i)) {
1060 { 1078 wvalue <<= (i - wend);
1061 wvalue<<=(i-wend); 1079 wvalue |= 1;
1062 wvalue|=1; 1080 wend = i;
1063 wend=i;
1064 }
1065 } 1081 }
1082 }
1066 1083
1067 /* wend is the size of the current window */ 1084 /* wend is the size of the current window */
1068 j=wend+1; 1085 j = wend + 1;
1069 /* add the 'bytes above' */ 1086 /* add the 'bytes above' */
1070 if (!start) 1087 if (!start)
1071 for (i=0; i<j; i++) 1088 for (i = 0; i < j; i++) {
1072 { 1089 if (!BN_mod_mul(r, r, r, m, ctx))
1073 if (!BN_mod_mul(r,r,r,m,ctx))
1074 goto err; 1090 goto err;
1075 } 1091 }
1076 1092
1077 /* wvalue will be an odd number < 2^window */ 1093 /* wvalue will be an odd number < 2^window */
1078 if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx)) 1094 if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
1079 goto err; 1095 goto err;
1080 1096
1081 /* move the 'window' down further */ 1097 /* move the 'window' down further */
1082 wstart-=wend+1; 1098 wstart -= wend + 1;
1083 wvalue=0; 1099 wvalue = 0;
1084 start=0; 1100 start = 0;
1085 if (wstart < 0) break; 1101 if (wstart < 0)
1086 } 1102 break;
1087 ret=1; 1103 }
1104 ret = 1;
1105
1088err: 1106err:
1089 BN_CTX_end(ctx); 1107 BN_CTX_end(ctx);
1090 bn_check_top(r); 1108 bn_check_top(r);
1091 return(ret); 1109 return (ret);
1092 } 1110}