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