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 (2 years, 8 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

# Content
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
16 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 typedef struct
82 {
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 typedef struct
112 {
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 static int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);
126
127 static int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);
128
129 static int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
130 int inputLen, BYTE *outBuffer);
131
132 static int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
133 int inputLen, BYTE *outBuffer);
134
135 static int reKey(keyInstance *key); /* do key schedule using modified key.keyDwords */
136
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 static int TableOp(int op);
144
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 call with a null IV string will skip the ASCII parse.
171
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 static int TestTwofish(int mode,int keySize) /* keySize must be 128, 192, or 256 */
198 { /* 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
212 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
230 /* 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 return 1;
240
241 /* make sure the decrypt output matches original plaintext */
242 if (memcmp(plainText,decryptOut,byteCnt))
243 return 1;
244
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