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