Annotation of pgp/src/idea.c, revision 1.1

1.1     ! 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.  Last modified 8 July 92.
        !             7: 
        !             8:        Zero-based indexing added, names changed from IPES to IDEA.
        !             9:        CFB functions added.  Random number routines added.
        !            10: 
        !            11:        The IDEA(tm) block cipher is covered by a patent held by ETH and a
        !            12:        Swiss company called Ascom-Tech AG.  The Swiss patent number is
        !            13:        PCT/CH91/00117.  International patents are pending. IDEA(tm) is a
        !            14:        trademark of Ascom-Tech AG.  There is no license fee required for
        !            15:        noncommercial use.  Commercial users may obtain licensing details
        !            16:        from Dieter Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502
        !            17:        Solothurn, Switzerland, Tel +41 65 242885, Fax +41 65 235761.
        !            18: 
        !            19:        The IDEA block cipher uses a 64-bit block size, and a 128-bit key 
        !            20:        size.  It breaks the 64-bit cipher block into four 16-bit words
        !            21:        because all of the primitive inner operations are done with 16-bit 
        !            22:        arithmetic.  It likewise breaks the 128-bit cipher key into eight 
        !            23:        16-bit words.
        !            24: 
        !            25:        For further information on the IDEA cipher, see these papers:
        !            26:        1)      Xuejia Lai, "Detailed Description and a Software Implementation of 
        !            27:        the IPES Cipher", Institute for Signal and Information
        !            28:        Processing, ETH-Zentrum, Zurich, Switzerland, 1991
        !            29:        2)      Xuejia Lai, James L. Massey, Sean Murphy, "Markov Ciphers and 
        !            30:        Differential Cryptanalysis", Advances in Cryptology- EUROCRYPT'91
        !            31: 
        !            32:        This code assumes that each pair of 8-bit bytes comprising a 16-bit 
        !            33:        word in the key and in the cipher block are externally represented 
        !            34:        with the Most Significant Byte (MSB) first, regardless of the
        !            35:        internal native byte order of the target CPU.
        !            36: 
        !            37: */
        !            38: #include <stdio.h>
        !            39: #include "idea.h"
        !            40: 
        !            41: /* #define lower16(x) ((word16)((x) & mask16)) */ /* unoptimized version */
        !            42: #define lower16(x)   ((word16)(x))     /* optimized version */
        !            43: 
        !            44: #define maxim        0x10001
        !            45: #define fuyi         0x10000   /* Why did Lai pick a name like this? */
        !            46: #define mask16       ((word16) 0xffff)
        !            47: #define ROUNDS       8         /* Don't change this value, should be 8 */
        !            48: 
        !            49: static void en_key_idea(word16 userkey[8], word16 Z[6][ROUNDS+1]);
        !            50: static void de_key_idea(word16 Z[6][ROUNDS+1], word16 DK[6][ROUNDS+1]);
        !            51: static void cipher_idea(word16 inblock[4], word16 outblock[4],
        !            52:                 word16 Z[6][ROUNDS+1]);
        !            53: 
        !            54: 
        !            55: /*     Multiplication, modulo (2**16)+1 */
        !            56: static word16 mul(register word16 a, register word16 b)
        !            57: {
        !            58:        register word32 q;
        !            59:        register long int p;
        !            60:        if (a==0)
        !            61:                p = maxim-b; 
        !            62:        else 
        !            63:                if (b==0)
        !            64:                        p = maxim-a;  
        !            65:                else
        !            66:                {       q = (word32)a * (word32)b; 
        !            67:                        p = (q & mask16) - (q>>16);
        !            68:                        if (p<=0) 
        !            69:                                p = p+maxim;
        !            70:                }
        !            71:        return (lower16(p));
        !            72: }        /* mul */
        !            73: 
        !            74: 
        !            75: /*     Compute multiplicative inverse of x, modulo (2**16)+1,
        !            76:        using Euclid's GCD algorithm. */
        !            77: static word16 inv(word16 x)     
        !            78: {
        !            79:        long n1,n2,q,r,b1,b2,t;
        !            80:        if (x == 0)
        !            81:                b2 = 0;
        !            82:        else
        !            83:        {       n1 = maxim;
        !            84:                n2 = x;
        !            85:                b2 = 1;
        !            86:                b1 = 0;
        !            87:                do   
        !            88:                {       r = (n1 % n2);
        !            89:                        q = (n1-r)/n2;
        !            90:                        if (r == 0)  
        !            91:                        {       if (b2 < 0)
        !            92:                                        b2 = maxim+b2;
        !            93:                        }
        !            94:                        else
        !            95:                        {       n1 = n2; 
        !            96:                                n2 = r; 
        !            97:                                t = b2;
        !            98:                                b2 = b1 - q*b2; 
        !            99:                                b1 = t;
        !           100:                        }
        !           101:                } while (r != 0);
        !           102:        } 
        !           103: #ifdef IDEA_DEBUG
        !           104:        if ( mul(x, (word16) b2) != 1) /* check answer */
        !           105:                printf("\n\07Error! inv(%u) = %u ?\n", x, (word16) b2 );
        !           106: #endif
        !           107:        return ((word16) b2);
        !           108: }        /* inv */
        !           109: 
        !           110: 
        !           111: /*     Compute IDEA encryption subkeys Z */
        !           112: static void en_key_idea(word16 userkey[8], word16 Z[6][ROUNDS+1])
        !           113: {
        !           114:        word16 S[54];
        !           115:        int i,j,r;
        !           116:        /*   shifts   */
        !           117:        for (i = 0; i<8; i++)
        !           118:                S[i] = userkey[i];
        !           119:        for (i = 8; i<54; i++)
        !           120:        {       if ((i+2)%8 == 0)  /* for S[14],S[22],...  */  
        !           121:                        S[i] = lower16((S[i-7] << 9) ^ (S[i-14] >> 7)); 
        !           122:                else
        !           123:                        if ((i+1)%8 == 0)  /* for S[15],S[23],...   */
        !           124:                        S[i] = lower16((S[i-15] << 9) ^ (S[i-14] >> 7)); 
        !           125:                else
        !           126:                        S[i] = lower16((S[i-7] << 9) ^ (S[i-6] >> 7));
        !           127:        }
        !           128:        /* get subkeys */
        !           129:        for (r=0; r<ROUNDS+1; r++)
        !           130:                for (j=0; j<6; j++)
        !           131:                        Z[j][r] = S[6*r + j];
        !           132: 
        !           133:        /* clear sensitive key data from memory... */
        !           134:        for (i=0; i<54; i++) S[i] = 0;
        !           135: 
        !           136: }        /* en_key_idea */
        !           137: 
        !           138: 
        !           139: /*     Compute IDEA decryption subkeys DK from encryption subkeys Z */
        !           140: static void de_key_idea(word16 Z[6][ROUNDS+1], word16 DK[6][ROUNDS+1])
        !           141: {  
        !           142:        int j;
        !           143:        for (j=0; j<ROUNDS+1; j++)
        !           144:        {       DK[0][ROUNDS-j] = inv(Z[0][j]);
        !           145:                DK[3][ROUNDS-j] = inv(Z[3][j]);
        !           146:                if (j==0 || j==ROUNDS)
        !           147:                {       DK[1][ROUNDS-j] = lower16(fuyi-Z[1][j]);
        !           148:                        DK[2][ROUNDS-j] = lower16(fuyi-Z[2][j]);
        !           149:                }
        !           150:                else
        !           151:                {       DK[1][ROUNDS-j] = lower16(fuyi-Z[2][j]);
        !           152:                        DK[2][ROUNDS-j] = lower16(fuyi-Z[1][j]);
        !           153:                }
        !           154:        }  
        !           155:        for (j=0; j<ROUNDS; j++)
        !           156:        {       DK[4][ROUNDS-1-j] = Z[4][j];
        !           157:                DK[5][ROUNDS-1-j] = Z[5][j];
        !           158:        }
        !           159: }        /* de_key_idea */
        !           160: 
        !           161: 
        !           162: /*     IDEA encryption/decryption algorithm */
        !           163: static void cipher_idea(word16 inblock[4], word16 outblock[4],
        !           164:                 register word16 Z[6][ROUNDS+1])
        !           165: {      /* Note that inblock and outblock can be the same buffer */ 
        !           166:        int r;
        !           167:        register word16 x1, x2, x3, x4, kk, t1, t2, a;
        !           168:        x1=inblock[0];
        !           169:        x2=inblock[1];
        !           170:        x3=inblock[2];
        !           171:        x4=inblock[3];
        !           172:        for (r=0; r<ROUNDS; r++)
        !           173:        {       x1 = mul(x1, Z[0][r]);
        !           174:                x4 = mul(x4, Z[3][r]);
        !           175:                x2 = lower16(x2 + Z[1][r]);
        !           176:                x3 = lower16(x3 + Z[2][r]);
        !           177:                kk = mul(Z[4][r], (x1^x3));      
        !           178:                t1 = mul(Z[5][r], lower16(kk + (x2^x4)) );
        !           179:                t2 = lower16(kk + t1);
        !           180:                x1 = x1^t1;
        !           181:                x4 = x4^t2; 
        !           182:                a  = x2^t2;
        !           183:                x2 = x3^t1;
        !           184:                x3 = a;
        !           185:        }
        !           186:        outblock[0] = mul(x1, Z[0][ROUNDS]);
        !           187:        outblock[3] = mul(x4, Z[3][ROUNDS]);
        !           188:        outblock[1] = lower16(x3 + Z[1][ROUNDS]);
        !           189:        outblock[2] = lower16(x2 + Z[2][ROUNDS]);
        !           190: }        /* cipher_idea */
        !           191: 
        !           192: 
        !           193: /*-------------------------------------------------------------*/
        !           194: 
        !           195: #ifdef TEST
        !           196: 
        !           197: void main(void)
        !           198: {      /* Test driver for IDEA cipher */ 
        !           199:        int i, j, k; 
        !           200:        word16 Z[6][ROUNDS+1], DK[6][ROUNDS+1], XX[4], TT[4], YY[4];     
        !           201:        word16 userkey[8];
        !           202: 
        !           203:        /* Make a sample user key for testing... */
        !           204:        for(i=0; i<8; i++)
        !           205:                userkey[i] = i+1;
        !           206: 
        !           207:        /* Compute encryption subkeys from user key... */
        !           208:        en_key_idea(userkey,Z);
        !           209:        printf("\nEncryption key subblocks: ");
        !           210:        for(j=0; j<ROUNDS+1; j++) 
        !           211:        {       printf("\nround %d:   ", j+1);
        !           212:                if (j==ROUNDS)
        !           213:                        for(i=0; i<4; i++)
        !           214:                                printf(" %6u", Z[i][j]);
        !           215:                else
        !           216:                        for(i=0; i<6; i++)
        !           217:                                printf(" %6u", Z[i][j]);
        !           218:        }
        !           219: 
        !           220:        /* Compute decryption subkeys from encryption subkeys... */
        !           221:        de_key_idea(Z,DK);
        !           222:        printf("\nDecryption key subblocks: ");
        !           223:        for(j=0; j<ROUNDS+1; j++) 
        !           224:        {       printf("\nround %d:   ", j+1);
        !           225:                if (j==ROUNDS)
        !           226:                        for(i=0; i<4; i++)
        !           227:                                printf(" %6u", DK[i][j]);
        !           228:                else
        !           229:                        for(i=0; i<6; i++)
        !           230:                                printf(" %6u", DK[i][j]);
        !           231:        }
        !           232: 
        !           233:        /* Make a sample plaintext pattern for testing... */
        !           234:        for (k=0; k<4; k++)
        !           235:                XX[k] = k;
        !           236: 
        !           237:        cipher_idea(XX,YY,Z);       /* encrypt plaintext XX, making YY */ 
        !           238: 
        !           239:        cipher_idea(YY,TT,DK);      /* decrypt ciphertext YY, making TT */ 
        !           240: 
        !           241:        printf("\nX %6u   %6u  %6u  %6u \n",    
        !           242:          XX[0], XX[1],  XX[2], XX[3]);
        !           243:        printf("Y %6u   %6u  %6u  %6u \n",
        !           244:          YY[0], YY[1],  YY[2], YY[3]);
        !           245:        printf("T %6u   %6u  %6u  %6u \n",
        !           246:          TT[0], TT[1],  TT[2], TT[3]);
        !           247: 
        !           248:        /* Now decrypted TT should be same as original XX */
        !           249:        for (k=0; k<4; k++)
        !           250:                if (TT[k] != XX[k])
        !           251:                {       printf("\n\07Error!  Noninvertable encryption.\n");
        !           252:                        exit(-1);       /* error exit */ 
        !           253:                }
        !           254:        printf("\nNormal exit.\n");
        !           255:        exit(0);        /* normal exit */ 
        !           256: }        /* main */
        !           257: 
        !           258: 
        !           259: #endif         /* TEST */
        !           260: 
        !           261: 
        !           262: /*************************************************************************/
        !           263: 
        !           264: 
        !           265: #define byteglue(lo,hi) ((((word16) hi) << 8) + (word16) lo)
        !           266: 
        !           267: /*
        !           268: **     xorbuf - change buffer via xor with random mask block
        !           269: **     Used for Cipher Feedback (CFB) or Cipher Block Chaining
        !           270: **     (CBC) modes of encryption.
        !           271: **     Can be applied for any block encryption algorithm,
        !           272: **     with any block size, such as the DES or the IDEA cipher.
        !           273: */
        !           274: static void xorbuf(register byteptr buf, register byteptr mask, register int count)
        !           275: /*     count must be > 0 */
        !           276: {      if (count) 
        !           277:                do
        !           278:                        *buf++ ^= *mask++;
        !           279:                while (--count);
        !           280: }      /* xorbuf */
        !           281: 
        !           282: 
        !           283: /*
        !           284: **     cfbshift - shift bytes into IV for CFB input
        !           285: **     Used only for Cipher Feedback (CFB) mode of encryption.
        !           286: **     Can be applied for any block encryption algorithm with any 
        !           287: **     block size, such as the DES or the IDEA cipher.
        !           288: */
        !           289: static void cfbshift(register byteptr iv, register byteptr buf, 
        !           290:                register int count, int blocksize)
        !           291: /*     iv is the initialization vector.
        !           292:        buf is the buffer pointer.
        !           293:        count is the number of bytes to shift in...must be > 0.
        !           294:        blocksize is 8 bytes for DES or IDEA ciphers.
        !           295: */
        !           296: {      int retained;
        !           297:        if (count)
        !           298:        {       retained = blocksize-count;     /* number bytes in iv to retain */
        !           299:                /* left-shift retained bytes of IV over by count bytes to make room */
        !           300:                while (retained--)
        !           301:                {       *iv = *(iv+count);
        !           302:                        iv++;
        !           303:                }
        !           304:                /* now copy count bytes from buf to shifted tail of IV */
        !           305:                do      *iv++ = *buf++;
        !           306:                while (--count);
        !           307:        }
        !           308: }      /* cfbshift */
        !           309: 
        !           310: 
        !           311: 
        !           312: /* Key schedules for IDEA encryption and decryption */
        !           313: static word16 Z[6][ROUNDS+1], DK[6][ROUNDS+1];
        !           314: static word16 (*keyschedule)[ROUNDS+1];        /* pointer to key schedule Z or DK */
        !           315: static word16 *iv_idea;                /* pointer to IV for CFB or CBC */
        !           316: static boolean cfb_dc_idea; /* TRUE iff CFB decrypting */
        !           317: 
        !           318: 
        !           319: /* initkey_idea initializes IDEA for ECB mode operations */
        !           320: void initkey_idea(byte key[16], boolean decryp)
        !           321: {
        !           322:        word16 userkey[8];      /* IDEA key is 16 bytes long */
        !           323:        int i;
        !           324:        /* Assume each pair of bytes comprising a word is ordered MSB-first. */
        !           325:        for (i=0; i<8; i++)
        !           326:        {       userkey[i] = byteglue(*(key+1),*key);
        !           327:                key++; key++;
        !           328:        }
        !           329:        en_key_idea(userkey,Z);
        !           330:        keyschedule = Z;
        !           331:        if (decryp)
        !           332:        {       int r,j;
        !           333:                de_key_idea(Z,DK);      /* compute inverse key schedule DK */
        !           334:                keyschedule = DK;
        !           335:                /* Don't need Z anymore.  Erase dangerous traces... */
        !           336:                for (r=0; r<ROUNDS+1; r++)
        !           337:                        for (j=0; j<6; j++)
        !           338:                                Z[j][r] = 0;
        !           339:        }
        !           340:        for (i=0; i<8; i++)     /* Erase dangerous traces */
        !           341:                userkey[i] = 0;
        !           342: }      /* initkey_idea */
        !           343: 
        !           344: 
        !           345: /*     Run a 64-bit block thru IDEA in ECB (Electronic Code Book) mode,
        !           346:        using the currently selected key schedule.
        !           347: */
        !           348: void idea_ecb(word16 *inbuf, word16 *outbuf)
        !           349: {
        !           350:        /* Assume each pair of bytes comprising a word is ordered MSB-first. */
        !           351: #ifndef HIGHFIRST      /* If this is a least-significant-byte-first CPU */
        !           352:        /* Invert the byte order for each 16-bit word for internal use. */
        !           353:        union {
        !           354:                word16 w[4];
        !           355:                byte b[8];
        !           356:        } inbuf2, outbuf2;
        !           357:        register byte *p;
        !           358:        p = (byte *) inbuf;
        !           359:        inbuf2.b[1] = *p++;
        !           360:        inbuf2.b[0] = *p++;
        !           361:        inbuf2.b[3] = *p++;
        !           362:        inbuf2.b[2] = *p++;
        !           363:        inbuf2.b[5] = *p++;
        !           364:        inbuf2.b[4] = *p++;
        !           365:        inbuf2.b[7] = *p++;
        !           366:        inbuf2.b[6] = *p++;
        !           367:        cipher_idea(inbuf2.w,outbuf2.w,keyschedule);
        !           368:        /* Now invert the byte order for each 16-bit word for external use. */
        !           369:        p = (byte *) outbuf;
        !           370:        *p++ = outbuf2.b[1];
        !           371:        *p++ = outbuf2.b[0];
        !           372:        *p++ = outbuf2.b[3];
        !           373:        *p++ = outbuf2.b[2];
        !           374:        *p++ = outbuf2.b[5];
        !           375:        *p++ = outbuf2.b[4];
        !           376:        *p++ = outbuf2.b[7];
        !           377:        *p++ = outbuf2.b[6];
        !           378: #else  /* HIGHFIRST */
        !           379:        /* Byte order for internal and external representations is the same. */
        !           380:        cipher_idea(inbuf,outbuf,keyschedule);
        !           381: #endif /* HIGHFIRST */
        !           382: }      /* idea_ecb */
        !           383: 
        !           384: 
        !           385: /*
        !           386: **     initcfb - Initializes the IDEA key schedule tables via key,
        !           387: **     and initializes the Cipher Feedback mode IV.
        !           388: **     References context variables cfb_dc_idea and iv_idea.
        !           389: */
        !           390: void initcfb_idea(word16 iv0[4], byte key[16], boolean decryp)
        !           391: /*     iv0 is copied to global iv_idea, buffer will be destroyed by ideacfb.
        !           392:        key is pointer to key buffer.
        !           393:        decryp is TRUE if decrypting, FALSE if encrypting.
        !           394: */
        !           395: {      iv_idea = iv0;
        !           396:        cfb_dc_idea = decryp;
        !           397:        initkey_idea(key,FALSE);
        !           398: } /* initcfb_idea */
        !           399: 
        !           400: 
        !           401: /*
        !           402: **     ideacfb - encipher a buffer with IDEA enciphering algorithm,
        !           403: **             using Cipher Feedback (CFB) mode.
        !           404: **
        !           405: **     Assumes initcfb_idea has already been called.
        !           406: **     References context variables cfb_dc_idea and iv_idea.
        !           407: */
        !           408: void ideacfb(byteptr buf, int count)
        !           409: /*     buf is input, output buffer, may be more than 1 block.
        !           410:        count is byte count of buffer.  May be > IDEABLOCKSIZE.
        !           411: */
        !           412: {      int chunksize;  /* smaller of count, IDEABLOCKSIZE */
        !           413:        word16 temp[IDEABLOCKSIZE/2];
        !           414: 
        !           415:        while ((chunksize = min(count,IDEABLOCKSIZE)) > 0)
        !           416:        {
        !           417:                idea_ecb(iv_idea,temp);  /* encrypt iv_idea, making temp. */ 
        !           418: 
        !           419:                if (cfb_dc_idea)        /* buf is ciphertext */
        !           420:                        /* shift in ciphertext to IV... */
        !           421:                        cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE);
        !           422: 
        !           423:                /* convert buf via xor */
        !           424:                xorbuf(buf,(byte *)temp,chunksize); /* buf now has enciphered output */
        !           425: 
        !           426:                if (!cfb_dc_idea)       /* buf was plaintext, is now ciphertext */
        !           427:                        /* shift in ciphertext to IV... */
        !           428:                        cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE);
        !           429: 
        !           430:                count -= chunksize;
        !           431:                buf += chunksize;
        !           432:        }
        !           433: } /* ideacfb */
        !           434: 
        !           435: 
        !           436: /*
        !           437:        close_idea function erases all the key schedule information when 
        !           438:        we are all done with a set of operations for a particular IDEA key 
        !           439:        context.  This is to prevent any sensitive data from being left 
        !           440:        around in memory.
        !           441: */
        !           442: void close_idea(void)  /* erase current key schedule tables */
        !           443: {      short r,j;
        !           444:        for (r=0; r<ROUNDS+1; r++)
        !           445:                for (j=0; j<6; j++)
        !           446:                        keyschedule[j][r] = 0;
        !           447: }      /* close_idea() */
        !           448: 
        !           449: /********************************************************************/
        !           450: 
        !           451: /*
        !           452: **     These buffers are used by init_idearand, idearand, and close_idearand.
        !           453: */
        !           454: static word16 dtbuf_idea[4] = {0}; /* buffer for enciphered timestamp */
        !           455: static word16 randseed_idea[4] = {0}; /* seed for IDEA random # generator */
        !           456: static word16 randbuf_idea[4] = {0}; /* buffer for IDEA random # generator */
        !           457: static byte randbuf_idea_counter = 0;  /* # of random bytes left in randbuf_idea */
        !           458: 
        !           459: /*
        !           460: **     init_idearand - initialize idearand, IDEA random number generator.
        !           461: **             Used for generating cryptographically strong random numbers.
        !           462: **             Much of the design comes from Appendix C of ANSI X9.17.
        !           463: **             key is pointer to IDEA key buffer.
        !           464: **             seed is pointer to random number seed buffer.
        !           465: **             tstamp is a 32-bit timestamp
        !           466: */
        !           467: void init_idearand(byte key[16], byte seed[8], word32 tstamp)
        !           468: {      int i;
        !           469:        initkey_idea(key, FALSE);       /* initialize IDEA */
        !           470: 
        !           471:        for (i=0; i<4; i++)     /* capture timestamp material */
        !           472:        {       dtbuf_idea[i] = tstamp; /* get bottom byte */
        !           473:                tstamp = tstamp >> 16;  /* drop bottom byte */
        !           474:                /* tstamp has only 4 bytes-- last 4 bytes will always be 0 */
        !           475:        }
        !           476:        /* Start with enciphered timestamp: */
        !           477:        idea_ecb(dtbuf_idea,dtbuf_idea);
        !           478: 
        !           479:        /* initialize seed material */
        !           480:        for (i=0; i<8; i++)
        !           481:                ((byte *)randseed_idea)[i] = seed[i];
        !           482: 
        !           483:        randbuf_idea_counter = 0;       /* # of random bytes left in randbuf_idea */
        !           484: 
        !           485: } /* init_idearand */
        !           486: 
        !           487: 
        !           488: /*
        !           489: **     idearand - IDEA pseudo-random number generator
        !           490: **             Used for generating cryptographically strong random numbers.
        !           491: **             Much of the design comes from Appendix C of ANSI X9.17.
        !           492: */
        !           493: byte idearand(void)
        !           494: {      int i;
        !           495:        if (randbuf_idea_counter==0)    /* if random buffer is spent...*/
        !           496:        {
        !           497:                /* Combine enciphered timestamp with seed material: */
        !           498:                for (i=0; i<4; i++)
        !           499:                        randseed_idea[i] ^= dtbuf_idea[i];
        !           500:                idea_ecb(randseed_idea,randbuf_idea); /* fill new block */
        !           501: 
        !           502:                /* Compute new seed vector: */
        !           503:                for (i=0; i<4; i++)
        !           504:                        randseed_idea[i] = randbuf_idea[i] ^ dtbuf_idea[i];
        !           505:                idea_ecb(randseed_idea,randseed_idea); /* fill new seed */
        !           506: 
        !           507:                randbuf_idea_counter = 8;       /* reset counter for full buffer */
        !           508:        }
        !           509:        /* Take a byte from randbuf_idea: */
        !           510:        return(((byte *)randbuf_idea)[--randbuf_idea_counter]);
        !           511: } /* idearand */
        !           512: 
        !           513: 
        !           514: void close_idearand(void)
        !           515: {      /* Erase random IDEA buffers and wipe out IDEA key info */
        !           516:        int i;
        !           517:        for (i=0; i<4; i++)
        !           518:        {       randbuf_idea[i] = 0;
        !           519:                randseed_idea[i] = 0;
        !           520:                dtbuf_idea[i] = 0;
        !           521:        }
        !           522:        close_idea();   /* erase current key schedule tables */
        !           523: }      /* close_idearand */
        !           524: 
        !           525: /* end of idea.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.