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