… | |
… | |
10 | National Institute of Standards and Technology |
10 | National Institute of Standards and Technology |
11 | |
11 | |
12 | This sample is to assist implementers developing to the |
12 | This sample is to assist implementers developing to the |
13 | Cryptographic API Profile for AES Candidate Algorithm Submissions. |
13 | Cryptographic API Profile for AES Candidate Algorithm Submissions. |
14 | Please consult this document as a cross-reference. |
14 | Please consult this document as a cross-reference. |
15 | |
15 | |
16 | ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE |
16 | ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE |
17 | MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH |
17 | MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH |
18 | THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS |
18 | THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS |
19 | CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO |
19 | CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO |
20 | INCLUDE IMPLEMENTATION SPECIFIC INFORMATION. |
20 | INCLUDE IMPLEMENTATION SPECIFIC INFORMATION. |
… | |
… | |
76 | */ |
76 | */ |
77 | |
77 | |
78 | typedef DWORD fullSbox[4][256]; |
78 | typedef DWORD fullSbox[4][256]; |
79 | |
79 | |
80 | /* The structure for key information */ |
80 | /* The structure for key information */ |
81 | typedef struct |
81 | typedef struct |
82 | { |
82 | { |
83 | BYTE direction; /* Key used for encrypting or decrypting? */ |
83 | BYTE direction; /* Key used for encrypting or decrypting? */ |
84 | #if ALIGN32 |
84 | #if ALIGN32 |
85 | BYTE dummyAlign[3]; /* keep 32-bit alignment */ |
85 | BYTE dummyAlign[3]; /* keep 32-bit alignment */ |
86 | #endif |
86 | #endif |
… | |
… | |
106 | #endif |
106 | #endif |
107 | #endif |
107 | #endif |
108 | } keyInstance; |
108 | } keyInstance; |
109 | |
109 | |
110 | /* The structure for cipher information */ |
110 | /* The structure for cipher information */ |
111 | typedef struct |
111 | typedef struct |
112 | { |
112 | { |
113 | BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ |
113 | BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ |
114 | #if ALIGN32 |
114 | #if ALIGN32 |
115 | BYTE dummyAlign[3]; /* keep 32-bit alignment */ |
115 | BYTE dummyAlign[3]; /* keep 32-bit alignment */ |
116 | #endif |
116 | #endif |
… | |
… | |
165 | initializes some internal keyInstance state, then parse the ASCII |
165 | initializes some internal keyInstance state, then parse the ASCII |
166 | string into the binary key32, and calls reKey(). To initialize the |
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 |
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. |
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 |
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. |
170 | call with a null IV string will skip the ASCII parse. |
171 | |
171 | |
172 | Note that CFB mode is not well tested nor defined by AES, so using the |
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, |
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 |
174 | build it external to the Twofish code, using the Twofish functions only |
175 | in ECB mode. |
175 | in ECB mode. |
… | |
… | |
206 | |
206 | |
207 | if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE) |
207 | if (makeKey(&ki,DIR_ENCRYPT,keySize,NULL) != TRUE) |
208 | return 1; /* 'dummy' setup for a 128-bit key */ |
208 | return 1; /* 'dummy' setup for a 128-bit key */ |
209 | if (cipherInit(&ci,mode,NULL) != TRUE) |
209 | if (cipherInit(&ci,mode,NULL) != TRUE) |
210 | return 1; /* 'dummy' setup for cipher */ |
210 | return 1; /* 'dummy' setup for cipher */ |
211 | |
211 | |
212 | for (i=0;i<keySize/32;i++) /* select key bits */ |
212 | for (i=0;i<keySize/32;i++) /* select key bits */ |
213 | ki.key32[i]=0x10003 * rand(); |
213 | ki.key32[i]=0x10003 * rand(); |
214 | reKey(&ki); /* run the key schedule */ |
214 | reKey(&ki); /* run the key schedule */ |
215 | |
215 | |
216 | if (mode != MODE_ECB) /* set up random iv (if needed)*/ |
216 | if (mode != MODE_ECB) /* set up random iv (if needed)*/ |
… | |
… | |
224 | /* e.g., byteCnt = 16, 32, 48, 64 */ |
224 | /* e.g., byteCnt = 16, 32, 48, 64 */ |
225 | byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT)); |
225 | byteCnt = (BLOCK_SIZE/8) * (1 + (rand() % MAX_BLK_CNT)); |
226 | |
226 | |
227 | for (i=0;i<byteCnt;i++) /* generate test data */ |
227 | for (i=0;i<byteCnt;i++) /* generate test data */ |
228 | plainText[i]=(BYTE) rand(); |
228 | plainText[i]=(BYTE) rand(); |
229 | |
229 | |
230 | /* encrypt the bytes */ |
230 | /* encrypt the bytes */ |
231 | if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8) |
231 | if (blockEncrypt(&ci,&ki, plainText,byteCnt*8,cipherText) != byteCnt*8) |
232 | return 1; |
232 | return 1; |
233 | |
233 | |
234 | /* decrypt the bytes */ |
234 | /* decrypt the bytes */ |
235 | if (mode != MODE_ECB) /* first re-init the IV (if needed) */ |
235 | if (mode != MODE_ECB) /* first re-init the IV (if needed) */ |
236 | memcpy(ci.iv32,iv,sizeof(ci.iv32)); |
236 | memcpy(ci.iv32,iv,sizeof(ci.iv32)); |
237 | |
237 | |
238 | if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8) |
238 | if (blockDecrypt(&ci,&ki,cipherText,byteCnt*8,decryptOut) != byteCnt*8) |
239 | return 1; |
239 | return 1; |
240 | |
240 | |
241 | /* make sure the decrypt output matches original plaintext */ |
241 | /* make sure the decrypt output matches original plaintext */ |
242 | if (memcmp(plainText,decryptOut,byteCnt)) |
242 | if (memcmp(plainText,decryptOut,byteCnt)) |
243 | return 1; |
243 | return 1; |
244 | |
244 | |
245 | return 0; /* tests passed! */ |
245 | return 0; /* tests passed! */ |
246 | } |
246 | } |
247 | |
247 | |
248 | void main(void) |
248 | void main(void) |