2 ---------------------------------------------------------------------------
\r
3 Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
\r
7 The redistribution and use of this software (with or without changes)
\r
8 is allowed without the payment of fees or royalties provided that:
\r
10 1. source code distributions include the above copyright notice, this
\r
11 list of conditions and the following disclaimer;
\r
13 2. binary distributions include the above copyright notice, this list
\r
14 of conditions and the following disclaimer in their documentation;
\r
16 3. the name of the copyright holder is not used to endorse products
\r
17 built using this software without specific written permission.
\r
21 This software is provided 'as is' with no explicit or implied warranties
\r
22 in respect of its properties, including, but not limited to, correctness
\r
23 and/or fitness for purpose.
\r
24 ---------------------------------------------------------------------------
\r
25 Issue Date: 20/12/2007
\r
33 #if defined(FIXED_TABLES)
\r
35 #define sb_data(w) {\
\r
36 w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
\r
37 w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
\r
38 w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
\r
39 w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
\r
40 w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
\r
41 w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
\r
42 w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
\r
43 w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
\r
44 w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
\r
45 w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
\r
46 w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
\r
47 w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
\r
48 w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
\r
49 w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
\r
50 w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
\r
51 w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
\r
52 w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
\r
53 w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
\r
54 w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
\r
55 w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
\r
56 w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
\r
57 w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
\r
58 w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
\r
59 w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
\r
60 w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
\r
61 w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
\r
62 w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
\r
63 w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
\r
64 w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
\r
65 w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
\r
66 w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
\r
67 w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
\r
69 #define isb_data(w) {\
\r
70 w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
\r
71 w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
\r
72 w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
\r
73 w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
\r
74 w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
\r
75 w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
\r
76 w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
\r
77 w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
\r
78 w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
\r
79 w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
\r
80 w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
\r
81 w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
\r
82 w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
\r
83 w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
\r
84 w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
\r
85 w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
\r
86 w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
\r
87 w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
\r
88 w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
\r
89 w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
\r
90 w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
\r
91 w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
\r
92 w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
\r
93 w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
\r
94 w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
\r
95 w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
\r
96 w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
\r
97 w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
\r
98 w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
\r
99 w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
\r
100 w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
\r
101 w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
\r
103 #define mm_data(w) {\
\r
104 w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
\r
105 w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
\r
106 w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
\r
107 w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
\r
108 w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
\r
109 w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
\r
110 w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
\r
111 w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
\r
112 w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
\r
113 w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
\r
114 w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
\r
115 w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
\r
116 w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
\r
117 w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
\r
118 w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
\r
119 w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
\r
120 w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
\r
121 w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
\r
122 w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
\r
123 w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
\r
124 w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
\r
125 w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
\r
126 w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
\r
127 w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
\r
128 w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
\r
129 w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
\r
130 w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
\r
131 w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
\r
132 w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
\r
133 w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
\r
134 w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
\r
135 w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
\r
137 #define rc_data(w) {\
\r
138 w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
\r
143 #define w0(p) bytes2word(p, 0, 0, 0)
\r
144 #define w1(p) bytes2word(0, p, 0, 0)
\r
145 #define w2(p) bytes2word(0, 0, p, 0)
\r
146 #define w3(p) bytes2word(0, 0, 0, p)
\r
148 #define u0(p) bytes2word(f2(p), p, p, f3(p))
\r
149 #define u1(p) bytes2word(f3(p), f2(p), p, p)
\r
150 #define u2(p) bytes2word(p, f3(p), f2(p), p)
\r
151 #define u3(p) bytes2word(p, p, f3(p), f2(p))
\r
153 #define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
\r
154 #define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
\r
155 #define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
\r
156 #define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
\r
160 #if defined(FIXED_TABLES) || !defined(FF_TABLES)
\r
162 #define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
\r
163 #define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
\r
164 #define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
\r
165 ^ (((x>>5) & 4) * WPOLY))
\r
166 #define f3(x) (f2(x) ^ x)
\r
167 #define f9(x) (f8(x) ^ x)
\r
168 #define fb(x) (f8(x) ^ f2(x) ^ x)
\r
169 #define fd(x) (f8(x) ^ f4(x) ^ x)
\r
170 #define fe(x) (f8(x) ^ f4(x) ^ f2(x))
\r
174 #define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
\r
175 #define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
\r
176 #define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
\r
177 #define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
\r
178 #define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
\r
179 #define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
\r
180 #define fi(x) ((x) ? pow[ 255 - log[x]] : 0)
\r
184 #include "aestab.h"
\r
186 #if defined(__cplusplus)
\r
191 #if defined(FIXED_TABLES)
\r
193 /* implemented in case of wrong call for fixed tables */
\r
195 AES_RETURN aes_init(void)
\r
197 return EXIT_SUCCESS;
\r
200 #else /* dynamic table generation */
\r
202 #if !defined(FF_TABLES)
\r
204 /* Generate the tables for the dynamic table option
\r
206 It will generally be sensible to use tables to compute finite
\r
207 field multiplies and inverses but where memory is scarse this
\r
208 code might sometimes be better. But it only has effect during
\r
209 initialisation so its pretty unimportant in overall terms.
\r
212 /* return 2 ^ (n - 1) where n is the bit number of the highest bit
\r
213 set in x with x in the range 1 < x < 0x00000200. This form is
\r
214 used so that locals within fi can be bytes rather than words
\r
217 static uint_8t hibit(const uint_32t x)
\r
218 { uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
\r
222 return (r + 1) >> 1;
\r
225 /* return the inverse of the finite field element x */
\r
227 static uint_8t gf_inv(const uint_8t x)
\r
228 { uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
\r
236 while(n2 >= n1) /* divide polynomial p2 by p1 */
\r
238 n2 /= n1; /* shift smaller polynomial left */
\r
239 p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
\r
240 v2 ^= v1 * n2; /* shift accumulated value and */
\r
241 n2 = hibit(p2); /* add into result */
\r
246 if(n2) /* repeat with values swapped */
\r
261 /* The forward and inverse affine transformations used in the S-box */
\r
262 uint_8t fwd_affine(const uint_8t x)
\r
264 w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
\r
265 return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
\r
268 uint_8t inv_affine(const uint_8t x)
\r
270 w = (w << 1) ^ (w << 3) ^ (w << 6);
\r
271 return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
\r
274 static int init = 0;
\r
276 AES_RETURN aes_init(void)
\r
279 #if defined(FF_TABLES)
\r
281 uint_8t pow[512], log[256];
\r
284 return EXIT_SUCCESS;
\r
285 /* log and power tables for GF(2^8) finite field with
\r
286 WPOLY as modular polynomial - the simplest primitive
\r
287 root is 0x03, used here to generate the tables
\r
293 pow[i] = (uint_8t)w;
\r
294 pow[i + 255] = (uint_8t)w;
\r
295 log[w] = (uint_8t)i++;
\r
296 w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
\r
302 return EXIT_SUCCESS;
\r
305 for(i = 0, w = 1; i < RC_LENGTH; ++i)
\r
307 t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
\r
311 for(i = 0; i < 256; ++i)
\r
314 b = fwd_affine(gf_inv((uint_8t)i));
\r
315 w = bytes2word(f2(b), b, b, f3(b));
\r
317 #if defined( SBX_SET )
\r
318 t_set(s,box)[i] = b;
\r
321 #if defined( FT1_SET ) /* tables for a normal encryption round */
\r
324 #if defined( FT4_SET )
\r
325 t_set(f,n)[0][i] = w;
\r
326 t_set(f,n)[1][i] = upr(w,1);
\r
327 t_set(f,n)[2][i] = upr(w,2);
\r
328 t_set(f,n)[3][i] = upr(w,3);
\r
330 w = bytes2word(b, 0, 0, 0);
\r
332 #if defined( FL1_SET ) /* tables for last encryption round (may also */
\r
333 t_set(f,l)[i] = w; /* be used in the key schedule) */
\r
335 #if defined( FL4_SET )
\r
336 t_set(f,l)[0][i] = w;
\r
337 t_set(f,l)[1][i] = upr(w,1);
\r
338 t_set(f,l)[2][i] = upr(w,2);
\r
339 t_set(f,l)[3][i] = upr(w,3);
\r
342 #if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
\r
343 t_set(l,s)[i] = w; /* not of the required form */
\r
345 #if defined( LS4_SET )
\r
346 t_set(l,s)[0][i] = w;
\r
347 t_set(l,s)[1][i] = upr(w,1);
\r
348 t_set(l,s)[2][i] = upr(w,2);
\r
349 t_set(l,s)[3][i] = upr(w,3);
\r
352 b = gf_inv(inv_affine((uint_8t)i));
\r
353 w = bytes2word(fe(b), f9(b), fd(b), fb(b));
\r
355 #if defined( IM1_SET ) /* tables for the inverse mix column operation */
\r
358 #if defined( IM4_SET )
\r
359 t_set(i,m)[0][b] = w;
\r
360 t_set(i,m)[1][b] = upr(w,1);
\r
361 t_set(i,m)[2][b] = upr(w,2);
\r
362 t_set(i,m)[3][b] = upr(w,3);
\r
365 #if defined( ISB_SET )
\r
366 t_set(i,box)[i] = b;
\r
368 #if defined( IT1_SET ) /* tables for a normal decryption round */
\r
371 #if defined( IT4_SET )
\r
372 t_set(i,n)[0][i] = w;
\r
373 t_set(i,n)[1][i] = upr(w,1);
\r
374 t_set(i,n)[2][i] = upr(w,2);
\r
375 t_set(i,n)[3][i] = upr(w,3);
\r
377 w = bytes2word(b, 0, 0, 0);
\r
378 #if defined( IL1_SET ) /* tables for last decryption round */
\r
381 #if defined( IL4_SET )
\r
382 t_set(i,l)[0][i] = w;
\r
383 t_set(i,l)[1][i] = upr(w,1);
\r
384 t_set(i,l)[2][i] = upr(w,2);
\r
385 t_set(i,l)[3][i] = upr(w,3);
\r
389 return EXIT_SUCCESS;
\r
394 #if defined(__cplusplus)
\r