ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Crypt-Twofish2/aes.h
Revision: 1.3
Committed: Sun Aug 1 12:32:14 2021 UTC (3 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_03, HEAD
Changes since 1.2: +9 -9 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 root 1.1 #ifndef AES_H
2     #define AES_H
3     /* aes.h */
4    
5     /* ---------- See examples at end of this file for typical usage -------- */
6    
7     /* AES Cipher header file for ANSI C Submissions
8     Lawrence E. Bassham III
9     Computer Security Division
10     National Institute of Standards and Technology
11    
12     This sample is to assist implementers developing to the
13     Cryptographic API Profile for AES Candidate Algorithm Submissions.
14     Please consult this document as a cross-reference.
15 root 1.3
16 root 1.1 ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
17     MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
18     THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS
19     CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO
20     INCLUDE IMPLEMENTATION SPECIFIC INFORMATION.
21     */
22    
23     /* Includes:
24     Standard include files
25     */
26    
27     #include <stdio.h>
28     #include "platform.h" /* platform-specific defines */
29    
30     /* Defines:
31     Add any additional defines you need
32     */
33    
34     #define DIR_ENCRYPT 0 /* Are we encrpyting? */
35     #define DIR_DECRYPT 1 /* Are we decrpyting? */
36     #define MODE_ECB 1 /* Are we ciphering in ECB mode? */
37     #define MODE_CBC 2 /* Are we ciphering in CBC mode? */
38     #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
39    
40     #define BAD_KEY_DIR -5 /* Key direction is invalid (unknown value) */
41     #define BAD_KEY_MAT -6 /* Key material not of correct length */
42     #define BAD_KEY_INSTANCE -7 /* Key passed is not valid */
43     #define BAD_CIPHER_MODE -8 /* Params struct passed to cipherInit invalid */
44     #define BAD_CIPHER_STATE -9 /* Cipher in wrong state (e.g., not initialized) */
45    
46     /* CHANGE POSSIBLE: inclusion of algorithm specific defines */
47     /* TWOFISH specific definitions */
48     #define MAX_KEY_SIZE 64 /* # of ASCII chars needed to represent a key */
49     #define MAX_IV_SIZE 16 /* # of bytes needed to represent an IV */
50     #define BAD_INPUT_LEN -6 /* inputLen not a multiple of block size */
51     #define BAD_PARAMS -7 /* invalid parameters */
52     #define BAD_IV_MAT -8 /* invalid IV text */
53     #define BAD_ENDIAN -9 /* incorrect endianness define */
54     #define BAD_ALIGN32 -10 /* incorrect 32-bit alignment */
55    
56     #define BLOCK_SIZE 128 /* number of bits per block */
57     #define MAX_ROUNDS 16 /* max # rounds (for allocating subkey array) */
58     #define ROUNDS_128 16 /* default number of rounds for 128-bit keys*/
59     #define ROUNDS_192 16 /* default number of rounds for 192-bit keys*/
60     #define ROUNDS_256 16 /* default number of rounds for 256-bit keys*/
61     #define MAX_KEY_BITS 256 /* max number of bits of key */
62     #define MIN_KEY_BITS 128 /* min number of bits of key (zero pad) */
63     #define VALID_SIG 0x48534946 /* initialization signature ('FISH') */
64     #define MCT_OUTER 400 /* MCT outer loop */
65     #define MCT_INNER 10000 /* MCT inner loop */
66     #define REENTRANT 1 /* nonzero forces reentrant code (slightly slower) */
67    
68     #define INPUT_WHITEN 0 /* subkey array indices */
69     #define OUTPUT_WHITEN ( INPUT_WHITEN + BLOCK_SIZE/32)
70     #define ROUND_SUBKEYS (OUTPUT_WHITEN + BLOCK_SIZE/32) /* use 2 * (# rounds) */
71     #define TOTAL_SUBKEYS (ROUND_SUBKEYS + 2*MAX_ROUNDS)
72    
73     /* Typedefs:
74     Typedef'ed data storage elements. Add any algorithm specific
75     parameters at the bottom of the structs as appropriate.
76     */
77    
78     typedef DWORD fullSbox[4][256];
79    
80     /* The structure for key information */
81 root 1.3 typedef struct
82 root 1.1 {
83     BYTE direction; /* Key used for encrypting or decrypting? */
84     #if ALIGN32
85     BYTE dummyAlign[3]; /* keep 32-bit alignment */
86     #endif
87     int keyLen; /* Length of the key */
88    
89     /* Twofish-specific parameters: */
90     DWORD keySig; /* set to VALID_SIG by makeKey() */
91     int numRounds; /* number of rounds in cipher */
92     DWORD key32[MAX_KEY_BITS/32]; /* actual key bits, in dwords */
93     DWORD sboxKeys[MAX_KEY_BITS/64];/* key bits used for S-boxes */
94     DWORD subKeys[TOTAL_SUBKEYS]; /* round subkeys, input/output whitening bits */
95     #if REENTRANT
96     fullSbox sBox8x32; /* fully expanded S-box */
97     #if defined(COMPILE_KEY) && defined(USE_ASM)
98     #undef VALID_SIG
99     #define VALID_SIG 0x504D4F43 /* 'COMP': C is compiled with -DCOMPILE_KEY */
100     DWORD cSig1; /* set after first "compile" (zero at "init") */
101     void *encryptFuncPtr; /* ptr to asm encrypt function */
102     void *decryptFuncPtr; /* ptr to asm decrypt function */
103     DWORD codeSize; /* size of compiledCode */
104     DWORD cSig2; /* set after first "compile" */
105     BYTE compiledCode[5000]; /* make room for the code itself */
106     #endif
107     #endif
108     } keyInstance;
109    
110     /* The structure for cipher information */
111 root 1.3 typedef struct
112 root 1.1 {
113     BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
114     #if ALIGN32
115     BYTE dummyAlign[3]; /* keep 32-bit alignment */
116     #endif
117     BYTE IV[MAX_IV_SIZE]; /* CFB1 iv bytes (CBC uses iv32) */
118    
119     /* Twofish-specific parameters: */
120     DWORD cipherSig; /* set to VALID_SIG by cipherInit() */
121     DWORD iv32[BLOCK_SIZE/32]; /* CBC IV bytes arranged as dwords */
122     } cipherInstance;
123    
124     /* Function protoypes */
125 root 1.2 static int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);
126 root 1.1
127 root 1.2 static int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);
128 root 1.1
129 root 1.2 static int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
130 root 1.1 int inputLen, BYTE *outBuffer);
131    
132 root 1.2 static int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
133 root 1.1 int inputLen, BYTE *outBuffer);
134    
135 root 1.2 static int reKey(keyInstance *key); /* do key schedule using modified key.keyDwords */
136 root 1.1
137     /* API to check table usage, for use in ECB_TBL KAT */
138     #define TAB_DISABLE 0
139     #define TAB_ENABLE 1
140     #define TAB_RESET 2
141     #define TAB_QUERY 3
142     #define TAB_MIN_QUERY 50
143 root 1.2 static int TableOp(int op);
144 root 1.1
145    
146     #define CONST /* helpful C++ syntax sugar, NOP for ANSI C */
147    
148     #if BLOCK_SIZE == 128 /* optimize block copies */
149     #define Copy1(d,s,N) ((DWORD *)(d))[N] = ((DWORD *)(s))[N]
150     #define BlockCopy(d,s) { Copy1(d,s,0);Copy1(d,s,1);Copy1(d,s,2);Copy1(d,s,3); }
151     #else
152     #define BlockCopy(d,s) { memcpy(d,s,BLOCK_SIZE/8); }
153     #endif
154    
155    
156     #ifdef TEST_2FISH
157     /* ----- EXAMPLES -----
158    
159     Unfortunately, the AES API is somewhat clumsy, and it is not entirely
160     obvious how to use the above functions. In particular, note that
161     makeKey() takes an ASCII hex nibble key string (e.g., 32 characters
162     for a 128-bit key), which is rarely the way that keys are internally
163     represented. The reKey() function uses instead the keyInstance.key32
164     array of key bits and is the preferred method. In fact, makeKey()
165     initializes some internal keyInstance state, then parse the ASCII
166     string into the binary key32, and calls reKey(). To initialize the
167     keyInstance state, use a 'dummy' call to makeKey(); i.e., set the
168     keyMaterial parameter to NULL. Then use reKey() for all key changes.
169     Similarly, cipherInit takes an IV string in ASCII hex, so a dummy setup
170 root 1.3 call with a null IV string will skip the ASCII parse.
171 root 1.1
172     Note that CFB mode is not well tested nor defined by AES, so using the
173     Twofish MODE_CFB it not recommended. If you wish to implement a CFB mode,
174     build it external to the Twofish code, using the Twofish functions only
175     in ECB mode.
176    
177     Below is a sample piece of code showing how the code is typically used
178     to set up a key, encrypt, and decrypt. Error checking is somewhat limited
179     in this example. Pseudorandom bytes are used for all key and text.
180    
181     If you compile TWOFISH2.C or TWOFISH.C as a DOS (or Windows Console) app
182     with this code enabled, the test will be run. For example, using
183     Borland C, you would compile using:
184     BCC32 -DTEST_2FISH twofish2.c
185     to run the test on the optimized code, or
186     BCC32 -DTEST_2FISH twofish.c
187     to run the test on the pedagogical code.
188    
189     */
190    
191     #include <stdio.h>
192     #include <stdlib.h>
193     #include <time.h>
194     #include <string.h>
195    
196     #define MAX_BLK_CNT 4 /* max # blocks per call in TestTwofish */
197 root 1.2 static int TestTwofish(int mode,int keySize) /* keySize must be 128, 192, or 256 */
198 root 1.1 { /* return 0 iff test passes */
199     keyInstance ki; /* key information, including tables */
200     cipherInstance ci; /* keeps mode (ECB, CBC) and IV */
201     BYTE plainText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
202     BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE/8)];
203     BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE/8)];
204     BYTE iv[BLOCK_SIZE/8];
205     int i,byteCnt;
206    
207     if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE)
208     return 1; /* 'dummy' setup for a 128-bit key */
209     if (cipherInit(&ci,mode,NULL) != TRUE)
210     return 1; /* 'dummy' setup for cipher */
211 root 1.3
212 root 1.1 for (i=0;i<keySize/32;i++) /* select key bits */
213     ki.key32[i]=0x10003 * rand();
214     reKey(&ki); /* run the key schedule */
215    
216     if (mode != MODE_ECB) /* set up random iv (if needed)*/
217     {
218     for (i=0;i<sizeof(iv);i++)
219     iv[i]=(BYTE) rand();
220     memcpy(ci.iv32,iv,sizeof(ci.iv32)); /* copy the IV to ci */
221     }
222    
223     /* select number of bytes to encrypt (multiple of block) */
224     /* e.g., byteCnt = 16, 32, 48, 64 */
225     byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT));
226    
227     for (i=0;i<byteCnt;i++) /* generate test data */
228     plainText[i]=(BYTE) rand();
229 root 1.3
230 root 1.1 /* encrypt the bytes */
231     if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8)
232     return 1;
233    
234     /* decrypt the bytes */
235     if (mode != MODE_ECB) /* first re-init the IV (if needed) */
236     memcpy(ci.iv32,iv,sizeof(ci.iv32));
237    
238     if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8)
239 root 1.3 return 1;
240    
241 root 1.1 /* make sure the decrypt output matches original plaintext */
242     if (memcmp(plainText,decryptOut,byteCnt))
243 root 1.3 return 1;
244 root 1.1
245     return 0; /* tests passed! */
246     }
247    
248     void main(void)
249     {
250     int testCnt,keySize;
251    
252     srand((unsigned) time(NULL)); /* randomize */
253    
254     for (keySize=128;keySize<=256;keySize+=64)
255     for (testCnt=0;testCnt<10;testCnt++)
256     {
257     if (TestTwofish(MODE_ECB,keySize))
258     { printf("ECB Failure at keySize=%d",keySize); return; }
259     if (TestTwofish(MODE_CBC,keySize))
260     { printf("CBC Failure at keySize=%d",keySize); return; }
261     }
262     printf("Tests passed");
263     }
264     #endif /* TEST_2FISH */
265    
266     #endif