Annotation of embedaddon/axTLS/crypto/bigint.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>