thig_aes.h

Go to the documentation of this file.
00001 
00027 /* Includes:
00028     Standard include files
00029 */
00030 
00031 #include    <stdio.h>
00032 #include    "thig_platform.h"           
00034 /*  Defines:
00035         Add any additional defines you need
00036 */
00037 
00038 #define     DIR_ENCRYPT     0       
00039 #define     DIR_DECRYPT     1       
00040 #define     MODE_ECB        1       
00041 #define     MODE_CBC        2       
00042 #define     MODE_CFB1       3       
00044 #define     TRUE            1
00045 #define     FALSE           0
00046 
00047 #define     BAD_KEY_DIR         -1  
00048 #define     BAD_KEY_MAT         -2  
00049 #define     BAD_KEY_INSTANCE    -3  
00050 #define     BAD_CIPHER_MODE     -4  
00051 #define     BAD_CIPHER_STATE    -5  
00053 /* CHANGE POSSIBLE: inclusion of algorithm specific defines */
00054 
00055 #define     MAX_KEY_SIZE        64  
00056 #define     MAX_IV_SIZE         16  
00057 #define     BAD_INPUT_LEN       -6  
00058 #define     BAD_PARAMS          -7  
00059 #define     BAD_IV_MAT          -8  
00060 #define     BAD_ENDIAN          -9  
00061 #define     BAD_ALIGN32         -10 
00063 #define     BLOCK_SIZE          128 
00064 #define     MAX_ROUNDS           16 
00065 #define     ROUNDS_128           16 
00066 #define     ROUNDS_192           16 
00067 #define     ROUNDS_256           16 
00068 #define     MAX_KEY_BITS        256 
00069 #define     MIN_KEY_BITS        128 
00070 #define     VALID_SIG    0x48534946 
00071 #define     MCT_OUTER           400 
00072 #define     MCT_INNER         10000 
00073 #define     REENTRANT             1 
00075 #define     INPUT_WHITEN          0 
00076 #define     OUTPUT_WHITEN       ( INPUT_WHITEN + BLOCK_SIZE/32)
00077 #define     ROUND_SUBKEYS       (OUTPUT_WHITEN + BLOCK_SIZE/32) 
00078 #define     TOTAL_SUBKEYS       (ROUND_SUBKEYS + 2*MAX_ROUNDS)
00079 
00080 /* Typedefs:
00081     Typedef'ed data storage elements. Add any algorithm specific
00082     parameters at the bottom of the structs as appropriate.
00083 */
00084 
00085 typedef unsigned char BYTE;
00086 typedef unsigned long DWORD;        /* 32-bit unsigned quantity */
00087 typedef DWORD fullSbox[4][256];
00088 
00090 typedef struct 
00091     {
00092     BYTE direction;                 
00093 #if ALIGN32
00094     BYTE dummyAlign[3];             
00095 #endif
00096     int  keyLen;                    
00097     char keyMaterial[MAX_KEY_SIZE+4];
00100     DWORD keySig;                   
00101     int   numRounds;                
00102     DWORD key32[MAX_KEY_BITS/32];   
00103     DWORD sboxKeys[MAX_KEY_BITS/64];
00104     DWORD subKeys[TOTAL_SUBKEYS];   
00105 #if REENTRANT
00106     fullSbox sBox8x32;              
00107 #if defined(COMPILE_KEY) && defined(USE_ASM)
00108 #undef  VALID_SIG
00109 #define VALID_SIG    0x504D4F43     
00110     DWORD cSig1;                    
00111     void *encryptFuncPtr;           
00112     void *decryptFuncPtr;           
00113     DWORD codeSize;                 
00114     DWORD cSig2;                    
00115     BYTE  compiledCode[5000];       
00116   #endif
00117 #endif
00118     } keyInstance;
00119 
00120 
00121 
00123 typedef struct {
00124     BYTE  mode;                     
00125 #if ALIGN32
00126     BYTE dummyAlign[3];             
00127 #endif
00128     BYTE  IV[MAX_IV_SIZE];          
00131     DWORD cipherSig;                
00132     DWORD iv32[BLOCK_SIZE/32];      
00133     } cipherInstance;
00134 
00136 int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);
00137 
00138 int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);
00139 
00140 int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
00141                 int inputLen, BYTE *outBuffer);
00142 
00143 int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
00144                 int inputLen, BYTE *outBuffer);
00145 
00146 int reKey(keyInstance *key);    
00149 #define     TAB_DISABLE         0
00150 #define     TAB_ENABLE          1
00151 #define     TAB_RESET           2
00152 #define     TAB_QUERY           3
00153 #define     TAB_MIN_QUERY       50
00154 int TableOp(int op);
00155 
00156 
00157 #define     CONST               
00159 #if BLOCK_SIZE == 128           
00160 #define     Copy1(d,s,N)    ((DWORD *)(d))[N] = ((DWORD *)(s))[N]
00161 #define     BlockCopy(d,s)  { Copy1(d,s,0);Copy1(d,s,1);Copy1(d,s,2);Copy1(d,s,3); }
00162 #else
00163 #define     BlockCopy(d,s)  { memcpy(d,s,BLOCK_SIZE/8); }
00164 #endif
00165 
00166 
00167 #ifdef TEST_2FISH
00168 /*                      ----- EXAMPLES -----
00169 
00170 Unfortunately, the AES API is somewhat clumsy, and it is not entirely
00171 obvious how to use the above functions.  In particular, note that
00172 makeKey() takes an ASCII hex nibble key string (e.g., 32 characters
00173 for a 128-bit key), which is rarely the way that keys are internally
00174 represented.  The reKey() function uses instead the keyInstance.key32
00175 array of key bits and is the preferred method.  In fact, makeKey()
00176 initializes some internal keyInstance state, then parse the ASCII
00177 string into the binary key32, and calls reKey().  To initialize the
00178 keyInstance state, use a 'dummy' call to makeKey(); i.e., set the
00179 keyMaterial parameter to NULL.  Then use reKey() for all key changes.
00180 Similarly, cipherInit takes an IV string in ASCII hex, so a dummy setup
00181 call with a null IV string will skip the ASCII parse.  
00182 
00183 Note that CFB mode is not well tested nor defined by AES, so using the
00184 Twofish MODE_CFB it not recommended.  If you wish to implement a CFB mode,
00185 build it external to the Twofish code, using the Twofish functions only
00186 in ECB mode.
00187 
00188 Below is a sample piece of code showing how the code is typically used
00189 to set up a key, encrypt, and decrypt.  Error checking is somewhat limited
00190 in this example.  Pseudorandom bytes are used for all key and text.
00191 
00192 If you compile TWOFISH2.C or TWOFISH.C as a DOS (or Windows Console) app
00193 with this code enabled, the test will be run.  For example, using
00194 Borland C, you would compile using:
00195   BCC32 -DTEST_2FISH twofish2.c
00196 to run the test on the optimized code, or
00197   BCC32 -DTEST_2FISH twofish.c
00198 to run the test on the pedagogical code.
00199 
00200 */
00201 
00202 #include <stdio.h>
00203 #include <stdlib.h>
00204 #include <time.h>
00205 #include <string.h>
00206 
00207 #define MAX_BLK_CNT     1       
00215 int TestTwofish(int mode,int keySize) /* keySize must be 128, 192, or 256 */
00216     {                           /* return 0 iff test passes */
00217     keyInstance    ki;          /* key information, including tables */
00218     cipherInstance ci;          /* keeps mode (ECB, CBC) and IV */
00219     BYTE  plainText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
00220     BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
00221     BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE/8)];
00222     BYTE iv[BLOCK_SIZE/8];
00223     int  i,byteCnt;
00224 
00225     if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE)
00226         return 1;               /* 'dummy' setup for a 128-bit key */
00227     if (cipherInit(&ci,mode,NULL) != TRUE)
00228         return 1;               /* 'dummy' setup for cipher */
00229     
00230     for (i=0;i<keySize/32;i++)  /* select key bits */
00231         ki.key32[i]=0x10003 * rand();
00232     reKey(&ki);                 /* run the key schedule */
00233 
00234     if (mode != MODE_ECB)       /* set up random iv (if needed)*/
00235         {
00236         for (i=0;i<sizeof(iv);i++)
00237             iv[i]=(BYTE) rand();
00238         memcpy(ci.iv32,iv,sizeof(ci.iv32)); /* copy the IV to ci */
00239         }
00240 
00241    /* select number of bytes to encrypt (multiple of block)
00242     *   e.g., byteCnt = 16, 32, 48, 64 
00243     */
00244     byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT));
00245 
00246     for (i=0;i<byteCnt;i++)     
00247         plainText[i]=(BYTE) rand();
00248     
00249     /* encrypt the bytes */
00250     if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8)
00251         return 1;
00252 
00253     /* decrypt the bytes */
00254     if (mode != MODE_ECB)       
00255         memcpy(ci.iv32,iv,sizeof(ci.iv32));
00256 
00257     if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8)
00258         return 1;               
00259     
00260     /* make sure the decrypt output matches original plaintext */
00261     if (memcmp(plainText,decryptOut,byteCnt))
00262         return 1;       
00263 
00264     return 0;                   
00265     }
00266 
00270 void main(void)
00271     {
00272     int testCnt,keySize;
00273 
00274     srand((unsigned) time(NULL));   /* randomize */
00275 
00276     for (keySize=128;keySize<=256;keySize+=64)
00277         for (testCnt=0;testCnt<10;testCnt++)
00278             {
00279             if (TestTwofish(MODE_ECB,keySize))
00280                 { printf("ECB Failure at keySize=%d",keySize); return; }
00281             if (TestTwofish(MODE_CBC,keySize))
00282                 { printf("CBC Failure at keySize=%d",keySize); return; }
00283             }
00284     printf("Tests passed");
00285     }
00286 #endif /* TEST_2FISH */

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