xref: /netbsd-src/sys/crypto/aes/aes_selftest.c (revision 68c4a8e2005a46a2ea032e19586dd82bdb732f65)
1 /*	$NetBSD: aes_selftest.c,v 1.7 2021/12/05 04:48:35 msaitoh 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.7 2021/12/05 04:48:35 msaitoh 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
aes_selftest_encdec(const struct aes_impl * impl)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 following");
137 
138 	/* Success!  */
139 	return 0;
140 }
141 
142 static int
aes_selftest_encdec_cbc(const struct aes_impl * impl)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, j;
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 		for (j = 0; j < 144; j += 16) {
241 			memcpy(iv, iv0, 16);
242 			impl->ai_cbc_enc(&enc, in, out, j, iv, aes_nrounds[i]);
243 			impl->ai_cbc_enc(&enc, in + j, out + j, 144 - j, iv,
244 			    aes_nrounds[i]);
245 			if (memcmp(out, expected[i], 144))
246 				return aes_selftest_fail(impl, out,
247 				    expected[i], 144, "AES-%u-CBC enc inc %u",
248 				    aes_keybits[i], j);
249 
250 			memcpy(iv, iv0, 16);
251 			impl->ai_cbc_dec(&dec, out, out, j, iv,
252 			    aes_nrounds[i]);
253 			impl->ai_cbc_dec(&dec, out + j, out + j, 144 - j, iv,
254 			    aes_nrounds[i]);
255 			if (memcmp(out, in, 144))
256 				return aes_selftest_fail(impl, out,
257 				    in, 144, "AES-%u-CBC dec inc %u",
258 				    aes_keybits[i], j);
259 		}
260 	}
261 
262 	if (outbuf[0] != 0x1a)
263 		return aes_selftest_fail(impl, outbuf,
264 		    (const uint8_t[1]){0x1a}, 1,
265 		    "AES-CBC overrun preceding");
266 	if (outbuf[145] != 0x1a)
267 		return aes_selftest_fail(impl, outbuf + 145,
268 		    (const uint8_t[1]){0x1a}, 1,
269 		    "AES-CBC overrun following");
270 
271 	/* Success!  */
272 	return 0;
273 }
274 
275 static int
aes_selftest_encdec_xts(const struct aes_impl * impl)276 aes_selftest_encdec_xts(const struct aes_impl *impl)
277 {
278 	uint64_t blkno[3] = { 0, 1, 0xff };
279 	static const uint8_t expected[3][144] = {
280 		[0] = {
281 			/* IEEE P1619-D16, XTS-AES-128, Vector 4, truncated */
282 			0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,
283 			0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,
284 			0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,
285 			0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c,
286 			0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,
287 			0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,
288 			0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,
289 			0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12,
290 			0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,
291 			0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,
292 			0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,
293 			0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce,
294 			0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,
295 			0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,
296 			0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,
297 			0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65,
298 			0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,
299 			0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,
300 		},
301 		[1] = {
302 		},
303 		[2] = {
304 			/* IEEE P1619-D16, XTS-AES-256, Vector 10, truncated */
305 			0x1c,0x3b,0x3a,0x10,0x2f,0x77,0x03,0x86,
306 			0xe4,0x83,0x6c,0x99,0xe3,0x70,0xcf,0x9b,
307 			0xea,0x00,0x80,0x3f,0x5e,0x48,0x23,0x57,
308 			0xa4,0xae,0x12,0xd4,0x14,0xa3,0xe6,0x3b,
309 			0x5d,0x31,0xe2,0x76,0xf8,0xfe,0x4a,0x8d,
310 			0x66,0xb3,0x17,0xf9,0xac,0x68,0x3f,0x44,
311 			0x68,0x0a,0x86,0xac,0x35,0xad,0xfc,0x33,
312 			0x45,0xbe,0xfe,0xcb,0x4b,0xb1,0x88,0xfd,
313 			0x57,0x76,0x92,0x6c,0x49,0xa3,0x09,0x5e,
314 			0xb1,0x08,0xfd,0x10,0x98,0xba,0xec,0x70,
315 			0xaa,0xa6,0x69,0x99,0xa7,0x2a,0x82,0xf2,
316 			0x7d,0x84,0x8b,0x21,0xd4,0xa7,0x41,0xb0,
317 			0xc5,0xcd,0x4d,0x5f,0xff,0x9d,0xac,0x89,
318 			0xae,0xba,0x12,0x29,0x61,0xd0,0x3a,0x75,
319 			0x71,0x23,0xe9,0x87,0x0f,0x8a,0xcf,0x10,
320 			0x00,0x02,0x08,0x87,0x89,0x14,0x29,0xca,
321 			0x2a,0x3e,0x7a,0x7d,0x7d,0xf7,0xb1,0x03,
322 			0x55,0x16,0x5c,0x8b,0x9a,0x6d,0x0a,0x7d,
323 		},
324 	};
325 	static const uint8_t key1[32] = {
326 		0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,
327 		0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26,
328 		0x62,0x49,0x77,0x57,0x24,0x70,0x93,0x69,
329 		0x99,0x59,0x57,0x49,0x66,0x96,0x76,0x27,
330 	};
331 	static const uint8_t key2[32] = {
332 		0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,
333 		0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95,
334 		0x02,0x88,0x41,0x97,0x16,0x93,0x99,0x37,
335 		0x51,0x05,0x82,0x09,0x74,0x94,0x45,0x92,
336 	};
337 	struct aesenc enc;
338 	struct aesdec dec;
339 	uint8_t in[144];
340 	uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1;
341 	uint8_t blkno_buf[16];
342 	uint8_t iv0[16], iv[16];
343 	unsigned i;
344 
345 	for (i = 0; i < 144; i++)
346 		in[i] = i;
347 
348 	for (i = 0; i < 3; i++) {
349 		if (i == 1)	/* XXX missing AES-192 test vector */
350 			continue;
351 
352 		/* Format the data unit sequence number.  */
353 		memset(blkno_buf, 0, sizeof blkno_buf);
354 		le64enc(blkno_buf, blkno[i]);
355 
356 		/* Generate the tweak.  */
357 		impl->ai_setenckey(&enc, key2, aes_nrounds[i]);
358 		impl->ai_enc(&enc, blkno_buf, iv0, aes_nrounds[i]);
359 
360 		/* Load the data encryption key.  */
361 		impl->ai_setenckey(&enc, key1, aes_nrounds[i]);
362 		impl->ai_setdeckey(&dec, key1, aes_nrounds[i]);
363 
364 		/* Try one swell foop.  */
365 		memcpy(iv, iv0, 16);
366 		impl->ai_xts_enc(&enc, in, out, 144, iv, aes_nrounds[i]);
367 		if (memcmp(out, expected[i], 144))
368 			return aes_selftest_fail(impl, out, expected[i], 144,
369 			    "AES-%u-XTS enc", aes_keybits[i]);
370 
371 		memcpy(iv, iv0, 16);
372 		impl->ai_xts_dec(&dec, out, out, 144, iv, aes_nrounds[i]);
373 		if (memcmp(out, in, 144))
374 			return aes_selftest_fail(impl, out, in, 144,
375 			    "AES-%u-XTS dec", aes_keybits[i]);
376 
377 		/* Try incrementally, with IV update.  */
378 		memcpy(iv, iv0, 16);
379 		impl->ai_xts_enc(&enc, in, out, 16, iv, aes_nrounds[i]);
380 		impl->ai_xts_enc(&enc, in + 16, out + 16, 128, iv,
381 		    aes_nrounds[i]);
382 		if (memcmp(out, expected[i], 144))
383 			return aes_selftest_fail(impl, out, expected[i], 144,
384 			    "AES-%u-XTS enc incremental", aes_keybits[i]);
385 
386 		memcpy(iv, iv0, 16);
387 		impl->ai_xts_dec(&dec, out, out, 128, iv, aes_nrounds[i]);
388 		impl->ai_xts_dec(&dec, out + 128, out + 128, 16, iv,
389 		    aes_nrounds[i]);
390 		if (memcmp(out, in, 144))
391 			return aes_selftest_fail(impl, out, in, 144,
392 			    "AES-%u-XTS dec incremental", aes_keybits[i]);
393 	}
394 
395 	if (outbuf[0] != 0x1a)
396 		return aes_selftest_fail(impl, outbuf,
397 		    (const uint8_t[1]){0x1a}, 1,
398 		    "AES-XTS overrun preceding");
399 	if (outbuf[145] != 0x1a)
400 		return aes_selftest_fail(impl, outbuf + 145,
401 		    (const uint8_t[1]){0x1a}, 1,
402 		    "AES-XTS overrun following");
403 
404 	/* Success!  */
405 	return 0;
406 }
407 
408 static int
aes_selftest_cbcmac(const struct aes_impl * impl)409 aes_selftest_cbcmac(const struct aes_impl *impl)
410 {
411 	static const uint8_t m[48] = {
412 		0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
413 		0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
414 		0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
415 		0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
416 		0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
417 		0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
418 	};
419 	static uint8_t auth16[16] = {
420 		0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c,
421 		0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82,
422 	};
423 	static uint8_t auth48[16] = {
424 		0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7,
425 		0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13,
426 	};
427 	static const uint8_t key[16];
428 	struct aesenc enc;
429 	uint8_t auth[16];
430 	const unsigned nr = AES_128_NROUNDS;
431 
432 	memset(auth, 0, sizeof auth);
433 
434 	impl->ai_setenckey(&enc, key, nr);
435 	impl->ai_cbcmac_update1(&enc, m, 16, auth, nr);
436 	if (memcmp(auth, auth16, 16))
437 		return aes_selftest_fail(impl, auth, auth16, 16,
438 		    "AES-128 CBC-MAC (16)");
439 	impl->ai_cbcmac_update1(&enc, m + 16, 32, auth, nr);
440 	if (memcmp(auth, auth48, 16))
441 		return aes_selftest_fail(impl, auth, auth48, 16,
442 		    "AES-128 CBC-MAC (48)");
443 
444 	return 0;
445 }
446 
447 static int
aes_selftest_ccm(const struct aes_impl * impl)448 aes_selftest_ccm(const struct aes_impl *impl)
449 {
450 	static const uint8_t ptxt[48] = {
451 		0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
452 		0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
453 		0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
454 		0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
455 		0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
456 		0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
457 	};
458 	static uint8_t ctr0[16] = {
459 		/* L - 1, #octets in counter */
460 		[0] = 0x01,
461 		/* nonce */
462 		[1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
463 		[14] = 0,
464 		[15] = 254,
465 	};
466 	static uint8_t authctr16[32] = {
467 		/* authentication tag */
468 		0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c,
469 		0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82,
470 
471 		/* L - 1, #octets in counter */
472 		[16 + 0] = 0x01,
473 		/* nonce */
474 		[16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
475 		[16 + 14] = 0,
476 		[16 + 15] = 255,
477 	};
478 	static uint8_t authctr48[32] = {
479 		/* authentication tag */
480 		0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7,
481 		0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13,
482 
483 		/* L - 1, #octets in counter */
484 		[16 + 0] = 0x01,
485 		/* nonce */
486 		[16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
487 		[16 + 14] = 1,
488 		[16 + 15] = 1,
489 	};
490 	static uint8_t ctxt[48] = {
491 		0xa4,0x35,0x07,0x5c, 0xdf,0x2d,0x67,0xd3,
492 		0xbf,0x1f,0x36,0x93, 0xe4,0x43,0xcb,0x1e,
493 		0xa0,0x82,0x9c,0x2a, 0x0b,0x66,0x46,0x05,
494 		0x80,0x17,0x71,0xa1, 0x7b,0x09,0xa7,0xd5,
495 		0x91,0x0b,0xb3,0x96, 0xd1,0x5e,0x29,0x3e,
496 		0x74,0x94,0x74,0x6d, 0x6b,0x25,0x43,0x8c,
497 	};
498 	static const uint8_t key[16];
499 	struct aesenc enc;
500 	uint8_t authctr[32];
501 	uint8_t buf[48];
502 	const unsigned nr = AES_128_NROUNDS;
503 	int result = 0;
504 
505 	impl->ai_setenckey(&enc, key, nr);
506 
507 	memset(authctr, 0, 16);
508 	memcpy(authctr + 16, ctr0, 16);
509 
510 	impl->ai_ccm_enc1(&enc, ptxt, buf, 16, authctr, nr);
511 	if (memcmp(authctr, authctr16, 32))
512 		result |= aes_selftest_fail(impl, authctr, authctr16, 32,
513 		    "AES-128 CCM encrypt auth/ctr (16)");
514 	impl->ai_ccm_enc1(&enc, ptxt + 16, buf + 16, 32, authctr, nr);
515 	if (memcmp(authctr, authctr48, 32))
516 		result |= aes_selftest_fail(impl, authctr, authctr48, 32,
517 		    "AES-128 CCM encrypt auth/ctr (48)");
518 
519 	if (memcmp(buf, ctxt, 32))
520 		result |= aes_selftest_fail(impl, buf, ctxt, 48,
521 		    "AES-128 CCM ciphertext");
522 
523 	memset(authctr, 0, 16);
524 	memcpy(authctr + 16, ctr0, 16);
525 
526 	impl->ai_ccm_dec1(&enc, ctxt, buf, 16, authctr, nr);
527 	if (memcmp(authctr, authctr16, 32))
528 		result |= aes_selftest_fail(impl, authctr, authctr16, 32,
529 		    "AES-128 CCM decrypt auth/ctr (16)");
530 	impl->ai_ccm_dec1(&enc, ctxt + 16, buf + 16, 32, authctr, nr);
531 	if (memcmp(authctr, authctr48, 32))
532 		result |= aes_selftest_fail(impl, authctr, authctr48, 32,
533 		    "AES-128 CCM decrypt auth/ctr (48)");
534 
535 	if (memcmp(buf, ptxt, 32))
536 		result |= aes_selftest_fail(impl, buf, ptxt, 48,
537 		    "AES-128 CCM plaintext");
538 
539 	return result;
540 }
541 
542 int
aes_selftest(const struct aes_impl * impl)543 aes_selftest(const struct aes_impl *impl)
544 {
545 	int result = 0;
546 
547 	if (impl->ai_probe())
548 		return -1;
549 
550 	if (aes_selftest_encdec(impl))
551 		result = -1;
552 	if (aes_selftest_encdec_cbc(impl))
553 		result = -1;
554 	if (aes_selftest_encdec_xts(impl))
555 		result = -1;
556 	if (aes_selftest_cbcmac(impl))
557 		result = -1;
558 	if (aes_selftest_ccm(impl))
559 		result = -1;
560 
561 	return result;
562 }
563