1
1
#include "CEncrypterAES.h"
3
//! Code take from "Hoozi Resources"
4
//! Encrypt: http://www.hoozi.com/post/829n1/advanced-encryption-standard-aes-implementation-in-c-c-with-comments-part-1-encryption
5
//! Decrypt: http://www.hoozi.com/post/neqd5/advanced-encryption-standard-aes-implementation-in-c-c-with-comments-part-2-decryption
9
//! xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}
10
inline s32 xtime(s32 x)
12
return (x<<1) ^ (((x>>7) & 1) * 0x1b);
15
//! Multiplty is a macro used to multiply numbers in the field GF(2^8)
16
inline s32 multiply(s32 x, s32 y)
18
return ((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))));
21
//! The number of columns comprising a state in AES. This is a constant in AES. Value=4
22
static u32 NumberColumns = 4;
24
//! The round constant word array, Rcon[i], contains the values given by
25
//! x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(28)
26
//! Note that i starts at 1, not 0).
27
static int Rcon[255] = {
28
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
29
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
30
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
31
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
32
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
33
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
34
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
35
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
36
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
37
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
38
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
39
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
40
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
41
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
42
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
43
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
46
s32 CEncrypterAES::getSBoxValue(u32 num)
49
//0 1 2 3 4 5 6 7 8 9 A B C D E F
50
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
51
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
52
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
53
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
54
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
55
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
56
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
57
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
58
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
59
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
60
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
61
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
62
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
63
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
64
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
65
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
71
s32 CEncrypterAES::getSBoxValueInvert(s32 num)
74
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
75
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
76
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
77
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
78
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
79
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
80
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
81
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
82
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
83
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
84
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
85
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
86
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
87
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
88
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
89
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
94
CEncrypterAES::CEncrypterAES() : RoundKey(0), Key(0), KeyLength(0), NumberRounds(0)
5
static u32 AES_BLOCK_SIZE = 16;
7
CEncrypterAES::CEncrypterAES() : valid(false)
98
11
CEncrypterAES::~CEncrypterAES()
104
//! This function produces numberStates*(numberRounds+1) round keys. The round keys are used in each round to encrypt the states.
105
void CEncrypterAES::keyExpansion()
113
RoundKey = new u8[4* NumberColumns * (NumberRounds+1)];
115
// The first round key is the key itself.
116
for(i=0; i < KeyLength/4; i++)
118
RoundKey[i*4] = Key[i*4];
119
RoundKey[i*4+1] = Key[i*4+1];
120
RoundKey[i*4+2] = Key[i*4+2];
121
RoundKey[i*4+3]= Key[i*4+3];
124
// All other round keys are found from the previous round keys.
125
while (i < (NumberColumns * (NumberRounds+1)))
129
temp[j]=RoundKey[(i-1) * 4 + j];
132
if (!(i % (KeyLength/4)))
134
// This function rotates the 4 bytes in a word to the left once.
135
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
137
// Function RotWord()
146
// SubWord() is a function that takes a four-byte input word and
147
// applies the S-box to each of the four bytes to produce an output word.
149
// Function Subword()
151
temp[0]=getSBoxValue(temp[0]);
152
temp[1]=getSBoxValue(temp[1]);
153
temp[2]=getSBoxValue(temp[2]);
154
temp[3]=getSBoxValue(temp[3]);
157
temp[0] = temp[0] ^ Rcon[i/(KeyLength/4)];
159
else if ((KeyLength/4) > 6 && i % (KeyLength/4) == 4)
161
// Function Subword()
163
temp[0]=getSBoxValue(temp[0]);
164
temp[1]=getSBoxValue(temp[1]);
165
temp[2]=getSBoxValue(temp[2]);
166
temp[3]=getSBoxValue(temp[3]);
169
RoundKey[i*4+0] = RoundKey[(i-(KeyLength/4))*4+0] ^ temp[0];
170
RoundKey[i*4+1] = RoundKey[(i-(KeyLength/4))*4+1] ^ temp[1];
171
RoundKey[i*4+2] = RoundKey[(i-(KeyLength/4))*4+2] ^ temp[2];
172
RoundKey[i*4+3] = RoundKey[(i-(KeyLength/4))*4+3] ^ temp[3];
178
//! This function adds the round key to state.
179
//! The round key is added to the state by an XOR function.
180
void CEncrypterAES::addRoundKey(u32 round)
182
for(u32 i=0; i<4; i++)
184
for(u32 j=0; j<4; j++)
186
std::cout << RoundKey[round * NumberColumns * 4 + i * NumberColumns + j] << std::endl;
188
state[j][i] ^= RoundKey[round * NumberColumns * 4 + i * NumberColumns + j];
193
//! The SubBytes Function Substitutes the values in the
194
//! state matrix with values in an S-box.
195
void CEncrypterAES::subBytes()
202
state[i][j] = getSBoxValue(state[i][j]);
207
//! The SubBytes Function Substitutes the values in the
208
//! state matrix with values in an S-box.
209
void CEncrypterAES::invSubBytes()
216
state[i][j] = getSBoxValueInvert(state[i][j]);
221
//! The ShiftRows() function shifts the rows in the state to the left.
222
//! Each row is shifted with different offset.
223
//! Offset = Row number. So the first row is not shifted.
224
void CEncrypterAES::shiftRows()
228
// Rotate first row 1 columns to left
230
state[1][0] = state[1][1];
231
state[1][1] = state[1][2];
232
state[1][2] = state[1][3];
235
// Rotate second row 2 columns to left
237
state[2][0] = state[2][2];
241
state[2][1] = state[2][3];
244
// Rotate third row 3 columns to left
246
state[3][0] = state[3][3];
247
state[3][3] = state[3][2];
248
state[3][2] = state[3][1];
252
void CEncrypterAES::invShiftRows()
256
// Rotate first row 1 columns to right
258
state[1][3]=state[1][2];
259
state[1][2]=state[1][1];
260
state[1][1]=state[1][0];
263
// Rotate second row 2 columns to right
265
state[2][0]=state[2][2];
269
state[2][1]=state[2][3];
272
// Rotate third row 3 columns to right
274
state[3][0]=state[3][1];
275
state[3][1]=state[3][2];
276
state[3][2]=state[3][3];
280
//! MixColumns function mixes the columns of the state matrix
281
void CEncrypterAES::mixColumns()
289
Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;
290
Tm = state[0][i] ^ state[1][i] ;
292
state[0][i] ^= Tm ^ Tmp ;
293
Tm = state[1][i] ^ state[2][i] ;
295
state[1][i] ^= Tm ^ Tmp ;
296
Tm = state[2][i] ^ state[3][i] ;
298
state[2][i] ^= Tm ^ Tmp ;
299
Tm = state[3][i] ^ t ;
301
state[3][i] ^= Tm ^ Tmp ;
305
//! MixColumns function mixes the columns of the state matrix.
306
//! The method used to multiply may be difficult to understand for beginners.
307
//! Please use the references to gain more information.
308
void CEncrypterAES::invMixColumns()
320
state[0][i] = multiply(a, 0x0e) ^ multiply(b, 0x0b) ^ multiply(c, 0x0d) ^ multiply(d, 0x09);
321
state[1][i] = multiply(a, 0x09) ^ multiply(b, 0x0e) ^ multiply(c, 0x0b) ^ multiply(d, 0x0d);
322
state[2][i] = multiply(a, 0x0d) ^ multiply(b, 0x09) ^ multiply(c, 0x0e) ^ multiply(d, 0x0b);
323
state[3][i] = multiply(a, 0x0b) ^ multiply(b, 0x0d) ^ multiply(c, 0x09) ^ multiply(d, 0x0e);
327
16
EEncryptionType CEncrypterAES::getType()
332
bool CEncrypterAES::setKey(std::string newKey)
334
if((newKey.size()*8 == 128 ) || (newKey.size()*8 == 192) || (newKey.size()*8 == 256))
18
return Encryption_AES;
21
void CEncrypterAES::reset()
26
EVP_CIPHER_CTX_cleanup(&e_ctx);
27
EVP_CIPHER_CTX_cleanup(&d_ctx);
32
bool CEncrypterAES::setKey(std::string key)
36
u32 keySize = key.size()*8;
38
u8* newkey = new u8[key.size()];
39
u8* iv = new u8[key.size()];
41
if((keySize != 128 ) && (keySize != 192) && (keySize != 256))
46
std::string salt = "yoginetworksalt";
49
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (u8*)salt.data(), (u8*)key.data(), key.size(), nrounds, newkey, iv);
50
else if(keySize == 192)
51
i = EVP_BytesToKey(EVP_aes_192_cbc(), EVP_sha1(), (u8*)salt.data(), (u8*)key.data(), key.size(), nrounds, newkey, iv);
52
else if(keySize == 128)
53
i = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), (u8*)salt.data(), (u8*)key.data(), key.size(), nrounds, newkey, iv);
339
Key = new u8[newKey.size()];
340
KeyLength = newKey.size();
342
NumberRounds = ( KeyLength/4 ) + 6;
344
for(u32 i = 0; i < KeyLength; i++)
347
this->keyExpansion();
63
EVP_CIPHER_CTX_init(&e_ctx);
66
EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), 0, newkey, iv);
67
else if(keySize == 192)
68
EVP_EncryptInit_ex(&e_ctx, EVP_aes_192_cbc(), 0, newkey, iv);
69
else if(keySize == 128)
70
EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), 0, newkey, iv);
72
EVP_CIPHER_CTX_init(&d_ctx);
75
EVP_DecryptInit_ex(&d_ctx, EVP_aes_256_cbc(), 0, newkey, iv);
76
else if(keySize == 192)
77
EVP_DecryptInit_ex(&d_ctx, EVP_aes_192_cbc(), 0, newkey, iv);
78
else if(keySize == 128)
79
EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), 0, newkey, iv);
355
89
std::string CEncrypterAES::getKey()
360
return std::string((const char*) Key);
363
94
std::list<u32> CEncrypterAES::getPossibleKeyLengths()