Annotation of embedaddon/axTLS/crypto/bigint.c, revision 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>