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 */
shift_rows(u8 * state)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 */
inv_shift_rows(u8 * state)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 */
mix_sub_columns(u8 * state)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 */
inv_mix_sub_columns(u8 * state)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 */
add_round_key(u32 * state,u32 * key)499 static void add_round_key(u32 *state, u32 *key)
500 {
501 int idx;
502
503 for (idx = 0; idx < 4; idx++)
504 state[idx] ^= key[idx];
505 }
506
507 static u8 rcon[11] = {
508 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
509 };
510
511 /* produce AES_STATECOLS bytes for each round */
aes_expand_key(u8 * key,u8 * expkey)512 void aes_expand_key(u8 *key, u8 *expkey)
513 {
514 u8 tmp0, tmp1, tmp2, tmp3, tmp4;
515 u32 idx;
516
517 memcpy(expkey, key, AES_KEYCOLS * 4);
518
519 for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
520 tmp0 = expkey[4*idx - 4];
521 tmp1 = expkey[4*idx - 3];
522 tmp2 = expkey[4*idx - 2];
523 tmp3 = expkey[4*idx - 1];
524 if (!(idx % AES_KEYCOLS)) {
525 tmp4 = tmp3;
526 tmp3 = sbox[tmp0];
527 tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
528 tmp1 = sbox[tmp2];
529 tmp2 = sbox[tmp4];
530 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
531 tmp0 = sbox[tmp0];
532 tmp1 = sbox[tmp1];
533 tmp2 = sbox[tmp2];
534 tmp3 = sbox[tmp3];
535 }
536
537 expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
538 expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
539 expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
540 expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
541 }
542 }
543
544 /* encrypt one 128 bit block */
aes_encrypt(u8 * in,u8 * expkey,u8 * out)545 void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
546 {
547 u8 state[AES_STATECOLS * 4];
548 u32 round;
549
550 memcpy(state, in, AES_STATECOLS * 4);
551 add_round_key((u32 *)state, (u32 *)expkey);
552
553 for (round = 1; round < AES_ROUNDS + 1; round++) {
554 if (round < AES_ROUNDS)
555 mix_sub_columns(state);
556 else
557 shift_rows(state);
558
559 add_round_key((u32 *)state,
560 (u32 *)expkey + round * AES_STATECOLS);
561 }
562
563 memcpy(out, state, sizeof(state));
564 }
565
aes_decrypt(u8 * in,u8 * expkey,u8 * out)566 void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
567 {
568 u8 state[AES_STATECOLS * 4];
569 int round;
570
571 memcpy(state, in, sizeof(state));
572
573 add_round_key((u32 *)state,
574 (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
575 inv_shift_rows(state);
576
577 for (round = AES_ROUNDS; round--; ) {
578 add_round_key((u32 *)state,
579 (u32 *)expkey + round * AES_STATECOLS);
580 if (round)
581 inv_mix_sub_columns(state);
582 }
583
584 memcpy(out, state, sizeof(state));
585 }
586
debug_print_vector(char * name,u32 num_bytes,u8 * data)587 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
588 {
589 #ifdef DEBUG
590 printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
591 print_buffer(0, data, 1, num_bytes, 16);
592 #endif
593 }
594
aes_apply_cbc_chain_data(u8 * cbc_chain_data,u8 * src,u8 * dst)595 void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
596 {
597 int i;
598
599 for (i = 0; i < AES_KEY_LENGTH; i++)
600 *dst++ = *src++ ^ *cbc_chain_data++;
601 }
602
aes_cbc_encrypt_blocks(u8 * key_exp,u8 * iv,u8 * src,u8 * dst,u32 num_aes_blocks)603 void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
604 u32 num_aes_blocks)
605 {
606 u8 tmp_data[AES_KEY_LENGTH];
607 u8 *cbc_chain_data = iv;
608 u32 i;
609
610 for (i = 0; i < num_aes_blocks; i++) {
611 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
612 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
613
614 /* Apply the chain data */
615 aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
616 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
617
618 /* Encrypt the AES block */
619 aes_encrypt(tmp_data, key_exp, dst);
620 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
621
622 /* Update pointers for next loop. */
623 cbc_chain_data = dst;
624 src += AES_KEY_LENGTH;
625 dst += AES_KEY_LENGTH;
626 }
627 }
628
aes_cbc_decrypt_blocks(u8 * key_exp,u8 * iv,u8 * src,u8 * dst,u32 num_aes_blocks)629 void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
630 u32 num_aes_blocks)
631 {
632 u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
633 /* Convenient array of 0's for IV */
634 u8 cbc_chain_data[AES_KEY_LENGTH];
635 u32 i;
636
637 memcpy(cbc_chain_data, iv, AES_KEY_LENGTH);
638 for (i = 0; i < num_aes_blocks; i++) {
639 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
640 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
641
642 memcpy(tmp_block, src, AES_KEY_LENGTH);
643
644 /* Decrypt the AES block */
645 aes_decrypt(src, key_exp, tmp_data);
646 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
647
648 /* Apply the chain data */
649 aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
650 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
651
652 /* Update pointers for next loop. */
653 memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
654 src += AES_KEY_LENGTH;
655 dst += AES_KEY_LENGTH;
656 }
657 }
658