2 * Copyright (c) 2011 The Chromium OS Authors.
3 * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
5 * SPDX-License-Identifier: GPL-2.0+
9 * advanced encryption standard
10 * author: karl malbrain, malbrain@yahoo.com
12 * This work, including the source code, documentation
13 * and related data, is placed into the public domain.
15 * The orginal author is Karl Malbrain.
17 * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
18 * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
19 * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
20 * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
21 * RESULTING FROM THE USE, MODIFICATION, OR
22 * REDISTRIBUTION OF THIS SOFTWARE.
29 static const u8 sbox[256] = {
30 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
31 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
32 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
33 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
34 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
35 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
36 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
37 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
38 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
39 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
40 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
41 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
42 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
43 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
44 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
45 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
46 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
47 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
48 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
49 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
50 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
51 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
52 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
53 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
54 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
55 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
56 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
57 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
58 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
59 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
60 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
61 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
65 static const u8 inv_sbox[256] = {
66 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
67 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
68 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
69 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
70 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
71 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
72 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
73 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
74 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
75 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
76 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
77 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
78 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
79 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
80 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
81 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
82 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
83 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
84 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
85 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
86 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
87 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
88 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
89 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
90 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
91 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
92 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
93 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
94 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
95 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
96 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
97 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
100 /* combined Xtimes2[Sbox[]] */
101 static const u8 x2_sbox[256] = {
102 0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
103 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
104 0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
105 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
106 0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
107 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
108 0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
109 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
110 0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
111 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
112 0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
113 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
114 0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
115 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
116 0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
117 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
118 0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
119 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
120 0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
121 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
122 0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
123 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
124 0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
125 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
126 0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
127 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
128 0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
129 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
130 0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
131 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
132 0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
133 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
136 /* combined Xtimes3[Sbox[]] */
137 static const u8 x3_sbox[256] = {
138 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
139 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
140 0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
141 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
142 0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
143 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
144 0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
145 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
146 0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
147 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
148 0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
149 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
150 0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
151 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
152 0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
153 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
154 0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
155 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
156 0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
157 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
158 0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
159 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
160 0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
161 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
162 0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
163 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
164 0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
165 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
166 0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
167 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
168 0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
169 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
173 * modular multiplication tables based on:
175 * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
176 * Xtime3[x] = x^Xtime2[x];
178 static const u8 x_time_9[256] = {
179 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
180 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
181 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
182 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
183 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
184 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
185 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
186 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
187 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
188 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
189 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
190 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
191 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
192 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
193 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
194 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
195 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
196 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
197 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
198 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
199 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
200 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
201 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
202 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
203 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
204 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
205 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
206 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
207 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
208 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
209 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
210 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
213 static const u8 x_time_b[256] = {
214 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
215 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
216 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
217 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
218 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
219 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
220 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
221 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
222 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
223 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
224 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
225 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
226 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
227 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
228 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
229 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
230 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
231 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
232 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
233 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
234 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
235 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
236 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
237 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
238 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
239 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
240 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
241 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
242 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
243 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
244 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
245 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
248 static const u8 x_time_d[256] = {
249 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
250 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
251 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
252 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
253 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
254 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
255 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
256 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
257 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
258 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
259 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
260 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
261 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
262 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
263 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
264 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
265 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
266 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
267 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
268 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
269 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
270 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
271 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
272 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
273 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
274 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
275 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
276 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
277 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
278 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
279 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
280 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
283 static const u8 x_time_e[256] = {
284 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
285 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
286 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
287 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
288 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
289 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
290 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
291 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
292 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
293 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
294 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
295 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
296 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
297 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
298 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
299 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
300 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
301 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
302 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
303 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
304 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
305 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
306 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
307 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
308 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
309 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
310 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
311 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
312 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
313 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
314 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
315 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
319 * Exchanges columns in each of 4 rows
320 * row0 - unchanged, row1- shifted left 1,
321 * row2 - shifted left 2 and row3 - shifted left 3
323 static void shift_rows(u8 *state)
327 /* just substitute row 0 */
328 state[0] = sbox[state[0]];
329 state[4] = sbox[state[4]];
330 state[8] = sbox[state[8]];
331 state[12] = sbox[state[12]];
334 tmp = sbox[state[1]];
335 state[1] = sbox[state[5]];
336 state[5] = sbox[state[9]];
337 state[9] = sbox[state[13]];
341 tmp = sbox[state[2]];
342 state[2] = sbox[state[10]];
344 tmp = sbox[state[6]];
345 state[6] = sbox[state[14]];
349 tmp = sbox[state[15]];
350 state[15] = sbox[state[11]];
351 state[11] = sbox[state[7]];
352 state[7] = sbox[state[3]];
357 * restores columns in each of 4 rows
358 * row0 - unchanged, row1- shifted right 1,
359 * row2 - shifted right 2 and row3 - shifted right 3
361 static void inv_shift_rows(u8 *state)
366 state[0] = inv_sbox[state[0]];
367 state[4] = inv_sbox[state[4]];
368 state[8] = inv_sbox[state[8]];
369 state[12] = inv_sbox[state[12]];
372 tmp = inv_sbox[state[13]];
373 state[13] = inv_sbox[state[9]];
374 state[9] = inv_sbox[state[5]];
375 state[5] = inv_sbox[state[1]];
379 tmp = inv_sbox[state[2]];
380 state[2] = inv_sbox[state[10]];
382 tmp = inv_sbox[state[6]];
383 state[6] = inv_sbox[state[14]];
387 tmp = inv_sbox[state[3]];
388 state[3] = inv_sbox[state[7]];
389 state[7] = inv_sbox[state[11]];
390 state[11] = inv_sbox[state[15]];
394 /* recombine and mix each row in a column */
395 static void mix_sub_columns(u8 *state)
397 u8 tmp[4 * AES_STATECOLS];
399 /* mixing column 0 */
400 tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
401 sbox[state[10]] ^ sbox[state[15]];
402 tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
403 x3_sbox[state[10]] ^ sbox[state[15]];
404 tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
405 x2_sbox[state[10]] ^ x3_sbox[state[15]];
406 tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
407 sbox[state[10]] ^ x2_sbox[state[15]];
409 /* mixing column 1 */
410 tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
411 sbox[state[14]] ^ sbox[state[3]];
412 tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
413 x3_sbox[state[14]] ^ sbox[state[3]];
414 tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
415 x2_sbox[state[14]] ^ x3_sbox[state[3]];
416 tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
417 sbox[state[14]] ^ x2_sbox[state[3]];
419 /* mixing column 2 */
420 tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
421 sbox[state[2]] ^ sbox[state[7]];
422 tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
423 x3_sbox[state[2]] ^ sbox[state[7]];
424 tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
425 x2_sbox[state[2]] ^ x3_sbox[state[7]];
426 tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
427 sbox[state[2]] ^ x2_sbox[state[7]];
429 /* mixing column 3 */
430 tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
431 sbox[state[6]] ^ sbox[state[11]];
432 tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
433 x3_sbox[state[6]] ^ sbox[state[11]];
434 tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
435 x2_sbox[state[6]] ^ x3_sbox[state[11]];
436 tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
437 sbox[state[6]] ^ x2_sbox[state[11]];
439 memcpy(state, tmp, sizeof(tmp));
442 /* restore and un-mix each row in a column */
443 static void inv_mix_sub_columns(u8 *state)
445 u8 tmp[4 * AES_STATECOLS];
448 /* restore column 0 */
449 tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
450 x_time_d[state[2]] ^ x_time_9[state[3]];
451 tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
452 x_time_b[state[2]] ^ x_time_d[state[3]];
453 tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
454 x_time_e[state[2]] ^ x_time_b[state[3]];
455 tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
456 x_time_9[state[2]] ^ x_time_e[state[3]];
458 /* restore column 1 */
459 tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
460 x_time_d[state[6]] ^ x_time_9[state[7]];
461 tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
462 x_time_b[state[6]] ^ x_time_d[state[7]];
463 tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
464 x_time_e[state[6]] ^ x_time_b[state[7]];
465 tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
466 x_time_9[state[6]] ^ x_time_e[state[7]];
468 /* restore column 2 */
469 tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
470 x_time_d[state[10]] ^ x_time_9[state[11]];
471 tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
472 x_time_b[state[10]] ^ x_time_d[state[11]];
473 tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
474 x_time_e[state[10]] ^ x_time_b[state[11]];
475 tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
476 x_time_9[state[10]] ^ x_time_e[state[11]];
478 /* restore column 3 */
479 tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
480 x_time_d[state[14]] ^ x_time_9[state[15]];
481 tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
482 x_time_b[state[14]] ^ x_time_d[state[15]];
483 tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
484 x_time_e[state[14]] ^ x_time_b[state[15]];
485 tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
486 x_time_9[state[14]] ^ x_time_e[state[15]];
488 for (i = 0; i < 4 * AES_STATECOLS; i++)
489 state[i] = inv_sbox[tmp[i]];
493 * encrypt/decrypt columns of the key
494 * n.b. you can replace this with byte-wise xor if you wish.
496 static void add_round_key(u32 *state, u32 *key)
500 for (idx = 0; idx < 4; idx++)
501 state[idx] ^= key[idx];
504 static u8 rcon[11] = {
505 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
508 /* produce AES_STATECOLS bytes for each round */
509 void aes_expand_key(u8 *key, u8 *expkey)
511 u8 tmp0, tmp1, tmp2, tmp3, tmp4;
514 memcpy(expkey, key, AES_KEYCOLS * 4);
516 for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
517 tmp0 = expkey[4*idx - 4];
518 tmp1 = expkey[4*idx - 3];
519 tmp2 = expkey[4*idx - 2];
520 tmp3 = expkey[4*idx - 1];
521 if (!(idx % AES_KEYCOLS)) {
524 tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
527 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
534 expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
535 expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
536 expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
537 expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
541 /* encrypt one 128 bit block */
542 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
544 u8 state[AES_STATECOLS * 4];
547 memcpy(state, in, AES_STATECOLS * 4);
548 add_round_key((u32 *)state, (u32 *)expkey);
550 for (round = 1; round < AES_ROUNDS + 1; round++) {
551 if (round < AES_ROUNDS)
552 mix_sub_columns(state);
556 add_round_key((u32 *)state,
557 (u32 *)expkey + round * AES_STATECOLS);
560 memcpy(out, state, sizeof(state));
563 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
565 u8 state[AES_STATECOLS * 4];
568 memcpy(state, in, sizeof(state));
570 add_round_key((u32 *)state,
571 (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
572 inv_shift_rows(state);
574 for (round = AES_ROUNDS; round--; ) {
575 add_round_key((u32 *)state,
576 (u32 *)expkey + round * AES_STATECOLS);
578 inv_mix_sub_columns(state);
581 memcpy(out, state, sizeof(state));