aes_selftest.c revision 1.2 1 1.2 riastrad /* $NetBSD: aes_selftest.c,v 1.2 2020/06/30 20:32:11 riastradh Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*-
4 1.1 riastrad * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * Redistribution and use in source and binary forms, with or without
8 1.1 riastrad * modification, are permitted provided that the following conditions
9 1.1 riastrad * are met:
10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
11 1.1 riastrad * notice, this list of conditions and the following disclaimer.
12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
14 1.1 riastrad * documentation and/or other materials provided with the distribution.
15 1.1 riastrad *
16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
27 1.1 riastrad */
28 1.1 riastrad
29 1.1 riastrad #include <sys/cdefs.h>
30 1.2 riastrad __KERNEL_RCSID(1, "$NetBSD: aes_selftest.c,v 1.2 2020/06/30 20:32:11 riastradh Exp $");
31 1.2 riastrad
32 1.2 riastrad #ifdef _KERNEL
33 1.1 riastrad
34 1.1 riastrad #include <sys/types.h>
35 1.1 riastrad #include <sys/systm.h>
36 1.1 riastrad
37 1.1 riastrad #include <lib/libkern/libkern.h>
38 1.1 riastrad
39 1.2 riastrad #else /* !_KERNEL */
40 1.2 riastrad
41 1.2 riastrad #include <stdint.h>
42 1.2 riastrad #include <stdio.h>
43 1.2 riastrad #include <string.h>
44 1.2 riastrad
45 1.2 riastrad static void
46 1.2 riastrad hexdump(int (*prf)(const char *, ...) __printflike(1,2), const char *prefix,
47 1.2 riastrad const void *buf, size_t len)
48 1.2 riastrad {
49 1.2 riastrad const uint8_t *p = buf;
50 1.2 riastrad size_t i;
51 1.2 riastrad
52 1.2 riastrad (*prf)("%s (%zu bytes)\n", prefix, len);
53 1.2 riastrad for (i = 0; i < len; i++) {
54 1.2 riastrad if (i % 16 == 8)
55 1.2 riastrad (*prf)(" ");
56 1.2 riastrad else
57 1.2 riastrad (*prf)(" ");
58 1.2 riastrad (*prf)("%02hhx", p[i]);
59 1.2 riastrad if ((i + 1) % 16 == 0)
60 1.2 riastrad (*prf)("\n");
61 1.2 riastrad }
62 1.2 riastrad if (i % 16)
63 1.2 riastrad (*prf)("\n");
64 1.2 riastrad }
65 1.2 riastrad
66 1.2 riastrad #endif /* _KERNEL */
67 1.2 riastrad
68 1.1 riastrad #include <crypto/aes/aes.h>
69 1.1 riastrad
70 1.1 riastrad static const unsigned aes_keybytes[] __unused = { 16, 24, 32 };
71 1.1 riastrad static const unsigned aes_keybits[] __unused = { 128, 192, 256 };
72 1.1 riastrad static const unsigned aes_nrounds[] = { 10, 12, 14 };
73 1.1 riastrad
74 1.1 riastrad #define aes_selftest_fail(impl, actual, expected, nbytes, fmt, args...) \
75 1.1 riastrad ({ \
76 1.1 riastrad printf("%s "fmt": self-test failed\n", (impl)->ai_name, ##args); \
77 1.1 riastrad hexdump(printf, "was", (actual), (nbytes)); \
78 1.1 riastrad hexdump(printf, "expected", (expected), (nbytes)); \
79 1.1 riastrad -1; \
80 1.1 riastrad })
81 1.1 riastrad
82 1.1 riastrad static int
83 1.1 riastrad aes_selftest_encdec(const struct aes_impl *impl)
84 1.1 riastrad {
85 1.1 riastrad /*
86 1.1 riastrad * head -c 16 < /dev/zero | openssl enc -aes-{128,192,256}-ecb
87 1.1 riastrad * -nopad -K 000102030405060708090a0b0c0d... | hexdump -C
88 1.1 riastrad */
89 1.1 riastrad static const uint8_t expected[3][16] = {
90 1.1 riastrad [0] = {
91 1.1 riastrad 0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,
92 1.1 riastrad 0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
93 1.1 riastrad },
94 1.1 riastrad [1] = {
95 1.1 riastrad 0x91,0x62,0x51,0x82,0x1c,0x73,0xa5,0x22,
96 1.1 riastrad 0xc3,0x96,0xd6,0x27,0x38,0x01,0x96,0x07,
97 1.1 riastrad },
98 1.1 riastrad [2] = {
99 1.1 riastrad 0xf2,0x90,0x00,0xb6,0x2a,0x49,0x9f,0xd0,
100 1.1 riastrad 0xa9,0xf3,0x9a,0x6a,0xdd,0x2e,0x77,0x80,
101 1.1 riastrad },
102 1.1 riastrad };
103 1.1 riastrad struct aesenc enc;
104 1.1 riastrad struct aesdec dec;
105 1.1 riastrad uint8_t key[32];
106 1.1 riastrad uint8_t in[16];
107 1.1 riastrad uint8_t outbuf[18] = { [0] = 0x1a, [17] = 0x1a }, *out = outbuf + 1;
108 1.1 riastrad unsigned i;
109 1.1 riastrad
110 1.1 riastrad for (i = 0; i < 32; i++)
111 1.1 riastrad key[i] = i;
112 1.1 riastrad for (i = 0; i < 16; i++)
113 1.1 riastrad in[i] = 0;
114 1.1 riastrad
115 1.1 riastrad for (i = 0; i < 3; i++) {
116 1.1 riastrad impl->ai_setenckey(&enc, key, aes_nrounds[i]);
117 1.1 riastrad impl->ai_setdeckey(&dec, key, aes_nrounds[i]);
118 1.1 riastrad impl->ai_enc(&enc, in, out, aes_nrounds[i]);
119 1.1 riastrad if (memcmp(out, expected[i], 16))
120 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 16,
121 1.1 riastrad "AES-%u enc", aes_keybits[i]);
122 1.1 riastrad impl->ai_dec(&dec, out, out, aes_nrounds[i]);
123 1.1 riastrad if (memcmp(out, in, 16))
124 1.1 riastrad return aes_selftest_fail(impl, out, in, 16,
125 1.1 riastrad "AES-%u dec", aes_keybits[i]);
126 1.1 riastrad }
127 1.1 riastrad
128 1.1 riastrad if (outbuf[0] != 0x1a)
129 1.1 riastrad return aes_selftest_fail(impl, outbuf,
130 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
131 1.1 riastrad "AES overrun preceding");
132 1.1 riastrad if (outbuf[17] != 0x1a)
133 1.1 riastrad return aes_selftest_fail(impl, outbuf + 17,
134 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
135 1.1 riastrad "AES overrun folllowing");
136 1.1 riastrad
137 1.1 riastrad /* Success! */
138 1.1 riastrad return 0;
139 1.1 riastrad }
140 1.1 riastrad
141 1.1 riastrad static int
142 1.1 riastrad aes_selftest_encdec_cbc(const struct aes_impl *impl)
143 1.1 riastrad {
144 1.1 riastrad static const uint8_t expected[3][144] = {
145 1.1 riastrad [0] = {
146 1.1 riastrad 0xfe,0xf1,0xa8,0xb6,0x25,0xf0,0xc4,0x3a,
147 1.1 riastrad 0x71,0x08,0xb6,0x23,0xa6,0xfb,0x90,0xca,
148 1.1 riastrad 0x9e,0x64,0x6d,0x95,0xb5,0xf5,0x41,0x24,
149 1.1 riastrad 0xd2,0xe6,0x60,0xda,0x6c,0x69,0xc4,0xa0,
150 1.1 riastrad 0x4d,0xaa,0x94,0xf6,0x66,0x1e,0xaa,0x85,
151 1.1 riastrad 0x68,0xc5,0x6b,0x2e,0x77,0x7a,0x68,0xff,
152 1.1 riastrad 0x45,0x15,0x45,0xc5,0x9c,0xbb,0x3a,0x23,
153 1.1 riastrad 0x08,0x3a,0x06,0xdd,0xc0,0x52,0xd2,0xb7,
154 1.1 riastrad 0x47,0xaa,0x1c,0xc7,0xb5,0xa9,0x7d,0x04,
155 1.1 riastrad 0x60,0x67,0x78,0xf6,0xb9,0xba,0x26,0x84,
156 1.1 riastrad 0x45,0x72,0x44,0xed,0xa3,0xd3,0xa0,0x3f,
157 1.1 riastrad 0x19,0xee,0x3f,0x94,0x59,0x52,0x4b,0x13,
158 1.1 riastrad 0xfd,0x81,0xcc,0xf9,0xf2,0x29,0xd7,0xec,
159 1.1 riastrad 0xde,0x03,0x56,0x01,0x4a,0x19,0x86,0xc0,
160 1.1 riastrad 0x87,0xce,0xe1,0xcc,0x13,0xf1,0x2e,0xda,
161 1.1 riastrad 0x3f,0xfe,0xa4,0x64,0xe7,0x48,0xb4,0x7b,
162 1.1 riastrad 0x73,0x62,0x5a,0x80,0x5e,0x01,0x20,0xa5,
163 1.1 riastrad 0x0a,0xd7,0x98,0xa7,0xd9,0x8b,0xff,0xc2,
164 1.1 riastrad },
165 1.1 riastrad [1] = {
166 1.1 riastrad 0xa6,0x87,0xf0,0x92,0x68,0xc8,0xd6,0x42,
167 1.1 riastrad 0xa8,0x83,0x1c,0x92,0x65,0x8c,0xd9,0xfe,
168 1.1 riastrad 0x0b,0x1a,0xc6,0x96,0x27,0x44,0xd4,0x14,
169 1.1 riastrad 0xfc,0xe7,0x85,0xb2,0x71,0xc7,0x11,0x39,
170 1.1 riastrad 0xed,0x36,0xd3,0x5c,0xa7,0xf7,0x3d,0xc9,
171 1.1 riastrad 0xa2,0x54,0x8b,0xb4,0xfa,0xe8,0x21,0xf9,
172 1.1 riastrad 0xfd,0x6a,0x42,0x85,0xde,0x66,0xd4,0xc0,
173 1.1 riastrad 0xa7,0xd3,0x5b,0xe1,0xe6,0xac,0xea,0xf9,
174 1.1 riastrad 0xa3,0x15,0x68,0xf4,0x66,0x4c,0x23,0x75,
175 1.1 riastrad 0x58,0xba,0x7f,0xca,0xbf,0x40,0x56,0x79,
176 1.1 riastrad 0x2f,0xbf,0xdf,0x5f,0x56,0xcb,0xa0,0xe4,
177 1.1 riastrad 0x22,0x65,0x6a,0x8f,0x4f,0xff,0x11,0x6b,
178 1.1 riastrad 0x57,0xeb,0x45,0xeb,0x9d,0x7f,0xfe,0x9c,
179 1.1 riastrad 0x8b,0x30,0xa8,0xb0,0x7e,0x27,0xf8,0xbc,
180 1.1 riastrad 0x1f,0xf8,0x15,0x34,0x36,0x4f,0x46,0x73,
181 1.1 riastrad 0x81,0x90,0x4b,0x4b,0x46,0x4d,0x01,0x45,
182 1.1 riastrad 0xa1,0xc3,0x0b,0xa8,0x5a,0xab,0xc1,0x88,
183 1.1 riastrad 0x66,0xc8,0x1a,0x94,0x17,0x64,0x6f,0xf4,
184 1.1 riastrad },
185 1.1 riastrad [2] = {
186 1.1 riastrad 0x22,0x4c,0x27,0xf4,0xba,0x37,0x8b,0x27,
187 1.1 riastrad 0xd3,0xd6,0x88,0x8a,0xdc,0xed,0x64,0x42,
188 1.1 riastrad 0x19,0x60,0x31,0x09,0xf3,0x72,0xd2,0xc2,
189 1.1 riastrad 0xd3,0xe3,0xff,0xce,0xc5,0x03,0x9f,0xce,
190 1.1 riastrad 0x99,0x49,0x8a,0xf2,0xe1,0xba,0xe2,0xa8,
191 1.1 riastrad 0xd7,0x32,0x07,0x2d,0xb0,0xb3,0xbc,0x67,
192 1.1 riastrad 0x32,0x9a,0x3e,0x7d,0x16,0x23,0xe7,0x24,
193 1.1 riastrad 0x84,0xe1,0x15,0x03,0x9c,0xa2,0x7a,0x95,
194 1.1 riastrad 0x34,0xa8,0x04,0x4e,0x79,0x31,0x50,0x26,
195 1.1 riastrad 0x76,0xd1,0x10,0xce,0xec,0x13,0xf7,0xfb,
196 1.1 riastrad 0x94,0x6b,0x76,0x50,0x5f,0xb2,0x3e,0x7c,
197 1.1 riastrad 0xbe,0x97,0xe7,0x13,0x06,0x9e,0x2d,0xc4,
198 1.1 riastrad 0x46,0x65,0xa7,0x69,0x37,0x07,0x25,0x37,
199 1.1 riastrad 0xe5,0x48,0x51,0xa8,0x58,0xe8,0x4d,0x7c,
200 1.1 riastrad 0xb5,0xbe,0x25,0x13,0xbc,0x11,0xc2,0xde,
201 1.1 riastrad 0xdb,0x00,0xef,0x1c,0x1d,0xeb,0xe3,0x49,
202 1.1 riastrad 0x1c,0xc0,0x78,0x29,0x76,0xc0,0xde,0x3a,
203 1.1 riastrad 0x0e,0x96,0x8f,0xea,0xd7,0x42,0x4e,0xb4,
204 1.1 riastrad },
205 1.1 riastrad };
206 1.1 riastrad struct aesenc enc;
207 1.1 riastrad struct aesdec dec;
208 1.1 riastrad uint8_t key[32];
209 1.1 riastrad uint8_t in[144];
210 1.1 riastrad uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1;
211 1.1 riastrad uint8_t iv0[16], iv[16];
212 1.1 riastrad unsigned i;
213 1.1 riastrad
214 1.1 riastrad for (i = 0; i < 32; i++)
215 1.1 riastrad key[i] = i;
216 1.1 riastrad for (i = 0; i < 16; i++)
217 1.1 riastrad iv0[i] = 0x20 ^ i;
218 1.1 riastrad for (i = 0; i < 144; i++)
219 1.1 riastrad in[i] = 0x80 ^ i;
220 1.1 riastrad
221 1.1 riastrad for (i = 0; i < 3; i++) {
222 1.1 riastrad impl->ai_setenckey(&enc, key, aes_nrounds[i]);
223 1.1 riastrad impl->ai_setdeckey(&dec, key, aes_nrounds[i]);
224 1.1 riastrad
225 1.1 riastrad /* Try one swell foop. */
226 1.1 riastrad memcpy(iv, iv0, 16);
227 1.1 riastrad impl->ai_cbc_enc(&enc, in, out, 144, iv, aes_nrounds[i]);
228 1.1 riastrad if (memcmp(out, expected[i], 144))
229 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
230 1.1 riastrad "AES-%u-CBC enc", aes_keybits[i]);
231 1.1 riastrad
232 1.1 riastrad memcpy(iv, iv0, 16);
233 1.1 riastrad impl->ai_cbc_dec(&dec, out, out, 144, iv, aes_nrounds[i]);
234 1.1 riastrad if (memcmp(out, in, 144))
235 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
236 1.1 riastrad "AES-%u-CBC dec", aes_keybits[i]);
237 1.1 riastrad
238 1.1 riastrad /* Try incrementally, with IV update. */
239 1.1 riastrad memcpy(iv, iv0, 16);
240 1.1 riastrad impl->ai_cbc_enc(&enc, in, out, 16, iv, aes_nrounds[i]);
241 1.1 riastrad impl->ai_cbc_enc(&enc, in + 16, out + 16, 128, iv,
242 1.1 riastrad aes_nrounds[i]);
243 1.1 riastrad if (memcmp(out, expected[i], 144))
244 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
245 1.1 riastrad "AES-%u-CBC enc incremental", aes_keybits[i]);
246 1.1 riastrad
247 1.1 riastrad memcpy(iv, iv0, 16);
248 1.1 riastrad impl->ai_cbc_dec(&dec, out, out, 128, iv, aes_nrounds[i]);
249 1.1 riastrad impl->ai_cbc_dec(&dec, out + 128, out + 128, 16, iv,
250 1.1 riastrad aes_nrounds[i]);
251 1.1 riastrad if (memcmp(out, in, 144))
252 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
253 1.1 riastrad "AES-%u-CBC dec incremental", aes_keybits[i]);
254 1.1 riastrad }
255 1.1 riastrad
256 1.1 riastrad if (outbuf[0] != 0x1a)
257 1.1 riastrad return aes_selftest_fail(impl, outbuf,
258 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
259 1.1 riastrad "AES-CBC overrun preceding");
260 1.1 riastrad if (outbuf[145] != 0x1a)
261 1.1 riastrad return aes_selftest_fail(impl, outbuf + 145,
262 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
263 1.1 riastrad "AES-CBC overrun following");
264 1.1 riastrad
265 1.1 riastrad /* Success! */
266 1.1 riastrad return 0;
267 1.1 riastrad }
268 1.1 riastrad
269 1.1 riastrad static int
270 1.1 riastrad aes_selftest_encdec_xts(const struct aes_impl *impl)
271 1.1 riastrad {
272 1.1 riastrad uint64_t blkno[3] = { 0, 1, 0xff };
273 1.1 riastrad static const uint8_t expected[3][144] = {
274 1.1 riastrad [0] = {
275 1.1 riastrad /* IEEE P1619-D16, XTS-AES-128, Vector 4, truncated */
276 1.1 riastrad 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,
277 1.1 riastrad 0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,
278 1.1 riastrad 0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,
279 1.1 riastrad 0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c,
280 1.1 riastrad 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,
281 1.1 riastrad 0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,
282 1.1 riastrad 0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,
283 1.1 riastrad 0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12,
284 1.1 riastrad 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,
285 1.1 riastrad 0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,
286 1.1 riastrad 0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,
287 1.1 riastrad 0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce,
288 1.1 riastrad 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,
289 1.1 riastrad 0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,
290 1.1 riastrad 0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,
291 1.1 riastrad 0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65,
292 1.1 riastrad 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,
293 1.1 riastrad 0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,
294 1.1 riastrad },
295 1.1 riastrad [1] = {
296 1.1 riastrad },
297 1.1 riastrad [2] = {
298 1.1 riastrad /* IEEE P1619-D16, XTS-AES-256, Vector 10, truncated */
299 1.1 riastrad 0x1c,0x3b,0x3a,0x10,0x2f,0x77,0x03,0x86,
300 1.1 riastrad 0xe4,0x83,0x6c,0x99,0xe3,0x70,0xcf,0x9b,
301 1.1 riastrad 0xea,0x00,0x80,0x3f,0x5e,0x48,0x23,0x57,
302 1.1 riastrad 0xa4,0xae,0x12,0xd4,0x14,0xa3,0xe6,0x3b,
303 1.1 riastrad 0x5d,0x31,0xe2,0x76,0xf8,0xfe,0x4a,0x8d,
304 1.1 riastrad 0x66,0xb3,0x17,0xf9,0xac,0x68,0x3f,0x44,
305 1.1 riastrad 0x68,0x0a,0x86,0xac,0x35,0xad,0xfc,0x33,
306 1.1 riastrad 0x45,0xbe,0xfe,0xcb,0x4b,0xb1,0x88,0xfd,
307 1.1 riastrad 0x57,0x76,0x92,0x6c,0x49,0xa3,0x09,0x5e,
308 1.1 riastrad 0xb1,0x08,0xfd,0x10,0x98,0xba,0xec,0x70,
309 1.1 riastrad 0xaa,0xa6,0x69,0x99,0xa7,0x2a,0x82,0xf2,
310 1.1 riastrad 0x7d,0x84,0x8b,0x21,0xd4,0xa7,0x41,0xb0,
311 1.1 riastrad 0xc5,0xcd,0x4d,0x5f,0xff,0x9d,0xac,0x89,
312 1.1 riastrad 0xae,0xba,0x12,0x29,0x61,0xd0,0x3a,0x75,
313 1.1 riastrad 0x71,0x23,0xe9,0x87,0x0f,0x8a,0xcf,0x10,
314 1.1 riastrad 0x00,0x02,0x08,0x87,0x89,0x14,0x29,0xca,
315 1.1 riastrad 0x2a,0x3e,0x7a,0x7d,0x7d,0xf7,0xb1,0x03,
316 1.1 riastrad 0x55,0x16,0x5c,0x8b,0x9a,0x6d,0x0a,0x7d,
317 1.1 riastrad },
318 1.1 riastrad };
319 1.1 riastrad static const uint8_t key1[32] = {
320 1.1 riastrad 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,
321 1.1 riastrad 0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26,
322 1.1 riastrad 0x62,0x49,0x77,0x57,0x24,0x70,0x93,0x69,
323 1.1 riastrad 0x99,0x59,0x57,0x49,0x66,0x96,0x76,0x27,
324 1.1 riastrad };
325 1.1 riastrad static const uint8_t key2[32] = {
326 1.1 riastrad 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,
327 1.1 riastrad 0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95,
328 1.1 riastrad 0x02,0x88,0x41,0x97,0x16,0x93,0x99,0x37,
329 1.1 riastrad 0x51,0x05,0x82,0x09,0x74,0x94,0x45,0x92,
330 1.1 riastrad };
331 1.1 riastrad struct aesenc enc;
332 1.1 riastrad struct aesdec dec;
333 1.1 riastrad uint8_t in[144];
334 1.1 riastrad uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1;
335 1.1 riastrad uint8_t blkno_buf[16];
336 1.1 riastrad uint8_t iv0[16], iv[16];
337 1.1 riastrad unsigned i;
338 1.1 riastrad
339 1.1 riastrad for (i = 0; i < 144; i++)
340 1.1 riastrad in[i] = i;
341 1.1 riastrad
342 1.1 riastrad for (i = 0; i < 3; i++) {
343 1.1 riastrad if (i == 1) /* XXX missing AES-192 test vector */
344 1.1 riastrad continue;
345 1.1 riastrad
346 1.1 riastrad /* Format the data unit sequence number. */
347 1.1 riastrad memset(blkno_buf, 0, sizeof blkno_buf);
348 1.1 riastrad le64enc(blkno_buf, blkno[i]);
349 1.1 riastrad
350 1.1 riastrad /* Generate the tweak. */
351 1.1 riastrad impl->ai_setenckey(&enc, key2, aes_nrounds[i]);
352 1.1 riastrad impl->ai_enc(&enc, blkno_buf, iv0, aes_nrounds[i]);
353 1.1 riastrad
354 1.1 riastrad /* Load the data encryption key. */
355 1.1 riastrad impl->ai_setenckey(&enc, key1, aes_nrounds[i]);
356 1.1 riastrad impl->ai_setdeckey(&dec, key1, aes_nrounds[i]);
357 1.1 riastrad
358 1.1 riastrad /* Try one swell foop. */
359 1.1 riastrad memcpy(iv, iv0, 16);
360 1.1 riastrad impl->ai_xts_enc(&enc, in, out, 144, iv, aes_nrounds[i]);
361 1.1 riastrad if (memcmp(out, expected[i], 144))
362 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
363 1.1 riastrad "AES-%u-XTS enc", aes_keybits[i]);
364 1.1 riastrad
365 1.1 riastrad memcpy(iv, iv0, 16);
366 1.1 riastrad impl->ai_xts_dec(&dec, out, out, 144, iv, aes_nrounds[i]);
367 1.1 riastrad if (memcmp(out, in, 144))
368 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
369 1.1 riastrad "AES-%u-XTS dec", aes_keybits[i]);
370 1.1 riastrad
371 1.1 riastrad /* Try incrementally, with IV update. */
372 1.1 riastrad memcpy(iv, iv0, 16);
373 1.1 riastrad impl->ai_xts_enc(&enc, in, out, 16, iv, aes_nrounds[i]);
374 1.1 riastrad impl->ai_xts_enc(&enc, in + 16, out + 16, 128, iv,
375 1.1 riastrad aes_nrounds[i]);
376 1.1 riastrad if (memcmp(out, expected[i], 144))
377 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
378 1.1 riastrad "AES-%u-XTS enc incremental", aes_keybits[i]);
379 1.1 riastrad
380 1.1 riastrad memcpy(iv, iv0, 16);
381 1.1 riastrad impl->ai_xts_dec(&dec, out, out, 128, iv, aes_nrounds[i]);
382 1.1 riastrad impl->ai_xts_dec(&dec, out + 128, out + 128, 16, iv,
383 1.1 riastrad aes_nrounds[i]);
384 1.1 riastrad if (memcmp(out, in, 144))
385 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
386 1.1 riastrad "AES-%u-XTS dec incremental", aes_keybits[i]);
387 1.1 riastrad }
388 1.1 riastrad
389 1.1 riastrad if (outbuf[0] != 0x1a)
390 1.1 riastrad return aes_selftest_fail(impl, outbuf,
391 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
392 1.1 riastrad "AES-XTS overrun preceding");
393 1.1 riastrad if (outbuf[145] != 0x1a)
394 1.1 riastrad return aes_selftest_fail(impl, outbuf + 145,
395 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
396 1.1 riastrad "AES-XTS overrun following");
397 1.1 riastrad
398 1.1 riastrad /* Success! */
399 1.1 riastrad return 0;
400 1.1 riastrad }
401 1.1 riastrad
402 1.1 riastrad int
403 1.1 riastrad aes_selftest(const struct aes_impl *impl)
404 1.1 riastrad {
405 1.1 riastrad int result = 0;
406 1.1 riastrad
407 1.1 riastrad if (impl->ai_probe())
408 1.1 riastrad return -1;
409 1.1 riastrad
410 1.1 riastrad if (aes_selftest_encdec(impl))
411 1.1 riastrad result = -1;
412 1.1 riastrad if (aes_selftest_encdec_cbc(impl))
413 1.1 riastrad result = -1;
414 1.1 riastrad if (aes_selftest_encdec_xts(impl))
415 1.1 riastrad result = -1;
416 1.1 riastrad
417 1.1 riastrad return result;
418 1.1 riastrad }
419