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 */
shift_rows(u8 * state)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 */
inv_shift_rows(u8 * state)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 */
mix_sub_columns(u8 * state)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 */
inv_mix_sub_columns(u8 * state)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 */
add_round_key(u32 * state,u32 * key)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
aes_get_rounds(u32 key_len)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
aes_get_keycols(u32 key_len)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 */
aes_expand_key(u8 * key,u32 key_len,u8 * expkey)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 */
aes_encrypt(u32 key_len,u8 * in,u8 * expkey,u8 * out)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
aes_decrypt(u32 key_len,u8 * in,u8 * expkey,u8 * out)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
debug_print_vector(char * name,u32 num_bytes,u8 * data)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
aes_apply_cbc_chain_data(u8 * cbc_chain_data,u8 * src,u8 * dst)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
aes_cbc_encrypt_blocks(u32 key_len,u8 * key_exp,u8 * iv,u8 * src,u8 * dst,u32 num_aes_blocks)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
aes_cbc_decrypt_blocks(u32 key_len,u8 * key_exp,u8 * iv,u8 * src,u8 * dst,u32 num_aes_blocks)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 }
690