• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright(C) 2006 Cameron Rich
3  *
4  *  This library is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU Lesser General Public License as published by
6  *  the Free Software Foundation; either version 2.1 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 /**
20  * @defgroup bigint_api Big Integer API
21  * @brief The bigint implementation as used by the axTLS project.
22  *
23  * The bigint library is for RSA encryption/decryption as well as signing.
24  * This code tries to minimise use of malloc/free by maintaining a small
25  * cache. A bigint context may maintain state by being made "permanent".
26  * It be be later released with a bi_depermanent() and bi_free() call.
27  *
28  * It supports the following reduction techniques:
29  * - Classical
30  * - Barrett
31  * - Montgomery
32  *
33  * It also implements the following:
34  * - Karatsuba multiplication
35  * - Squaring
36  * - Sliding window exponentiation
37  * - Chinese Remainder Theorem (implemented in rsa.c).
38  *
39  * All the algorithms used are pretty standard, and designed for different
40  * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
41  * may need to be tested for negativity.
42  *
43  * This library steals some ideas from Jef Poskanzer
44  * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
45  * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
46  * detail from "The Handbook of Applied Cryptography"
47  * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
48  * @{
49  */
50 
51 #include <stdlib.h>
52 #include <limits.h>
53 #include <string.h>
54 #include <stdio.h>
55 #include <time.h>
56 #include "bigint.h"
57 #include "crypto.h"
58 
59 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
60 static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
61 static bigint __malloc *alloc(BI_CTX *ctx, int size);
62 static bigint *trim(bigint *bi);
63 static void more_comps(bigint *bi, int n);
64 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
65     defined(CONFIG_BIGINT_MONTGOMERY)
66 static bigint *comp_right_shift(bigint *biR, int num_shifts);
67 static bigint *comp_left_shift(bigint *biR, int num_shifts);
68 #endif
69 
70 #ifdef CONFIG_BIGINT_CHECK_ON
71 static void check(const bigint *bi);
72 #endif
73 
74 /**
75  * @brief Start a new bigint context.
76  * @return A bigint context.
77  */
bi_initialize(void)78 BI_CTX *bi_initialize(void)
79 {
80     /* calloc() sets everything to zero */
81     BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
82 
83     /* the radix */
84     ctx->bi_radix = alloc(ctx, 2);
85     ctx->bi_radix->comps[0] = 0;
86     ctx->bi_radix->comps[1] = 1;
87     bi_permanent(ctx->bi_radix);
88     return ctx;
89 }
90 
91 /**
92  * @brief Close the bigint context and free any resources.
93  *
94  * Free up any used memory - a check is done if all objects were not
95  * properly freed.
96  * @param ctx [in]   The bigint session context.
97  */
bi_terminate(BI_CTX * ctx)98 void bi_terminate(BI_CTX *ctx)
99 {
100     bigint *p, *pn;
101 
102     bi_depermanent(ctx->bi_radix);
103     bi_free(ctx, ctx->bi_radix);
104 
105     if (ctx->active_count != 0)
106     {
107 #ifdef CONFIG_SSL_FULL_MODE
108         printf("bi_terminate: there were %d un-freed bigints\n",
109                        ctx->active_count);
110 #endif
111         abort();
112     }
113 
114     for (p = ctx->free_list; p != NULL; p = pn)
115     {
116         pn = p->next;
117         free(p->comps);
118         free(p);
119     }
120 
121     free(ctx);
122 }
123 
124 /**
125  * @brief Increment the number of references to this object.
126  * It does not do a full copy.
127  * @param bi [in]   The bigint to copy.
128  * @return A reference to the same bigint.
129  */
bi_copy(bigint * bi)130 bigint *bi_copy(bigint *bi)
131 {
132     check(bi);
133     if (bi->refs != PERMANENT)
134         bi->refs++;
135     return bi;
136 }
137 
138 /**
139  * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
140  *
141  * For this object to be freed, bi_depermanent() must be called.
142  * @param bi [in]   The bigint to be made permanent.
143  */
bi_permanent(bigint * bi)144 void bi_permanent(bigint *bi)
145 {
146     check(bi);
147     if (bi->refs != 1)
148     {
149 #ifdef CONFIG_SSL_FULL_MODE
150         printf("bi_permanent: refs was not 1\n");
151 #endif
152         abort();
153     }
154 
155     bi->refs = PERMANENT;
156 }
157 
158 /**
159  * @brief Take a permanent object and make it eligible for freedom.
160  * @param bi [in]   The bigint to be made back to temporary.
161  */
bi_depermanent(bigint * bi)162 void bi_depermanent(bigint *bi)
163 {
164     check(bi);
165     if (bi->refs != PERMANENT)
166     {
167 #ifdef CONFIG_SSL_FULL_MODE
168         printf("bi_depermanent: bigint was not permanent\n");
169 #endif
170         abort();
171     }
172 
173     bi->refs = 1;
174 }
175 
176 /**
177  * @brief Free a bigint object so it can be used again.
178  *
179  * The memory itself it not actually freed, just tagged as being available
180  * @param ctx [in]   The bigint session context.
181  * @param bi [in]    The bigint to be freed.
182  */
bi_free(BI_CTX * ctx,bigint * bi)183 void bi_free(BI_CTX *ctx, bigint *bi)
184 {
185     check(bi);
186     if (bi->refs == PERMANENT)
187     {
188         return;
189     }
190 
191     if (--bi->refs > 0)
192     {
193         return;
194     }
195 
196     bi->next = ctx->free_list;
197     ctx->free_list = bi;
198     ctx->free_count++;
199 
200     if (--ctx->active_count < 0)
201     {
202 #ifdef CONFIG_SSL_FULL_MODE
203         printf("bi_free: active_count went negative "
204                 "- double-freed bigint?\n");
205 #endif
206         abort();
207     }
208 }
209 
210 /**
211  * @brief Convert an (unsigned) integer into a bigint.
212  * @param ctx [in]   The bigint session context.
213  * @param i [in]     The (unsigned) integer to be converted.
214  *
215  */
int_to_bi(BI_CTX * ctx,comp i)216 bigint *int_to_bi(BI_CTX *ctx, comp i)
217 {
218     bigint *biR = alloc(ctx, 1);
219     biR->comps[0] = i;
220     return biR;
221 }
222 
223 /**
224  * @brief Do a full copy of the bigint object.
225  * @param ctx [in]   The bigint session context.
226  * @param bi  [in]   The bigint object to be copied.
227  */
bi_clone(BI_CTX * ctx,const bigint * bi)228 bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
229 {
230     bigint *biR = alloc(ctx, bi->size);
231     check(bi);
232     memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
233     return biR;
234 }
235 
236 /**
237  * @brief Perform an addition operation between two bigints.
238  * @param ctx [in]  The bigint session context.
239  * @param bia [in]  A bigint.
240  * @param bib [in]  Another bigint.
241  * @return The result of the addition.
242  */
bi_add(BI_CTX * ctx,bigint * bia,bigint * bib)243 bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
244 {
245     int n;
246     comp carry = 0;
247     comp *pa, *pb;
248 
249     check(bia);
250     check(bib);
251 
252     n = max(bia->size, bib->size);
253     more_comps(bia, n+1);
254     more_comps(bib, n);
255     pa = bia->comps;
256     pb = bib->comps;
257 
258     do
259     {
260         comp  sl, rl, cy1;
261         sl = *pa + *pb++;
262         rl = sl + carry;
263         cy1 = sl < *pa;
264         carry = cy1 | (rl < sl);
265         *pa++ = rl;
266     } while (--n != 0);
267 
268     *pa = carry;                  /* do overflow */
269     bi_free(ctx, bib);
270     return trim(bia);
271 }
272 
273 /**
274  * @brief Perform a subtraction operation between two bigints.
275  * @param ctx [in]  The bigint session context.
276  * @param bia [in]  A bigint.
277  * @param bib [in]  Another bigint.
278  * @param is_negative [out] If defined, indicates that the result was negative.
279  * is_negative may be null.
280  * @return The result of the subtraction. The result is always positive.
281  */
bi_subtract(BI_CTX * ctx,bigint * bia,bigint * bib,int * is_negative)282 bigint *bi_subtract(BI_CTX *ctx,
283         bigint *bia, bigint *bib, int *is_negative)
284 {
285     int n = bia->size;
286     comp *pa, *pb, carry = 0;
287 
288     check(bia);
289     check(bib);
290 
291     more_comps(bib, n);
292     pa = bia->comps;
293     pb = bib->comps;
294 
295     do
296     {
297         comp sl, rl, cy1;
298         sl = *pa - *pb++;
299         rl = sl - carry;
300         cy1 = sl > *pa;
301         carry = cy1 | (rl > sl);
302         *pa++ = rl;
303     } while (--n != 0);
304 
305     if (is_negative)    /* indicate a negative result */
306     {
307         *is_negative = carry;
308     }
309 
310     bi_free(ctx, trim(bib));    /* put bib back to the way it was */
311     return trim(bia);
312 }
313 
314 /**
315  * Perform a multiply between a bigint an an (unsigned) integer
316  */
bi_int_multiply(BI_CTX * ctx,bigint * bia,comp b)317 static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
318 {
319     int j = 0, n = bia->size;
320     bigint *biR = alloc(ctx, n + 1);
321     comp carry = 0;
322     comp *r = biR->comps;
323     comp *a = bia->comps;
324 
325     check(bia);
326 
327     /* clear things to start with */
328     memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
329 
330     do
331     {
332         long_comp tmp = *r + (long_comp)a[j]*b + carry;
333         *r++ = (comp)tmp;              /* downsize */
334         carry = (comp)(tmp >> COMP_BIT_SIZE);
335     } while (++j < n);
336 
337     *r = carry;
338     bi_free(ctx, bia);
339     return trim(biR);
340 }
341 
342 /**
343  * @brief Does both division and modulo calculations.
344  *
345  * Used extensively when doing classical reduction.
346  * @param ctx [in]  The bigint session context.
347  * @param u [in]    A bigint which is the numerator.
348  * @param v [in]    Either the denominator or the modulus depending on the mode.
349  * @param is_mod [n] Determines if this is a normal division (0) or a reduction
350  * (1).
351  * @return  The result of the division/reduction.
352  */
bi_divide(BI_CTX * ctx,bigint * u,bigint * v,int is_mod)353 bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
354 {
355     int n = v->size, m = u->size-n;
356     int j = 0, orig_u_size = u->size;
357     uint8_t mod_offset = ctx->mod_offset;
358     comp d;
359     bigint *quotient, *tmp_u;
360     comp q_dash;
361 
362     check(u);
363     check(v);
364 
365     /* if doing reduction and we are < mod, then return mod */
366     if (is_mod && bi_compare(v, u) > 0)
367     {
368         bi_free(ctx, v);
369         return u;
370     }
371 
372     quotient = alloc(ctx, m+1);
373     tmp_u = alloc(ctx, n+1);
374     v = trim(v);        /* make sure we have no leading 0's */
375     d = (comp)((long_comp)COMP_RADIX/(V1+1));
376 
377     /* clear things to start with */
378     memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
379 
380     /* normalise */
381     if (d > 1)
382     {
383         u = bi_int_multiply(ctx, u, d);
384 
385         if (is_mod)
386         {
387             v = ctx->bi_normalised_mod[mod_offset];
388         }
389         else
390         {
391             v = bi_int_multiply(ctx, v, d);
392         }
393     }
394 
395     if (orig_u_size == u->size)  /* new digit position u0 */
396     {
397         more_comps(u, orig_u_size + 1);
398     }
399 
400     do
401     {
402         /* get a temporary short version of u */
403         memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
404 
405         /* calculate q' */
406         if (U(0) == V1)
407         {
408             q_dash = COMP_RADIX-1;
409         }
410         else
411         {
412             q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
413         }
414 
415         if (v->size > 1 && V2)
416         {
417             /* we are implementing the following:
418             if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
419                     q_dash*V1)*COMP_RADIX) + U(2))) ... */
420             comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
421                                         (long_comp)q_dash*V1);
422             if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
423             {
424                 q_dash--;
425             }
426         }
427 
428         /* multiply and subtract */
429         if (q_dash)
430         {
431             int is_negative;
432             tmp_u = bi_subtract(ctx, tmp_u,
433                     bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
434             more_comps(tmp_u, n+1);
435 
436             Q(j) = q_dash;
437 
438             /* add back */
439             if (is_negative)
440             {
441                 Q(j)--;
442                 tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
443 
444                 /* lop off the carry */
445                 tmp_u->size--;
446                 v->size--;
447             }
448         }
449         else
450         {
451             Q(j) = 0;
452         }
453 
454         /* copy back to u */
455         memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
456     } while (++j <= m);
457 
458     bi_free(ctx, tmp_u);
459     bi_free(ctx, v);
460 
461     if (is_mod)     /* get the remainder */
462     {
463         bi_free(ctx, quotient);
464         return bi_int_divide(ctx, trim(u), d);
465     }
466     else            /* get the quotient */
467     {
468         bi_free(ctx, u);
469         return trim(quotient);
470     }
471 }
472 
473 /*
474  * Perform an integer divide on a bigint.
475  */
bi_int_divide(BI_CTX * ctx __unused,bigint * biR,comp denom)476 static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
477 {
478     int i = biR->size - 1;
479     long_comp r = 0;
480 
481     check(biR);
482 
483     do
484     {
485         r = (r<<COMP_BIT_SIZE) + biR->comps[i];
486         biR->comps[i] = (comp)(r / denom);
487         r %= denom;
488     } while (--i != 0);
489 
490     return trim(biR);
491 }
492 
493 #ifdef CONFIG_BIGINT_MONTGOMERY
494 /**
495  * There is a need for the value of integer N' such that B^-1(B-1)-N^-1N'=1,
496  * where B^-1(B-1) mod N=1. Actually, only the least significant part of
497  * N' is needed, hence the definition N0'=N' mod b. We reproduce below the
498  * simple algorithm from an article by Dusse and Kaliski to efficiently
499  * find N0' from N0 and b */
modular_inverse(bigint * bim)500 static comp modular_inverse(bigint *bim)
501 {
502     int i;
503     comp t = 1;
504     comp two_2_i_minus_1 = 2;   /* 2^(i-1) */
505     long_comp two_2_i = 4;      /* 2^i */
506     comp N = bim->comps[0];
507 
508     for (i = 2; i <= COMP_BIT_SIZE; i++)
509     {
510         if ((long_comp)N*t%two_2_i >= two_2_i_minus_1)
511         {
512             t += two_2_i_minus_1;
513         }
514 
515         two_2_i_minus_1 <<= 1;
516         two_2_i <<= 1;
517     }
518 
519     return (comp)(COMP_RADIX-t);
520 }
521 #endif
522 
523 #if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
524     defined(CONFIG_BIGINT_MONTGOMERY)
525 /**
526  * Take each component and shift down (in terms of components)
527  */
comp_right_shift(bigint * biR,int num_shifts)528 static bigint *comp_right_shift(bigint *biR, int num_shifts)
529 {
530     int i = biR->size-num_shifts;
531     comp *x = biR->comps;
532     comp *y = &biR->comps[num_shifts];
533 
534     check(biR);
535 
536     if (i <= 0)     /* have we completely right shifted? */
537     {
538         biR->comps[0] = 0;  /* return 0 */
539         biR->size = 1;
540         return biR;
541     }
542 
543     do
544     {
545         *x++ = *y++;
546     } while (--i > 0);
547 
548     biR->size -= num_shifts;
549     return biR;
550 }
551 
552 /**
553  * Take each component and shift it up (in terms of components)
554  */
comp_left_shift(bigint * biR,int num_shifts)555 static bigint *comp_left_shift(bigint *biR, int num_shifts)
556 {
557     int i = biR->size-1;
558     comp *x, *y;
559 
560     check(biR);
561 
562     if (num_shifts <= 0)
563     {
564         return biR;
565     }
566 
567     more_comps(biR, biR->size + num_shifts);
568 
569     x = &biR->comps[i+num_shifts];
570     y = &biR->comps[i];
571 
572     do
573     {
574         *x-- = *y--;
575     } while (i--);
576 
577     memset(biR->comps, 0, num_shifts*COMP_BYTE_SIZE); /* zero LS comps */
578     return biR;
579 }
580 #endif
581 
582 /**
583  * @brief Allow a binary sequence to be imported as a bigint.
584  * @param ctx [in]  The bigint session context.
585  * @param data [in] The data to be converted.
586  * @param size [in] The number of bytes of data.
587  * @return A bigint representing this data.
588  */
bi_import(BI_CTX * ctx,const uint8_t * data,int size)589 bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
590 {
591     bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
592     int i, j = 0, offset = 0;
593 
594     memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
595 
596     for (i = size-1; i >= 0; i--)
597     {
598         biR->comps[offset] += data[i] << (j*8);
599 
600         if (++j == COMP_BYTE_SIZE)
601         {
602             j = 0;
603             offset ++;
604         }
605     }
606 
607     return trim(biR);
608 }
609 
610 #ifdef CONFIG_SSL_FULL_MODE
611 /**
612  * @brief The testharness uses this code to import text hex-streams and
613  * convert them into bigints.
614  * @param ctx [in]  The bigint session context.
615  * @param data [in] A string consisting of hex characters. The characters must
616  * be in upper case.
617  * @return A bigint representing this data.
618  */
bi_str_import(BI_CTX * ctx,const char * data)619 bigint *bi_str_import(BI_CTX *ctx, const char *data)
620 {
621     int size = strlen(data);
622     bigint *biR = alloc(ctx, (size+COMP_NUM_NIBBLES-1)/COMP_NUM_NIBBLES);
623     int i, j = 0, offset = 0;
624     memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
625 
626     for (i = size-1; i >= 0; i--)
627     {
628         int num = (data[i] <= '9') ? (data[i] - '0') : (data[i] - 'A' + 10);
629         biR->comps[offset] += num << (j*4);
630 
631         if (++j == COMP_NUM_NIBBLES)
632         {
633             j = 0;
634             offset ++;
635         }
636     }
637 
638     return biR;
639 }
640 
bi_print(const char * label,bigint * x)641 void bi_print(const char *label, bigint *x)
642 {
643     int i, j;
644 
645     if (x == NULL)
646     {
647         printf("%s: (null)\n", label);
648         return;
649     }
650 
651     printf("%s: (size %d)\n", label, x->size);
652     for (i = x->size-1; i >= 0; i--)
653     {
654         for (j = COMP_NUM_NIBBLES-1; j >= 0; j--)
655         {
656             comp mask = 0x0f << (j*4);
657             comp num = (x->comps[i] & mask) >> (j*4);
658             putc((num <= 9) ? (num + '0') : (num + 'A' - 10), stdout);
659         }
660     }
661 
662     printf("\n");
663 }
664 #endif
665 
666 /**
667  * @brief Take a bigint and convert it into a byte sequence.
668  *
669  * This is useful after a decrypt operation.
670  * @param ctx [in]  The bigint session context.
671  * @param x [in]  The bigint to be converted.
672  * @param data [out] The converted data as a byte stream.
673  * @param size [in] The maximum size of the byte stream. Unused bytes will be
674  * zeroed.
675  */
bi_export(BI_CTX * ctx,bigint * x,uint8_t * data,int size)676 void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
677 {
678     int i, j, k = size-1;
679 
680     check(x);
681     memset(data, 0, size);  /* ensure all leading 0's are cleared */
682 
683     for (i = 0; i < x->size; i++)
684     {
685         for (j = 0; j < COMP_BYTE_SIZE; j++)
686         {
687             comp mask = 0xff << (j*8);
688             int num = (x->comps[i] & mask) >> (j*8);
689             data[k--] = num;
690 
691             if (k < 0)
692             {
693                 break;
694             }
695         }
696     }
697 
698     bi_free(ctx, x);
699 }
700 
701 /**
702  * @brief Pre-calculate some of the expensive steps in reduction.
703  *
704  * This function should only be called once (normally when a session starts).
705  * When the session is over, bi_free_mod() should be called. bi_mod_power()
706  * relies on this function being called.
707  * @param ctx [in]  The bigint session context.
708  * @param bim [in]  The bigint modulus that will be used.
709  * @param mod_offset [in] There are three moduluii that can be stored - the
710  * standard modulus, and its two primes p and q. This offset refers to which
711  * modulus we are referring to.
712  * @see bi_free_mod(), bi_mod_power().
713  */
bi_set_mod(BI_CTX * ctx,bigint * bim,int mod_offset)714 void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
715 {
716     int k = bim->size;
717     comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
718 #ifdef CONFIG_BIGINT_MONTGOMERY
719     bigint *R, *R2;
720 #endif
721 
722     ctx->bi_mod[mod_offset] = bim;
723     bi_permanent(ctx->bi_mod[mod_offset]);
724     ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
725     bi_permanent(ctx->bi_normalised_mod[mod_offset]);
726 
727 #if defined(CONFIG_BIGINT_MONTGOMERY)
728     /* set montgomery variables */
729     R = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k-1);     /* R */
730     R2 = comp_left_shift(bi_clone(ctx, ctx->bi_radix), k*2-1);  /* R^2 */
731     ctx->bi_RR_mod_m[mod_offset] = bi_mod(ctx, R2);             /* R^2 mod m */
732     ctx->bi_R_mod_m[mod_offset] = bi_mod(ctx, R);               /* R mod m */
733 
734     bi_permanent(ctx->bi_RR_mod_m[mod_offset]);
735     bi_permanent(ctx->bi_R_mod_m[mod_offset]);
736 
737     ctx->N0_dash[mod_offset] = modular_inverse(ctx->bi_mod[mod_offset]);
738 
739 #elif defined (CONFIG_BIGINT_BARRETT)
740     ctx->bi_mu[mod_offset] =
741         bi_divide(ctx, comp_left_shift(
742             bi_clone(ctx, ctx->bi_radix), k*2-1), ctx->bi_mod[mod_offset], 0);
743     bi_permanent(ctx->bi_mu[mod_offset]);
744 #endif
745 }
746 
747 /**
748  * @brief Used when cleaning various bigints at the end of a session.
749  * @param ctx [in]  The bigint session context.
750  * @param mod_offset [in] The offset to use.
751  * @see bi_set_mod().
752  */
bi_free_mod(BI_CTX * ctx,int mod_offset)753 void bi_free_mod(BI_CTX *ctx, int mod_offset)
754 {
755     bi_depermanent(ctx->bi_mod[mod_offset]);
756     bi_free(ctx, ctx->bi_mod[mod_offset]);
757 #if defined (CONFIG_BIGINT_MONTGOMERY)
758     bi_depermanent(ctx->bi_RR_mod_m[mod_offset]);
759     bi_depermanent(ctx->bi_R_mod_m[mod_offset]);
760     bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]);
761     bi_free(ctx, ctx->bi_R_mod_m[mod_offset]);
762 #elif defined(CONFIG_BIGINT_BARRETT)
763     bi_depermanent(ctx->bi_mu[mod_offset]);
764     bi_free(ctx, ctx->bi_mu[mod_offset]);
765 #endif
766     bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
767     bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
768 }
769 
770 /**
771  * Perform a standard multiplication between two bigints.
772  */
regular_multiply(BI_CTX * ctx,bigint * bia,bigint * bib)773 static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
774 {
775     int i, j, i_plus_j;
776     int n = bia->size;
777     int t = bib->size;
778     bigint *biR = alloc(ctx, n + t);
779     comp *sr = biR->comps;
780     comp *sa = bia->comps;
781     comp *sb = bib->comps;
782 
783     check(bia);
784     check(bib);
785 
786     /* clear things to start with */
787     memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
788     i = 0;
789 
790     do
791     {
792         comp carry = 0;
793         comp b = *sb++;
794         i_plus_j = i;
795         j = 0;
796 
797         do
798         {
799             long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
800             sr[i_plus_j++] = (comp)tmp;              /* downsize */
801             carry = (comp)(tmp >> COMP_BIT_SIZE);
802         } while (++j < n);
803 
804         sr[i_plus_j] = carry;
805     } while (++i < t);
806 
807     bi_free(ctx, bia);
808     bi_free(ctx, bib);
809     return trim(biR);
810 }
811 
812 #ifdef CONFIG_BIGINT_KARATSUBA
813 /*
814  * Karatsuba improves on regular multiplication due to only 3 multiplications
815  * being done instead of 4. The additional additions/subtractions are O(N)
816  * rather than O(N^2) and so for big numbers it saves on a few operations
817  */
karatsuba(BI_CTX * ctx,bigint * bia,bigint * bib,int is_square)818 static bigint *karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square)
819 {
820     bigint *x0, *x1;
821     bigint *p0, *p1, *p2;
822     int m;
823 
824     if (is_square)
825     {
826         m = (bia->size + 1)/2;
827     }
828     else
829     {
830         m = (max(bia->size, bib->size) + 1)/2;
831     }
832 
833     x0 = bi_clone(ctx, bia);
834     x0->size = m;
835     x1 = bi_clone(ctx, bia);
836     comp_right_shift(x1, m);
837     bi_free(ctx, bia);
838 
839     /* work out the 3 partial products */
840     if (is_square)
841     {
842         p0 = bi_square(ctx, bi_copy(x0));
843         p2 = bi_square(ctx, bi_copy(x1));
844         p1 = bi_square(ctx, bi_add(ctx, x0, x1));
845     }
846     else /* normal multiply */
847     {
848         bigint *y0, *y1;
849         y0 = bi_clone(ctx, bib);
850         y0->size = m;
851         y1 = bi_clone(ctx, bib);
852         comp_right_shift(y1, m);
853         bi_free(ctx, bib);
854 
855         p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0));
856         p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1));
857         p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1));
858     }
859 
860     p1 = bi_subtract(ctx,
861             bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL);
862 
863     comp_left_shift(p1, m);
864     comp_left_shift(p2, 2*m);
865     return bi_add(ctx, p1, bi_add(ctx, p0, p2));
866 }
867 #endif
868 
869 /**
870  * @brief Perform a multiplication operation between two bigints.
871  * @param ctx [in]  The bigint session context.
872  * @param bia [in]  A bigint.
873  * @param bib [in]  Another bigint.
874  * @return The result of the multiplication.
875  */
bi_multiply(BI_CTX * ctx,bigint * bia,bigint * bib)876 bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
877 {
878     check(bia);
879     check(bib);
880 
881 #ifdef CONFIG_BIGINT_KARATSUBA
882     if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH)
883     {
884         return regular_multiply(ctx, bia, bib);
885     }
886 
887     return karatsuba(ctx, bia, bib, 0);
888 #else
889     return regular_multiply(ctx, bia, bib);
890 #endif
891 }
892 
893 #ifdef CONFIG_BIGINT_SQUARE
894 /*
895  * Perform the actual square operion. It takes into account overflow.
896  */
regular_square(BI_CTX * ctx,bigint * bi)897 static bigint *regular_square(BI_CTX *ctx, bigint *bi)
898 {
899     int t = bi->size;
900     int i = 0, j;
901     bigint *biR = alloc(ctx, t*2);
902     comp *w = biR->comps;
903     comp *x = bi->comps;
904     comp carry;
905 
906     memset(w, 0, biR->size*COMP_BYTE_SIZE);
907 
908     do
909     {
910         long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
911         comp u = 0;
912         w[2*i] = (comp)tmp;
913         carry = (comp)(tmp >> COMP_BIT_SIZE);
914 
915         for (j = i+1; j < t; j++)
916         {
917             long_comp xx = (long_comp)x[i]*x[j];
918             long_comp blob = (long_comp)w[i+j]+carry;
919 
920             if (u)                  /* previous overflow */
921             {
922                 blob += COMP_RADIX;
923             }
924 
925             u = 0;
926             if (xx & COMP_BIG_MSB)  /* check for overflow */
927             {
928                 u = 1;
929             }
930 
931             tmp = 2*xx + blob;
932             w[i+j] = (comp)tmp;
933             carry = (comp)(tmp >> COMP_BIT_SIZE);
934         }
935 
936         w[i+t] += carry;
937 
938         if (u)
939         {
940             w[i+t+1] = 1;   /* add carry */
941         }
942     } while (++i < t);
943 
944     bi_free(ctx, bi);
945     return trim(biR);
946 }
947 
948 /**
949  * @brief Perform a square operation on a bigint.
950  * @param ctx [in]  The bigint session context.
951  * @param bia [in]  A bigint.
952  * @return The result of the multiplication.
953  */
bi_square(BI_CTX * ctx,bigint * bia)954 bigint *bi_square(BI_CTX *ctx, bigint *bia)
955 {
956     check(bia);
957 
958 #ifdef CONFIG_BIGINT_KARATSUBA
959     if (bia->size < SQU_KARATSUBA_THRESH)
960     {
961         return regular_square(ctx, bia);
962     }
963 
964     return karatsuba(ctx, bia, NULL, 1);
965 #else
966     return regular_square(ctx, bia);
967 #endif
968 }
969 #endif
970 
971 /**
972  * @brief Compare two bigints.
973  * @param bia [in]  A bigint.
974  * @param bib [in]  Another bigint.
975  * @return -1 if smaller, 1 if larger and 0 if equal.
976  */
bi_compare(bigint * bia,bigint * bib)977 int bi_compare(bigint *bia, bigint *bib)
978 {
979     int r, i;
980 
981     check(bia);
982     check(bib);
983 
984     if (bia->size > bib->size)
985         r = 1;
986     else if (bia->size < bib->size)
987         r = -1;
988     else
989     {
990         comp *a = bia->comps;
991         comp *b = bib->comps;
992 
993         /* Same number of components.  Compare starting from the high end
994          * and working down. */
995         r = 0;
996         i = bia->size - 1;
997 
998         do
999         {
1000             if (a[i] > b[i])
1001             {
1002                 r = 1;
1003                 break;
1004             }
1005             else if (a[i] < b[i])
1006             {
1007                 r = -1;
1008                 break;
1009             }
1010         } while (--i >= 0);
1011     }
1012 
1013     return r;
1014 }
1015 
1016 /*
1017  * Allocate and zero more components.  Does not consume bi.
1018  */
more_comps(bigint * bi,int n)1019 static void more_comps(bigint *bi, int n)
1020 {
1021     if (n > bi->max_comps)
1022     {
1023         bi->max_comps = max(bi->max_comps * 2, n);
1024         bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1025     }
1026 
1027     if (n > bi->size)
1028     {
1029         memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1030     }
1031 
1032     bi->size = n;
1033 }
1034 
1035 /*
1036  * Make a new empty bigint. It may just use an old one if one is available.
1037  * Otherwise get one off the heap.
1038  */
alloc(BI_CTX * ctx,int size)1039 static bigint *alloc(BI_CTX *ctx, int size)
1040 {
1041     bigint *biR;
1042 
1043     /* Can we recycle an old bigint? */
1044     if (ctx->free_list != NULL)
1045     {
1046         biR = ctx->free_list;
1047         ctx->free_list = biR->next;
1048         ctx->free_count--;
1049 
1050         if (biR->refs != 0)
1051         {
1052 #ifdef CONFIG_SSL_FULL_MODE
1053             printf("alloc: refs was not 0\n");
1054 #endif
1055             abort();    /* create a stack trace from a core dump */
1056         }
1057 
1058         more_comps(biR, size);
1059     }
1060     else
1061     {
1062         /* No free bigints available - create a new one. */
1063         biR = (bigint *)malloc(sizeof(bigint));
1064         biR->comps = (comp*)malloc(size * COMP_BYTE_SIZE);
1065         biR->max_comps = size;  /* give some space to spare */
1066     }
1067 
1068     biR->size = size;
1069     biR->refs = 1;
1070     biR->next = NULL;
1071     ctx->active_count++;
1072     return biR;
1073 }
1074 
1075 /*
1076  * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1077  * exponentiation.
1078  */
find_max_exp_index(bigint * biexp)1079 static int find_max_exp_index(bigint *biexp)
1080 {
1081     int i = COMP_BIT_SIZE-1;
1082     comp shift = COMP_RADIX/2;
1083     comp test = biexp->comps[biexp->size-1];    /* assume no leading zeroes */
1084 
1085     check(biexp);
1086 
1087     do
1088     {
1089         if (test & shift)
1090         {
1091             return i+(biexp->size-1)*COMP_BIT_SIZE;
1092         }
1093 
1094         shift >>= 1;
1095     } while (--i != 0);
1096 
1097     return -1;      /* error - must have been a leading 0 */
1098 }
1099 
1100 /*
1101  * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1102  * exponentiation.
1103  */
exp_bit_is_one(bigint * biexp,int offset)1104 static int exp_bit_is_one(bigint *biexp, int offset)
1105 {
1106     comp test = biexp->comps[offset / COMP_BIT_SIZE];
1107     int num_shifts = offset % COMP_BIT_SIZE;
1108     comp shift = 1;
1109     int i;
1110 
1111     check(biexp);
1112 
1113     for (i = 0; i < num_shifts; i++)
1114     {
1115         shift <<= 1;
1116     }
1117 
1118     return test & shift;
1119 }
1120 
1121 #ifdef CONFIG_BIGINT_CHECK_ON
1122 /*
1123  * Perform a sanity check on bi.
1124  */
check(const bigint * bi)1125 static void check(const bigint *bi)
1126 {
1127     if (bi->refs <= 0)
1128     {
1129         printf("check: zero or negative refs in bigint\n");
1130         abort();
1131     }
1132 
1133     if (bi->next != NULL)
1134     {
1135         printf("check: attempt to use a bigint from "
1136                 "the free list\n");
1137         abort();
1138     }
1139 }
1140 #endif
1141 
1142 /*
1143  * Delete any leading 0's (and allow for 0).
1144  */
trim(bigint * bi)1145 static bigint *trim(bigint *bi)
1146 {
1147     check(bi);
1148 
1149     while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1150     {
1151         bi->size--;
1152     }
1153 
1154     return bi;
1155 }
1156 
1157 #if defined(CONFIG_BIGINT_MONTGOMERY)
1158 /**
1159  * @brief Perform a single montgomery reduction.
1160  * @param ctx [in]  The bigint session context.
1161  * @param bixy [in]  A bigint.
1162  * @return The result of the montgomery reduction.
1163  */
bi_mont(BI_CTX * ctx,bigint * bixy)1164 bigint *bi_mont(BI_CTX *ctx, bigint *bixy)
1165 {
1166     int i = 0, n;
1167     uint8_t mod_offset = ctx->mod_offset;
1168     bigint *bim = ctx->bi_mod[mod_offset];
1169     comp mod_inv = ctx->N0_dash[mod_offset];
1170 
1171     check(bixy);
1172 
1173     if (ctx->use_classical)     /* just use classical instead */
1174     {
1175         return bi_mod(ctx, bixy);
1176     }
1177 
1178     n = bim->size;
1179 
1180     do
1181     {
1182         bixy = bi_add(ctx, bixy, comp_left_shift(
1183                     bi_int_multiply(ctx, bim, bixy->comps[i]*mod_inv), i));
1184     } while (++i < n);
1185 
1186     comp_right_shift(bixy, n);
1187 
1188     if (bi_compare(bixy, bim) >= 0)
1189     {
1190         bixy = bi_subtract(ctx, bixy, bim, NULL);
1191     }
1192 
1193     return bixy;
1194 }
1195 
1196 #elif defined(CONFIG_BIGINT_BARRETT)
1197 /*
1198  * Stomp on the most significant components to give the illusion of a "mod base
1199  * radix" operation
1200  */
comp_mod(bigint * bi,int mod)1201 static bigint *comp_mod(bigint *bi, int mod)
1202 {
1203     check(bi);
1204 
1205     if (bi->size > mod)
1206     {
1207         bi->size = mod;
1208     }
1209 
1210     return bi;
1211 }
1212 
1213 /*
1214  * Barrett reduction has no need for some parts of the product, so ignore bits
1215  * of the multiply. This routine gives Barrett its big performance
1216  * improvements over Classical/Montgomery reduction methods.
1217  */
partial_multiply(BI_CTX * ctx,bigint * bia,bigint * bib,int inner_partial,int outer_partial)1218 static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
1219         int inner_partial, int outer_partial)
1220 {
1221     int i = 0, j, n = bia->size, t = bib->size;
1222     bigint *biR;
1223     comp carry;
1224     comp *sr, *sa, *sb;
1225 
1226     check(bia);
1227     check(bib);
1228 
1229     biR = alloc(ctx, n + t);
1230     sa = bia->comps;
1231     sb = bib->comps;
1232     sr = biR->comps;
1233 
1234     if (inner_partial)
1235     {
1236         memset(sr, 0, inner_partial*COMP_BYTE_SIZE);
1237     }
1238     else    /* outer partial */
1239     {
1240         if (n < outer_partial || t < outer_partial) /* should we bother? */
1241         {
1242             bi_free(ctx, bia);
1243             bi_free(ctx, bib);
1244             biR->comps[0] = 0;      /* return 0 */
1245             biR->size = 1;
1246             return biR;
1247         }
1248 
1249         memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
1250     }
1251 
1252     do
1253     {
1254         comp *a = sa;
1255         comp b = *sb++;
1256         long_comp tmp;
1257         int i_plus_j = i;
1258         carry = 0;
1259         j = n;
1260 
1261         if (outer_partial && i_plus_j < outer_partial)
1262         {
1263             i_plus_j = outer_partial;
1264             a = &sa[outer_partial-i];
1265             j = n-(outer_partial-i);
1266         }
1267 
1268         do
1269         {
1270             if (inner_partial && i_plus_j >= inner_partial)
1271             {
1272                 break;
1273             }
1274 
1275             tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
1276             sr[i_plus_j++] = (comp)tmp;              /* downsize */
1277             carry = (comp)(tmp >> COMP_BIT_SIZE);
1278         } while (--j != 0);
1279 
1280         sr[i_plus_j] = carry;
1281     } while (++i < t);
1282 
1283     bi_free(ctx, bia);
1284     bi_free(ctx, bib);
1285     return trim(biR);
1286 }
1287 
1288 /**
1289  * @brief Perform a single Barrett reduction.
1290  * @param ctx [in]  The bigint session context.
1291  * @param bi [in]  A bigint.
1292  * @return The result of the Barrett reduction.
1293  */
bi_barrett(BI_CTX * ctx,bigint * bi)1294 bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
1295 {
1296     bigint *q1, *q2, *q3, *r1, *r2, *r;
1297     uint8_t mod_offset = ctx->mod_offset;
1298     bigint *bim = ctx->bi_mod[mod_offset];
1299     int k = bim->size;
1300 
1301     check(bi);
1302     check(bim);
1303 
1304     /* use Classical method instead  - Barrett cannot help here */
1305     if (bi->size > k*2)
1306     {
1307         return bi_mod(ctx, bi);
1308     }
1309 
1310     q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
1311 
1312     /* do outer partial multiply */
1313     q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
1314     q3 = comp_right_shift(q2, k+1);
1315     r1 = comp_mod(bi, k+1);
1316 
1317     /* do inner partial multiply */
1318     r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
1319     r = bi_subtract(ctx, r1, r2, NULL);
1320 
1321     /* if (r >= m) r = r - m; */
1322     if (bi_compare(r, bim) >= 0)
1323     {
1324         r = bi_subtract(ctx, r, bim, NULL);
1325     }
1326 
1327     return r;
1328 }
1329 #endif /* CONFIG_BIGINT_BARRETT */
1330 
1331 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1332 /*
1333  * Work out g1, g3, g5, g7... etc for the sliding-window algorithm
1334  */
precompute_slide_window(BI_CTX * ctx,int window,bigint * g1)1335 static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
1336 {
1337     int k = 1, i;
1338     bigint *g2;
1339 
1340     for (i = 0; i < window-1; i++)   /* compute 2^(window-1) */
1341     {
1342         k <<= 1;
1343     }
1344 
1345     ctx->g = (bigint **)malloc(k*sizeof(bigint *));
1346     ctx->g[0] = bi_clone(ctx, g1);
1347     bi_permanent(ctx->g[0]);
1348     g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0]));   /* g^2 */
1349 
1350     for (i = 1; i < k; i++)
1351     {
1352         ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i-1], bi_copy(g2)));
1353         bi_permanent(ctx->g[i]);
1354     }
1355 
1356     bi_free(ctx, g2);
1357     ctx->window = k;
1358 }
1359 #endif
1360 
1361 /**
1362  * @brief Perform a modular exponentiation.
1363  *
1364  * This function requires bi_set_mod() to have been called previously. This is
1365  * one of the optimisations used for performance.
1366  * @param ctx [in]  The bigint session context.
1367  * @param bi  [in]  The bigint on which to perform the mod power operation.
1368  * @param biexp [in] The bigint exponent.
1369  * @see bi_set_mod().
1370  */
bi_mod_power(BI_CTX * ctx,bigint * bi,bigint * biexp)1371 bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1372 {
1373     int i = find_max_exp_index(biexp), j, window_size = 1;
1374     bigint *biR = int_to_bi(ctx, 1);
1375 
1376 #if defined(CONFIG_BIGINT_MONTGOMERY)
1377     uint8_t mod_offset = ctx->mod_offset;
1378     if (!ctx->use_classical)
1379     {
1380         /* preconvert */
1381         bi = bi_mont(ctx,
1382                 bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset]));    /* x' */
1383         bi_free(ctx, biR);
1384         biR = ctx->bi_R_mod_m[mod_offset];                              /* A */
1385     }
1386 #endif
1387 
1388     check(bi);
1389     check(biexp);
1390 
1391 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1392     for (j = i; j > 32; j /= 5) /* work out an optimum size */
1393         window_size++;
1394 
1395     /* work out the slide constants */
1396     precompute_slide_window(ctx, window_size, bi);
1397 #else   /* just one constant */
1398     ctx->g = (bigint **)malloc(sizeof(bigint *));
1399     ctx->g[0] = bi_clone(ctx, bi);
1400     ctx->window = 1;
1401     bi_permanent(ctx->g[0]);
1402 #endif
1403 
1404     /* if sliding-window is off, then only one bit will be done at a time and
1405      * will reduce to standard left-to-right exponentiation */
1406     do
1407     {
1408         if (exp_bit_is_one(biexp, i))
1409         {
1410             int l = i-window_size+1;
1411             int part_exp = 0;
1412 
1413             if (l < 0)  /* LSB of exponent will always be 1 */
1414                 l = 0;
1415             else
1416             {
1417                 while (exp_bit_is_one(biexp, l) == 0)
1418                     l++;    /* go back up */
1419             }
1420 
1421             /* build up the section of the exponent */
1422             for (j = i; j >= l; j--)
1423             {
1424                 biR = bi_residue(ctx, bi_square(ctx, biR));
1425                 if (exp_bit_is_one(biexp, j))
1426                     part_exp++;
1427 
1428                 if (j != l)
1429                     part_exp <<= 1;
1430             }
1431 
1432             part_exp = (part_exp-1)/2;  /* adjust for array */
1433             biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp]));
1434             i = l-1;
1435         }
1436         else    /* square it */
1437         {
1438             biR = bi_residue(ctx, bi_square(ctx, biR));
1439             i--;
1440         }
1441     } while (i >= 0);
1442 
1443     /* cleanup */
1444     for (i = 0; i < ctx->window; i++)
1445     {
1446         bi_depermanent(ctx->g[i]);
1447         bi_free(ctx, ctx->g[i]);
1448     }
1449 
1450     free(ctx->g);
1451     bi_free(ctx, bi);
1452     bi_free(ctx, biexp);
1453 #if defined CONFIG_BIGINT_MONTGOMERY
1454     return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */
1455 #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */
1456     return biR;
1457 #endif
1458 }
1459 
1460 #ifdef CONFIG_SSL_CERT_VERIFICATION
1461 /**
1462  * @brief Perform a modular exponentiation using a temporary modulus.
1463  *
1464  * We need this function to check the signatures of certificates. The modulus
1465  * of this function is temporary as it's just used for authentication.
1466  * @param ctx [in]  The bigint session context.
1467  * @param bi  [in]  The bigint to perform the exp/mod.
1468  * @param bim [in]  The temporary modulus.
1469  * @param biexp [in] The bigint exponent.
1470  * @see bi_set_mod().
1471  */
bi_mod_power2(BI_CTX * ctx,bigint * bi,bigint * bim,bigint * biexp)1472 bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
1473 {
1474     bigint *biR, *tmp_biR;
1475 
1476     /* Set up a temporary bigint context and transfer what we need between
1477      * them. We need to do this since we want to keep the original modulus
1478      * which is already in this context. This operation is only called when
1479      * doing peer verification, and so is not expensive :-) */
1480     BI_CTX *tmp_ctx = bi_initialize();
1481     bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET);
1482     tmp_biR = bi_mod_power(tmp_ctx,
1483                 bi_clone(tmp_ctx, bi),
1484                 bi_clone(tmp_ctx, biexp));
1485     biR = bi_clone(ctx, tmp_biR);
1486     bi_free(tmp_ctx, tmp_biR);
1487     bi_free_mod(tmp_ctx, BIGINT_M_OFFSET);
1488     bi_terminate(tmp_ctx);
1489 
1490     bi_free(ctx, bi);
1491     bi_free(ctx, bim);
1492     bi_free(ctx, biexp);
1493     return biR;
1494 }
1495 #endif
1496 /** @} */
1497