1 /* 2 /////////////////////////////////////////////////////////////////////////////// 3 // Name: rijndael.h 4 // Purpose: 5 // Author: Ulrich Telle 6 // Modified by: 7 // Created: 2006-12-06 8 // Copyright: (c) Ulrich Telle (Copyright for original code see below) 9 // Licence: wxWindows licence 10 // 11 // The original code is unchanged 12 /////////////////////////////////////////////////////////////////////////////// 13 14 /// \file rijndael.h Interface of the Rijndael cipher 15 */ 16 17 #ifndef _RIJNDAEL_H_ 18 #define _RIJNDAEL_H_ 19 20 /* 21 // File : rijndael.h 22 // Creation date : Sun Nov 5 2000 03:21:05 CEST 23 // Author : Szymon Stefanek (stefanek@tin.it) 24 // 25 // Another implementation of the Rijndael cipher. 26 // This is intended to be an easily usable library file. 27 // This code is public domain. 28 // Based on the Vincent Rijmen and K.U.Leuven implementation 2.4. 29 // 30 // Original Copyright notice: 31 // 32 // rijndael-alg-fst.c v2.4 April '2000 33 // rijndael-alg-fst.h 34 // rijndael-api-fst.c 35 // rijndael-api-fst.h 36 // 37 // Optimised ANSI C code 38 // 39 // authors: v1.0: Antoon Bosselaers 40 // v2.0: Vincent Rijmen, K.U.Leuven 41 // v2.3: Paulo Barreto 42 // v2.4: Vincent Rijmen, K.U.Leuven 43 // 44 // This code is placed in the public domain. 45 // 46 47 // 48 // This implementation works on 128 , 192 , 256 bit keys 49 // and on 128 bit blocks 50 // 51 52 // 53 // Example of usage: 54 // 55 // // Input data 56 // unsigned char key[32]; // The key 57 // initializeYour256BitKey(); // Obviously initialized with sth 58 // const unsigned char * plainText = getYourPlainText(); // Your plain text 59 // int plainTextLen = strlen(plainText); // Plain text length 60 // 61 // // Encrypting 62 // Rijndael rin; 63 // unsigned char output[plainTextLen + 16]; 64 // 65 // rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes); 66 // // It is a good idea to check the error code 67 // int len = rin.padEncrypt(plainText,len,output); 68 // if(len >= 0)useYourEncryptedText(); 69 // else encryptError(len); 70 // 71 // // Decrypting: we can reuse the same object 72 // unsigned char output2[len]; 73 // rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes)); 74 // len = rin.padDecrypt(output,len,output2); 75 // if(len >= 0)useYourDecryptedText(); 76 // else decryptError(len); 77 // 78 */ 79 80 #define _MAX_KEY_COLUMNS (256/32) 81 #define _MAX_ROUNDS 14 82 #define MAX_IV_SIZE 16 83 84 /* We assume that unsigned int is 32 bits long.... */ 85 typedef unsigned char UINT8; 86 typedef unsigned int UINT32; 87 typedef unsigned short UINT16; 88 89 /* Error codes */ 90 #define RIJNDAEL_SUCCESS 0 91 #define RIJNDAEL_UNSUPPORTED_MODE -1 92 #define RIJNDAEL_UNSUPPORTED_DIRECTION -2 93 #define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3 94 #define RIJNDAEL_BAD_KEY -4 95 #define RIJNDAEL_NOT_INITIALIZED -5 96 #define RIJNDAEL_BAD_DIRECTION -6 97 #define RIJNDAEL_CORRUPTED_DATA -7 98 99 #define RIJNDAEL_Direction_Encrypt 0 100 #define RIJNDAEL_Direction_Decrypt 1 101 102 #define RIJNDAEL_Direction_Mode_ECB 0 103 #define RIJNDAEL_Direction_Mode_CBC 1 104 #define RIJNDAEL_Direction_Mode_CFB1 2 105 106 #define RIJNDAEL_Direction_KeyLength_Key16Bytes 0 107 #define RIJNDAEL_Direction_KeyLength_Key24Bytes 1 108 #define RIJNDAEL_Direction_KeyLength_Key32Bytes 2 109 110 #define RIJNDAEL_State_Valid 0 111 #define RIJNDAEL_State_Invalid 1 112 113 /* 114 /// Class implementing the Rijndael cipher. (For internal use only) 115 */ 116 117 typedef struct _Rijndael 118 { 119 int m_state; 120 int m_mode; 121 int m_direction; 122 UINT8 m_initVector[MAX_IV_SIZE]; 123 UINT32 m_uRounds; 124 UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; 125 } Rijndael; 126 127 void RijndaelCreate(Rijndael* rijndael); 128 129 /* 130 ////////////////////////////////////////////////////////////////////////////////////////// 131 // API 132 ////////////////////////////////////////////////////////////////////////////////////////// 133 134 // init(): Initializes the crypt session 135 // Returns RIJNDAEL_SUCCESS or an error code 136 // mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1 137 // You have to use the same mode for encrypting and decrypting 138 // dir : Rijndael::Encrypt or Rijndael::Decrypt 139 // A cipher instance works only in one direction 140 // (Well , it could be easily modified to work in both 141 // directions with a single init() call, but it looks 142 // useless to me...anyway , it is a matter of generating 143 // two expanded keys) 144 // key : array of unsigned octets , it can be 16 , 24 or 32 bytes long 145 // this CAN be binary data (it is not expected to be null terminated) 146 // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes 147 // initVector: initialization vector, you will usually use 0 here 148 */ 149 int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector); 150 151 /* 152 // Encrypts the input array (can be binary data) 153 // The input array length must be a multiple of 16 bytes, the remaining part 154 // is DISCARDED. 155 // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer 156 // Input len is in BITS! 157 // outBuffer must be at least inputLen / 8 bytes long. 158 // Returns the encrypted buffer length in BITS or an error code < 0 in case of error 159 */ 160 int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); 161 162 /* 163 // Encrypts the input array (can be binary data) 164 // The input array can be any length , it is automatically padded on a 16 byte boundary. 165 // Input len is in BYTES! 166 // outBuffer must be at least (inputLen + 16) bytes long 167 // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error 168 */ 169 int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); 170 171 /* 172 // Decrypts the input vector 173 // Input len is in BITS! 174 // outBuffer must be at least inputLen / 8 bytes long 175 // Returns the decrypted buffer length in BITS and an error code < 0 in case of error 176 */ 177 int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); 178 179 /* 180 // Decrypts the input vector 181 // Input len is in BYTES! 182 // outBuffer must be at least inputLen bytes long 183 // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error 184 */ 185 int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); 186 187 void RijndaelInvalidate(Rijndael* rijndael); 188 void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]); 189 void RijndaelKeyEncToDec(Rijndael* rijndael); 190 void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); 191 void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); 192 193 #endif /* _RIJNDAEL_H_ */ 194