|
|
1.1.1.2 ! root 1: /* idea.c - C source code for IDEA block cipher. ! 2: * IDEA (International Data Encryption Algorithm), formerly known as ! 3: * IPES (Improved Proposed Encryption Standard). ! 4: * Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich. ! 5: * This implementation modified and derived from original C code ! 6: * developed by Xuejia Lai. ! 7: * Zero-based indexing added, names changed from IPES to IDEA. ! 8: * CFB functions added. Random number routines added. ! 9: * ! 10: * Optimized for speed 21 Oct 92 by Colin Plumb <[email protected]> ! 11: * ! 12: * There are two adjustments that can be made to this code to ! 13: * speed it up. Defaults may be used for PCs. Only the -DIDEA32 ! 14: * pays off significantly if selectively set or not set. ! 15: * Experiment to see what works better for you. ! 16: * ! 17: * Multiplication: default is inline, -DAVOID_JUMPS uses a ! 18: * different version that does not do any conditional ! 19: * jumps (a few percent worse on a SPARC), while ! 20: * -DSMALL_CACHE takes it out of line to stay ! 21: * within a small on-chip code cache. ! 22: * Variables: normally, 16-bit variables are used, but some ! 23: * machines (notably RISCs) do not have 16-bit registers, ! 24: * so they do a great deal of masking. -DIDEA32 uses "int" ! 25: * register variables and masks explicitly only where ! 26: * necessary. On a SPARC, for example, this boosts ! 27: * performace by 30%. ! 28: * ! 29: * The IDEA(tm) block cipher is covered by a patent held by ETH and a ! 30: * Swiss company called Ascom-Tech AG. The Swiss patent number is ! 31: * PCT/CH91/00117. International patents are pending. IDEA(tm) is a ! 32: * trademark of Ascom-Tech AG. There is no license fee required for ! 33: * noncommercial use. Commercial users may obtain licensing details ! 34: * from Dieter Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 ! 35: * Solothurn, Switzerland, Tel +41 65 242885, Fax +41 65 235761. ! 36: * ! 37: * The IDEA block cipher uses a 64-bit block size, and a 128-bit key ! 38: * size. It breaks the 64-bit cipher block into four 16-bit words ! 39: * because all of the primitive inner operations are done with 16-bit ! 40: * arithmetic. It likewise breaks the 128-bit cipher key into eight ! 41: * 16-bit words. ! 42: * ! 43: * For further information on the IDEA cipher, see these papers: ! 44: * 1) Xuejia Lai, "Detailed Description and a Software Implementation of ! 45: * the IPES Cipher", Institute for Signal and Information ! 46: * Processing, ETH-Zentrum, Zurich, Switzerland, 1991 ! 47: * 2) Xuejia Lai, James L. Massey, Sean Murphy, "Markov Ciphers and ! 48: * Differential Cryptanalysis", Advances in Cryptology- EUROCRYPT'91 ! 49: * ! 50: * This code assumes that each pair of 8-bit bytes comprising a 16-bit ! 51: * word in the key and in the cipher block are externally represented ! 52: * with the Most Significant Byte (MSB) first, regardless of the ! 53: * internal native byte order of the target CPU. ! 54: */ ! 55: ! 56: #include "idea.h" ! 57: ! 58: #ifdef TEST ! 59: #include <stdio.h> ! 60: #include <time.h> ! 61: #endif ! 62: ! 63: #define ROUNDS 8 /* Don't change this value, should be 8 */ ! 64: #define KEYLEN (6*ROUNDS+4) /* length of key schedule */ ! 65: ! 66: typedef word16 IDEAkey[KEYLEN]; ! 67: ! 68: #ifdef IDEA32 /* Use >16-bit temporaries */ ! 69: #define low16(x) ((x) & 0xFFFF) ! 70: typedef unsigned int uint16; /* at LEAST 16 bits, maybe more */ ! 71: #else ! 72: #define low16(x) (x) /* this is only ever applied to uint16's */ ! 73: typedef word16 uint16; ! 74: #endif ! 75: ! 76: #ifdef _GNUC_ ! 77: /* __const__ simply means there are no side effects for this function, ! 78: * which is useful info for the gcc optimizer */ ! 79: #define CONST __const__ ! 80: #else ! 81: #define CONST ! 82: #endif ! 83: ! 84: static void en_key_idea(word16 userkey[8], IDEAkey Z); ! 85: static void de_key_idea(IDEAkey Z, IDEAkey DK); ! 86: static void cipher_idea(word16 in[4], word16 out[4], CONST IDEAkey Z); ! 87: ! 88: /* ! 89: * Multiplication, modulo (2**16)+1 ! 90: * Note that this code is structured like this on the assumption that ! 91: * untaken branches are cheaper than taken branches, and the compiler ! 92: * doesn't schedule branches. ! 93: */ ! 94: #ifdef SMALL_CACHE ! 95: CONST static uint16 mul(register uint16 a, register uint16 b) ! 96: { ! 97: register word32 p; ! 98: ! 99: if (a) ! 100: { if (b) ! 101: { p = (word32)a * b; ! 102: b = low16(p); ! 103: a = p>>16; ! 104: return b - a + (b < a); ! 105: } ! 106: else ! 107: { return 1-a; ! 108: } ! 109: } ! 110: else ! 111: { return 1-b; ! 112: } ! 113: } /* mul */ ! 114: #endif /* SMALL_CACHE */ ! 115: ! 116: /* ! 117: * Compute multiplicative inverse of x, modulo (2**16)+1, ! 118: * using Euclid's GCD algorithm. It is unrolled twice to ! 119: * avoid swapping the meaning of the registers each iteration, ! 120: * and some subtracts of t have been changed to adds. ! 121: */ ! 122: CONST static uint16 inv(uint16 x) ! 123: { ! 124: uint16 t0, t1; ! 125: uint16 q, y; ! 126: ! 127: if (x <= 1) ! 128: return x; /* 0 and 1 are self-inverse */ ! 129: t1 = 0x10001 / x; /* Since x >= 2, this fits into 16 bits */ ! 130: y = 0x10001 % x; ! 131: if (y == 1) ! 132: return low16(1-t1); ! 133: t0 = 1; ! 134: do ! 135: { q = x / y; ! 136: x = x % y; ! 137: t0 += q * t1; ! 138: if (x == 1) ! 139: return t0; ! 140: q = y / x; ! 141: y = y % x; ! 142: t1 += q * t0; ! 143: } while (y != 1); ! 144: return low16(1-t1); ! 145: } /* inv */ ! 146: ! 147: /* Compute IDEA encryption subkeys Z */ ! 148: static void en_key_idea(word16 *userkey, word16 *Z) ! 149: { ! 150: int i,j; ! 151: ! 152: /* ! 153: * shifts ! 154: */ ! 155: for (j=0; j<8; j++) ! 156: Z[j] = *userkey++; ! 157: ! 158: for (i=0; j<KEYLEN; j++) ! 159: { i++; ! 160: Z[i+7] = Z[i & 7] << 9 | Z[i+1 & 7] >> 7; ! 161: Z += i & 8; ! 162: i &= 7; ! 163: } ! 164: } /* en_key_idea */ ! 165: ! 166: /* Compute IDEA decryption subkeys DK from encryption subkeys Z */ ! 167: /* Note: these buffers *may* overlap! */ ! 168: static void de_key_idea(IDEAkey Z, IDEAkey DK) ! 169: { ! 170: int j; ! 171: uint16 t1, t2, t3; ! 172: IDEAkey T; ! 173: word16 *p = T + KEYLEN; ! 174: ! 175: t1 = inv(*Z++); ! 176: t2 = -*Z++; ! 177: t3 = -*Z++; ! 178: *--p = inv(*Z++); ! 179: *--p = t3; ! 180: *--p = t2; ! 181: *--p = t1; ! 182: ! 183: for (j = 1; j < ROUNDS; j++) ! 184: { ! 185: t1 = *Z++; ! 186: *--p = *Z++; ! 187: *--p = t1; ! 188: ! 189: t1 = inv(*Z++); ! 190: t2 = -*Z++; ! 191: t3 = -*Z++; ! 192: *--p = inv(*Z++); ! 193: *--p = t2; ! 194: *--p = t3; ! 195: *--p = t1; ! 196: } ! 197: t1 = *Z++; ! 198: *--p = *Z++; ! 199: *--p = t1; ! 200: ! 201: t1 = inv(*Z++); ! 202: t2 = -*Z++; ! 203: t3 = -*Z++; ! 204: *--p = inv(*Z++); ! 205: *--p = t3; ! 206: *--p = t2; ! 207: *--p = t1; ! 208: /* Copy and destroy temp copy */ ! 209: for (j = 0, p = T; j < KEYLEN; j++) ! 210: { ! 211: *DK++ = *p; ! 212: *p++ = 0; ! 213: } ! 214: } /* de_key_idea */ ! 215: ! 216: /* ! 217: * MUL(x,y) computes x = x*y, modulo 0x10001. Requires two temps, ! 218: * t16 and t32. x must me a side-effect-free lvalue. y may be ! 219: * anything, but unlike x, must be strictly 16 bits even if low16() ! 220: * is #defined. ! 221: * All of these are equivalent - see which is faster on your machine ! 222: */ ! 223: #ifdef SMALL_CACHE ! 224: #define MUL(x,y) (x = mul(low16(x),y)) ! 225: #else ! 226: #ifdef AVOID_JUMPS ! 227: #define MUL(x,y) (x = low16(x-1), t16 = low16((y)-1), \ ! 228: t32 = (word32)x*t16+x+t16+1, x = low16(t32), \ ! 229: t16 = t32>>16, x = x-t16+(x<t16) ) ! 230: #else ! 231: #define MUL(x,y) ((t16 = (y)) ? (x=low16(x)) ? \ ! 232: t32 = (word32)x*t16, x = low16(t32), t16 = t32>>16, \ ! 233: x = x-t16+(x<t16) : \ ! 234: (x = 1-t16) : (x = 1-x)) ! 235: #endif ! 236: #endif ! 237: ! 238: /* IDEA encryption/decryption algorithm */ ! 239: /* Note that in and out can be the same buffer */ ! 240: static void cipher_idea(word16 in[4], word16 out[4], register CONST IDEAkey Z) ! 241: { ! 242: register uint16 x1, x2, x3, x4, t1, t2; ! 243: register uint16 t16; ! 244: register word32 t32; ! 245: ! 246: int r = ROUNDS; ! 247: ! 248: x1 = *in++; x2 = *in++; ! 249: x3 = *in++; x4 = *in; ! 250: do ! 251: { ! 252: MUL(x1,*Z++); ! 253: x2 += *Z++; ! 254: x3 += *Z++; ! 255: MUL(x4, *Z++); ! 256: ! 257: t2 = x1^x3; ! 258: MUL(t2, *Z++); ! 259: t1 = t2 + (x2^x4); ! 260: MUL(t1, *Z++); ! 261: t2 = t1+t2; ! 262: ! 263: x1 ^= t1; ! 264: x4 ^= t2; ! 265: ! 266: t2 ^= x2; ! 267: x2 = x3^t1; ! 268: x3 = t2; ! 269: } while (--r); ! 270: MUL(x1, *Z++); ! 271: *out++ = x1; ! 272: *out++ = x3 + *Z++; ! 273: *out++ = x2 + *Z++; ! 274: MUL(x4, *Z); ! 275: *out = x4; ! 276: } /* cipher_idea */ ! 277: ! 278: /*-------------------------------------------------------------*/ ! 279: ! 280: #ifdef TEST ! 281: /* ! 282: * This is the number of Kbytes of test data to encrypt. ! 283: * It defaults to 1 MByte. ! 284: */ ! 285: #ifndef KBYTES ! 286: #define KBYTES 1024 ! 287: #endif ! 288: ! 289: void main(void) ! 290: { /* Test driver for IDEA cipher */ ! 291: int i, j, k; ! 292: IDEAkey Z, DK; ! 293: word16 XX[4], TT[4], YY[4]; ! 294: word16 userkey[8]; ! 295: clock_t start, end; ! 296: long l; ! 297: ! 298: /* Make a sample user key for testing... */ ! 299: for(i=0; i<8; i++) ! 300: userkey[i] = i+1; ! 301: ! 302: /* Compute encryption subkeys from user key... */ ! 303: en_key_idea(userkey,Z); ! 304: printf("\nEncryption key subblocks: "); ! 305: for(j=0; j<ROUNDS+1; j++) ! 306: { ! 307: printf("\nround %d: ", j+1); ! 308: if (j==ROUNDS) ! 309: for(i=0; i<4; i++) ! 310: printf(" %6u", Z[j*6+i]); ! 311: else ! 312: for(i=0; i<6; i++) ! 313: printf(" %6u", Z[j*6+i]); ! 314: } ! 315: ! 316: /* Compute decryption subkeys from encryption subkeys... */ ! 317: de_key_idea(Z,DK); ! 318: printf("\nDecryption key subblocks: "); ! 319: for(j=0; j<ROUNDS+1; j++) ! 320: { ! 321: printf("\nround %d: ", j+1); ! 322: if (j==ROUNDS) ! 323: for(i=0; i<4; i++) ! 324: printf(" %6u", DK[j*6+i]); ! 325: else ! 326: for(i=0; i<6; i++) ! 327: printf(" %6u", DK[j*6+i]); ! 328: } ! 329: ! 330: /* Make a sample plaintext pattern for testing... */ ! 331: for (k=0; k<4; k++) ! 332: XX[k] = k; ! 333: ! 334: printf("\n Encrypting %d KBytes (%ld blocks)...", KBYTES, KBYTES*64l); ! 335: fflush(stdout); ! 336: start = clock(); ! 337: cipher_idea(XX,YY,Z); /* encrypt plaintext XX, making YY */ ! 338: for (l = 1; l < 64*KBYTES; l++) ! 339: cipher_idea(YY,YY,Z); /* repeated encryption */ ! 340: cipher_idea(YY,TT,DK); /* decrypt ciphertext YY, making TT */ ! 341: for (l = 1; l < 64*KBYTES; l++) ! 342: cipher_idea(TT,TT,DK); /* repeated decryption */ ! 343: end = clock() - start; ! 344: l = end * 1000. / CLOCKS_PER_SEC + 1; ! 345: i = l/1000; ! 346: j = l%1000; ! 347: l = KBYTES * 1024. * CLOCKS_PER_SEC / end; ! 348: printf("%d.%03d seconds = %ld bytes per second\n", i, j, l); ! 349: ! 350: printf("\nX %6u %6u %6u %6u \n", ! 351: XX[0], XX[1], XX[2], XX[3]); ! 352: printf("Y %6u %6u %6u %6u \n", ! 353: YY[0], YY[1], YY[2], YY[3]); ! 354: printf("T %6u %6u %6u %6u \n", ! 355: TT[0], TT[1], TT[2], TT[3]); ! 356: ! 357: /* Now decrypted TT should be same as original XX */ ! 358: for (k=0; k<4; k++) ! 359: if (TT[k] != XX[k]) ! 360: { ! 361: printf("\n\07Error! Noninvertable encryption.\n"); ! 362: exit(-1); /* error exit */ ! 363: } ! 364: printf("\nNormal exit.\n"); ! 365: exit(0); /* normal exit */ ! 366: } /* main */ ! 367: ! 368: ! 369: #endif /* TEST */ ! 370: ! 371: ! 372: /*************************************************************************/ ! 373: ! 374: ! 375: /* ! 376: * xorbuf - change buffer via xor with random mask block ! 377: * Used for Cipher Feedback (CFB) or Cipher Block Chaining ! 378: * (CBC) modes of encryption. ! 379: * Can be applied for any block encryption algorithm, ! 380: * with any block size, such as the DES or the IDEA cipher. ! 381: */ ! 382: static void xorbuf(register byteptr buf, register byteptr mask, ! 383: register int count) ! 384: /* count must be > 0 */ ! 385: { ! 386: if (count) ! 387: do ! 388: *buf++ ^= *mask++; ! 389: while (--count); ! 390: } /* xorbuf */ ! 391: ! 392: ! 393: /* ! 394: * cfbshift - shift bytes into IV for CFB input ! 395: * Used only for Cipher Feedback (CFB) mode of encryption. ! 396: * Can be applied for any block encryption algorithm with any ! 397: * block size, such as the DES or the IDEA cipher. ! 398: */ ! 399: static void cfbshift(register byteptr iv, register byteptr buf, ! 400: register int count, int blocksize) ! 401: /* iv is the initialization vector. ! 402: * buf is the buffer pointer. ! 403: * count is the number of bytes to shift in...must be > 0. ! 404: * blocksize is 8 bytes for DES or IDEA ciphers. ! 405: */ ! 406: { ! 407: int retained; ! 408: if (count) ! 409: { ! 410: retained = blocksize-count; /* number bytes in iv to retain */ ! 411: /* left-shift retained bytes of IV over by count bytes to make room */ ! 412: while (retained--) ! 413: { ! 414: *iv = *(iv+count); ! 415: iv++; ! 416: } ! 417: /* now copy count bytes from buf to shifted tail of IV */ ! 418: do *iv++ = *buf++; ! 419: while (--count); ! 420: } ! 421: } /* cfbshift */ ! 422: ! 423: ! 424: ! 425: /* Key schedules for IDEA encryption and decryption */ ! 426: static IDEAkey Z, DK; ! 427: static word16 *iv_idea; /* pointer to IV for CFB or CBC */ ! 428: static boolean cfb_dc_idea; /* TRUE iff CFB decrypting */ ! 429: ! 430: ! 431: /* initkey_idea initializes IDEA for ECB mode operations */ ! 432: void initkey_idea(byte key[16], boolean decryp) ! 433: { ! 434: word16 userkey[8]; /* IDEA key is 16 bytes long */ ! 435: int i; ! 436: /* Assume each pair of bytes comprising a word is ordered MSB-first. */ ! 437: for (i=0; i<8; i++) ! 438: { ! 439: userkey[i] = (key[0]<<8) + key[1]; ! 440: key++; key++; ! 441: } ! 442: en_key_idea(userkey,Z); ! 443: if (decryp) ! 444: { ! 445: de_key_idea(Z,Z); /* compute inverse key schedule DK */ ! 446: } ! 447: for (i=0; i<8; i++) /* Erase dangerous traces */ ! 448: userkey[i] = 0; ! 449: } /* initkey_idea */ ! 450: ! 451: ! 452: /* Run a 64-bit block thru IDEA in ECB (Electronic Code Book) mode, ! 453: using the currently selected key schedule. ! 454: */ ! 455: void idea_ecb(word16 *inbuf, word16 *outbuf) ! 456: { ! 457: /* Assume each pair of bytes comprising a word is ordered MSB-first. */ ! 458: #ifndef HIGHFIRST /* If this is a least-significant-byte-first CPU */ ! 459: word16 x; ! 460: ! 461: /* Invert the byte order for each 16-bit word for internal use. */ ! 462: x = inbuf[0]; outbuf[0] = x >> 8 | x << 8; ! 463: x = inbuf[1]; outbuf[1] = x >> 8 | x << 8; ! 464: x = inbuf[2]; outbuf[2] = x >> 8 | x << 8; ! 465: x = inbuf[3]; outbuf[3] = x >> 8 | x << 8; ! 466: cipher_idea(outbuf, outbuf, Z); ! 467: x = outbuf[0]; outbuf[0] = x >> 8 | x << 8; ! 468: x = outbuf[1]; outbuf[1] = x >> 8 | x << 8; ! 469: x = outbuf[2]; outbuf[2] = x >> 8 | x << 8; ! 470: x = outbuf[3]; outbuf[3] = x >> 8 | x << 8; ! 471: #else /* HIGHFIRST */ ! 472: /* Byte order for internal and external representations is the same. */ ! 473: cipher_idea(inbuf, outbuf, Z); ! 474: #endif /* HIGHFIRST */ ! 475: } /* idea_ecb */ ! 476: ! 477: ! 478: /* ! 479: * initcfb - Initializes the IDEA key schedule tables via key, ! 480: * and initializes the Cipher Feedback mode IV. ! 481: * References context variables cfb_dc_idea and iv_idea. ! 482: */ ! 483: void initcfb_idea(word16 iv0[4], byte key[16], boolean decryp) ! 484: /* iv0 is copied to global iv_idea, buffer will be destroyed by ideacfb. ! 485: key is pointer to key buffer. ! 486: decryp is TRUE if decrypting, FALSE if encrypting. ! 487: */ ! 488: { ! 489: iv_idea = iv0; ! 490: cfb_dc_idea = decryp; ! 491: initkey_idea(key,FALSE); ! 492: } /* initcfb_idea */ ! 493: ! 494: ! 495: /* ! 496: * ideacfb - encipher a buffer with IDEA enciphering algorithm, ! 497: * using Cipher Feedback (CFB) mode. ! 498: * ! 499: * Assumes initcfb_idea has already been called. ! 500: * References context variables cfb_dc_idea and iv_idea. ! 501: */ ! 502: void ideacfb(byteptr buf, int count) ! 503: /* buf is input, output buffer, may be more than 1 block. ! 504: * count is byte count of buffer. May be > IDEABLOCKSIZE. ! 505: */ ! 506: { ! 507: int chunksize; /* smaller of count, IDEABLOCKSIZE */ ! 508: word16 temp[IDEABLOCKSIZE/2]; ! 509: ! 510: while ((chunksize = min(count,IDEABLOCKSIZE)) > 0) ! 511: { ! 512: idea_ecb(iv_idea,temp); /* encrypt iv_idea, making temp. */ ! 513: ! 514: if (cfb_dc_idea) /* buf is ciphertext */ ! 515: /* shift in ciphertext to IV... */ ! 516: cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE); ! 517: ! 518: /* convert buf via xor */ ! 519: xorbuf(buf,(byte *)temp,chunksize); /* buf now has enciphered output */ ! 520: ! 521: if (!cfb_dc_idea) /* buf was plaintext, is now ciphertext */ ! 522: /* shift in ciphertext to IV... */ ! 523: cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE); ! 524: ! 525: count -= chunksize; ! 526: buf += chunksize; ! 527: } ! 528: } /* ideacfb */ ! 529: ! 530: ! 531: /* ! 532: close_idea function erases all the key schedule information when ! 533: we are all done with a set of operations for a particular IDEA key ! 534: context. This is to prevent any sensitive data from being left ! 535: around in memory. ! 536: */ ! 537: void close_idea(void) /* erase current key schedule tables */ ! 538: { ! 539: short i; ! 540: for (i = 0; i < KEYLEN; i++) ! 541: Z[i] = 0; ! 542: } /* close_idea() */ ! 543: ! 544: /********************************************************************/ ! 545: ! 546: /* ! 547: * These buffers are used by init_idearand, idearand, and close_idearand. ! 548: */ ! 549: static word16 dtbuf_idea[4] = {0}; /* buffer for enciphered timestamp */ ! 550: static word16 randseed_idea[4] = {0}; /* seed for IDEA random # generator */ ! 551: static word16 randbuf_idea[4] = {0}; /* buffer for IDEA random # generator */ ! 552: static byte randbuf_idea_counter = 0; /* # of random bytes left in randbuf_idea */ ! 553: ! 554: /* ! 555: * init_idearand - initialize idearand, IDEA random number generator. ! 556: * Used for generating cryptographically strong random numbers. ! 557: * Much of the design comes from Appendix C of ANSI X9.17. ! 558: * key is pointer to IDEA key buffer. ! 559: * seed is pointer to random number seed buffer. ! 560: * tstamp is a 32-bit timestamp ! 561: */ ! 562: void init_idearand(byte key[16], byte seed[8], word32 tstamp) ! 563: { ! 564: int i; ! 565: initkey_idea(key, FALSE); /* initialize IDEA */ ! 566: ! 567: for (i=0; i<4; i++) /* capture timestamp material */ ! 568: { dtbuf_idea[i] = tstamp; /* get bottom word */ ! 569: tstamp = tstamp >> 16; /* drop bottom word */ ! 570: /* tstamp has only 4 bytes-- last 4 bytes will always be 0 */ ! 571: } ! 572: /* Start with enciphered timestamp: */ ! 573: idea_ecb(dtbuf_idea,dtbuf_idea); ! 574: ! 575: /* initialize seed material */ ! 576: for (i=0; i<8; i++) ! 577: ((byte *)randseed_idea)[i] = seed[i]; ! 578: ! 579: randbuf_idea_counter = 0; /* # of random bytes left in randbuf_idea */ ! 580: ! 581: } /* init_idearand */ ! 582: ! 583: ! 584: /* ! 585: * idearand - IDEA pseudo-random number generator ! 586: * Used for generating cryptographically strong random numbers. ! 587: * Much of the design comes from Appendix C of ANSI X9.17. ! 588: */ ! 589: byte idearand(void) ! 590: { ! 591: int i; ! 592: if (randbuf_idea_counter==0) /* if random buffer is spent...*/ ! 593: { /* Combine enciphered timestamp with seed material: */ ! 594: for (i=0; i<4; i++) ! 595: randseed_idea[i] ^= dtbuf_idea[i]; ! 596: idea_ecb(randseed_idea,randbuf_idea); /* fill new block */ ! 597: ! 598: /* Compute new seed vector: */ ! 599: for (i=0; i<4; i++) ! 600: randseed_idea[i] = randbuf_idea[i] ^ dtbuf_idea[i]; ! 601: idea_ecb(randseed_idea,randseed_idea); /* fill new seed */ ! 602: ! 603: randbuf_idea_counter = 8; /* reset counter for full buffer */ ! 604: } ! 605: /* Take a byte from randbuf_idea: */ ! 606: return(((byte *)randbuf_idea)[--randbuf_idea_counter]); ! 607: } /* idearand */ ! 608: ! 609: ! 610: void close_idearand(void) ! 611: { /* Erase random IDEA buffers and wipe out IDEA key info */ ! 612: int i; ! 613: for (i=0; i<4; i++) ! 614: { randbuf_idea[i] = 0; ! 615: randseed_idea[i] = 0; ! 616: dtbuf_idea[i] = 0; ! 617: } ! 618: close_idea(); /* erase current key schedule tables */ ! 619: } /* close_idearand */ ! 620: ! 621: /* end of idea.c */ ! 622:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.