]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - lib/aes.c
tools/mkenvimage.c: fix basename(3) usage
[karo-tx-uboot.git] / lib / aes.c
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * advanced encryption standard
26  * author: karl malbrain, malbrain@yahoo.com
27  *
28  * This work, including the source code, documentation
29  * and related data, is placed into the public domain.
30  *
31  * The orginal author is Karl Malbrain.
32  *
33  * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
34  * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
35  * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
36  * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
37  * RESULTING FROM THE USE, MODIFICATION, OR
38  * REDISTRIBUTION OF THIS SOFTWARE.
39 */
40
41 #include <common.h>
42 #include "aes.h"
43
44 /* forward s-box */
45 static const u8 sbox[256] = {
46         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
47         0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
48         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
49         0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
50         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
51         0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
52         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
53         0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
54         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
55         0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
56         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
57         0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
58         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
59         0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
60         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
61         0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
62         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
63         0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
64         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
65         0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
66         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
67         0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
68         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
69         0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
70         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
71         0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
72         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
73         0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
74         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
75         0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
76         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
77         0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
78 };
79
80 /* inverse s-box */
81 static const u8 inv_sbox[256] = {
82         0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
83         0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
84         0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
85         0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
86         0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
87         0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
88         0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
89         0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
90         0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
91         0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
92         0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
93         0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
94         0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
95         0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
96         0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
97         0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
98         0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
99         0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
100         0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
101         0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
102         0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
103         0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
104         0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
105         0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
106         0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
107         0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
108         0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
109         0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
110         0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
111         0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
112         0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
113         0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
114 };
115
116 /* combined Xtimes2[Sbox[]] */
117 static const u8 x2_sbox[256] = {
118         0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
119         0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
120         0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
121         0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
122         0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
123         0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
124         0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
125         0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
126         0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
127         0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
128         0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
129         0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
130         0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
131         0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
132         0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
133         0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
134         0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
135         0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
136         0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
137         0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
138         0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
139         0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
140         0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
141         0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
142         0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
143         0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
144         0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
145         0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
146         0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
147         0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
148         0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
149         0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
150 };
151
152 /* combined Xtimes3[Sbox[]] */
153 static const u8 x3_sbox[256] = {
154         0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
155         0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
156         0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
157         0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
158         0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
159         0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
160         0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
161         0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
162         0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
163         0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
164         0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
165         0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
166         0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
167         0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
168         0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
169         0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
170         0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
171         0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
172         0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
173         0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
174         0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
175         0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
176         0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
177         0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
178         0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
179         0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
180         0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
181         0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
182         0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
183         0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
184         0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
185         0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
186 };
187
188 /*
189  * modular multiplication tables based on:
190  *
191  * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
192  * Xtime3[x] = x^Xtime2[x];
193  */
194 static const u8 x_time_9[256] = {
195         0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
196         0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
197         0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
198         0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
199         0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
200         0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
201         0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
202         0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
203         0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
204         0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
205         0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
206         0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
207         0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
208         0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
209         0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
210         0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
211         0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
212         0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
213         0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
214         0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
215         0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
216         0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
217         0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
218         0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
219         0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
220         0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
221         0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
222         0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
223         0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
224         0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
225         0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
226         0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
227 };
228
229 static const u8 x_time_b[256] = {
230         0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
231         0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
232         0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
233         0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
234         0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
235         0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
236         0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
237         0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
238         0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
239         0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
240         0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
241         0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
242         0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
243         0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
244         0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
245         0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
246         0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
247         0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
248         0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
249         0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
250         0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
251         0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
252         0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
253         0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
254         0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
255         0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
256         0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
257         0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
258         0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
259         0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
260         0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
261         0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
262 };
263
264 static const u8 x_time_d[256] = {
265         0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
266         0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
267         0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
268         0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
269         0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
270         0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
271         0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
272         0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
273         0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
274         0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
275         0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
276         0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
277         0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
278         0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
279         0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
280         0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
281         0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
282         0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
283         0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
284         0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
285         0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
286         0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
287         0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
288         0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
289         0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
290         0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
291         0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
292         0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
293         0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
294         0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
295         0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
296         0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
297 };
298
299 static const u8 x_time_e[256] = {
300         0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
301         0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
302         0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
303         0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
304         0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
305         0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
306         0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
307         0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
308         0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
309         0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
310         0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
311         0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
312         0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
313         0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
314         0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
315         0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
316         0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
317         0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
318         0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
319         0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
320         0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
321         0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
322         0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
323         0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
324         0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
325         0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
326         0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
327         0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
328         0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
329         0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
330         0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
331         0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
332 };
333
334 /*
335  * Exchanges columns in each of 4 rows
336  * row0 - unchanged, row1- shifted left 1,
337  * row2 - shifted left 2 and row3 - shifted left 3
338  */
339 static void shift_rows(u8 *state)
340 {
341         u8 tmp;
342
343         /* just substitute row 0 */
344         state[0] = sbox[state[0]];
345         state[4] = sbox[state[4]];
346         state[8] = sbox[state[8]];
347         state[12] = sbox[state[12]];
348
349         /* rotate row 1 */
350         tmp = sbox[state[1]];
351         state[1] = sbox[state[5]];
352         state[5] = sbox[state[9]];
353         state[9] = sbox[state[13]];
354         state[13] = tmp;
355
356         /* rotate row 2 */
357         tmp = sbox[state[2]];
358         state[2] = sbox[state[10]];
359         state[10] = tmp;
360         tmp = sbox[state[6]];
361         state[6] = sbox[state[14]];
362         state[14] = tmp;
363
364         /* rotate row 3 */
365         tmp = sbox[state[15]];
366         state[15] = sbox[state[11]];
367         state[11] = sbox[state[7]];
368         state[7] = sbox[state[3]];
369         state[3] = tmp;
370 }
371
372 /*
373  * restores columns in each of 4 rows
374  * row0 - unchanged, row1- shifted right 1,
375  * row2 - shifted right 2 and row3 - shifted right 3
376  */
377 static void inv_shift_rows(u8 *state)
378 {
379         u8 tmp;
380
381         /* restore row 0 */
382         state[0] = inv_sbox[state[0]];
383         state[4] = inv_sbox[state[4]];
384         state[8] = inv_sbox[state[8]];
385         state[12] = inv_sbox[state[12]];
386
387         /* restore row 1 */
388         tmp = inv_sbox[state[13]];
389         state[13] = inv_sbox[state[9]];
390         state[9] = inv_sbox[state[5]];
391         state[5] = inv_sbox[state[1]];
392         state[1] = tmp;
393
394         /* restore row 2 */
395         tmp = inv_sbox[state[2]];
396         state[2] = inv_sbox[state[10]];
397         state[10] = tmp;
398         tmp = inv_sbox[state[6]];
399         state[6] = inv_sbox[state[14]];
400         state[14] = tmp;
401
402         /* restore row 3 */
403         tmp = inv_sbox[state[3]];
404         state[3] = inv_sbox[state[7]];
405         state[7] = inv_sbox[state[11]];
406         state[11] = inv_sbox[state[15]];
407         state[15] = tmp;
408 }
409
410 /* recombine and mix each row in a column */
411 static void mix_sub_columns(u8 *state)
412 {
413         u8 tmp[4 * AES_STATECOLS];
414
415         /* mixing column 0 */
416         tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
417                  sbox[state[10]] ^ sbox[state[15]];
418         tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
419                  x3_sbox[state[10]] ^ sbox[state[15]];
420         tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
421                  x2_sbox[state[10]] ^ x3_sbox[state[15]];
422         tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
423                  sbox[state[10]] ^ x2_sbox[state[15]];
424
425         /* mixing column 1 */
426         tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
427                  sbox[state[14]] ^ sbox[state[3]];
428         tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
429                  x3_sbox[state[14]] ^ sbox[state[3]];
430         tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
431                  x2_sbox[state[14]] ^ x3_sbox[state[3]];
432         tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
433                  sbox[state[14]] ^ x2_sbox[state[3]];
434
435         /* mixing column 2 */
436         tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
437                  sbox[state[2]] ^ sbox[state[7]];
438         tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
439                  x3_sbox[state[2]] ^ sbox[state[7]];
440         tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
441                   x2_sbox[state[2]] ^ x3_sbox[state[7]];
442         tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
443                   sbox[state[2]] ^ x2_sbox[state[7]];
444
445         /* mixing column 3 */
446         tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
447                   sbox[state[6]] ^ sbox[state[11]];
448         tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
449                   x3_sbox[state[6]] ^ sbox[state[11]];
450         tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
451                   x2_sbox[state[6]] ^ x3_sbox[state[11]];
452         tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
453                   sbox[state[6]] ^ x2_sbox[state[11]];
454
455         memcpy(state, tmp, sizeof(tmp));
456 }
457
458 /* restore and un-mix each row in a column */
459 static void inv_mix_sub_columns(u8 *state)
460 {
461         u8 tmp[4 * AES_STATECOLS];
462         int  i;
463
464         /* restore column 0 */
465         tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
466                  x_time_d[state[2]] ^ x_time_9[state[3]];
467         tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
468                  x_time_b[state[2]] ^ x_time_d[state[3]];
469         tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
470                   x_time_e[state[2]] ^ x_time_b[state[3]];
471         tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
472                   x_time_9[state[2]] ^ x_time_e[state[3]];
473
474         /* restore column 1 */
475         tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
476                  x_time_d[state[6]] ^ x_time_9[state[7]];
477         tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
478                  x_time_b[state[6]] ^ x_time_d[state[7]];
479         tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
480                   x_time_e[state[6]] ^ x_time_b[state[7]];
481         tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
482                  x_time_9[state[6]] ^ x_time_e[state[7]];
483
484         /* restore column 2 */
485         tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
486                  x_time_d[state[10]] ^ x_time_9[state[11]];
487         tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
488                   x_time_b[state[10]] ^ x_time_d[state[11]];
489         tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
490                  x_time_e[state[10]] ^ x_time_b[state[11]];
491         tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
492                  x_time_9[state[10]] ^ x_time_e[state[11]];
493
494         /* restore column 3 */
495         tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
496                   x_time_d[state[14]] ^ x_time_9[state[15]];
497         tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
498                  x_time_b[state[14]] ^ x_time_d[state[15]];
499         tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
500                  x_time_e[state[14]] ^ x_time_b[state[15]];
501         tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
502                   x_time_9[state[14]] ^ x_time_e[state[15]];
503
504         for (i = 0; i < 4 * AES_STATECOLS; i++)
505                 state[i] = inv_sbox[tmp[i]];
506 }
507
508 /*
509  * encrypt/decrypt columns of the key
510  * n.b. you can replace this with byte-wise xor if you wish.
511  */
512 static void add_round_key(u32 *state, u32 *key)
513 {
514         int idx;
515
516         for (idx = 0; idx < 4; idx++)
517                 state[idx] ^= key[idx];
518 }
519
520 static u8 rcon[11] = {
521         0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
522 };
523
524 /* produce AES_STATECOLS bytes for each round */
525 void aes_expand_key(u8 *key, u8 *expkey)
526 {
527         u8 tmp0, tmp1, tmp2, tmp3, tmp4;
528         u32 idx;
529
530         memcpy(expkey, key, AES_KEYCOLS * 4);
531
532         for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
533                 tmp0 = expkey[4*idx - 4];
534                 tmp1 = expkey[4*idx - 3];
535                 tmp2 = expkey[4*idx - 2];
536                 tmp3 = expkey[4*idx - 1];
537                 if (!(idx % AES_KEYCOLS)) {
538                         tmp4 = tmp3;
539                         tmp3 = sbox[tmp0];
540                         tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
541                         tmp1 = sbox[tmp2];
542                         tmp2 = sbox[tmp4];
543                 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
544                         tmp0 = sbox[tmp0];
545                         tmp1 = sbox[tmp1];
546                         tmp2 = sbox[tmp2];
547                         tmp3 = sbox[tmp3];
548                 }
549
550                 expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
551                 expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
552                 expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
553                 expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
554         }
555 }
556
557 /* encrypt one 128 bit block */
558 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
559 {
560         u8 state[AES_STATECOLS * 4];
561         u32 round;
562
563         memcpy(state, in, AES_STATECOLS * 4);
564         add_round_key((u32 *)state, (u32 *)expkey);
565
566         for (round = 1; round < AES_ROUNDS + 1; round++) {
567                 if (round < AES_ROUNDS)
568                         mix_sub_columns(state);
569                 else
570                         shift_rows(state);
571
572                 add_round_key((u32 *)state,
573                               (u32 *)expkey + round * AES_STATECOLS);
574         }
575
576         memcpy(out, state, sizeof(state));
577 }
578
579 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
580 {
581         u8 state[AES_STATECOLS * 4];
582         int round;
583
584         memcpy(state, in, sizeof(state));
585
586         add_round_key((u32 *)state,
587                       (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
588         inv_shift_rows(state);
589
590         for (round = AES_ROUNDS; round--; ) {
591                 add_round_key((u32 *)state,
592                               (u32 *)expkey + round * AES_STATECOLS);
593                 if (round)
594                         inv_mix_sub_columns(state);
595         }
596
597         memcpy(out, state, sizeof(state));
598 }