efi_loader: correct includes in efi_variable.c
[oweals/u-boot.git] / lib / aes.c
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 }