| 1 | #ifndef _RIJNDAEL_H_ |
|---|
| 2 | #define _RIJNDAEL_H_ |
|---|
| 3 | |
|---|
| 4 | /* $Id$ |
|---|
| 5 | // |
|---|
| 6 | // File : rijndael.h |
|---|
| 7 | // Creation date : Sun Nov 5 2000 03:21:05 CEST |
|---|
| 8 | // Author : Szymon Stefanek (stefanek@tin.it) |
|---|
| 9 | // |
|---|
| 10 | // Another implementation of the Rijndael cipher. |
|---|
| 11 | // This is intended to be an easily usable library file. |
|---|
| 12 | // This code is public domain. |
|---|
| 13 | // Based on the Vincent Rijmen and K.U.Leuven implementation 2.4. |
|---|
| 14 | */ |
|---|
| 15 | |
|---|
| 16 | /* |
|---|
| 17 | // Original Copyright notice: |
|---|
| 18 | // |
|---|
| 19 | // rijndael-alg-fst.c v2.4 April '2000 |
|---|
| 20 | // rijndael-alg-fst.h |
|---|
| 21 | // rijndael-api-fst.c |
|---|
| 22 | // rijndael-api-fst.h |
|---|
| 23 | // |
|---|
| 24 | // Optimised ANSI C code |
|---|
| 25 | // |
|---|
| 26 | // authors: v1.0: Antoon Bosselaers |
|---|
| 27 | // v2.0: Vincent Rijmen, K.U.Leuven |
|---|
| 28 | // v2.3: Paulo Barreto |
|---|
| 29 | // v2.4: Vincent Rijmen, K.U.Leuven |
|---|
| 30 | // |
|---|
| 31 | // This code is placed in the public domain. |
|---|
| 32 | */ |
|---|
| 33 | |
|---|
| 34 | /* |
|---|
| 35 | // This implementation works on 128 , 192 , 256 bit keys |
|---|
| 36 | // and on 128 bit blocks |
|---|
| 37 | */ |
|---|
| 38 | |
|---|
| 39 | /* |
|---|
| 40 | // Example of usage: |
|---|
| 41 | // |
|---|
| 42 | // // Input data |
|---|
| 43 | // unsigned char key[32]; // The key |
|---|
| 44 | // initializeYour256BitKey(); // Obviously initialized with sth |
|---|
| 45 | // const unsigned char * plainText = getYourPlainText(); // Your plain text |
|---|
| 46 | // int plainTextLen = strlen(plainText); // Plain text length |
|---|
| 47 | // |
|---|
| 48 | // // Encrypting |
|---|
| 49 | // Rijndael rin; |
|---|
| 50 | // unsigned char output[plainTextLen + 16]; |
|---|
| 51 | // |
|---|
| 52 | // rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes); |
|---|
| 53 | // // It is a good idea to check the error code |
|---|
| 54 | // int len = rin.padEncrypt(plainText,len,output); |
|---|
| 55 | // if(len >= 0)useYourEncryptedText(); |
|---|
| 56 | // else encryptError(len); |
|---|
| 57 | // |
|---|
| 58 | // // Decrypting: we can reuse the same object |
|---|
| 59 | // unsigned char output2[len]; |
|---|
| 60 | // rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes)); |
|---|
| 61 | // len = rin.padDecrypt(output,len,output2); |
|---|
| 62 | // if(len >= 0)useYourDecryptedText(); |
|---|
| 63 | // else decryptError(len); |
|---|
| 64 | */ |
|---|
| 65 | |
|---|
| 66 | #define _MAX_KEY_COLUMNS (256/32) |
|---|
| 67 | #define _MAX_ROUNDS 14 |
|---|
| 68 | #define MAX_IV_SIZE 16 |
|---|
| 69 | |
|---|
| 70 | /* We assume that unsigned int is 32 bits long.... */ |
|---|
| 71 | typedef unsigned char UINT8; |
|---|
| 72 | typedef unsigned int UINT32; |
|---|
| 73 | typedef unsigned short UINT16; |
|---|
| 74 | |
|---|
| 75 | /* Error codes */ |
|---|
| 76 | #define RIJNDAEL_SUCCESS 0 |
|---|
| 77 | #define RIJNDAEL_UNSUPPORTED_MODE -1 |
|---|
| 78 | #define RIJNDAEL_UNSUPPORTED_DIRECTION -2 |
|---|
| 79 | #define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3 |
|---|
| 80 | #define RIJNDAEL_BAD_KEY -4 |
|---|
| 81 | #define RIJNDAEL_NOT_INITIALIZED -5 |
|---|
| 82 | #define RIJNDAEL_BAD_DIRECTION -6 |
|---|
| 83 | #define RIJNDAEL_CORRUPTED_DATA -7 |
|---|
| 84 | |
|---|
| 85 | /*class Rijndael |
|---|
| 86 | //{ |
|---|
| 87 | //public: |
|---|
| 88 | */ |
|---|
| 89 | |
|---|
| 90 | enum Direction_e { Encrypt , Decrypt }; |
|---|
| 91 | enum Mode_e { ECB , CBC , CFB1 }; |
|---|
| 92 | enum KeyLength_e { Key16Bytes , Key24Bytes , Key32Bytes }; |
|---|
| 93 | enum State_e { Valid , Invalid }; |
|---|
| 94 | |
|---|
| 95 | typedef enum Mode_e Mode; |
|---|
| 96 | typedef enum Direction_e Direction; |
|---|
| 97 | typedef enum KeyLength_e KeyLength; |
|---|
| 98 | typedef enum State_e State; |
|---|
| 99 | |
|---|
| 100 | /* |
|---|
| 101 | // Creates a Rijndael cipher object |
|---|
| 102 | // You have to call init() before you can encrypt or decrypt stuff |
|---|
| 103 | // |
|---|
| 104 | // Rijndael(); |
|---|
| 105 | // ~Rijndael(); |
|---|
| 106 | //protected: |
|---|
| 107 | // // Internal stuff |
|---|
| 108 | |
|---|
| 109 | //public: |
|---|
| 110 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 111 | // API |
|---|
| 112 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 113 | |
|---|
| 114 | // init(): Initializes the crypt session |
|---|
| 115 | // Returns RIJNDAEL_SUCCESS or an error code |
|---|
| 116 | // mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1 |
|---|
| 117 | // You have to use the same mode for encrypting and decrypting |
|---|
| 118 | // dir : Rijndael::Encrypt or Rijndael::Decrypt |
|---|
| 119 | // A cipher instance works only in one direction |
|---|
| 120 | // (Well , it could be easily modified to work in both |
|---|
| 121 | // directions with a single init() call, but it looks |
|---|
| 122 | // useless to me...anyway , it is a matter of generating |
|---|
| 123 | // two expanded keys) |
|---|
| 124 | // key : array of unsigned octets , it can be 16 , 24 or 32 bytes long |
|---|
| 125 | // this CAN be binary data (it is not expected to be null terminated) |
|---|
| 126 | // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes |
|---|
| 127 | // initVector: initialization vector, you will usually use 0 here |
|---|
| 128 | |
|---|
| 129 | int rijndael_init(Mode mode, Direction dir, const UINT8 *key, KeyLength keyLen, UINT8 * initVector); |
|---|
| 130 | |
|---|
| 131 | // Encrypts the input array (can be binary data) |
|---|
| 132 | // The input array length must be a multiple of 16 bytes, the remaining part |
|---|
| 133 | // is DISCARDED. |
|---|
| 134 | // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer |
|---|
| 135 | // Input len is in BITS! |
|---|
| 136 | // outBuffer must be at least inputLen / 8 bytes long. |
|---|
| 137 | // Returns the encrypted buffer length in BITS or an error code < 0 in case of error |
|---|
| 138 | int blockEncrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer); |
|---|
| 139 | // Encrypts the input array (can be binary data) |
|---|
| 140 | // The input array can be any length , it is automatically padded on a 16 byte boundary. |
|---|
| 141 | // Input len is in BYTES! |
|---|
| 142 | // outBuffer must be at least (inputLen + 16) bytes long |
|---|
| 143 | // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error |
|---|
| 144 | int padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer); |
|---|
| 145 | // Decrypts the input vector |
|---|
| 146 | // Input len is in BITS! |
|---|
| 147 | // outBuffer must be at least inputLen / 8 bytes long |
|---|
| 148 | // Returns the decrypted buffer length in BITS and an error code < 0 in case of error |
|---|
| 149 | int blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer); |
|---|
| 150 | // Decrypts the input vector |
|---|
| 151 | // Input len is in BYTES! |
|---|
| 152 | // outBuffer must be at least inputLen bytes long |
|---|
| 153 | // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error |
|---|
| 154 | int padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer); |
|---|
| 155 | //protected: |
|---|
| 156 | void keySched(UINT8 key[_MAX_KEY_COLUMNS][4]); |
|---|
| 157 | void keyEncToDec(); |
|---|
| 158 | void r_encrypt(const UINT8 a[16], UINT8 b[16]); |
|---|
| 159 | void r_decrypt(const UINT8 a[16], UINT8 b[16]); |
|---|
| 160 | //}; |
|---|
| 161 | */ |
|---|
| 162 | |
|---|
| 163 | #endif /* _RIJNDAEL_H_ */ |
|---|