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