00001 /* aes.h */ 00002 00003 /* ---------- See examples at end of this file for typical usage -------- */ 00004 00005 /* AES Cipher header file for ANSI C Submissions 00006 Lawrence E. Bassham III 00007 Computer Security Division 00008 National Institute of Standards and Technology 00009 00010 This sample is to assist implementers developing to the 00011 Cryptographic API Profile for AES Candidate Algorithm Submissions. 00012 Please consult this document as a cross-reference. 00013 00014 ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE 00015 MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH 00016 THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS 00017 CANNOT BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO 00018 INCLUDE IMPLEMENTATION SPECIFIC INFORMATION. 00019 */ 00020 00021 /* Includes: 00022 Standard include files 00023 */ 00024 00025 #include <stdio.h> 00026 #include "platform.h" /* platform-specific defines */ 00027 00028 /* Defines: 00029 Add any additional defines you need 00030 */ 00031 00032 #define DIR_ENCRYPT 0 /* Are we encrpyting? */ 00033 #define DIR_DECRYPT 1 /* Are we decrpyting? */ 00034 #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ 00035 #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ 00036 #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ 00037 00038 #define TRUE 1 00039 #define FALSE 0 00040 00041 #define BAD_KEY_DIR -1 /* Key direction is invalid (unknown value) */ 00042 #define BAD_KEY_MAT -2 /* Key material not of correct length */ 00043 #define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ 00044 #define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ 00045 #define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ 00046 00047 /* CHANGE POSSIBLE: inclusion of algorithm specific defines */ 00048 /* TWOFISH specific definitions */ 00049 #define MAX_KEY_SIZE 64 /* # of ASCII chars needed to represent a key */ 00050 #define MAX_IV_SIZE 16 /* # of bytes needed to represent an IV */ 00051 #define BAD_INPUT_LEN -6 /* inputLen not a multiple of block size */ 00052 #define BAD_PARAMS -7 /* invalid parameters */ 00053 #define BAD_IV_MAT -8 /* invalid IV text */ 00054 #define BAD_ENDIAN -9 /* incorrect endianness define */ 00055 #define BAD_ALIGN32 -10 /* incorrect 32-bit alignment */ 00056 00057 #define BLOCK_SIZE 128 /* number of bits per block */ 00058 #define MAX_ROUNDS 16 /* max # rounds (for allocating subkey array) */ 00059 #define ROUNDS_128 16 /* default number of rounds for 128-bit keys*/ 00060 #define ROUNDS_192 16 /* default number of rounds for 192-bit keys*/ 00061 #define ROUNDS_256 16 /* default number of rounds for 256-bit keys*/ 00062 #define MAX_KEY_BITS 256 /* max number of bits of key */ 00063 #define MIN_KEY_BITS 128 /* min number of bits of key (zero pad) */ 00064 #define VALID_SIG 0x48534946 /* initialization signature ('FISH') */ 00065 #define MCT_OUTER 400 /* MCT outer loop */ 00066 #define MCT_INNER 10000 /* MCT inner loop */ 00067 #define REENTRANT 1 /* nonzero forces reentrant code (slightly slower) */ 00068 00069 #define INPUT_WHITEN 0 /* subkey array indices */ 00070 #define OUTPUT_WHITEN ( INPUT_WHITEN + BLOCK_SIZE/32) 00071 #define ROUND_SUBKEYS (OUTPUT_WHITEN + BLOCK_SIZE/32) /* use 2 * (# rounds) */ 00072 #define TOTAL_SUBKEYS (ROUND_SUBKEYS + 2*MAX_ROUNDS) 00073 00074 /* Typedefs: 00075 Typedef'ed data storage elements. Add any algorithm specific 00076 parameters at the bottom of the structs as appropriate. 00077 */ 00078 00079 typedef unsigned char BYTE; 00080 typedef unsigned long DWORD; /* 32-bit unsigned quantity */ 00081 typedef DWORD fullSbox[4][256]; 00082 00083 /* The structure for key information */ 00084 typedef struct 00085 { 00086 BYTE direction; /* Key used for encrypting or decrypting? */ 00087 #if ALIGN32 00088 BYTE dummyAlign[3]; /* keep 32-bit alignment */ 00089 #endif 00090 int keyLen; /* Length of the key */ 00091 char keyMaterial[MAX_KEY_SIZE+4];/* Raw key data in ASCII */ 00092 00093 /* Twofish-specific parameters: */ 00094 DWORD keySig; /* set to VALID_SIG by makeKey() */ 00095 int numRounds; /* number of rounds in cipher */ 00096 DWORD key32[MAX_KEY_BITS/32]; /* actual key bits, in dwords */ 00097 DWORD sboxKeys[MAX_KEY_BITS/64];/* key bits used for S-boxes */ 00098 DWORD subKeys[TOTAL_SUBKEYS]; /* round subkeys, input/output whitening bits */ 00099 #if REENTRANT 00100 fullSbox sBox8x32; /* fully expanded S-box */ 00101 #if defined(COMPILE_KEY) && defined(USE_ASM) 00102 #undef VALID_SIG 00103 #define VALID_SIG 0x504D4F43 /* 'COMP': C is compiled with -DCOMPILE_KEY */ 00104 DWORD cSig1; /* set after first "compile" (zero at "init") */ 00105 void *encryptFuncPtr; /* ptr to asm encrypt function */ 00106 void *decryptFuncPtr; /* ptr to asm decrypt function */ 00107 DWORD codeSize; /* size of compiledCode */ 00108 DWORD cSig2; /* set after first "compile" */ 00109 BYTE compiledCode[5000]; /* make room for the code itself */ 00110 #endif 00111 #endif 00112 } keyInstance; 00113 00114 /* The structure for cipher information */ 00115 typedef struct 00116 { 00117 BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ 00118 #if ALIGN32 00119 BYTE dummyAlign[3]; /* keep 32-bit alignment */ 00120 #endif 00121 BYTE IV[MAX_IV_SIZE]; /* CFB1 iv bytes (CBC uses iv32) */ 00122 00123 /* Twofish-specific parameters: */ 00124 DWORD cipherSig; /* set to VALID_SIG by cipherInit() */ 00125 DWORD iv32[BLOCK_SIZE/32]; /* CBC IV bytes arranged as dwords */ 00126 } cipherInstance; 00127 00128 /* API to check table usage, for use in ECB_TBL KAT */ 00129 #define TAB_DISABLE 0 00130 #define TAB_ENABLE 1 00131 #define TAB_RESET 2 00132 #define TAB_QUERY 3 00133 #define TAB_MIN_QUERY 50 00134 int TableOp(int op); 00135 00136 #ifndef CONST 00137 #define CONST /* helpful C++ syntax sugar, NOP for ANSI C */ 00138 #endif 00139 00140 #if BLOCK_SIZE == 128 /* optimize block copies */ 00141 #define Copy1(d,s,N) ((DWORD *)(d))[N] = ((DWORD *)(s))[N] 00142 #define BlockCopy(d,s) { Copy1(d,s,0);Copy1(d,s,1);Copy1(d,s,2);Copy1(d,s,3); } 00143 #else 00144 #define BlockCopy(d,s) { memcpy(d,s,BLOCK_SIZE/8); } 00145 #endif 00146