2 ---------------------------------------------------------------------------
3 Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
7 The free distribution and use of this software is allowed (with or without
8 changes) provided that:
10 1. source code distributions include the above copyright notice, this
11 list of conditions and the following disclaimer;
13 2. binary distributions include the above copyright notice, this list
14 of conditions and the following disclaimer in their documentation;
16 3. the name of the copyright holder is not used to endorse products
17 built using this software without specific written permission.
21 This software is provided 'as is' with no explicit or implied warranties
22 in respect of its properties, including, but not limited to, correctness
23 and/or fitness for purpose.
24 ---------------------------------------------------------------------------
25 Issue Date: 20/12/2007
28 /* Adapted for TrueCrypt by the TrueCrypt Foundation:
29 - Added run-time table generator for Aes_x86_v2.asm
37 #if defined(FIXED_TABLES)
40 w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
41 w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
42 w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
43 w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
44 w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
45 w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
46 w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
47 w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
48 w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
49 w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
50 w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
51 w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
52 w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
53 w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
54 w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
55 w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
56 w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
57 w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
58 w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
59 w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
60 w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
61 w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
62 w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
63 w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
64 w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
65 w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
66 w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
67 w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
68 w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
69 w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
70 w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
71 w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
73 #define isb_data(w) {\
74 w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
75 w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
76 w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
77 w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
78 w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
79 w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
80 w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
81 w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
82 w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
83 w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
84 w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
85 w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
86 w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
87 w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
88 w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
89 w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
90 w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
91 w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
92 w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
93 w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
94 w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
95 w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
96 w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
97 w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
98 w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
99 w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
100 w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
101 w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
102 w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
103 w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
104 w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
105 w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
107 #define mm_data(w) {\
108 w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
109 w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
110 w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
111 w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
112 w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
113 w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
114 w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
115 w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
116 w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
117 w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
118 w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
119 w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
120 w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
121 w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
122 w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
123 w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
124 w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
125 w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
126 w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
127 w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
128 w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
129 w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
130 w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
131 w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
132 w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
133 w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
134 w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
135 w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
136 w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
137 w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
138 w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
139 w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
141 #define rc_data(w) {\
142 w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
147 #define w0(p) bytes2word(p, 0, 0, 0)
148 #define w1(p) bytes2word(0, p, 0, 0)
149 #define w2(p) bytes2word(0, 0, p, 0)
150 #define w3(p) bytes2word(0, 0, 0, p)
152 #define u0(p) bytes2word(f2(p), p, p, f3(p))
153 #define u1(p) bytes2word(f3(p), f2(p), p, p)
154 #define u2(p) bytes2word(p, f3(p), f2(p), p)
155 #define u3(p) bytes2word(p, p, f3(p), f2(p))
157 #define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
158 #define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
159 #define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
160 #define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
164 #if defined(FIXED_TABLES) || !defined(FF_TABLES)
166 #define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
167 #define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
168 #define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
169 ^ (((x>>5) & 4) * WPOLY))
170 #define f3(x) (f2(x) ^ x)
171 #define f9(x) (f8(x) ^ x)
172 #define fb(x) (f8(x) ^ f2(x) ^ x)
173 #define fd(x) (f8(x) ^ f4(x) ^ x)
174 #define fe(x) (f8(x) ^ f4(x) ^ f2(x))
178 #define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
179 #define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
180 #define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
181 #define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
182 #define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
183 #define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
184 #define fi(x) ((x) ? pow[ 255 - log[x]] : 0)
190 #if defined(__cplusplus)
195 #if defined(FIXED_TABLES)
197 /* implemented in case of wrong call for fixed tables */
199 AES_RETURN
aes_init(void)
204 #else /* dynamic table generation */
206 #if !defined(FF_TABLES)
208 /* Generate the tables for the dynamic table option
210 It will generally be sensible to use tables to compute finite
211 field multiplies and inverses but where memory is scarse this
212 code might sometimes be better. But it only has effect during
213 initialisation so its pretty unimportant in overall terms.
216 /* return 2 ^ (n - 1) where n is the bit number of the highest bit
217 set in x with x in the range 1 < x < 0x00000200. This form is
218 used so that locals within fi can be bytes rather than words
221 static uint_8t
hibit(const uint_32t x
)
222 { uint_8t r
= (uint_8t
)((x
>> 1) | (x
>> 2));
229 /* return the inverse of the finite field element x */
231 static uint_8t
fi(const uint_8t x
)
232 { uint_8t p1
= x
, p2
= BPOLY
, n1
= hibit(x
), n2
= 0x80, v1
= 1, v2
= 0;
242 n2
/= n1
; p2
^= p1
* n2
; v2
^= v1
* n2
; n2
= hibit(p2
);
249 n1
/= n2
; p1
^= p2
* n1
; v1
^= v2
* n1
; n1
= hibit(p1
);
256 /* The forward and inverse affine transformations used in the S-box */
258 #define fwd_affine(x) \
259 (w = (uint_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(uint_8t)(w^(w>>8)))
261 #define inv_affine(x) \
262 (w = (uint_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(uint_8t)(w^(w>>8)))
266 #ifdef TC_WINDOWS_BOOT
268 #pragma optimize ("l", on)
269 uint_8t aes_enc_tab
[256][8];
270 uint_8t aes_dec_tab
[256][8];
274 AES_RETURN
aes_init(void)
277 #ifdef TC_WINDOWS_BOOT
282 for (i
= 0; i
< 256; ++i
)
284 uint_8t x
= fwd_affine(fi((uint_8t
)i
));
285 aes_enc_tab
[i
][0] = 0;
286 aes_enc_tab
[i
][1] = x
;
287 aes_enc_tab
[i
][2] = x
;
288 aes_enc_tab
[i
][3] = f3(x
);
289 aes_enc_tab
[i
][4] = f2(x
);
290 aes_enc_tab
[i
][5] = x
;
291 aes_enc_tab
[i
][6] = x
;
292 aes_enc_tab
[i
][7] = f3(x
);
294 x
= fi((uint_8t
)inv_affine((uint_8t
)i
));
295 aes_dec_tab
[i
][0] = fe(x
);
296 aes_dec_tab
[i
][1] = f9(x
);
297 aes_dec_tab
[i
][2] = fd(x
);
298 aes_dec_tab
[i
][3] = fb(x
);
299 aes_dec_tab
[i
][4] = fe(x
);
300 aes_dec_tab
[i
][5] = f9(x
);
301 aes_dec_tab
[i
][6] = fd(x
);
302 aes_dec_tab
[i
][7] = x
;
305 #else // TC_WINDOWS_BOOT
307 #if defined(FF_TABLES)
309 uint_8t pow
[512], log
[256];
313 /* log and power tables for GF(2^8) finite field with
314 WPOLY as modular polynomial - the simplest primitive
315 root is 0x03, used here to generate the tables
322 pow
[i
+ 255] = (uint_8t
)w
;
323 log
[w
] = (uint_8t
)i
++;
324 w
^= (w
<< 1) ^ (w
& 0x80 ? WPOLY
: 0);
333 for(i
= 0, w
= 1; i
< RC_LENGTH
; ++i
)
335 t_set(r
,c
)[i
] = bytes2word(w
, 0, 0, 0);
339 for(i
= 0; i
< 256; ++i
)
342 b
= fwd_affine(fi((uint_8t
)i
));
343 w
= bytes2word(f2(b
), b
, b
, f3(b
));
345 #if defined( SBX_SET )
349 #if defined( FT1_SET ) /* tables for a normal encryption round */
352 #if defined( FT4_SET )
353 t_set(f
,n
)[0][i
] = w
;
354 t_set(f
,n
)[1][i
] = upr(w
,1);
355 t_set(f
,n
)[2][i
] = upr(w
,2);
356 t_set(f
,n
)[3][i
] = upr(w
,3);
358 w
= bytes2word(b
, 0, 0, 0);
360 #if defined( FL1_SET ) /* tables for last encryption round (may also */
361 t_set(f
,l
)[i
] = w
; /* be used in the key schedule) */
363 #if defined( FL4_SET )
364 t_set(f
,l
)[0][i
] = w
;
365 t_set(f
,l
)[1][i
] = upr(w
,1);
366 t_set(f
,l
)[2][i
] = upr(w
,2);
367 t_set(f
,l
)[3][i
] = upr(w
,3);
370 #if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
371 t_set(l
,s
)[i
] = w
; /* not of the required form */
373 #if defined( LS4_SET )
374 t_set(l
,s
)[0][i
] = w
;
375 t_set(l
,s
)[1][i
] = upr(w
,1);
376 t_set(l
,s
)[2][i
] = upr(w
,2);
377 t_set(l
,s
)[3][i
] = upr(w
,3);
380 b
= fi(inv_affine((uint_8t
)i
));
381 w
= bytes2word(fe(b
), f9(b
), fd(b
), fb(b
));
383 #if defined( IM1_SET ) /* tables for the inverse mix column operation */
386 #if defined( IM4_SET )
387 t_set(i
,m
)[0][b
] = w
;
388 t_set(i
,m
)[1][b
] = upr(w
,1);
389 t_set(i
,m
)[2][b
] = upr(w
,2);
390 t_set(i
,m
)[3][b
] = upr(w
,3);
393 #if defined( ISB_SET )
396 #if defined( IT1_SET ) /* tables for a normal decryption round */
399 #if defined( IT4_SET )
400 t_set(i
,n
)[0][i
] = w
;
401 t_set(i
,n
)[1][i
] = upr(w
,1);
402 t_set(i
,n
)[2][i
] = upr(w
,2);
403 t_set(i
,n
)[3][i
] = upr(w
,3);
405 w
= bytes2word(b
, 0, 0, 0);
406 #if defined( IL1_SET ) /* tables for last decryption round */
409 #if defined( IL4_SET )
410 t_set(i
,l
)[0][i
] = w
;
411 t_set(i
,l
)[1][i
] = upr(w
,1);
412 t_set(i
,l
)[2][i
] = upr(w
,2);
413 t_set(i
,l
)[3][i
] = upr(w
,3);
417 #endif // TC_WINDOWS_BOOT
425 #if defined(__cplusplus)