1 /*
2 * aes_tables.c
3 *
4 * generate tables for the AES cipher
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9 /*
10 *
11 * Copyright(c) 2001-2006 Cisco Systems, Inc.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials provided
24 * with the distribution.
25 *
26 * Neither the name of the Cisco Systems, Inc. nor the names of its
27 * contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 * OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44
45 #include <stdio.h>
46 #include "gf2_8.h"
47 #include "crypto_math.h"
48
49
50 unsigned char aes_sbox[256];
51
52 unsigned char aes_inv_sbox[256];
53
54 uint32_t T0[256], T1[256], T2[256], T3[256], T4[256];
55
56
57 #define AES_INVERSE_TEST 0 /* set to 1 to test forward/backwards aes */
58
59 /* functions for precomputing AES values */
60
61 /*
62 * A[] is the 8 x 8 binary matrix (represented as an array of columns,
63 * where each column is an octet) which defines the affine
64 * transformation used in the AES substitution table (Section
65 * 4.2.1 of the spec).
66 */
67
68 uint8_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 };
69
70 /*
71 * b is the 8 bit vector (represented as an octet) used in the affine
72 * transform described above.
73 */
74
75 uint8_t b = 99;
76
77
78 void
aes_init_sbox(void)79 aes_init_sbox(void) {
80 unsigned int i;
81 uint8_t x;
82
83 for (i=0; i < 256; i++) {
84 x = gf2_8_compute_inverse((gf2_8)i);
85 x = A_times_x_plus_b(A, x, b);
86 aes_sbox[i] = x;
87 aes_inv_sbox[x] = i;
88 }
89 }
90
91 void
aes_compute_tables(void)92 aes_compute_tables(void) {
93 int i;
94 uint32_t x1, x2, x3;
95 v32_t tmp;
96
97 /* initialize substitution table */
98 aes_init_sbox();
99
100 /* combine sbox with linear operations to form 8-bit to 32-bit tables */
101 for (i=0; i < 256; i++) {
102 x1 = aes_sbox[i];
103 x2 = gf2_8_shift(x1);
104 x3 = x2 ^ x1;
105
106 tmp.v8[0] = x2;
107 tmp.v8[1] = x1;
108 tmp.v8[2] = x1;
109 tmp.v8[3] = x3;
110 T0[i] = tmp.value;
111
112 tmp.v8[0] = x3;
113 tmp.v8[1] = x2;
114 tmp.v8[2] = x1;
115 tmp.v8[3] = x1;
116 T1[i] = tmp.value;
117
118 tmp.v8[0] = x1;
119 tmp.v8[1] = x3;
120 tmp.v8[2] = x2;
121 tmp.v8[3] = x1;
122 T2[i] = tmp.value;
123
124 tmp.v8[0] = x1;
125 tmp.v8[1] = x1;
126 tmp.v8[2] = x3;
127 tmp.v8[3] = x2;
128 T3[i] = tmp.value;
129
130 }
131 }
132
133
134 /*
135 * the tables U0, U1, U2, U3 implement the aes operations invSubBytes,
136 * invMixColumns, and invShiftRows
137 */
138
139 uint32_t U0[256], U1[256], U2[256], U3[256], U4[256];
140
141 extern uint8_t aes_inv_sbox[256];
142
143 void
aes_compute_inv_tables(void)144 aes_compute_inv_tables(void) {
145 int i;
146 uint8_t x, xe, x9, xd, xb;
147 v32_t tmp;
148
149 /* combine sbox with linear operations to form 8-bit to 32-bit tables */
150 for (i=0; i < 256; i++) {
151 x = aes_inv_sbox[i];
152
153 xe = gf2_8_multiply(0x0e, x);
154 x9 = gf2_8_multiply(0x09, x);
155 xd = gf2_8_multiply(0x0d, x);
156 xb = gf2_8_multiply(0x0b, x);
157
158 tmp.v8[0] = xe;
159 tmp.v8[1] = x9;
160 tmp.v8[2] = xd;
161 tmp.v8[3] = xb;
162 U0[i] = tmp.value;
163
164 tmp.v8[0] = xb;
165 tmp.v8[1] = xe;
166 tmp.v8[2] = x9;
167 tmp.v8[3] = xd;
168 U1[i] = tmp.value;
169
170 tmp.v8[0] = xd;
171 tmp.v8[1] = xb;
172 tmp.v8[2] = xe;
173 tmp.v8[3] = x9;
174 U2[i] = tmp.value;
175
176 tmp.v8[0] = x9;
177 tmp.v8[1] = xd;
178 tmp.v8[2] = xb;
179 tmp.v8[3] = xe;
180 U3[i] = tmp.value;
181
182 tmp.v8[0] = tmp.v8[1] = tmp.v8[2] = tmp.v8[3] = x;
183 U4[i] = tmp.value;
184 }
185 }
186
187
188 /*
189 * aes_test_inverse() returns err_status_ok if aes
190 * encryption and decryption are true inverses of each other, and
191 * returns err_status_algo_fail otherwise
192 */
193
194 #include "err.h"
195
196 err_status_t
197 aes_test_inverse(void);
198
199 #define TABLES_32BIT 1
200
201 #ifndef HIDE_AES_TABLES_MAIN
202
203 int
main(void)204 main(void) {
205 int i;
206
207 aes_init_sbox();
208 aes_compute_inv_tables();
209
210 #if TABLES_32BIT
211 printf("uint32_t U0 = {");
212 for (i=0; i < 256; i++) {
213 if ((i % 4) == 0)
214 printf("\n");
215 printf("0x%0x, ", U0[i]);
216 }
217 printf("\n}\n");
218
219 printf("uint32_t U1 = {");
220 for (i=0; i < 256; i++) {
221 if ((i % 4) == 0)
222 printf("\n");
223 printf("0x%x, ", U1[i]);
224 }
225 printf("\n}\n");
226
227 printf("uint32_t U2 = {");
228 for (i=0; i < 256; i++) {
229 if ((i % 4) == 0)
230 printf("\n");
231 printf("0x%x, ", U2[i]);
232 }
233 printf("\n}\n");
234
235 printf("uint32_t U3 = {");
236 for (i=0; i < 256; i++) {
237 if ((i % 4) == 0)
238 printf("\n");
239 printf("0x%x, ", U3[i]);
240 }
241 printf("\n}\n");
242
243 printf("uint32_t U4 = {");
244 for (i=0; i < 256; i++) {
245 if ((i % 4) == 0)
246 printf("\n");
247 printf("0x%x, ", U4[i]);
248 }
249 printf("\n}\n");
250
251 #else
252
253 printf("uint32_t U0 = {");
254 for (i=0; i < 256; i++) {
255 if ((i % 4) == 0)
256 printf("\n");
257 printf("0x%lx, ", U0[i]);
258 }
259 printf("\n}\n");
260
261 printf("uint32_t U1 = {");
262 for (i=0; i < 256; i++) {
263 if ((i % 4) == 0)
264 printf("\n");
265 printf("0x%lx, ", U1[i]);
266 }
267 printf("\n}\n");
268
269 printf("uint32_t U2 = {");
270 for (i=0; i < 256; i++) {
271 if ((i % 4) == 0)
272 printf("\n");
273 printf("0x%lx, ", U2[i]);
274 }
275 printf("\n}\n");
276
277 printf("uint32_t U3 = {");
278 for (i=0; i < 256; i++) {
279 if ((i % 4) == 0)
280 printf("\n");
281 printf("0x%lx, ", U3[i]);
282 }
283 printf("\n}\n");
284
285 printf("uint32_t U4 = {");
286 for (i=0; i < 256; i++) {
287 if ((i % 4) == 0)
288 printf("\n");
289 printf("0x%lx, ", U4[i]);
290 }
291 printf("\n}\n");
292
293
294 #endif /* TABLES_32BIT */
295
296
297 #if AES_INVERSE_TEST
298 /*
299 * test that aes_encrypt and aes_decrypt are actually
300 * inverses of each other
301 */
302
303 printf("aes inverse test: ");
304 if (aes_test_inverse() == err_status_ok)
305 printf("passed\n");
306 else {
307 printf("failed\n");
308 exit(1);
309 }
310 #endif
311
312 return 0;
313 }
314
315 #endif // HIDE_AES_TABLES_MAIN
316
317 #if AES_INVERSE_TEST
318
319 err_status_t
aes_test_inverse(void)320 aes_test_inverse(void) {
321 v128_t x, y;
322 aes_expanded_key_t expanded_key, decrypt_key;
323 uint8_t plaintext[16] = {
324 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
325 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
326 };
327 uint8_t key[16] = {
328 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
329 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
330 };
331 v128_t k;
332 v128_set_to_zero(&x);
333
334 v128_copy_octet_string(&k, key);
335 v128_copy_octet_string(&x, plaintext);
336 aes_expand_encryption_key(k, expanded_key);
337 aes_expand_decryption_key(k, decrypt_key);
338 aes_encrypt(&x, expanded_key);
339 aes_decrypt(&x, decrypt_key);
340
341 /* compare to expected value then report */
342 v128_copy_octet_string(&y, plaintext);
343
344 if (v128_is_eq(&x, &y))
345 return err_status_ok;
346 return err_status_algo_fail;
347
348 }
349
350 #endif
351