OKlibrary
0.2.1.6
|
00001 00010 #ifndef _RIJNDAEL_H_8uuHgt 00011 #define _RIJNDAEL_H_8uuHgt 00012 00013 // 00014 // File : rijndael.h 00015 // Creation date : Sun Nov 5 2000 03:21:05 CEST 00016 // Author : Szymon Stefanek (stefanek@tin.it) 00017 // 00018 // Another implementation of the Rijndael cipher. 00019 // This is intended to be an easily usable library file. 00020 // This code is public domain. 00021 // Based on the Vincent Rijmen and K.U.Leuven implementation 2.4. 00022 // 00023 // Oliver Kullmann (O.Kullmann@swansea.ac.uk), 1.1.2006: Coding style improvements 00024 00025 // 00026 // Original Copyright notice: 00027 // 00028 // rijndael-alg-fst.c v2.4 April '2000 00029 // rijndael-alg-fst.h 00030 // rijndael-api-fst.c 00031 // rijndael-api-fst.h 00032 // 00033 // Optimised ANSI C code 00034 // 00035 // authors: v1.0: Antoon Bosselaers 00036 // v2.0: Vincent Rijmen, K.U.Leuven 00037 // v2.3: Paulo Barreto 00038 // v2.4: Vincent Rijmen, K.U.Leuven 00039 // 00040 // This code is placed in the public domain. 00041 // 00042 00043 // 00044 // This implementation works on 128 , 192 , 256 bit keys 00045 // and on 128 bit blocks 00046 // 00047 00048 // 00049 // Example of usage: 00050 // 00051 // // Input data 00052 // unsigned char key[32]; // The key 00053 // initializeYour256BitKey(); // Obviously initialized with sth 00054 // const unsigned char * plainText = getYourPlainText(); // Your plain text 00055 // int plainTextLen = strlen(plainText); // Plain text length 00056 // 00057 // // Encrypting 00058 // Rijndael rin; 00059 // unsigned char output[plainTextLen + 16]; 00060 // 00061 // rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes); 00062 // // It is a good idea to check the error code 00063 // int len = rin.padEncrypt(plainText,len,output); 00064 // if(len >= 0)useYourEncryptedText(); 00065 // else encryptError(len); 00066 // 00067 // // Decrypting: we can reuse the same object 00068 // unsigned char output2[len]; 00069 // rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes)); 00070 // len = rin.padDecrypt(output,len,output2); 00071 // if(len >= 0)useYourDecryptedText(); 00072 // else decryptError(len); 00073 // 00074 00075 #include <stdint.h> 00076 00077 namespace OKlib { 00078 namespace Rijndael { 00079 00080 const int max_key_columns = 256/32; 00081 const int max_rounds = 14; 00082 const int max_iv_size = 16; 00083 00084 typedef uint8_t UInt8; 00085 typedef uint32_t UInt32; 00086 00087 // Error codes 00088 const int rijndael_success = 0; 00089 const int rijndael_unsupported_mode = -1; 00090 const int rijndael_unsupported_direction = -2; 00091 const int rijndael_unsupported_key_length = -3; 00092 const int rijndael_bad_key = -4; 00093 const int rijndael_not_initialized = -5; 00094 const int rijndael_bad_direction = -6; 00095 const int rijndael_corrupted_data = -7; 00096 00097 class Rijndael 00098 { 00099 public: 00100 enum Direction { Encrypt , Decrypt }; 00101 enum Mode { ECB , CBC , CFB1 }; 00102 enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes }; 00103 // 00104 // Creates a Rijndael cipher object 00105 // You have to call init() before you can encrypt or decrypt stuff 00106 // 00107 Rijndael(); 00108 ~Rijndael(); 00109 protected: 00110 // Internal stuff 00111 enum State { Valid , Invalid }; 00112 00113 State m_state; 00114 Mode m_mode; 00115 Direction m_direction; 00116 UInt8 m_initVector[max_iv_size]; 00117 UInt32 m_uRounds; 00118 UInt8 m_expandedKey[max_rounds+1][4][4]; 00119 public: 00121 // API 00123 00124 // init(): Initializes the crypt session 00125 // Returns rijndael_success or an error code 00126 // mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1 00127 // You have to use the same mode for encrypting and decrypting 00128 // dir : Rijndael::Encrypt or Rijndael::Decrypt 00129 // A cipher instance works only in one direction 00130 // (Well , it could be easily modified to work in both 00131 // directions with a single init() call, but it looks 00132 // useless to me...anyway , it is a matter of generating 00133 // two expanded keys) 00134 // key : array of unsigned octets , it can be 16 , 24 or 32 bytes long 00135 // this CAN be binary data (it is not expected to be null terminated) 00136 // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes 00137 // initVector: initialization vector, you will usually use 0 here 00138 int init(Mode mode,Direction dir,const UInt8 *key,KeyLength keyLen,UInt8 * initVector = 0); 00139 // Encrypts the input array (can be binary data) 00140 // The input array length must be a multiple of 16 bytes, the remaining part 00141 // is DISCARDED. 00142 // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer 00143 // Input len is in BITS! 00144 // outBuffer must be at least inputLen / 8 bytes long. 00145 // Returns the encrypted buffer length in BITS or an error code < 0 in case of error 00146 int blockEncrypt(const UInt8 *input, int inputLen, UInt8 *outBuffer); 00147 // Encrypts the input array (can be binary data) 00148 // The input array can be any length , it is automatically padded on a 16 byte boundary. 00149 // Input len is in BYTES! 00150 // outBuffer must be at least (inputLen + 16) bytes long 00151 // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error 00152 int padEncrypt(const UInt8 *input, int inputOctets, UInt8 *outBuffer); 00153 // Decrypts the input vector 00154 // Input len is in BITS! 00155 // outBuffer must be at least inputLen / 8 bytes long 00156 // Returns the decrypted buffer length in BITS and an error code < 0 in case of error 00157 int blockDecrypt(const UInt8 *input, int inputLen, UInt8 *outBuffer); 00158 // Decrypts the input vector 00159 // Input len is in BYTES! 00160 // outBuffer must be at least inputLen bytes long 00161 // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error 00162 int padDecrypt(const UInt8 *input, int inputOctets, UInt8 *outBuffer); 00163 protected: 00164 void keySched(UInt8 key[max_key_columns][4]); 00165 void keyEncToDec(); 00166 void encrypt(const UInt8 a[16], UInt8 b[16]); 00167 void decrypt(const UInt8 a[16], UInt8 b[16]); 00168 }; 00169 00170 } 00171 00172 } 00173 00174 #endif