xref: /openbmc/u-boot/lib/aes.c (revision 3bddafaa)
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 /*
9  * advanced encryption standard
10  * author: karl malbrain, malbrain@yahoo.com
11  *
12  * This work, including the source code, documentation
13  * and related data, is placed into the public domain.
14  *
15  * The orginal author is Karl Malbrain.
16  *
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.
23 */
24 
25 #include <common.h>
26 #include "aes.h"
27 
28 /* forward s-box */
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
62 };
63 
64 /* inverse s-box */
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
98 };
99 
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
134 };
135 
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
170 };
171 
172 /*
173  * modular multiplication tables based on:
174  *
175  * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
176  * Xtime3[x] = x^Xtime2[x];
177  */
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
211 };
212 
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
246 };
247 
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
281 };
282 
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
316 };
317 
318 /*
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
322  */
323 static void shift_rows(u8 *state)
324 {
325 	u8 tmp;
326 
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]];
332 
333 	/* rotate row 1 */
334 	tmp = sbox[state[1]];
335 	state[1] = sbox[state[5]];
336 	state[5] = sbox[state[9]];
337 	state[9] = sbox[state[13]];
338 	state[13] = tmp;
339 
340 	/* rotate row 2 */
341 	tmp = sbox[state[2]];
342 	state[2] = sbox[state[10]];
343 	state[10] = tmp;
344 	tmp = sbox[state[6]];
345 	state[6] = sbox[state[14]];
346 	state[14] = tmp;
347 
348 	/* rotate row 3 */
349 	tmp = sbox[state[15]];
350 	state[15] = sbox[state[11]];
351 	state[11] = sbox[state[7]];
352 	state[7] = sbox[state[3]];
353 	state[3] = tmp;
354 }
355 
356 /*
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
360  */
361 static void inv_shift_rows(u8 *state)
362 {
363 	u8 tmp;
364 
365 	/* restore row 0 */
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]];
370 
371 	/* restore row 1 */
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]];
376 	state[1] = tmp;
377 
378 	/* restore row 2 */
379 	tmp = inv_sbox[state[2]];
380 	state[2] = inv_sbox[state[10]];
381 	state[10] = tmp;
382 	tmp = inv_sbox[state[6]];
383 	state[6] = inv_sbox[state[14]];
384 	state[14] = tmp;
385 
386 	/* restore row 3 */
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]];
391 	state[15] = tmp;
392 }
393 
394 /* recombine and mix each row in a column */
395 static void mix_sub_columns(u8 *state)
396 {
397 	u8 tmp[4 * AES_STATECOLS];
398 
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]];
408 
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]];
418 
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]];
428 
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]];
438 
439 	memcpy(state, tmp, sizeof(tmp));
440 }
441 
442 /* restore and un-mix each row in a column */
443 static void inv_mix_sub_columns(u8 *state)
444 {
445 	u8 tmp[4 * AES_STATECOLS];
446 	int  i;
447 
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]];
457 
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]];
467 
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]];
477 
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]];
487 
488 	for (i = 0; i < 4 * AES_STATECOLS; i++)
489 		state[i] = inv_sbox[tmp[i]];
490 }
491 
492 /*
493  * encrypt/decrypt columns of the key
494  * n.b. you can replace this with byte-wise xor if you wish.
495  */
496 static void add_round_key(u32 *state, u32 *key)
497 {
498 	int idx;
499 
500 	for (idx = 0; idx < 4; idx++)
501 		state[idx] ^= key[idx];
502 }
503 
504 static u8 rcon[11] = {
505 	0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
506 };
507 
508 /* produce AES_STATECOLS bytes for each round */
509 void aes_expand_key(u8 *key, u8 *expkey)
510 {
511 	u8 tmp0, tmp1, tmp2, tmp3, tmp4;
512 	u32 idx;
513 
514 	memcpy(expkey, key, AES_KEYCOLS * 4);
515 
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)) {
522 			tmp4 = tmp3;
523 			tmp3 = sbox[tmp0];
524 			tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
525 			tmp1 = sbox[tmp2];
526 			tmp2 = sbox[tmp4];
527 		} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
528 			tmp0 = sbox[tmp0];
529 			tmp1 = sbox[tmp1];
530 			tmp2 = sbox[tmp2];
531 			tmp3 = sbox[tmp3];
532 		}
533 
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;
538 	}
539 }
540 
541 /* encrypt one 128 bit block */
542 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
543 {
544 	u8 state[AES_STATECOLS * 4];
545 	u32 round;
546 
547 	memcpy(state, in, AES_STATECOLS * 4);
548 	add_round_key((u32 *)state, (u32 *)expkey);
549 
550 	for (round = 1; round < AES_ROUNDS + 1; round++) {
551 		if (round < AES_ROUNDS)
552 			mix_sub_columns(state);
553 		else
554 			shift_rows(state);
555 
556 		add_round_key((u32 *)state,
557 			      (u32 *)expkey + round * AES_STATECOLS);
558 	}
559 
560 	memcpy(out, state, sizeof(state));
561 }
562 
563 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
564 {
565 	u8 state[AES_STATECOLS * 4];
566 	int round;
567 
568 	memcpy(state, in, sizeof(state));
569 
570 	add_round_key((u32 *)state,
571 		      (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
572 	inv_shift_rows(state);
573 
574 	for (round = AES_ROUNDS; round--; ) {
575 		add_round_key((u32 *)state,
576 			      (u32 *)expkey + round * AES_STATECOLS);
577 		if (round)
578 			inv_mix_sub_columns(state);
579 	}
580 
581 	memcpy(out, state, sizeof(state));
582 }
583