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