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