1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2011 The Chromium OS Authors.
4 * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
8 * advanced encryption standard
9 * author: karl malbrain, malbrain@yahoo.com
11 * This work, including the source code, documentation
12 * and related data, is placed into the public domain.
14 * The orginal author is Karl Malbrain.
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.
30 #include "uboot_aes.h"
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
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
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
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
177 * modular multiplication tables based on:
179 * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
180 * Xtime3[x] = x^Xtime2[x];
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
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
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
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
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
327 static void shift_rows(u8 *state)
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]];
338 tmp = sbox[state[1]];
339 state[1] = sbox[state[5]];
340 state[5] = sbox[state[9]];
341 state[9] = sbox[state[13]];
345 tmp = sbox[state[2]];
346 state[2] = sbox[state[10]];
348 tmp = sbox[state[6]];
349 state[6] = sbox[state[14]];
353 tmp = sbox[state[15]];
354 state[15] = sbox[state[11]];
355 state[11] = sbox[state[7]];
356 state[7] = sbox[state[3]];
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
365 static void inv_shift_rows(u8 *state)
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]];
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]];
383 tmp = inv_sbox[state[2]];
384 state[2] = inv_sbox[state[10]];
386 tmp = inv_sbox[state[6]];
387 state[6] = inv_sbox[state[14]];
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]];
398 /* recombine and mix each row in a column */
399 static void mix_sub_columns(u8 *state)
401 u8 tmp[4 * AES_STATECOLS];
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]];
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]];
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]];
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]];
443 memcpy(state, tmp, sizeof(tmp));
446 /* restore and un-mix each row in a column */
447 static void inv_mix_sub_columns(u8 *state)
449 u8 tmp[4 * AES_STATECOLS];
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]];
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]];
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]];
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]];
492 for (i = 0; i < 4 * AES_STATECOLS; i++)
493 state[i] = inv_sbox[tmp[i]];
497 * encrypt/decrypt columns of the key
498 * n.b. you can replace this with byte-wise xor if you wish.
500 static void add_round_key(u32 *state, u32 *key)
504 for (idx = 0; idx < 4; idx++)
505 state[idx] ^= key[idx];
508 static u8 rcon[11] = {
509 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
512 static u32 aes_get_rounds(u32 key_len)
514 u32 rounds = AES128_ROUNDS;
516 if (key_len == AES192_KEY_LENGTH)
517 rounds = AES192_ROUNDS;
518 else if (key_len == AES256_KEY_LENGTH)
519 rounds = AES256_ROUNDS;
524 static u32 aes_get_keycols(u32 key_len)
526 u32 keycols = AES128_KEYCOLS;
528 if (key_len == AES192_KEY_LENGTH)
529 keycols = AES192_KEYCOLS;
530 else if (key_len == AES256_KEY_LENGTH)
531 keycols = AES256_KEYCOLS;
536 /* produce AES_STATECOLS bytes for each round */
537 void aes_expand_key(u8 *key, u32 key_len, u8 *expkey)
539 u8 tmp0, tmp1, tmp2, tmp3, tmp4;
540 u32 idx, aes_rounds, aes_keycols;
542 aes_rounds = aes_get_rounds(key_len);
543 aes_keycols = aes_get_keycols(key_len);
545 memcpy(expkey, key, key_len);
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)) {
555 tmp0 = sbox[tmp1] ^ rcon[idx / aes_keycols];
558 } else if ((aes_keycols > 6) && (idx % aes_keycols == 4)) {
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;
572 /* encrypt one 128 bit block */
573 void aes_encrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
575 u8 state[AES_STATECOLS * 4];
576 u32 round, aes_rounds;
578 aes_rounds = aes_get_rounds(key_len);
580 memcpy(state, in, AES_STATECOLS * 4);
581 add_round_key((u32 *)state, (u32 *)expkey);
583 for (round = 1; round < aes_rounds + 1; round++) {
584 if (round < aes_rounds)
585 mix_sub_columns(state);
589 add_round_key((u32 *)state,
590 (u32 *)expkey + round * AES_STATECOLS);
593 memcpy(out, state, sizeof(state));
596 void aes_decrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
598 u8 state[AES_STATECOLS * 4];
599 int round, aes_rounds;
601 aes_rounds = aes_get_rounds(key_len);
603 memcpy(state, in, sizeof(state));
605 add_round_key((u32 *)state,
606 (u32 *)expkey + aes_rounds * AES_STATECOLS);
607 inv_shift_rows(state);
609 for (round = aes_rounds; round--; ) {
610 add_round_key((u32 *)state,
611 (u32 *)expkey + round * AES_STATECOLS);
613 inv_mix_sub_columns(state);
616 memcpy(out, state, sizeof(state));
619 static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
622 printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
623 print_buffer(0, data, 1, num_bytes, 16);
627 void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
631 for (i = 0; i < AES_BLOCK_LENGTH; i++)
632 *dst++ = *src++ ^ *cbc_chain_data++;
635 void aes_cbc_encrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
638 u8 tmp_data[AES_BLOCK_LENGTH];
639 u8 *cbc_chain_data = iv;
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);
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);
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);
654 /* Update pointers for next loop. */
655 cbc_chain_data = dst;
656 src += AES_BLOCK_LENGTH;
657 dst += AES_BLOCK_LENGTH;
661 void aes_cbc_decrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
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];
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);
674 memcpy(tmp_block, src, AES_BLOCK_LENGTH);
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);
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);
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;