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