| 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 |