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