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