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