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