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