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