config: apalis-imx8: Enable FEC TXC delay
[platform/kernel/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 static u32 aes_get_rounds(u32 key_len)
512 {
513         u32 rounds = AES128_ROUNDS;
514
515         if (key_len == AES192_KEY_LENGTH)
516                 rounds = AES192_ROUNDS;
517         else if (key_len == AES256_KEY_LENGTH)
518                 rounds = AES256_ROUNDS;
519
520         return rounds;
521 }
522
523 static u32 aes_get_keycols(u32 key_len)
524 {
525         u32 keycols = AES128_KEYCOLS;
526
527         if (key_len == AES192_KEY_LENGTH)
528                 keycols = AES192_KEYCOLS;
529         else if (key_len == AES256_KEY_LENGTH)
530                 keycols = AES256_KEYCOLS;
531
532         return keycols;
533 }
534
535 /* produce AES_STATECOLS bytes for each round */
536 void aes_expand_key(u8 *key, u32 key_len, u8 *expkey)
537 {
538         u8 tmp0, tmp1, tmp2, tmp3, tmp4;
539         u32 idx, aes_rounds, aes_keycols;
540
541         aes_rounds = aes_get_rounds(key_len);
542         aes_keycols = aes_get_keycols(key_len);
543
544         memcpy(expkey, key, key_len);
545
546         for (idx = aes_keycols; idx < AES_STATECOLS * (aes_rounds + 1); idx++) {
547                 tmp0 = expkey[4*idx - 4];
548                 tmp1 = expkey[4*idx - 3];
549                 tmp2 = expkey[4*idx - 2];
550                 tmp3 = expkey[4*idx - 1];
551                 if (!(idx % aes_keycols)) {
552                         tmp4 = tmp3;
553                         tmp3 = sbox[tmp0];
554                         tmp0 = sbox[tmp1] ^ rcon[idx / aes_keycols];
555                         tmp1 = sbox[tmp2];
556                         tmp2 = sbox[tmp4];
557                 } else if ((aes_keycols > 6) && (idx % aes_keycols == 4)) {
558                         tmp0 = sbox[tmp0];
559                         tmp1 = sbox[tmp1];
560                         tmp2 = sbox[tmp2];
561                         tmp3 = sbox[tmp3];
562                 }
563
564                 expkey[4*idx+0] = expkey[4*idx - 4*aes_keycols + 0] ^ tmp0;
565                 expkey[4*idx+1] = expkey[4*idx - 4*aes_keycols + 1] ^ tmp1;
566                 expkey[4*idx+2] = expkey[4*idx - 4*aes_keycols + 2] ^ tmp2;
567                 expkey[4*idx+3] = expkey[4*idx - 4*aes_keycols + 3] ^ tmp3;
568         }
569 }
570
571 /* encrypt one 128 bit block */
572 void aes_encrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
573 {
574         u8 state[AES_STATECOLS * 4];
575         u32 round, aes_rounds;
576
577         aes_rounds = aes_get_rounds(key_len);
578
579         memcpy(state, in, AES_STATECOLS * 4);
580         add_round_key((u32 *)state, (u32 *)expkey);
581
582         for (round = 1; round < aes_rounds + 1; round++) {
583                 if (round < aes_rounds)
584                         mix_sub_columns(state);
585                 else
586                         shift_rows(state);
587
588                 add_round_key((u32 *)state,
589                               (u32 *)expkey + round * AES_STATECOLS);
590         }
591
592         memcpy(out, state, sizeof(state));
593 }
594
595 void aes_decrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
596 {
597         u8 state[AES_STATECOLS * 4];
598         int round, aes_rounds;
599
600         aes_rounds = aes_get_rounds(key_len);
601
602         memcpy(state, in, sizeof(state));
603
604         add_round_key((u32 *)state,
605                       (u32 *)expkey + aes_rounds * AES_STATECOLS);
606         inv_shift_rows(state);
607
608         for (round = aes_rounds; round--; ) {
609                 add_round_key((u32 *)state,
610                               (u32 *)expkey + round * AES_STATECOLS);
611                 if (round)
612                         inv_mix_sub_columns(state);
613         }
614
615         memcpy(out, state, sizeof(state));
616 }
617
618 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
619 {
620 #ifdef DEBUG
621         printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
622         print_buffer(0, data, 1, num_bytes, 16);
623 #endif
624 }
625
626 void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
627 {
628         int i;
629
630         for (i = 0; i < AES_BLOCK_LENGTH; i++)
631                 *dst++ = *src++ ^ *cbc_chain_data++;
632 }
633
634 void aes_cbc_encrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
635                             u32 num_aes_blocks)
636 {
637         u8 tmp_data[AES_BLOCK_LENGTH];
638         u8 *cbc_chain_data = iv;
639         u32 i;
640
641         for (i = 0; i < num_aes_blocks; i++) {
642                 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
643                 debug_print_vector("AES Src", AES_BLOCK_LENGTH, src);
644
645                 /* Apply the chain data */
646                 aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
647                 debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
648
649                 /* Encrypt the AES block */
650                 aes_encrypt(key_len, tmp_data, key_exp, dst);
651                 debug_print_vector("AES Dst", AES_BLOCK_LENGTH, dst);
652
653                 /* Update pointers for next loop. */
654                 cbc_chain_data = dst;
655                 src += AES_BLOCK_LENGTH;
656                 dst += AES_BLOCK_LENGTH;
657         }
658 }
659
660 void aes_cbc_decrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
661                             u32 num_aes_blocks)
662 {
663         u8 tmp_data[AES_BLOCK_LENGTH], tmp_block[AES_BLOCK_LENGTH];
664         /* Convenient array of 0's for IV */
665         u8 cbc_chain_data[AES_BLOCK_LENGTH];
666         u32 i;
667
668         memcpy(cbc_chain_data, iv, AES_BLOCK_LENGTH);
669         for (i = 0; i < num_aes_blocks; i++) {
670                 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
671                 debug_print_vector("AES Src", AES_BLOCK_LENGTH, src);
672
673                 memcpy(tmp_block, src, AES_BLOCK_LENGTH);
674
675                 /* Decrypt the AES block */
676                 aes_decrypt(key_len, src, key_exp, tmp_data);
677                 debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
678
679                 /* Apply the chain data */
680                 aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
681                 debug_print_vector("AES Dst", AES_BLOCK_LENGTH, dst);
682
683                 /* Update pointers for next loop. */
684                 memcpy(cbc_chain_data, tmp_block, AES_BLOCK_LENGTH);
685                 src += AES_BLOCK_LENGTH;
686                 dst += AES_BLOCK_LENGTH;
687         }
688 }