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
183 #include "aestab.h"
\r
185 #if defined(__cplusplus)
\r
190 #if defined(FIXED_TABLES)
\r
192 /* implemented in case of wrong call for fixed tables */
\r
194 AES_RETURN aes_init(void)
\r
196 return EXIT_SUCCESS;
\r
199 #else /* Generate the tables for the dynamic table option */
\r
201 #if defined(FF_TABLES)
\r
203 #define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0)
\r
207 /* It will generally be sensible to use tables to compute finite
\r
208 field multiplies and inverses but where memory is scarse this
\r
209 code might sometimes be better. But it only has effect during
\r
210 initialisation so its pretty unimportant in overall terms.
\r
213 /* return 2 ^ (n - 1) where n is the bit number of the highest bit
\r
214 set in x with x in the range 1 < x < 0x00000200. This form is
\r
215 used so that locals within fi can be bytes rather than words
\r
218 static uint_8t hibit(const uint_32t x)
\r
219 { uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
\r
223 return (r + 1) >> 1;
\r
226 /* return the inverse of the finite field element x */
\r
228 static uint_8t gf_inv(const uint_8t x)
\r
229 { uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
\r
237 while(n2 >= n1) /* divide polynomial p2 by p1 */
\r
239 n2 /= n1; /* shift smaller polynomial left */
\r
240 p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
\r
241 v2 ^= v1 * n2; /* shift accumulated value and */
\r
242 n2 = hibit(p2); /* add into result */
\r
247 if(n2) /* repeat with values swapped */
\r
262 /* The forward and inverse affine transformations used in the S-box */
\r
263 uint_8t fwd_affine(const uint_8t x)
\r
265 w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
\r
266 return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
\r
269 uint_8t inv_affine(const uint_8t x)
\r
271 w = (w << 1) ^ (w << 3) ^ (w << 6);
\r
272 return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
\r
275 static int init = 0;
\r
277 AES_RETURN aes_init(void)
\r
280 #if defined(FF_TABLES)
\r
282 uint_8t pow[512], log[256];
\r
285 return EXIT_SUCCESS;
\r
286 /* log and power tables for GF(2^8) finite field with
\r
287 WPOLY as modular polynomial - the simplest primitive
\r
288 root is 0x03, used here to generate the tables
\r
294 pow[i] = (uint_8t)w;
\r
295 pow[i + 255] = (uint_8t)w;
\r
296 log[w] = (uint_8t)i++;
\r
297 w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
\r
303 return EXIT_SUCCESS;
\r
306 for(i = 0, w = 1; i < RC_LENGTH; ++i)
\r
308 t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
\r
312 for(i = 0; i < 256; ++i)
\r
315 b = fwd_affine(gf_inv((uint_8t)i));
\r
316 w = bytes2word(f2(b), b, b, f3(b));
\r
318 #if defined( SBX_SET )
\r
319 t_set(s,box)[i] = b;
\r
322 #if defined( FT1_SET ) /* tables for a normal encryption round */
\r
325 #if defined( FT4_SET )
\r
326 t_set(f,n)[0][i] = w;
\r
327 t_set(f,n)[1][i] = upr(w,1);
\r
328 t_set(f,n)[2][i] = upr(w,2);
\r
329 t_set(f,n)[3][i] = upr(w,3);
\r
331 w = bytes2word(b, 0, 0, 0);
\r
333 #if defined( FL1_SET ) /* tables for last encryption round (may also */
\r
334 t_set(f,l)[i] = w; /* be used in the key schedule) */
\r
336 #if defined( FL4_SET )
\r
337 t_set(f,l)[0][i] = w;
\r
338 t_set(f,l)[1][i] = upr(w,1);
\r
339 t_set(f,l)[2][i] = upr(w,2);
\r
340 t_set(f,l)[3][i] = upr(w,3);
\r
343 #if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
\r
344 t_set(l,s)[i] = w; /* not of the required form */
\r
346 #if defined( LS4_SET )
\r
347 t_set(l,s)[0][i] = w;
\r
348 t_set(l,s)[1][i] = upr(w,1);
\r
349 t_set(l,s)[2][i] = upr(w,2);
\r
350 t_set(l,s)[3][i] = upr(w,3);
\r
353 b = gf_inv(inv_affine((uint_8t)i));
\r
354 w = bytes2word(fe(b), f9(b), fd(b), fb(b));
\r
356 #if defined( IM1_SET ) /* tables for the inverse mix column operation */
\r
359 #if defined( IM4_SET )
\r
360 t_set(i,m)[0][b] = w;
\r
361 t_set(i,m)[1][b] = upr(w,1);
\r
362 t_set(i,m)[2][b] = upr(w,2);
\r
363 t_set(i,m)[3][b] = upr(w,3);
\r
366 #if defined( ISB_SET )
\r
367 t_set(i,box)[i] = b;
\r
369 #if defined( IT1_SET ) /* tables for a normal decryption round */
\r
372 #if defined( IT4_SET )
\r
373 t_set(i,n)[0][i] = w;
\r
374 t_set(i,n)[1][i] = upr(w,1);
\r
375 t_set(i,n)[2][i] = upr(w,2);
\r
376 t_set(i,n)[3][i] = upr(w,3);
\r
378 w = bytes2word(b, 0, 0, 0);
\r
379 #if defined( IL1_SET ) /* tables for last decryption round */
\r
382 #if defined( IL4_SET )
\r
383 t_set(i,l)[0][i] = w;
\r
384 t_set(i,l)[1][i] = upr(w,1);
\r
385 t_set(i,l)[2][i] = upr(w,2);
\r
386 t_set(i,l)[3][i] = upr(w,3);
\r
390 return EXIT_SUCCESS;
\r
395 #if defined(__cplusplus)
\r