]> git.ipfire.org Git - people/ms/u-boot.git/blob - lib/aes.c
Add AES crypto library
[people/ms/u-boot.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 }