cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
bn_exp.c
Go to the documentation of this file.
1 /* crypto/bn/bn_exp.c */
2 /* Copyright (C) 1995-1998 Eric Young ([email protected])
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young ([email protected]).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to. The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson ([email protected]).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  * must display the following acknowledgement:
33  * "This product includes cryptographic software written by
34  * Eric Young ([email protected])"
35  * The word 'cryptographic' can be left out if the rouines from the library
36  * being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  * the apps directory (application code) you must include an acknowledgement:
39  * "This product includes software written by Tim Hudson ([email protected])"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed. i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 /* ====================================================================
59  * Copyright (c) 1998-2005 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
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  * ([email protected]). This product includes software written by Tim
108  * Hudson ([email protected]).
109  *
110  */
111 
112 #if defined( INC_ALL )
113  #include "bn_lcl.h"
114 #else
115  #include "bn/bn_lcl.h"
116 #endif /* Compiler-specific includes */
117 #if defined( _MSC_VER )
118  #pragma warning( disable: 4311 ) /* Warning about ugly 32-bit align ptr.cast - pcg */
119 #endif /* VC++ */
120 
121 /* maximum precomputation table size for *variable* sliding windows */
122 #define TABLE_SIZE 32
123 
124 /* this one works - simple but works */
125 int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
126  {
127  int i,bits,ret=0;
128  BIGNUM *v,*rr;
129 
130  if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
131  {
132  /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
133  BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
134  return -1;
135  }
136 
137  BN_CTX_start(ctx);
138  if ((r == a) || (r == p))
139  {
140  rr = BN_CTX_get(ctx);
141  if( rr == NULL ) goto err; /* pcg */
142  }
143  else
144  rr = r;
145  if ((v = BN_CTX_get(ctx)) == NULL) goto err;
146 
147  if (BN_copy(v,a) == NULL) goto err;
148  bits=BN_num_bits(p);
149 
150  if (BN_is_odd(p))
151  { if (BN_copy(rr,a) == NULL) goto err; }
152  else { if (!BN_one(rr)) goto err; }
153 
154  for (i=1; i<bits; i++)
155  {
156  if (!BN_sqr(v,v,ctx)) goto err;
157  if (BN_is_bit_set(p,i))
158  {
159  if (!BN_mul(rr,rr,v,ctx)) goto err;
160  }
161  }
162  ret=1;
163 err:
164  if (r != rr) BN_copy(r,rr);
165  BN_CTX_end(ctx);
166  bn_check_top(r);
167  return(ret);
168  }
169 
170 
171 int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
172  BN_CTX *ctx)
173  {
174  int ret;
175 
176  bn_check_top(a);
177  bn_check_top(p);
178  bn_check_top(m);
179 
180  /* For even modulus m = 2^k*m_odd, it might make sense to compute
181  * a^p mod m_odd and a^p mod 2^k separately (with Montgomery
182  * exponentiation for the odd part), using appropriate exponent
183  * reductions, and combine the results using the CRT.
184  *
185  * For now, we use Montgomery only if the modulus is odd; otherwise,
186  * exponentiation using the reciprocal-based quick remaindering
187  * algorithm is used.
188  *
189  * (Timing obtained with expspeed.c [computations a^p mod m
190  * where a, p, m are of the same length: 256, 512, 1024, 2048,
191  * 4096, 8192 bits], compared to the running time of the
192  * standard algorithm:
193  *
194  * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
195  * 55 .. 77 % [UltraSparc processor, but
196  * debug-solaris-sparcv8-gcc conf.]
197  *
198  * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
199  * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
200  *
201  * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
202  * at 2048 and more bits, but at 512 and 1024 bits, it was
203  * slower even than the standard algorithm!
204  *
205  * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
206  * should be obtained when the new Montgomery reduction code
207  * has been integrated into OpenSSL.)
208  */
209 
210 #define MONT_MUL_MOD
211 #define MONT_EXP_WORD
212 #define RECP_MUL_MOD
213 
214 #ifdef MONT_MUL_MOD
215  /* I have finally been able to take out this pre-condition of
216  * the top bit being set. It was caused by an error in BN_div
217  * with negatives. There was also another problem when for a^b%m
218  * a >= m. eay 07-May-97 */
219 /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
220 
221  if (BN_is_odd(m))
222  {
223 # ifdef MONT_EXP_WORD
224  if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0))
225  {
226  BN_ULONG A = a->d[0];
227  ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
228  }
229  else
230 # endif
231  ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
232  }
233  else
234 #endif
235 #ifdef RECP_MUL_MOD
236  { ret=BN_mod_exp_recp(r,a,p,m,ctx); }
237 #else
238  { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
239 #endif
240 
241  bn_check_top(r);
242  return(ret);
243  }
244 
245 
246 int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
247  const BIGNUM *m, BN_CTX *ctx)
248  {
249  int i,j,bits,ret=0,wstart,wend,window,wvalue;
250  int start=1;
251  BIGNUM *aa;
252  /* Table of variables obtained from 'ctx' */
253  BIGNUM *val[TABLE_SIZE];
254  BN_RECP_CTX recp;
255 
256  if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
257  {
258  /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
259  BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
260  return -1;
261  }
262 
263  bits=BN_num_bits(p);
264 
265  if (bits == 0)
266  {
267  ret = BN_one(r);
268  return ret;
269  }
270 
271  BN_CTX_start(ctx);
272  aa = BN_CTX_get(ctx);
273  val[0] = BN_CTX_get(ctx);
274  if(!aa || !val[0]) goto err;
275 
276  BN_RECP_CTX_init(&recp);
277  if (m->neg)
278  {
279  /* ignore sign of 'm' */
280  if (!BN_copy(aa, m)) goto err;
281  aa->neg = 0;
282  if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
283  }
284  else
285  {
286  if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
287  }
288 
289  if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */
290  if (BN_is_zero(val[0]))
291  {
292  BN_zero(r);
293  ret = 1;
294  goto err;
295  }
296 
297  window = BN_window_bits_for_exponent_size(bits);
298  if (window > 1)
299  {
300  if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
301  goto err; /* 2 */
302  j=1<<(window-1);
303  for (i=1; i<j; i++)
304  {
305  if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
306  !BN_mod_mul_reciprocal(val[i],val[i-1],
307  aa,&recp,ctx))
308  goto err;
309  }
310  }
311 
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 
319  if (!BN_one(r)) goto err;
320 
321  for (;;)
322  {
323  if (BN_is_bit_set(p,wstart) == 0)
324  {
325  if (!start)
326  if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
327  goto err;
328  if (wstart == 0) break;
329  wstart--;
330  continue;
331  }
332  /* 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
334  * forward until the last set bit before the end of the
335  * window */
336  j=wstart;
337  wvalue=1;
338  wend=0;
339  for (i=1; i<window; i++)
340  {
341  if (wstart-i < 0) break;
342  if (BN_is_bit_set(p,wstart-i))
343  {
344  wvalue<<=(i-wend);
345  wvalue|=1;
346  wend=i;
347  }
348  }
349 
350  /* wend is the size of the current window */
351  j=wend+1;
352  /* add the 'bytes above' */
353  if (!start)
354  for (i=0; i<j; i++)
355  {
356  if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
357  goto err;
358  }
359 
360  /* wvalue will be an odd number < 2^window */
361  if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx))
362  goto err;
363 
364  /* move the 'window' down further */
365  wstart-=wend+1;
366  wvalue=0;
367  start=0;
368  if (wstart < 0) break;
369  }
370  ret=1;
371 err:
372  BN_CTX_end(ctx);
373  BN_RECP_CTX_free(&recp);
374  bn_check_top(r);
375  return(ret);
376  }
377 
378 
379 int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
380  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
381  {
382  int i,j,bits,ret=0,wstart,wend,window,wvalue;
383  int start=1;
384  BIGNUM *d,*r;
385  const BIGNUM *aa;
386  /* Table of variables obtained from 'ctx' */
387  BIGNUM *val[TABLE_SIZE];
388  BN_MONT_CTX *mont=NULL;
389 
390  if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
391  {
392  return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
393  }
394 
395  bn_check_top(a);
396  bn_check_top(p);
397  bn_check_top(m);
398 
399  if (!BN_is_odd(m))
400  {
402  return(0);
403  }
404  bits=BN_num_bits(p);
405  if (bits == 0)
406  {
407  ret = BN_one(rr);
408  return ret;
409  }
410 
411  BN_CTX_start(ctx);
412  d = BN_CTX_get(ctx);
413  r = BN_CTX_get(ctx);
414  val[0] = BN_CTX_get(ctx);
415  if (!d || !r || !val[0]) goto err;
416 
417  /* If this is not done, things will break in the montgomery
418  * part */
419 
420  if (in_mont != NULL)
421  mont=in_mont;
422  else
423  {
424  if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
425  if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
426  }
427 
428  if (a->neg || BN_ucmp(a,m) >= 0)
429  {
430  if (!BN_nnmod(val[0],a,m,ctx))
431  goto err;
432  aa= val[0];
433  }
434  else
435  aa=a;
436  if (BN_is_zero(aa))
437  {
438  BN_zero(rr);
439  ret = 1;
440  goto err;
441  }
442  if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
443 
444  window = BN_window_bits_for_exponent_size(bits);
445  if (window > 1)
446  {
447  if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */
448  j=1<<(window-1);
449  for (i=1; i<j; i++)
450  {
451  if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
452  !BN_mod_mul_montgomery(val[i],val[i-1],
453  d,mont,ctx))
454  goto err;
455  }
456  }
457 
458  start=1; /* This is used to avoid multiplication etc
459  * when there is only the value '1' in the
460  * buffer. */
461  wvalue=0; /* The 'value' of the window */
462  wstart=bits-1; /* The top bit of the window */
463  wend=0; /* The bottom bit of the window */
464 
465  if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
466  for (;;)
467  {
468  if (BN_is_bit_set(p,wstart) == 0)
469  {
470  if (!start)
471  {
472  if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
473  goto err;
474  }
475  if (wstart == 0) break;
476  wstart--;
477  continue;
478  }
479  /* 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  * forward until the last set bit before the end of the
482  * window */
483  j=wstart;
484  wvalue=1;
485  wend=0;
486  for (i=1; i<window; i++)
487  {
488  if (wstart-i < 0) break;
489  if (BN_is_bit_set(p,wstart-i))
490  {
491  wvalue<<=(i-wend);
492  wvalue|=1;
493  wend=i;
494  }
495  }
496 
497  /* wend is the size of the current window */
498  j=wend+1;
499  /* add the 'bytes above' */
500  if (!start)
501  for (i=0; i<j; i++)
502  {
503  if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
504  goto err;
505  }
506 
507  /* wvalue will be an odd number < 2^window */
508  if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx))
509  goto err;
510 
511  /* move the 'window' down further */
512  wstart-=wend+1;
513  wvalue=0;
514  start=0;
515  if (wstart < 0) break;
516  }
517  if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
518  ret=1;
519 err:
520  if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
521  BN_CTX_end(ctx);
522  bn_check_top(rr);
523  return(ret);
524  }
525 
526 
527 /* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
528  * so that accessing any of these table values shows the same access pattern as far
529  * as cache lines are concerned. The following functions are used to transfer a BIGNUM
530  * from/to that table. */
531 
532 static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
533  {
534  size_t i, j;
535 
536  if (bn_wexpand(b, top) == NULL)
537  return 0;
538  while (b->top < top)
539  {
540  b->d[b->top++] = 0;
541  }
542 
543  for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
544  {
545  buf[j] = ((unsigned char*)b->d)[i];
546  }
547 
548  bn_correct_top(b);
549  return 1;
550  }
551 
552 static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
553  {
554  size_t i, j;
555 
556  if (bn_wexpand(b, top) == NULL)
557  return 0;
558 
559  for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
560  {
561  ((unsigned char*)b->d)[i] = buf[j];
562  }
563 
564  b->top = top;
565  bn_correct_top(b);
566  return 1;
567  }
568 
569 /* Given a pointer value, compute the next address that is a cache line multiple. */
570 #define MOD_EXP_CTIME_ALIGN(x_) \
571  ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((BN_ULONG)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
572 
573 /* This variant of BN_mod_exp_mont() uses fixed windows and the special
574  * precomputation memory layout to limit data-dependency to a minimum
575  * to protect secret exponents (cf. the hyper-threading timing attacks
576  * pointed out by Colin Percival,
577  * http://www.daemonology.net/hyperthreading-considered-harmful/)
578  */
579 int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
580  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
581  {
582  int i,bits,ret=0,idx,window,wvalue;
583  int top;
584  BIGNUM *r;
585  const BIGNUM *aa;
586  BN_MONT_CTX *mont=NULL;
587 
588  int numPowers;
589  unsigned char *powerbufFree=NULL;
590  int powerbufLen = 0;
591  unsigned char *powerbuf=NULL;
592  BIGNUM *computeTemp=NULL, *am=NULL;
593 
594  bn_check_top(a);
595  bn_check_top(p);
596  bn_check_top(m);
597 
598  top = m->top;
599 
600  if (!(m->d[0] & 1))
601  {
603  return(0);
604  }
605  bits=BN_num_bits(p);
606  if (bits == 0)
607  {
608  ret = BN_one(rr);
609  return ret;
610  }
611 
612  /* Initialize BIGNUM context and allocate intermediate result */
613  BN_CTX_start(ctx);
614  r = BN_CTX_get(ctx);
615  if (r == NULL) goto err;
616 
617  /* Allocate a montgomery context if it was not supplied by the caller.
618  * If this is not done, things will break in the montgomery part.
619  */
620  if (in_mont != NULL)
621  mont=in_mont;
622  else
623  {
624  if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
625  if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
626  }
627 
628  /* Get the window size to use with size of p. */
630 
631  /* Allocate a buffer large enough to hold all of the pre-computed
632  * powers of a.
633  */
634  numPowers = 1 << window;
635  powerbufLen = sizeof(m->d[0])*top*numPowers;
636  if ((powerbufFree=(unsigned char*)clBnAlloc("BN_mod_exp_mont_consttime",
637  powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
638  goto err;
639 
640  powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
641  memset(powerbuf, 0, powerbufLen);
642 
643  /* Initialize the intermediate result. Do this early to save double conversion,
644  * once each for a^0 and intermediate result.
645  */
646  if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
647  if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers)) goto err;
648 
649  /* Initialize computeTemp as a^1 with montgomery precalcs */
650  computeTemp = BN_CTX_get(ctx);
651  am = BN_CTX_get(ctx);
652  if (computeTemp==NULL || am==NULL) goto err;
653 
654  if (a->neg || BN_ucmp(a,m) >= 0)
655  {
656  if (!BN_mod(am,a,m,ctx))
657  goto err;
658  aa= am;
659  }
660  else
661  aa=a;
662  if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
663  if (!BN_copy(computeTemp, am)) goto err;
664  if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers)) goto err;
665 
666  /* If the window size is greater than 1, then calculate
667  * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
668  * (even powers could instead be computed as (a^(i/2))^2
669  * to use the slight performance advantage of sqr over mul).
670  */
671  if (window > 1)
672  {
673  for (i=2; i<numPowers; i++)
674  {
675  /* Calculate a^i = a^(i-1) * a */
676  if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
677  goto err;
678  if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, numPowers)) goto err;
679  }
680  }
681 
682  /* Adjust the number of bits up to a multiple of the window size.
683  * If the exponent length is not a multiple of the window size, then
684  * this pads the most significant bits with zeros to normalize the
685  * scanning loop to there's no special cases.
686  *
687  * * NOTE: Making the window size a power of two less than the native
688  * * word size ensures that the padded bits won't go past the last
689  * * word in the internal BIGNUM structure. Going past the end will
690  * * still produce the correct result, but causes a different branch
691  * * to be taken in the BN_is_bit_set function.
692  */
693  bits = ((bits+window-1)/window)*window;
694  idx=bits-1; /* The top bit of the window */
695 
696  /* Scan the exponent one window at a time starting from the most
697  * significant bits.
698  */
699  while (idx >= 0)
700  {
701  wvalue=0; /* The 'value' of the window */
702 
703  /* Scan the window, squaring the result as we go */
704  for (i=0; i<window; i++,idx--)
705  {
706  if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) goto err;
707  wvalue = (wvalue<<1)+BN_is_bit_set(p,idx);
708  }
709 
710  /* Fetch the appropriate pre-computed value from the pre-buf */
711  if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue, numPowers)) goto err;
712 
713  /* Multiply the result into the intermediate result */
714  if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
715  }
716 
717  /* Convert the final result from montgomery to standard format */
718  if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
719  ret=1;
720 err:
721  if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
722  if (powerbuf!=NULL)
723  {
724  OPENSSL_cleanse(powerbuf,powerbufLen);
725  OPENSSL_free(powerbufFree);
726  }
727  if (am!=NULL) BN_clear(am);
728  if (computeTemp!=NULL) BN_clear(computeTemp);
729  BN_CTX_end(ctx);
730  return(ret);
731  }
732 
734  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
735  {
736  BN_MONT_CTX *mont = NULL;
737  int b, bits, ret=0;
738  int r_is_one;
739  BN_ULONG w, next_w;
740  BIGNUM *d, *r, *t;
741  BIGNUM *swap_tmp;
742 #define BN_MOD_MUL_WORD(r, w, m) \
743  (BN_mul_word(r, (w)) && \
744  (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
745  (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
746  /* BN_MOD_MUL_WORD is only used with 'w' large,
747  * so the BN_ucmp test is probably more overhead
748  * than always using BN_mod (which uses BN_copy if
749  * a similar test returns true). */
750  /* We can use BN_mod and do not need BN_nnmod because our
751  * accumulator is never negative (the result of BN_mod does
752  * not depend on the sign of the modulus).
753  */
754 #define BN_TO_MONTGOMERY_WORD(r, w, mont) \
755  (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
756 
757  if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
758  {
759  /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
760  BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
761  return -1;
762  }
763 
764  bn_check_top(p);
765  bn_check_top(m);
766 
767  if (!BN_is_odd(m))
768  {
770  return(0);
771  }
772  if (m->top == 1)
773  a %= m->d[0]; /* make sure that 'a' is reduced */
774 
775  bits = BN_num_bits(p);
776  if (bits == 0)
777  {
778  ret = BN_one(rr);
779  return ret;
780  }
781  if (a == 0)
782  {
783  BN_zero(rr);
784  ret = 1;
785  return ret;
786  }
787 
788  BN_CTX_start(ctx);
789  d = BN_CTX_get(ctx);
790  r = BN_CTX_get(ctx);
791  t = BN_CTX_get(ctx);
792  if (d == NULL || r == NULL || t == NULL) goto err;
793 
794  if (in_mont != NULL)
795  mont=in_mont;
796  else
797  {
798  if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
799  if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
800  }
801 
802  r_is_one = 1; /* except for Montgomery factor */
803 
804  /* bits-1 >= 0 */
805 
806  /* The result is accumulated in the product r*w. */
807  w = a; /* bit 'bits-1' of 'p' is always set */
808  for (b = bits-2; b >= 0; b--)
809  {
810  /* First, square r*w. */
811  next_w = w*w;
812  if ((next_w/w) != w) /* overflow */
813  {
814  if (r_is_one)
815  {
816  if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
817  r_is_one = 0;
818  }
819  else
820  {
821  if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
822  }
823  next_w = 1;
824  }
825  w = next_w;
826  if (!r_is_one)
827  {
828  if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
829  }
830 
831  /* Second, multiply r*w by 'a' if exponent bit is set. */
832  if (BN_is_bit_set(p, b))
833  {
834  next_w = w*a;
835  if ((next_w/a) != w) /* overflow */
836  {
837  if (r_is_one)
838  {
839  if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
840  r_is_one = 0;
841  }
842  else
843  {
844  if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
845  }
846  next_w = a;
847  }
848  w = next_w;
849  }
850  }
851 
852  /* Finally, set r:=r*w. */
853  if (w != 1)
854  {
855  if (r_is_one)
856  {
857  if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
858  r_is_one = 0;
859  }
860  else
861  {
862  if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
863  }
864  }
865 
866  if (r_is_one) /* can happen only if a == 1*/
867  {
868  if (!BN_one(rr)) goto err;
869  }
870  else
871  {
872  if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
873  }
874  ret = 1;
875 err:
876  if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
877  BN_CTX_end(ctx);
878  bn_check_top(rr);
879  return(ret);
880  }
881 
882 
883 /* The old fallback, simple version :-) */
884 int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
885  const BIGNUM *m, BN_CTX *ctx)
886  {
887  int i,j,bits,ret=0,wstart,wend,window,wvalue;
888  int start=1;
889  BIGNUM *d;
890  /* Table of variables obtained from 'ctx' */
891  BIGNUM *val[TABLE_SIZE];
892 
893  if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
894  {
895  /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
896  BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
897  return -1;
898  }
899 
900  bits=BN_num_bits(p);
901 
902  if (bits == 0)
903  {
904  ret = BN_one(r);
905  return ret;
906  }
907 
908  BN_CTX_start(ctx);
909  d = BN_CTX_get(ctx);
910  val[0] = BN_CTX_get(ctx);
911  if(!d || !val[0]) goto err;
912 
913  if (!BN_nnmod(val[0],a,m,ctx)) goto err; /* 1 */
914  if (BN_is_zero(val[0]))
915  {
916  BN_zero(r);
917  ret = 1;
918  goto err;
919  }
920 
921  window = BN_window_bits_for_exponent_size(bits);
922  if (window > 1)
923  {
924  if (!BN_mod_mul(d,val[0],val[0],m,ctx))
925  goto err; /* 2 */
926  j=1<<(window-1);
927  for (i=1; i<j; i++)
928  {
929  if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
930  !BN_mod_mul(val[i],val[i-1],d,m,ctx))
931  goto err;
932  }
933  }
934 
935  start=1; /* This is used to avoid multiplication etc
936  * when there is only the value '1' in the
937  * buffer. */
938  wvalue=0; /* The 'value' of the window */
939  wstart=bits-1; /* The top bit of the window */
940  wend=0; /* The bottom bit of the window */
941 
942  if (!BN_one(r)) goto err;
943 
944  for (;;)
945  {
946  if (BN_is_bit_set(p,wstart) == 0)
947  {
948  if (!start)
949  if (!BN_mod_mul(r,r,r,m,ctx))
950  goto err;
951  if (wstart == 0) break;
952  wstart--;
953  continue;
954  }
955  /* We now have wstart on a 'set' bit, we now need to work out
956  * how bit a window to do. To do this we need to scan
957  * forward until the last set bit before the end of the
958  * window */
959  j=wstart;
960  wvalue=1;
961  wend=0;
962  for (i=1; i<window; i++)
963  {
964  if (wstart-i < 0) break;
965  if (BN_is_bit_set(p,wstart-i))
966  {
967  wvalue<<=(i-wend);
968  wvalue|=1;
969  wend=i;
970  }
971  }
972 
973  /* wend is the size of the current window */
974  j=wend+1;
975  /* add the 'bytes above' */
976  if (!start)
977  for (i=0; i<j; i++)
978  {
979  if (!BN_mod_mul(r,r,r,m,ctx))
980  goto err;
981  }
982 
983  /* wvalue will be an odd number < 2^window */
984  if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx))
985  goto err;
986 
987  /* move the 'window' down further */
988  wstart-=wend+1;
989  wvalue=0;
990  start=0;
991  if (wstart < 0) break;
992  }
993  ret=1;
994 err:
995  BN_CTX_end(ctx);
996  bn_check_top(r);
997  return(ret);
998  }
999