blob: d6144e61d6ef089a8138cc6f33a3560e6b44c2ba [file] [log] [blame]
Yen Lin5b1a5452012-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 Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Yen Lin5b1a5452012-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
Marek Vasuta8a752c2014-03-05 19:59:52 +010025#ifndef USE_HOSTCC
Yen Lin5b1a5452012-04-05 11:54:58 +000026#include <common.h>
Marek Vasuta8a752c2014-03-05 19:59:52 +010027#else
28#include <string.h>
29#endif
Stefano Babicb80c0b92017-04-05 18:08:00 +020030#include "uboot_aes.h"
Yen Lin5b1a5452012-04-05 11:54:58 +000031
32/* forward s-box */
33static 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 */
69static 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[]] */
105static 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[]] */
141static 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 */
182static 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
217static 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
252static 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
287static 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 */
327static 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 */
365static 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 */
399static 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 */
447static 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 */
500static 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
508static u8 rcon[11] = {
509 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
510};
511
512/* produce AES_STATECOLS bytes for each round */
513void aes_expand_key(u8 *key, u8 *expkey)
514{
515 u8 tmp0, tmp1, tmp2, tmp3, tmp4;
516 u32 idx;
517
518 memcpy(expkey, key, AES_KEYCOLS * 4);
519
520 for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
521 tmp0 = expkey[4*idx - 4];
522 tmp1 = expkey[4*idx - 3];
523 tmp2 = expkey[4*idx - 2];
524 tmp3 = expkey[4*idx - 1];
525 if (!(idx % AES_KEYCOLS)) {
526 tmp4 = tmp3;
527 tmp3 = sbox[tmp0];
528 tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
529 tmp1 = sbox[tmp2];
530 tmp2 = sbox[tmp4];
531 } else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
532 tmp0 = sbox[tmp0];
533 tmp1 = sbox[tmp1];
534 tmp2 = sbox[tmp2];
535 tmp3 = sbox[tmp3];
536 }
537
538 expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
539 expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
540 expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
541 expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
542 }
543}
544
545/* encrypt one 128 bit block */
546void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
547{
548 u8 state[AES_STATECOLS * 4];
549 u32 round;
550
551 memcpy(state, in, AES_STATECOLS * 4);
552 add_round_key((u32 *)state, (u32 *)expkey);
553
554 for (round = 1; round < AES_ROUNDS + 1; round++) {
555 if (round < AES_ROUNDS)
556 mix_sub_columns(state);
557 else
558 shift_rows(state);
559
560 add_round_key((u32 *)state,
561 (u32 *)expkey + round * AES_STATECOLS);
562 }
563
564 memcpy(out, state, sizeof(state));
565}
566
567void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
568{
569 u8 state[AES_STATECOLS * 4];
570 int round;
571
572 memcpy(state, in, sizeof(state));
573
574 add_round_key((u32 *)state,
575 (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
576 inv_shift_rows(state);
577
578 for (round = AES_ROUNDS; round--; ) {
579 add_round_key((u32 *)state,
580 (u32 *)expkey + round * AES_STATECOLS);
581 if (round)
582 inv_mix_sub_columns(state);
583 }
584
585 memcpy(out, state, sizeof(state));
586}
Marek Vasut6e7b9f42014-03-05 19:58:37 +0100587
588static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
589{
590#ifdef DEBUG
591 printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
592 print_buffer(0, data, 1, num_bytes, 16);
593#endif
594}
595
Stephen Warren53eb7682014-04-18 10:28:58 -0600596void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
Marek Vasut6e7b9f42014-03-05 19:58:37 +0100597{
598 int i;
599
600 for (i = 0; i < AES_KEY_LENGTH; i++)
601 *dst++ = *src++ ^ *cbc_chain_data++;
602}
603
604void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
605{
606 u8 zero_key[AES_KEY_LENGTH] = { 0 };
607 u8 tmp_data[AES_KEY_LENGTH];
608 /* Convenient array of 0's for IV */
609 u8 *cbc_chain_data = zero_key;
610 u32 i;
611
612 for (i = 0; i < num_aes_blocks; i++) {
613 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
614 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
615
616 /* Apply the chain data */
Stephen Warren53eb7682014-04-18 10:28:58 -0600617 aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
Marek Vasut6e7b9f42014-03-05 19:58:37 +0100618 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
619
620 /* Encrypt the AES block */
621 aes_encrypt(tmp_data, key_exp, dst);
622 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
623
624 /* Update pointers for next loop. */
625 cbc_chain_data = dst;
626 src += AES_KEY_LENGTH;
627 dst += AES_KEY_LENGTH;
628 }
629}
Marek Vasutdc24bb62014-03-05 19:58:38 +0100630
631void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
632{
633 u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
634 /* Convenient array of 0's for IV */
635 u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 };
636 u32 i;
637
638 for (i = 0; i < num_aes_blocks; i++) {
639 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
640 debug_print_vector("AES Src", AES_KEY_LENGTH, src);
641
642 memcpy(tmp_block, src, AES_KEY_LENGTH);
643
644 /* Decrypt the AES block */
645 aes_decrypt(src, key_exp, tmp_data);
646 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
647
648 /* Apply the chain data */
Stephen Warren53eb7682014-04-18 10:28:58 -0600649 aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
Marek Vasutdc24bb62014-03-05 19:58:38 +0100650 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
651
652 /* Update pointers for next loop. */
653 memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
654 src += AES_KEY_LENGTH;
655 dst += AES_KEY_LENGTH;
656 }
657}