2 * Copyright (c) 2011 The Chromium OS Authors.
3 * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
25 * advanced encryption standard
26 * author: karl malbrain, malbrain@yahoo.com
28 * This work, including the source code, documentation
29 * and related data, is placed into the public domain.
31 * The orginal author is Karl Malbrain.
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.
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
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
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
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
189 * modular multiplication tables based on:
191 * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
192 * Xtime3[x] = x^Xtime2[x];
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
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
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
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
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
339 static void shift_rows(u8 *state)
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]];
350 tmp = sbox[state[1]];
351 state[1] = sbox[state[5]];
352 state[5] = sbox[state[9]];
353 state[9] = sbox[state[13]];
357 tmp = sbox[state[2]];
358 state[2] = sbox[state[10]];
360 tmp = sbox[state[6]];
361 state[6] = sbox[state[14]];
365 tmp = sbox[state[15]];
366 state[15] = sbox[state[11]];
367 state[11] = sbox[state[7]];
368 state[7] = sbox[state[3]];
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
377 static void inv_shift_rows(u8 *state)
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]];
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]];
395 tmp = inv_sbox[state[2]];
396 state[2] = inv_sbox[state[10]];
398 tmp = inv_sbox[state[6]];
399 state[6] = inv_sbox[state[14]];
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]];
410 /* recombine and mix each row in a column */
411 static void mix_sub_columns(u8 *state)
413 u8 tmp[4 * AES_STATECOLS];
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]];
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]];
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]];
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]];
455 memcpy(state, tmp, sizeof(tmp));
458 /* restore and un-mix each row in a column */
459 static void inv_mix_sub_columns(u8 *state)
461 u8 tmp[4 * AES_STATECOLS];
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]];
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]];
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]];
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]];
504 for (i = 0; i < 4 * AES_STATECOLS; i++)
505 state[i] = inv_sbox[tmp[i]];
509 * encrypt/decrypt columns of the key
510 * n.b. you can replace this with byte-wise xor if you wish.
512 static void add_round_key(u32 *state, u32 *key)
516 for (idx = 0; idx < 4; idx++)
517 state[idx] ^= key[idx];
520 static u8 rcon[11] = {
521 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
524 /* produce AES_STATECOLS bytes for each round */
525 void aes_expand_key(u8 *key, u8 *expkey)
527 u8 tmp0, tmp1, tmp2, tmp3, tmp4;
530 memcpy(expkey, key, AES_KEYCOLS * 4);
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)) {
540 tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
543 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
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;
557 /* encrypt one 128 bit block */
558 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
560 u8 state[AES_STATECOLS * 4];
563 memcpy(state, in, AES_STATECOLS * 4);
564 add_round_key((u32 *)state, (u32 *)expkey);
566 for (round = 1; round < AES_ROUNDS + 1; round++) {
567 if (round < AES_ROUNDS)
568 mix_sub_columns(state);
572 add_round_key((u32 *)state,
573 (u32 *)expkey + round * AES_STATECOLS);
576 memcpy(out, state, sizeof(state));
579 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
581 u8 state[AES_STATECOLS * 4];
584 memcpy(state, in, sizeof(state));
586 add_round_key((u32 *)state,
587 (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
588 inv_shift_rows(state);
590 for (round = AES_ROUNDS; round--; ) {
591 add_round_key((u32 *)state,
592 (u32 *)expkey + round * AES_STATECOLS);
594 inv_mix_sub_columns(state);
597 memcpy(out, state, sizeof(state));