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