thig_twofish2.c File Reference


Detailed Description

C API calls for TWOFISH AES submission.

Note:
Code taken from http://www.schneier.com/twofish-download.html
TWOFISH.C -- C API calls for TWOFISH AES submission

Submitters: Bruce Schneier, Counterpane Systems Doug Whiting, Hi/fn John Kelsey, Counterpane Systems Chris Hall, Counterpane Systems David Wagner, UC Berkeley

Code Author: Doug Whiting, Hi/fn

Version 1.00 April 1998

Copyright 1998, Hi/fn and Counterpane Systems. All rights reserved.

Notes: Pedagogical version (non-optimized) Tab size is set to 4 characters in this file

Definition in file thig_twofish2.c.

#include "thig_aes.h"
#include "thig_table.h"
#include "thig_debug.h"

Go to the source code of this file.

Defines

#define VALIDATE_PARMS   1
 nonzero --> check all parameters
#define FEISTEL   0
 nonzero --> use Feistel version (slow)
#define P0_USED   0x01
#define P1_USED   0x02
#define B0_USED   0x04
#define B1_USED   0x08
#define B2_USED   0x10
#define B3_USED   0x20
#define ALL_USED   0x3F

Functions

int TableOp (int op)
int ParseHexDword (int bits, CONST char *srcTxt, DWORD *d, char *dstTxt)
DWORD f32 (DWORD x, CONST DWORD *k32, int keyLen)
DWORD RS_MDS_Encode (DWORD k0, DWORD k1)
int reKey (keyInstance *key)
 do key schedule using modified key.keyDwords
int makeKey (keyInstance *key, BYTE direction, int keyLen, CONST char *keyMaterial)
int cipherInit (cipherInstance *cipher, BYTE mode, CONST char *IV)
int blockEncrypt (cipherInstance *cipher, keyInstance *key, CONST BYTE *input, int inputLen, BYTE *outBuffer)
int blockDecrypt (cipherInstance *cipher, keyInstance *key, CONST BYTE *input, int inputLen, BYTE *outBuffer)

Variables

int tabEnable = 0
 are we gathering stats?
BYTE tabUsed [256]
 one bit per table
CONST char * moduleDescription = "Pedagogical C code"
CONST char * modeString = ""
int numRounds [4] = {0,ROUNDS_128,ROUNDS_192,ROUNDS_256}
 number of rounds for various key sizes: 128, 192, 256


Define Documentation

#define VALIDATE_PARMS   1

nonzero --> check all parameters

Definition at line 39 of file thig_twofish2.c.

#define FEISTEL   0

nonzero --> use Feistel version (slow)

Definition at line 40 of file thig_twofish2.c.

Referenced by blockEncrypt().

#define P0_USED   0x01

Definition at line 52 of file thig_twofish2.c.

Referenced by f32().

#define P1_USED   0x02

Definition at line 53 of file thig_twofish2.c.

Referenced by f32().

#define B0_USED   0x04

Definition at line 54 of file thig_twofish2.c.

Referenced by f32().

#define B1_USED   0x08

Definition at line 55 of file thig_twofish2.c.

Referenced by f32().

#define B2_USED   0x10

Definition at line 56 of file thig_twofish2.c.

Referenced by f32().

#define B3_USED   0x20

Definition at line 57 of file thig_twofish2.c.

Referenced by f32().

#define ALL_USED   0x3F

Definition at line 58 of file thig_twofish2.c.

Referenced by TableOp().


Function Documentation

int TableOp ( int  op  ) 

Definition at line 83 of file thig_twofish2.c.

References ALL_USED, FALSE, TAB_DISABLE, TAB_ENABLE, TAB_MIN_QUERY, TAB_QUERY, TAB_RESET, tabEnable, tabUsed, and TRUE.

00084     {
00085     static int queryCnt=0;
00086     int i;
00087     switch (op)
00088         {
00089         case TAB_DISABLE:
00090             tabEnable=0;
00091             break;
00092         case TAB_ENABLE:
00093             tabEnable=1;
00094             break;
00095         case TAB_RESET:
00096             queryCnt=0;
00097             for (i=0;i<256;i++)
00098                 tabUsed[i]=0;
00099             break;
00100         case TAB_QUERY:
00101             queryCnt++;
00102             for (i=0;i<256;i++)
00103                 if (tabUsed[i] != ALL_USED)
00104                     return FALSE;
00105             if (queryCnt < TAB_MIN_QUERY)   /* do a certain minimum number */
00106                 return FALSE;
00107             break;
00108         }
00109     return TRUE;
00110     }

int ParseHexDword ( int  bits,
CONST char *  srcTxt,
DWORD d,
char *  dstTxt 
)

Definition at line 132 of file thig_twofish2.c.

References ADDR_XOR, BAD_ALIGN32, BAD_ENDIAN, and BAD_KEY_MAT.

Referenced by cipherInit(), and makeKey().

00133     {
00134     int i;
00135     DWORD b;
00136     char c;
00137 //#if ALIGN32
00138     //char alignDummy[3];   /* keep dword alignment */
00139 //#endif
00140 
00141     union   /* make sure LittleEndian is defined correctly */
00142         {
00143         BYTE  b[4];
00144         DWORD d[1];
00145         } v;
00146     v.d[0]=1;
00147     if (v.b[0 ^ ADDR_XOR] != 1) /* sanity check on compile-time switch */
00148         return BAD_ENDIAN;
00149 
00150 #if VALIDATE_PARMS
00151   #if ALIGN32
00152     if (((int)d) & 3)
00153         return BAD_ALIGN32;
00154   #endif
00155 #endif
00156 
00157     for (i=0;i*32<bits;i++)
00158         d[i]=0;                 /* first, zero the field */
00159 
00160     for (i=0;i*4<bits;i++)      /* parse one nibble at a time */
00161         {                       /* case out the hexadecimal characters */
00162         c=srcTxt[i];
00163         if (dstTxt) dstTxt[i]=c;
00164         if ((c >= '0') && (c <= '9'))
00165             b=c-'0';
00166         else if ((c >= 'a') && (c <= 'f'))
00167             b=c-'a'+10;
00168         else if ((c >= 'A') && (c <= 'F'))
00169             b=c-'A'+10;
00170         else
00171             return BAD_KEY_MAT; /* invalid hex character */
00172         /* works for big and little endian! */
00173         d[i/8] |= b << (4*((i^1)&7));       
00174         }
00175 
00176     return 0;                   /* no error */
00177     }

DWORD f32 ( DWORD  x,
CONST DWORD k32,
int  keyLen 
)

Definition at line 208 of file thig_twofish2.c.

References b0, B0_USED, b1, B1_USED, b2, B2_USED, b3, B3_USED, Bswap, M00, M01, M02, M03, M10, M11, M12, M13, M20, M21, M22, M23, M30, M31, M32, M33, P0_USED, P1_USED, p8, P_00, P_10, P_20, P_30, tabEnable, and tabUsed.

Referenced by blockDecrypt(), blockEncrypt(), and reKey().

00209     {
00210     BYTE  b[4];
00211     
00212     /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */
00213     /* Note that each byte goes through a different combination of S-boxes.*/
00214 
00215     *((DWORD *)b) = Bswap(x);   /* make b[0] = LSB, b[3] = MSB */
00216     switch (((keyLen + 63)/64) & 3)
00217         {
00218         case 0:     /* 256 bits of key */
00219             b[0] = p8(04)[b[0]] ^ b0(k32[3]);
00220             b[1] = p8(14)[b[1]] ^ b1(k32[3]);
00221             b[2] = p8(24)[b[2]] ^ b2(k32[3]);
00222             b[3] = p8(34)[b[3]] ^ b3(k32[3]);
00223             /* fall thru, having pre-processed b[0]..b[3] with k32[3] */
00224         case 3:     /* 192 bits of key */
00225             b[0] = p8(03)[b[0]] ^ b0(k32[2]);
00226             b[1] = p8(13)[b[1]] ^ b1(k32[2]);
00227             b[2] = p8(23)[b[2]] ^ b2(k32[2]);
00228             b[3] = p8(33)[b[3]] ^ b3(k32[2]);
00229             /* fall thru, having pre-processed b[0]..b[3] with k32[2] */
00230         case 2:     /* 128 bits of key */
00231             b[0] = p8(00)[p8(01)[p8(02)[b[0]] ^ b0(k32[1])] ^ b0(k32[0])];
00232             b[1] = p8(10)[p8(11)[p8(12)[b[1]] ^ b1(k32[1])] ^ b1(k32[0])];
00233             b[2] = p8(20)[p8(21)[p8(22)[b[2]] ^ b2(k32[1])] ^ b2(k32[0])];
00234             b[3] = p8(30)[p8(31)[p8(32)[b[3]] ^ b3(k32[1])] ^ b3(k32[0])];
00235         }
00236 
00237     if (tabEnable)
00238         {   /* we could give a "tighter" bound, but this works acceptably well */
00239         tabUsed[b0(x)] |= (P_00 == 0) ? P0_USED : P1_USED;
00240         tabUsed[b1(x)] |= (P_10 == 0) ? P0_USED : P1_USED;
00241         tabUsed[b2(x)] |= (P_20 == 0) ? P0_USED : P1_USED;
00242         tabUsed[b3(x)] |= (P_30 == 0) ? P0_USED : P1_USED;
00243 
00244         tabUsed[b[0] ] |= B0_USED;
00245         tabUsed[b[1] ] |= B1_USED;
00246         tabUsed[b[2] ] |= B2_USED;
00247         tabUsed[b[3] ] |= B3_USED;
00248         }
00249 
00250     /* Now perform the MDS matrix multiply inline. */
00251     return  ((M00(b[0]) ^ M01(b[1]) ^ M02(b[2]) ^ M03(b[3]))      ) ^
00252             ((M10(b[0]) ^ M11(b[1]) ^ M12(b[2]) ^ M13(b[3])) <<  8) ^
00253             ((M20(b[0]) ^ M21(b[1]) ^ M22(b[2]) ^ M23(b[3])) << 16) ^
00254             ((M30(b[0]) ^ M31(b[1]) ^ M32(b[2]) ^ M33(b[3])) << 24) ;
00255     }

DWORD RS_MDS_Encode ( DWORD  k0,
DWORD  k1 
)

Definition at line 276 of file thig_twofish2.c.

References RS_rem.

Referenced by reKey().

00277     {
00278     int i,j;
00279     DWORD r;
00280 
00281     for (i=r=0;i<2;i++)
00282         {
00283         r ^= (i) ? k0 : k1;         /* merge in 32 more key bits */
00284         for (j=0;j<4;j++)           /* shift one byte at a time */
00285             RS_rem(r);              
00286         }
00287     return r;
00288     }

int reKey ( keyInstance key  ) 

do key schedule using modified key.keyDwords

Definition at line 303 of file thig_twofish2.c.

References BAD_ALIGN32, BAD_KEY_INSTANCE, DebugDumpKey, f32(), keyInstance::keyLen, MAX_KEY_BITS, MIN_KEY_BITS, keyInstance::numRounds, ROL, ROUND_SUBKEYS, RS_MDS_Encode(), SK_BUMP, SK_ROTL, SK_STEP, TOTAL_SUBKEYS, and TRUE.

Referenced by makeKey(), and thig_key_and_cipher_init().

00304     {
00305     int     i,k64Cnt;
00306     int     keyLen    = key->keyLen;
00307     int     subkeyCnt = ROUND_SUBKEYS + 2*key->numRounds;
00308     DWORD   A,B;
00309     DWORD   k32e[MAX_KEY_BITS/64],k32o[MAX_KEY_BITS/64]; /* even/odd key dwords */
00310 
00311 #if VALIDATE_PARMS
00312   #if ALIGN32
00313     if ((((int)key) & 3) || (((int)key->key32) & 3))
00314         return BAD_ALIGN32;
00315   #endif
00316     if ((key->keyLen % 64) || (key->keyLen < MIN_KEY_BITS))
00317         return BAD_KEY_INSTANCE;
00318     if (subkeyCnt > TOTAL_SUBKEYS)
00319         return BAD_KEY_INSTANCE;
00320 #endif
00321 
00322     k64Cnt=(keyLen+63)/64;      /* round up to next multiple of 64 bits */
00323     for (i=0;i<k64Cnt;i++)
00324         {                       /* split into even/odd key dwords */
00325         k32e[i]=key->key32[2*i  ];
00326         k32o[i]=key->key32[2*i+1];
00327         /* compute S-box keys using (12,8) Reed-Solomon code over GF(256) */
00328         key->sboxKeys[k64Cnt-1-i]=RS_MDS_Encode(k32e[i],k32o[i]); /* reverse order */
00329         }
00330 
00331     for (i=0;i<subkeyCnt/2;i++)                 /* compute round subkeys for PHT */
00332         {
00333         A = f32(i*SK_STEP        ,k32e,keyLen); /* A uses even key dwords */
00334         B = f32(i*SK_STEP+SK_BUMP,k32o,keyLen); /* B uses odd  key dwords */
00335         B = ROL(B,8);
00336         key->subKeys[2*i  ] = A+  B;            /* combine with a PHT */
00337         key->subKeys[2*i+1] = ROL(A+2*B,SK_ROTL);
00338         }
00339 
00340     DebugDumpKey(key);
00341 
00342     return TRUE;
00343     }

int makeKey ( keyInstance key,
BYTE  direction,
int  keyLen,
CONST char *  keyMaterial 
)

Definition at line 361 of file thig_twofish2.c.

References BAD_ALIGN32, BAD_KEY_DIR, BAD_KEY_INSTANCE, BAD_KEY_MAT, DIR_DECRYPT, DIR_ENCRYPT, if, keyInstance::keySig, MAX_KEY_BITS, MAX_KEY_SIZE, NULL, numRounds, ParseHexDword(), reKey(), TRUE, and VALID_SIG.

00362     {
00363     int i;
00364 
00365 #if VALIDATE_PARMS              /* first, sanity check on parameters */
00366     if (key == NULL)            
00367         return BAD_KEY_INSTANCE;/* must have a keyInstance to initialize */
00368     if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT))
00369         return BAD_KEY_DIR;     /* must have valid direction */
00370     if ((keyLen > MAX_KEY_BITS) || (keyLen < 8))    
00371         return BAD_KEY_MAT;     /* length must be valid */
00372     key->keySig = VALID_SIG;    /* show that we are initialized */
00373   #if ALIGN32
00374     if ((((int)key) & 3) || (((int)key->key32) & 3))
00375         return BAD_ALIGN32;
00376   #endif
00377 #endif
00378 
00379     key->direction  = direction;    /* set our cipher direction */
00380     key->keyLen     = (keyLen+63) & ~63;        /* round up to multiple of 64 */
00381     key->numRounds  = numRounds[(keyLen-1)/64];
00382     for (i=0;i<MAX_KEY_BITS/32;i++) /* zero unused bits */
00383            key->key32[i]=0;
00384     key->keyMaterial[MAX_KEY_SIZE]=0;   /* terminate ASCII string */
00385 
00386     if ((keyMaterial == NULL) || (keyMaterial[0]==0))
00387         return TRUE;            /* allow a "dummy" call */
00388         
00389     if (ParseHexDword(keyLen,keyMaterial,key->key32,key->keyMaterial))
00390         return BAD_KEY_MAT; 
00391 
00392     return reKey(key);          /* generate round subkeys */
00393     }

int cipherInit ( cipherInstance cipher,
BYTE  mode,
CONST char *  IV 
)

Definition at line 407 of file thig_twofish2.c.

References BAD_ALIGN32, BAD_CIPHER_MODE, BAD_IV_MAT, BAD_PARAMS, BLOCK_SIZE, Bswap, cipherInstance::cipherSig, MODE_CBC, MODE_CFB1, MODE_ECB, NULL, ParseHexDword(), TRUE, and VALID_SIG.

00408     {
00409     int i;
00410 #if VALIDATE_PARMS              /* first, sanity check on parameters */
00411     if (cipher == NULL)         
00412         return BAD_PARAMS;      /* must have a cipherInstance to initialize */
00413     if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1))
00414         return BAD_CIPHER_MODE; /* must have valid cipher mode */
00415     cipher->cipherSig   =   VALID_SIG;
00416   #if ALIGN32
00417     if ((((int)cipher) & 3) || (((int)cipher->IV) & 3) || (((int)cipher->iv32) & 3))
00418         return BAD_ALIGN32;
00419   #endif
00420 #endif
00421 
00422     if ((mode != MODE_ECB) && (IV)) /* parse the IV */
00423         {
00424         if (ParseHexDword(BLOCK_SIZE,IV,cipher->iv32,NULL))
00425             return BAD_IV_MAT;
00426         for (i=0;i<BLOCK_SIZE/32;i++)   /* make byte-oriented copy for CFB1 */
00427             ((DWORD *)cipher->IV)[i] = Bswap(cipher->iv32[i]);
00428         }
00429 
00430     cipher->mode        =   mode;
00431 
00432     return TRUE;
00433     }

int blockEncrypt ( cipherInstance cipher,
keyInstance key,
CONST BYTE input,
int  inputLen,
BYTE outBuffer 
)

Definition at line 453 of file thig_twofish2.c.

References BAD_ALIGN32, BAD_CIPHER_STATE, BAD_INPUT_LEN, BAD_KEY_INSTANCE, BLOCK_SIZE, blockEncrypt(), Bswap, cipherInstance::cipherSig, DebugDump, f32(), FEISTEL, if, INPUT_WHITEN, keyInstance::keySig, MAX_ROUNDS, cipherInstance::mode, MODE_CBC, MODE_CFB1, MODE_ECB, NULL, keyInstance::numRounds, OUTPUT_WHITEN, ROL, ROR, ROUND_SUBKEYS, and VALID_SIG.

00455     {
00456     int   i,n,r;                    /* loop variables */
00457     DWORD x[BLOCK_SIZE/32];         /* block being encrypted */
00458     DWORD t0,t1,tmp;                /* temp variables */
00459     int   rounds=key->numRounds;    /* number of rounds */
00460     BYTE  bit,ctBit,carry;          /* temps for CFB */
00461 //#if ALIGN32
00462     //BYTE alignDummy;              /* keep 32-bit variable alignment on stack */
00463 //#endif
00464 
00465 #if VALIDATE_PARMS
00466     if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
00467         return BAD_CIPHER_STATE;
00468     if ((key == NULL) || (key->keySig != VALID_SIG))
00469         return BAD_KEY_INSTANCE;
00470     if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
00471         return BAD_KEY_INSTANCE;
00472     if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
00473         return BAD_INPUT_LEN;
00474   #if ALIGN32
00475     if ( (((int)cipher) & 3) || (((int)key      ) & 3) ||
00476          (((int)input ) & 3) || (((int)outBuffer) & 3))
00477         return BAD_ALIGN32;
00478   #endif
00479 #endif
00480 
00481     if (cipher->mode == MODE_CFB1)
00482         {   /* use recursion here to handle CFB, one block at a time */
00483         cipher->mode = MODE_ECB;    /* do encryption in ECB */
00484         for (n=0;n<inputLen;n++)
00485             {
00486             blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
00487             bit   = 0x80 >> (n & 7);/* which bit position in byte */
00488             ctBit = (input[n/8] & bit) ^ ((((BYTE *) x)[0] & 0x80) >> (n&7));
00489             outBuffer[n/8] = (outBuffer[n/8] & ~ bit) | ctBit;
00490             carry = ctBit >> (7 - (n&7));
00491             for (i=BLOCK_SIZE/8-1;i>=0;i--)
00492                 {
00493                 bit = cipher->IV[i] >> 7;   /* save next "carry" from shift */
00494                 cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
00495                 carry = bit;
00496                 }
00497             }
00498         cipher->mode = MODE_CFB1;   /* restore mode for next time */
00499         return inputLen;
00500         }
00501 
00502     /* here for ECB, CBC modes */
00503     for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
00504         {
00505 #ifdef DEBUG
00506         DebugDump(input,"\n",-1,0,0,0,1);
00507         if (cipher->mode == MODE_CBC)
00508             DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
00509 #endif
00510         for (i=0;i<BLOCK_SIZE/32;i++)   /* copy in the block, add whitening */
00511             {
00512             x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[INPUT_WHITEN+i];
00513             if (cipher->mode == MODE_CBC)
00514                 x[i] ^= cipher->iv32[i];
00515             }
00516 
00517         DebugDump(x,"",0,0,0,0,0);
00518         for (r=0;r<rounds;r++)          /* main Twofish encryption loop */
00519             {   
00520 #if FEISTEL
00521             t0   = f32(ROR(x[0],  (r+1)/2),key->sboxKeys,key->keyLen);
00522             t1   = f32(ROL(x[1],8+(r+1)/2),key->sboxKeys,key->keyLen);
00523                                         /* PHT, round keys */
00524             x[2]^= ROL(t0 +   t1 + key->subKeys[ROUND_SUBKEYS+2*r  ], r    /2);
00525             x[3]^= ROR(t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1],(r+2) /2);
00526 
00527             DebugDump(x,"",r+1,2*(r&1),1,1,0);
00528 #else
00529             t0   = f32(    x[0]   ,key->sboxKeys,key->keyLen);
00530             t1   = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
00531 
00532             x[3] = ROL(x[3],1);
00533             x[2]^= t0 +   t1 + key->subKeys[ROUND_SUBKEYS+2*r  ]; /* PHT, round keys */
00534             x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
00535             x[2] = ROR(x[2],1);
00536 
00537             DebugDump(x,"",r+1,2*(r&1),0,1,0);/* make format compatible with optimized code */
00538 #endif
00539             if (r < rounds-1)                       /* swap for next round */
00540                 {
00541                 tmp = x[0]; x[0]= x[2]; x[2] = tmp;
00542                 tmp = x[1]; x[1]= x[3]; x[3] = tmp;
00543                 }
00544             }
00545 #if FEISTEL
00546         x[0] = ROR(x[0],8);                     /* "final permutation" */
00547         x[1] = ROL(x[1],8);
00548         x[2] = ROR(x[2],8);
00549         x[3] = ROL(x[3],8);
00550 #endif
00551         for (i=0;i<BLOCK_SIZE/32;i++)   /* copy out, with whitening */
00552             {
00553             ((DWORD *)outBuffer)[i] = Bswap(x[i] ^ key->subKeys[OUTPUT_WHITEN+i]);
00554             if (cipher->mode == MODE_CBC)
00555                 cipher->iv32[i] = Bswap(((DWORD *)outBuffer)[i]);
00556             }
00557 #ifdef DEBUG
00558         DebugDump(outBuffer,"",rounds+1,0,0,0,1);
00559         if (cipher->mode == MODE_CBC)
00560             DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
00561 #endif
00562         }
00563 
00564     return inputLen;
00565     }

int blockDecrypt ( cipherInstance cipher,
keyInstance key,
CONST BYTE input,
int  inputLen,
BYTE outBuffer 
)

Definition at line 585 of file thig_twofish2.c.

References BAD_ALIGN32, BAD_CIPHER_STATE, BAD_INPUT_LEN, BAD_KEY_INSTANCE, BLOCK_SIZE, blockEncrypt(), Bswap, cipherInstance::cipherSig, DebugDump, f32(), if, INPUT_WHITEN, keyInstance::keySig, MAX_ROUNDS, cipherInstance::mode, MODE_CBC, MODE_CFB1, MODE_ECB, NULL, keyInstance::numRounds, OUTPUT_WHITEN, ROL, ROR, ROUND_SUBKEYS, and VALID_SIG.

00587     {
00588     int   i,n,r;                    /* loop counters */
00589     DWORD x[BLOCK_SIZE/32];         /* block being encrypted */
00590     DWORD t0,t1;                    /* temp variables */
00591     int   rounds=key->numRounds;    /* number of rounds */
00592     BYTE  bit,ctBit,carry;          /* temps for CFB */
00593 //#if ALIGN32
00594     //BYTE alignDummy;              /* keep 32-bit variable alignment on stack */
00595 //#endif
00596 
00597 #if VALIDATE_PARMS
00598     if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
00599         return BAD_CIPHER_STATE;
00600     if ((key == NULL) || (key->keySig != VALID_SIG))
00601         return BAD_KEY_INSTANCE;
00602     if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
00603         return BAD_KEY_INSTANCE;
00604     if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
00605         return BAD_INPUT_LEN;
00606   #if ALIGN32
00607     if ( (((int)cipher) & 3) || (((int)key      ) & 3) ||
00608          (((int)input)  & 3) || (((int)outBuffer) & 3))
00609         return BAD_ALIGN32;
00610   #endif
00611 #endif
00612 
00613     if (cipher->mode == MODE_CFB1)
00614         {   /* use blockEncrypt here to handle CFB, one block at a time */
00615         cipher->mode = MODE_ECB;    /* do encryption in ECB */
00616         for (n=0;n<inputLen;n++)
00617             {
00618             blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
00619             bit   = 0x80 >> (n & 7);
00620             ctBit = input[n/8] & bit;
00621             outBuffer[n/8] = (outBuffer[n/8] & ~ bit) |
00622                              (ctBit ^ ((((BYTE *) x)[0] & 0x80) >> (n&7)));
00623             carry = ctBit >> (7 - (n&7));
00624             for (i=BLOCK_SIZE/8-1;i>=0;i--)
00625                 {
00626                 bit = cipher->IV[i] >> 7;   /* save next "carry" from shift */
00627                 cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
00628                 carry = bit;
00629                 }
00630             }
00631         cipher->mode = MODE_CFB1;   /* restore mode for next time */
00632         return inputLen;
00633         }
00634 
00635     /* here for ECB, CBC modes */
00636     for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
00637         {
00638         DebugDump(input,"\n",rounds+1,0,0,0,1);
00639 
00640         for (i=0;i<BLOCK_SIZE/32;i++)   /* copy in the block, add whitening */
00641             x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[OUTPUT_WHITEN+i];
00642 
00643         for (r=rounds-1;r>=0;r--)           /* main Twofish decryption loop */
00644             {
00645             t0   = f32(    x[0]   ,key->sboxKeys,key->keyLen);
00646             t1   = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
00647 
00648             DebugDump(x,"",r+1,2*(r&1),0,1,0);/* make format compatible with optimized code */
00649             x[2] = ROL(x[2],1);
00650             x[2]^= t0 +   t1 + key->subKeys[ROUND_SUBKEYS+2*r  ]; /* PHT, round keys */
00651             x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
00652             x[3] = ROR(x[3],1);
00653 
00654             if (r)                                  /* unswap, except for last round */
00655                 {
00656                 t0   = x[0]; x[0]= x[2]; x[2] = t0; 
00657                 t1   = x[1]; x[1]= x[3]; x[3] = t1;
00658                 }
00659             }
00660         DebugDump(x,"",0,0,0,0,0);/* make final output match encrypt initial output */
00661 
00662         for (i=0;i<BLOCK_SIZE/32;i++)   /* copy out, with whitening */
00663             {
00664             x[i] ^= key->subKeys[INPUT_WHITEN+i];
00665             if (cipher->mode == MODE_CBC)
00666                 {
00667                 x[i] ^= cipher->iv32[i];
00668                 cipher->iv32[i] = Bswap(((DWORD *)input)[i]);
00669                 }
00670             ((DWORD *)outBuffer)[i] = Bswap(x[i]);
00671             }
00672         DebugDump(outBuffer,"",-1,0,0,0,1);
00673         }
00674 
00675     return inputLen;
00676     }


Variable Documentation

int tabEnable = 0

are we gathering stats?

Definition at line 42 of file thig_twofish2.c.

Referenced by f32(), and TableOp().

BYTE tabUsed[256]

one bit per table

Definition at line 43 of file thig_twofish2.c.

Referenced by f32(), and TableOp().

CONST char* moduleDescription = "Pedagogical C code"

Definition at line 48 of file thig_twofish2.c.

CONST char* modeString = ""

Definition at line 50 of file thig_twofish2.c.

int numRounds[4] = {0,ROUNDS_128,ROUNDS_192,ROUNDS_256}

number of rounds for various key sizes: 128, 192, 256

Definition at line 61 of file thig_twofish2.c.

Referenced by makeKey().


Generated on Thu Oct 23 04:14:41 2008 for Open IMS Core CSCFs by  doxygen 1.5.2