1
// ---------------------------------------------------------------------------
3
// - afnix:sec module - eas (rijndael) class implementation -
4
// ---------------------------------------------------------------------------
5
// - This program is free software; you can redistribute it and/or modify -
6
// - it provided that this copyright notice is kept intact. -
8
// - This program is distributed in the hope that it will be useful, but -
9
// - without any warranty; without even the implied warranty of -
10
// - merchantability or fitness for a particular purpose. In no event shall -
11
// - the copyright holder be liable for any direct, indirect, incidental or -
12
// - special damages arising in any way out of the use of this software. -
13
// ---------------------------------------------------------------------------
14
// - copyright (c) 1999-2011 amaury darsch -
15
// ---------------------------------------------------------------------------
22
// -------------------------------------------------------------------------
23
// - private section -
24
// -------------------------------------------------------------------------
26
// aes state definitions
27
static const long AES_STATE_COL = 4;
28
static const long AES_STATE_ROW = 4;
29
static const long AES_STATE_LEN = AES_STATE_COL * AES_STATE_ROW;
31
// aes block cipher constants
32
static const char* AES_ALGO_NAME = "AES";
33
static const long AES_BLOK_SIZE = AES_STATE_LEN;
35
// aes valid keys constants
36
static const long AES_K128_BITS = 128;
37
static const long AES_K192_BITS = 192;
38
static const long AES_K256_BITS = 256;
41
const t_byte AES_FORWARD_SBOX [256] = {
42
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
43
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
44
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
45
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
46
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
47
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
48
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
49
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
50
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
51
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
52
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
53
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
54
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
55
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
56
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
57
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
58
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
59
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
60
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
61
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
62
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
63
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
64
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
65
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
66
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
67
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
68
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
69
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
70
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
71
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
72
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
73
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
77
const t_byte AES_REVERSE_SBOX [256] = {
78
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
79
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
80
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
81
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
82
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
83
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
84
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
85
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
86
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
87
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
88
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
89
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
90
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
91
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
92
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
93
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
94
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
95
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
96
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
97
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
98
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
99
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
100
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
101
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
102
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
103
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
104
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
105
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
106
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
107
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
108
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
109
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
112
// multiplication in CF2(8) with 0x02
113
const t_byte AES_MULT_02 [256] = {
114
0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
115
0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,
116
0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E,
117
0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E,
118
0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E,
119
0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E,
120
0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E,
121
0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E,
122
0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E,
123
0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E,
124
0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE,
125
0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE,
126
0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
127
0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
128
0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
129
0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE,
130
0x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15,
131
0x0B, 0x09, 0x0F, 0x0D, 0x03, 0x01, 0x07, 0x05,
132
0x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35,
133
0x2B, 0x29, 0x2F, 0x2D, 0x23, 0x21, 0x27, 0x25,
134
0x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55,
135
0x4B, 0x49, 0x4F, 0x4D, 0x43, 0x41, 0x47, 0x45,
136
0x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75,
137
0x6B, 0x69, 0x6F, 0x6D, 0x63, 0x61, 0x67, 0x65,
138
0x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95,
139
0x8B, 0x89, 0x8F, 0x8D, 0x83, 0x81, 0x87, 0x85,
140
0xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5,
141
0xAB, 0xA9, 0xAF, 0xAD, 0xA3, 0xA1, 0xA7, 0xA5,
142
0xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5,
143
0xCB, 0xC9, 0xCF, 0xCD, 0xC3, 0xC1, 0xC7, 0xC5,
144
0xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5,
145
0xEB, 0xE9, 0xEF, 0xED, 0xE3, 0xE1, 0xE7, 0xE5
148
// multiplication in CF2(8) with 0x03
149
const t_byte AES_MULT_03 [256] = {
150
0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09,
151
0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11,
152
0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39,
153
0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21,
154
0x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69,
155
0x78, 0x7B, 0x7E, 0x7D, 0x74, 0x77, 0x72, 0x71,
156
0x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59,
157
0x48, 0x4B, 0x4E, 0x4D, 0x44, 0x47, 0x42, 0x41,
158
0xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9,
159
0xD8, 0xDB, 0xDE, 0xDD, 0xD4, 0xD7, 0xD2, 0xD1,
160
0xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9,
161
0xE8, 0xEB, 0xEE, 0xED, 0xE4, 0xE7, 0xE2, 0xE1,
162
0xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9,
163
0xB8, 0xBB, 0xBE, 0xBD, 0xB4, 0xB7, 0xB2, 0xB1,
164
0x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99,
165
0x88, 0x8B, 0x8E, 0x8D, 0x84, 0x87, 0x82, 0x81,
166
0x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92,
167
0x83, 0x80, 0x85, 0x86, 0x8F, 0x8C, 0x89, 0x8A,
168
0xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2,
169
0xB3, 0xB0, 0xB5, 0xB6, 0xBF, 0xBC, 0xB9, 0xBA,
170
0xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2,
171
0xE3, 0xE0, 0xE5, 0xE6, 0xEF, 0xEC, 0xE9, 0xEA,
172
0xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2,
173
0xD3, 0xD0, 0xD5, 0xD6, 0xDF, 0xDC, 0xD9, 0xDA,
174
0x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52,
175
0x43, 0x40, 0x45, 0x46, 0x4F, 0x4C, 0x49, 0x4A,
176
0x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62,
177
0x73, 0x70, 0x75, 0x76, 0x7F, 0x7C, 0x79, 0x7A,
178
0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32,
179
0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A,
180
0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02,
181
0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A
184
// multiplication in CF2(8) with 0x09
185
const t_byte AES_MULT_09 [256] = {
186
0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F,
187
0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77,
188
0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF,
189
0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7,
190
0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04,
191
0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C,
192
0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94,
193
0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC,
194
0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49,
195
0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01,
196
0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9,
197
0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91,
198
0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72,
199
0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A,
200
0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2,
201
0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA,
202
0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3,
203
0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B,
204
0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43,
205
0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B,
206
0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8,
207
0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0,
208
0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78,
209
0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30,
210
0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5,
211
0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED,
212
0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35,
213
0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D,
214
0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E,
215
0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6,
216
0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E,
217
0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46
220
// multiplication in CF2(8) with 0x0B
221
const t_byte AES_MULT_0B [256] = {
222
0x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31,
223
0x58, 0x53, 0x4E, 0x45, 0x74, 0x7F, 0x62, 0x69,
224
0xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81,
225
0xE8, 0xE3, 0xFE, 0xF5, 0xC4, 0xCF, 0xD2, 0xD9,
226
0x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A,
227
0x23, 0x28, 0x35, 0x3E, 0x0F, 0x04, 0x19, 0x12,
228
0xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA,
229
0x93, 0x98, 0x85, 0x8E, 0xBF, 0xB4, 0xA9, 0xA2,
230
0xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7,
231
0xAE, 0xA5, 0xB8, 0xB3, 0x82, 0x89, 0x94, 0x9F,
232
0x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77,
233
0x1E, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2F,
234
0x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC,
235
0xD5, 0xDE, 0xC3, 0xC8, 0xF9, 0xF2, 0xEF, 0xE4,
236
0x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C,
237
0x65, 0x6E, 0x73, 0x78, 0x49, 0x42, 0x5F, 0x54,
238
0xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6,
239
0xAF, 0xA4, 0xB9, 0xB2, 0x83, 0x88, 0x95, 0x9E,
240
0x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76,
241
0x1F, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2E,
242
0x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD,
243
0xD4, 0xDF, 0xC2, 0xC9, 0xF8, 0xF3, 0xEE, 0xE5,
244
0x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D,
245
0x64, 0x6F, 0x72, 0x79, 0x48, 0x43, 0x5E, 0x55,
246
0x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30,
247
0x59, 0x52, 0x4F, 0x44, 0x75, 0x7E, 0x63, 0x68,
248
0xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80,
249
0xE9, 0xE2, 0xFF, 0xF4, 0xC5, 0xCE, 0xD3, 0xD8,
250
0x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B,
251
0x22, 0x29, 0x34, 0x3F, 0x0E, 0x05, 0x18, 0x13,
252
0xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB,
253
0x92, 0x99, 0x84, 0x8F, 0xBE, 0xB5, 0xA8, 0xA3
256
// multiplication in CF2(8) with 0x0D
257
const t_byte AES_MULT_0D [256] = {
258
0x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23,
259
0x68, 0x65, 0x72, 0x7F, 0x5C, 0x51, 0x46, 0x4B,
260
0xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3,
261
0xB8, 0xB5, 0xA2, 0xAF, 0x8C, 0x81, 0x96, 0x9B,
262
0xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98,
263
0xD3, 0xDE, 0xC9, 0xC4, 0xE7, 0xEA, 0xFD, 0xF0,
264
0x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48,
265
0x03, 0x0E, 0x19, 0x14, 0x37, 0x3A, 0x2D, 0x20,
266
0x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E,
267
0x05, 0x08, 0x1F, 0x12, 0x31, 0x3C, 0x2B, 0x26,
268
0xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E,
269
0xD5, 0xD8, 0xCF, 0xC2, 0xE1, 0xEC, 0xFB, 0xF6,
270
0xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5,
271
0xBE, 0xB3, 0xA4, 0xA9, 0x8A, 0x87, 0x90, 0x9D,
272
0x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25,
273
0x6E, 0x63, 0x74, 0x79, 0x5A, 0x57, 0x40, 0x4D,
274
0xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9,
275
0xB2, 0xBF, 0xA8, 0xA5, 0x86, 0x8B, 0x9C, 0x91,
276
0x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29,
277
0x62, 0x6F, 0x78, 0x75, 0x56, 0x5B, 0x4C, 0x41,
278
0x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42,
279
0x09, 0x04, 0x13, 0x1E, 0x3D, 0x30, 0x27, 0x2A,
280
0xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92,
281
0xD9, 0xD4, 0xC3, 0xCE, 0xED, 0xE0, 0xF7, 0xFA,
282
0xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94,
283
0xDF, 0xD2, 0xC5, 0xC8, 0xEB, 0xE6, 0xF1, 0xFC,
284
0x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44,
285
0x0F, 0x02, 0x15, 0x18, 0x3B, 0x36, 0x21, 0x2C,
286
0x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F,
287
0x64, 0x69, 0x7E, 0x73, 0x50, 0x5D, 0x4A, 0x47,
288
0xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF,
289
0xB4, 0xB9, 0xAE, 0xA3, 0x80, 0x8D, 0x9A, 0x97
292
// multiplication in CF2(8) with 0x0E
293
const t_byte AES_MULT_0E [256] = {
294
0x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A,
295
0x70, 0x7E, 0x6C, 0x62, 0x48, 0x46, 0x54, 0x5A,
296
0xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA,
297
0x90, 0x9E, 0x8C, 0x82, 0xA8, 0xA6, 0xB4, 0xBA,
298
0xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1,
299
0xAB, 0xA5, 0xB7, 0xB9, 0x93, 0x9D, 0x8F, 0x81,
300
0x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11,
301
0x4B, 0x45, 0x57, 0x59, 0x73, 0x7D, 0x6F, 0x61,
302
0xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87,
303
0xDD, 0xD3, 0xC1, 0xCF, 0xE5, 0xEB, 0xF9, 0xF7,
304
0x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67,
305
0x3D, 0x33, 0x21, 0x2F, 0x05, 0x0B, 0x19, 0x17,
306
0x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C,
307
0x06, 0x08, 0x1A, 0x14, 0x3E, 0x30, 0x22, 0x2C,
308
0x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC,
309
0xE6, 0xE8, 0xFA, 0xF4, 0xDE, 0xD0, 0xC2, 0xCC,
310
0x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B,
311
0x31, 0x3F, 0x2D, 0x23, 0x09, 0x07, 0x15, 0x1B,
312
0xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B,
313
0xD1, 0xDF, 0xCD, 0xC3, 0xE9, 0xE7, 0xF5, 0xFB,
314
0x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0,
315
0xEA, 0xE4, 0xF6, 0xF8, 0xD2, 0xDC, 0xCE, 0xC0,
316
0x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50,
317
0x0A, 0x04, 0x16, 0x18, 0x32, 0x3C, 0x2E, 0x20,
318
0xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6,
319
0x9C, 0x92, 0x80, 0x8E, 0xA4, 0xAA, 0xB8, 0xB6,
320
0x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26,
321
0x7C, 0x72, 0x60, 0x6E, 0x44, 0x4A, 0x58, 0x56,
322
0x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D,
323
0x47, 0x49, 0x5B, 0x55, 0x7F, 0x71, 0x63, 0x6D,
324
0xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD,
325
0xA7, 0xA9, 0xBB, 0xB5, 0x9F, 0x91, 0x83, 0x8D
329
const t_byte AES_RCON[10] = {
330
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
334
// map key type to cipher round
335
static inline long aes_key_round (const Key& key) {
336
if (key.gettype () == Key::KSYM) {
337
// 128 bits: 10 rounds
338
if (key.getbits () == AES_K128_BITS) return 10;
339
// 192 bits: 12 rounds
340
if (key.getbits () == AES_K192_BITS) return 12;
341
// 256 bits: 14 rounds
342
if (key.getbits () == AES_K256_BITS) return 14;
344
throw Exception ("aes-error", "invalid key type or size with aes");
348
static inline void aes_key_rotw (t_byte* word) {
356
// substitute a key word
357
static inline void aes_key_subw (t_byte* word) {
358
word[0] = AES_FORWARD_SBOX[word[0]];
359
word[1] = AES_FORWARD_SBOX[word[1]];
360
word[2] = AES_FORWARD_SBOX[word[2]];
361
word[3] = AES_FORWARD_SBOX[word[3]];
364
// mix a key word with a round constant
365
static inline void aes_key_mixw (t_byte* word, const long ri) {
366
word[0] = word[0] ^ AES_RCON[ri];
367
word[1] = word[1] ^ 0x00;
368
word[2] = word[2] ^ 0x00;
369
word[3] = word[3] ^ 0x00;
373
static void aes_key_expand (t_byte* rkey, const long rksz, const Key& key) {
374
// key size in bytes and words
375
long cksz = key.getsize ();
376
long kwsz = cksz / 4;
377
// copy the key at the beginning
378
for (long i = 0; i < cksz; i++) rkey[i] = key.getbyte (i);
380
for (long i = cksz; i < rksz; i+= 4) {
390
if ((wi % kwsz) == 0) {
393
// substitute the word
395
// mix with the round constant
396
aes_key_mixw (word, wi/kwsz-1);
397
} else if ((kwsz > 6) && ((wi % kwsz) == 4)) {
401
rkey[i] = rkey[i - cksz] ^ word[0];
402
rkey[i+1] = rkey[i + 1 - cksz] ^ word[1];
403
rkey[i+2] = rkey[i + 2 - cksz] ^ word[2];
404
rkey[i+3] = rkey[i + 3 - cksz] ^ word[3];
408
// state byte substitute with s-box
409
static void aes_state_sub_bytes (t_byte* state) {
410
if (state == nilp) return;
411
for (long i = 0; i < AES_STATE_LEN; i++) {
413
state[i] = AES_FORWARD_SBOX[idx];
417
// shift the state rows
418
static void aes_state_shift_rows (t_byte* state) {
419
// check state and compute columns
420
if (state == nilp) return;
422
t_byte s10 = state[1];
425
state[9] = state[13];
428
t_byte s20 = state[2];
429
t_byte s21 = state[6];
430
state[2] = state[10];
431
state[6] = state[14];
435
t_byte s30 = state[3];
436
t_byte s31 = state[7];
437
t_byte s32 = state[11];
438
state[3] = state[15];
444
// mix the state column
445
static void aes_state_mix_columns (t_byte* state) {
446
if (state == nilp) return;
447
for (long i = 0; i < AES_STATE_COL; i++) {
449
t_byte s0 = state[i*4];
450
t_byte s1 = state[i*4+1];
451
t_byte s2 = state[i*4+2];
452
t_byte s3 = state[i*4+3];
453
// mix column by multiplication
454
t_byte r0 = AES_MULT_02[s0] ^ AES_MULT_03[s1] ^ s2 ^ s3;
455
t_byte r1 = s0 ^ AES_MULT_02[s1] ^ AES_MULT_03[s2] ^ s3;
456
t_byte r2 = s0 ^ s1 ^ AES_MULT_02[s2] ^ AES_MULT_03[s3];
457
t_byte r3 = AES_MULT_03[s0] ^ s1 ^ s2 ^ AES_MULT_02[s3];
466
// add the round key to the state
467
static void aes_state_add_round_key (t_byte* state, const t_byte* rkey,
469
if ((state == nilp) || (rkey == nilp)) return;
470
long ridx = round * AES_STATE_LEN;
471
for (long i = 0; i < AES_STATE_LEN; i++) {
472
state[i] = state[i] ^ rkey[ridx+i];
476
// state byte substitute with reverse s-box
477
static void aes_inv_state_sub_bytes (t_byte* state) {
478
if (state == nilp) return;
479
for (long i = 0; i < AES_STATE_LEN; i++) {
481
state[i] = AES_REVERSE_SBOX[idx];
485
// shift the state rows
486
static void aes_inv_state_shift_rows (t_byte* state) {
487
// check state and compute columns
488
if (state == nilp) return;
490
t_byte s13 = state[13];
491
state[13] = state[9];
496
t_byte s23 = state[14];
497
t_byte s22 = state[10];
498
state[14] = state[6];
499
state[10] = state[2];
503
t_byte s33 = state[15];
504
t_byte s32 = state[11];
505
t_byte s31 = state[7];
506
state[15] = state[3];
512
// mix the state column
513
static void aes_inv_state_mix_columns (t_byte* state) {
514
if (state == nilp) return;
515
for (long i = 0; i < AES_STATE_COL; i++) {
517
t_byte s0 = state[i*4];
518
t_byte s1 = state[i*4+1];
519
t_byte s2 = state[i*4+2];
520
t_byte s3 = state[i*4+3];
521
// mix column by multiplication
522
t_byte r0 = AES_MULT_0E[s0] ^ AES_MULT_0B[s1] ^
523
AES_MULT_0D[s2] ^ AES_MULT_09[s3];
524
t_byte r1 = AES_MULT_09[s0] ^ AES_MULT_0E[s1] ^
525
AES_MULT_0B[s2] ^ AES_MULT_0D[s3];
526
t_byte r2 = AES_MULT_0D[s0] ^ AES_MULT_09[s1] ^
527
AES_MULT_0E[s2] ^ AES_MULT_0B[s3];
528
t_byte r3 = AES_MULT_0B[s0] ^ AES_MULT_0D[s1] ^
529
AES_MULT_09[s2] ^ AES_MULT_0E[s3];
539
// -------------------------------------------------------------------------
541
// -------------------------------------------------------------------------
543
// create an aes cipher by key
545
Aes::Aes (const Key& key) : BlockCipher (AES_ALGO_NAME, AES_BLOK_SIZE) {
546
// initialize the cipher
547
d_rnum = aes_key_round (d_ckey);
548
d_rksz = AES_STATE_LEN * (d_rnum + 1);
549
p_rkey = new t_byte[d_rksz];
554
// create an aes cipher by key and flag
556
Aes::Aes (const Key& key,
557
const bool rflg) : BlockCipher (AES_ALGO_NAME, AES_BLOK_SIZE) {
558
// initialize the cipher
559
d_rnum = aes_key_round (d_ckey);
560
d_rksz = AES_STATE_LEN * (d_rnum + 1);
561
p_rkey = new t_byte[d_rksz];
564
// set the reverse flag
568
// destroy this cipher
574
// return the class name
576
String Aes::repr (void) const {
582
void Aes::reset (void) {
585
// reset the block cipher
586
BlockCipher::reset ();
587
// round key and state buffer reset
588
for (long i = 0; i < d_rksz; i++) p_rkey[i] = nilc;
590
aes_key_expand (p_rkey, d_rksz, d_ckey);
598
// encode a block buffer into another one
600
void Aes::encode (t_byte* bo, const t_byte* bi) {
603
// copy the input buffer to the state
605
for (long i = 0; i < AES_STATE_LEN; i++) cbuf[i] = bi[i];
607
aes_state_add_round_key (cbuf, p_rkey, 0);
608
// loop for all rounds
609
for (long i = 1; i < d_rnum; i++) {
610
aes_state_sub_bytes (cbuf);
611
aes_state_shift_rows (cbuf);
612
aes_state_mix_columns (cbuf);
613
aes_state_add_round_key (cbuf, p_rkey, i);
615
aes_state_sub_bytes (cbuf);
616
aes_state_shift_rows (cbuf);
617
aes_state_add_round_key (cbuf, p_rkey, d_rnum);
618
// copy the state to the output buffer
619
for (long i = 0; i < AES_STATE_LEN; i++) bo[i] = cbuf[i];
627
// decode a block buffer into another one
629
void Aes::decode (t_byte* bo, const t_byte* bi) {
632
// copy the input buffer to the state
634
for (long i = 0; i < AES_STATE_LEN; i++) cbuf[i] = bi[i];
636
aes_state_add_round_key (cbuf, p_rkey, d_rnum);
637
// loop for all rounds
638
for (long i = d_rnum-1; i > 0; i--) {
639
aes_inv_state_shift_rows (cbuf);
640
aes_inv_state_sub_bytes (cbuf);
641
aes_state_add_round_key (cbuf, p_rkey, i);
642
aes_inv_state_mix_columns (cbuf);
644
aes_inv_state_shift_rows (cbuf);
645
aes_inv_state_sub_bytes (cbuf);
646
aes_state_add_round_key (cbuf, p_rkey, 0);
647
// copy the state to the output buffer
648
for (long i = 0; i < AES_STATE_LEN; i++) bo[i] = cbuf[i];
656
// -------------------------------------------------------------------------
658
// -------------------------------------------------------------------------
660
// create a new object in a generic way
662
Object* Aes::mknew (Vector* argv) {
663
long argc = (argv == nilp) ? 0 : argv->length ();
664
// check for 1 argument
667
Object* obj = argv->get (0);
668
Key* key = dynamic_cast <Key*> (obj);
669
if (key != nilp) return new Aes (*key);
670
throw Exception ("argument-error", "invalid arguments with aes");
672
// check for 2 arguments
675
Object* obj = argv->get (0);
676
Key* key = dynamic_cast <Key*> (obj);
678
throw Exception ("argument-error", "invalid arguments with aes");
680
// get the reverse flag and object
681
bool rflg = argv->getbool (1);
682
return new Aes (*key, rflg);
684
throw Exception ("argument-error", "too many arguments with aes");