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