Merge branch 'rmobile' of git://git.denx.de/u-boot-sh
[platform/kernel/u-boot.git] / lib / aes.c
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * advanced encryption standard
10  * author: karl malbrain, malbrain@yahoo.com
11  *
12  * This work, including the source code, documentation
13  * and related data, is placed into the public domain.
14  *
15  * The orginal author is Karl Malbrain.
16  *
17  * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
18  * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
19  * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
20  * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
21  * RESULTING FROM THE USE, MODIFICATION, OR
22  * REDISTRIBUTION OF THIS SOFTWARE.
23 */
24
25 #ifndef USE_HOSTCC
26 #include <common.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 /* produce AES_STATECOLS bytes for each round */
513 void aes_expand_key(u8 *key, u8 *expkey)
514 {
515         u8 tmp0, tmp1, tmp2, tmp3, tmp4;
516         u32 idx;
517
518         memcpy(expkey, key, AES_KEYCOLS * 4);
519
520         for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
521                 tmp0 = expkey[4*idx - 4];
522                 tmp1 = expkey[4*idx - 3];
523                 tmp2 = expkey[4*idx - 2];
524                 tmp3 = expkey[4*idx - 1];
525                 if (!(idx % AES_KEYCOLS)) {
526                         tmp4 = tmp3;
527                         tmp3 = sbox[tmp0];
528                         tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
529                         tmp1 = sbox[tmp2];
530                         tmp2 = sbox[tmp4];
531                 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
532                         tmp0 = sbox[tmp0];
533                         tmp1 = sbox[tmp1];
534                         tmp2 = sbox[tmp2];
535                         tmp3 = sbox[tmp3];
536                 }
537
538                 expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
539                 expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
540                 expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
541                 expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
542         }
543 }
544
545 /* encrypt one 128 bit block */
546 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
547 {
548         u8 state[AES_STATECOLS * 4];
549         u32 round;
550
551         memcpy(state, in, AES_STATECOLS * 4);
552         add_round_key((u32 *)state, (u32 *)expkey);
553
554         for (round = 1; round < AES_ROUNDS + 1; round++) {
555                 if (round < AES_ROUNDS)
556                         mix_sub_columns(state);
557                 else
558                         shift_rows(state);
559
560                 add_round_key((u32 *)state,
561                               (u32 *)expkey + round * AES_STATECOLS);
562         }
563
564         memcpy(out, state, sizeof(state));
565 }
566
567 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
568 {
569         u8 state[AES_STATECOLS * 4];
570         int round;
571
572         memcpy(state, in, sizeof(state));
573
574         add_round_key((u32 *)state,
575                       (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
576         inv_shift_rows(state);
577
578         for (round = AES_ROUNDS; round--; ) {
579                 add_round_key((u32 *)state,
580                               (u32 *)expkey + round * AES_STATECOLS);
581                 if (round)
582                         inv_mix_sub_columns(state);
583         }
584
585         memcpy(out, state, sizeof(state));
586 }
587
588 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
589 {
590 #ifdef DEBUG
591         printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
592         print_buffer(0, data, 1, num_bytes, 16);
593 #endif
594 }
595
596 void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
597 {
598         int i;
599
600         for (i = 0; i < AES_KEY_LENGTH; i++)
601                 *dst++ = *src++ ^ *cbc_chain_data++;
602 }
603
604 void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
605 {
606         u8 zero_key[AES_KEY_LENGTH] = { 0 };
607         u8 tmp_data[AES_KEY_LENGTH];
608         /* Convenient array of 0's for IV */
609         u8 *cbc_chain_data = zero_key;
610         u32 i;
611
612         for (i = 0; i < num_aes_blocks; i++) {
613                 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
614                 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
615
616                 /* Apply the chain data */
617                 aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
618                 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
619
620                 /* Encrypt the AES block */
621                 aes_encrypt(tmp_data, key_exp, dst);
622                 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
623
624                 /* Update pointers for next loop. */
625                 cbc_chain_data = dst;
626                 src += AES_KEY_LENGTH;
627                 dst += AES_KEY_LENGTH;
628         }
629 }
630
631 void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
632 {
633         u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
634         /* Convenient array of 0's for IV */
635         u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 };
636         u32 i;
637
638         for (i = 0; i < num_aes_blocks; i++) {
639                 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
640                 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
641
642                 memcpy(tmp_block, src, AES_KEY_LENGTH);
643
644                 /* Decrypt the AES block */
645                 aes_decrypt(src, key_exp, tmp_data);
646                 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
647
648                 /* Apply the chain data */
649                 aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
650                 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
651
652                 /* Update pointers for next loop. */
653                 memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
654                 src += AES_KEY_LENGTH;
655                 dst += AES_KEY_LENGTH;
656         }
657 }