xref: /freebsd/tools/tools/crypto/cryptocheck.c (revision 81b22a98)
1 /*-
2  * Copyright (c) 2017 Chelsio Communications, Inc.
3  * All rights reserved.
4  * Copyright (c) 2021 The FreeBSD Foundation
5  * Written by: John Baldwin <jhb@FreeBSD.org>
6  *
7  * Portions of this software were developed by Ararat River
8  * Consulting, LLC under sponsorship of the FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 /*-
32  * Copyright (c) 2004 Sam Leffler, Errno Consulting
33  * All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  * 1. Redistributions of source code must retain the above copyright
39  *    notice, this list of conditions and the following disclaimer,
40  *    without modification.
41  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
42  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
43  *    redistribution must be conditioned upon including a substantially
44  *    similar Disclaimer requirement for further binary redistribution.
45  * 3. Neither the names of the above-listed copyright holders nor the names
46  *    of any contributors may be used to endorse or promote products derived
47  *    from this software without specific prior written permission.
48  *
49  * NO WARRANTY
50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
53  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
55  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
58  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
60  * THE POSSIBILITY OF SUCH DAMAGES.
61  *
62  * $FreeBSD$
63  */
64 
65 /*
66  * A different tool for checking hardware crypto support.  Whereas
67  * cryptotest is focused on simple performance numbers, this tool is
68  * focused on correctness.  For each crypto operation, it performs the
69  * operation once in software via OpenSSL and a second time via
70  * OpenCrypto and compares the results.
71  *
72  * cryptocheck [-vz] [-A aad length] [-a algorithm] [-d dev] [-I IV length]
73  *	       [size ...]
74  *
75  * Options:
76  *	-v	Verbose.
77  *	-z	Run all algorithms on a variety of buffer sizes.
78  *
79  * Supported algorithms:
80  *	all		Run all tests
81  *	hash		Run all hash tests
82  *	mac		Run all mac tests
83  *	cipher		Run all cipher tests
84  *	eta		Run all encrypt-then-authenticate tests
85  *	aead		Run all authenticated encryption with associated data
86  *			tests
87  *
88  * Hashes:
89  *	sha1		SHA-1
90  *	sha224		224-bit SHA-2
91  *	sha256		256-bit SHA-2
92  *	sha384		384-bit SHA-2
93  *	sha512		512-bit	SHA-2
94  *	blake2b		Blake2-B
95  *	blake2s		Blake2-S
96  *
97  * MACs:
98  *	sha1hmac	SHA-1 HMAC
99  *	sha224hmac	224-bit SHA-2 HMAC
100  *	sha256hmac	256-bit SHA-2 HMAC
101  *	sha384hmac	384-bit SHA-2 HMAC
102  *	sha512hmac	512-bit	SHA-2 HMAC
103  *	gmac		128-bit GMAC
104  *	gmac192		192-bit GMAC
105  *	gmac256		256-bit GMAC
106  *	poly1305
107  *
108  * Ciphers:
109  *	aes-cbc		128-bit AES-CBC
110  *	aes-cbc192	192-bit	AES-CBC
111  *	aes-cbc256	256-bit AES-CBC
112  *	aes-ctr		128-bit AES-CTR
113  *	aes-ctr192	192-bit AES-CTR
114  *	aes-ctr256	256-bit AES-CTR
115  *	aes-xts		128-bit AES-XTS
116  *	aes-xts256	256-bit AES-XTS
117  *	chacha20
118  *
119  * Encrypt then Authenticate:
120  *	<cipher>+<mac>
121  *
122  * Authenticated Encryption with Associated Data:
123  *	aes-gcm		128-bit AES-GCM
124  *	aes-gcm192	192-bit AES-GCM
125  *	aes-gcm256	256-bit AES-GCM
126  *	aes-ccm		128-bit AES-CCM
127  *	aes-ccm192	192-bit AES-CCM
128  *	aes-ccm256	256-bit AES-CCM
129  *	chacha20-poly1305 Chacha20 with Poly1305 per RFC 8439
130  */
131 
132 #include <sys/param.h>
133 #include <sys/sysctl.h>
134 #include <assert.h>
135 #include <err.h>
136 #include <fcntl.h>
137 #include <libutil.h>
138 #include <stdbool.h>
139 #include <stdio.h>
140 #include <string.h>
141 #include <unistd.h>
142 
143 #include <openssl/err.h>
144 #include <openssl/hmac.h>
145 
146 #include <crypto/cryptodev.h>
147 
148 struct ocf_session {
149 	int fd;
150 	int ses;
151 	int crid;
152 };
153 
154 static const struct alg {
155 	const char *name;
156 	int cipher;
157 	int mac;
158 	enum { T_HASH, T_HMAC, T_GMAC, T_DIGEST, T_CIPHER, T_ETA, T_AEAD } type;
159 	int key_len;
160 	int tag_len;
161 	u_int iv_sizes[8];
162 	const EVP_CIPHER *(*evp_cipher)(void);
163 	const EVP_MD *(*evp_md)(void);
164 	int pkey;
165 } algs[] = {
166 	{ .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH,
167 	  .evp_md = EVP_sha1 },
168 	{ .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH,
169 	  .evp_md = EVP_sha224 },
170 	{ .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH,
171 	  .evp_md = EVP_sha256 },
172 	{ .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH,
173 	  .evp_md = EVP_sha384 },
174 	{ .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH,
175 	  .evp_md = EVP_sha512 },
176 	{ .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
177 	  .evp_md = EVP_sha1 },
178 	{ .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
179 	  .evp_md = EVP_sha224 },
180 	{ .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
181 	  .evp_md = EVP_sha256 },
182 	{ .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
183 	  .evp_md = EVP_sha384 },
184 	{ .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
185 	  .evp_md = EVP_sha512 },
186 	{ .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH,
187 	  .evp_md = EVP_blake2b512 },
188 	{ .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH,
189 	  .evp_md = EVP_blake2s256 },
190 	{ .name = "gmac", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
191 	  .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_128_gcm },
192 	{ .name = "gmac192", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
193 	  .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_192_gcm },
194 	{ .name = "gmac256", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
195 	  .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_256_gcm },
196 	{ .name = "poly1305", .mac = CRYPTO_POLY1305, .type = T_DIGEST,
197 	  .key_len = POLY1305_KEY_LEN, .pkey = EVP_PKEY_POLY1305 },
198 	{ .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
199 	  .evp_cipher = EVP_aes_128_cbc },
200 	{ .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
201 	  .evp_cipher = EVP_aes_192_cbc },
202 	{ .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
203 	  .evp_cipher = EVP_aes_256_cbc },
204 	{ .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
205 	  .evp_cipher = EVP_aes_128_ctr },
206 	{ .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
207 	  .evp_cipher = EVP_aes_192_ctr },
208 	{ .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
209 	  .evp_cipher = EVP_aes_256_ctr },
210 	{ .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
211 	  .evp_cipher = EVP_aes_128_xts },
212 	{ .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
213 	  .evp_cipher = EVP_aes_256_xts },
214 	{ .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_CIPHER,
215 	  .evp_cipher = EVP_chacha20 },
216 	{ .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16, .type = T_AEAD,
217 	  .tag_len = AES_GMAC_HASH_LEN, .iv_sizes = { AES_GCM_IV_LEN },
218 	  .evp_cipher = EVP_aes_128_gcm },
219 	{ .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16,
220 	  .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN,
221 	  .iv_sizes = { AES_GCM_IV_LEN }, .evp_cipher = EVP_aes_192_gcm },
222 	{ .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16,
223 	  .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN,
224 	  .iv_sizes = { AES_GCM_IV_LEN }, .evp_cipher = EVP_aes_256_gcm },
225 	{ .name = "aes-ccm", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
226 	  .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
227 	  .evp_cipher = EVP_aes_128_ccm },
228 	{ .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
229 	  .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
230 	  .evp_cipher = EVP_aes_192_ccm },
231 	{ .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
232 	  .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
233 	  .evp_cipher = EVP_aes_256_ccm },
234 	{ .name = "chacha20-poly1305", .cipher = CRYPTO_CHACHA20_POLY1305,
235 	  .type = T_AEAD, .tag_len = POLY1305_HASH_LEN,
236 	  .iv_sizes = { CHACHA20_POLY1305_IV_LEN, 8 },
237 	  .evp_cipher = EVP_chacha20_poly1305 },
238 };
239 
240 static bool testall, verbose;
241 static int requested_crid;
242 static size_t aad_sizes[48], sizes[EALG_MAX_BLOCK_LEN * 2];
243 static u_int naad_sizes, nsizes;
244 static u_int iv_size;
245 
246 static void
247 usage(void)
248 {
249 	fprintf(stderr,
250 	    "usage: cryptocheck [-vz] [-A aad size] [-a algorithm]\n"
251 	    "                   [-d dev] [-I IV size] [size ...]\n");
252 	exit(1);
253 }
254 
255 static const struct alg *
256 find_alg(const char *name)
257 {
258 	u_int i;
259 
260 	for (i = 0; i < nitems(algs); i++)
261 		if (strcasecmp(algs[i].name, name) == 0)
262 			return (&algs[i]);
263 	return (NULL);
264 }
265 
266 static struct alg *
267 build_eta(const struct alg *cipher, const struct alg *mac)
268 {
269 	struct alg *eta;
270 	char *name;
271 
272 	assert(cipher->type == T_CIPHER);
273 	assert(mac->type == T_HMAC);
274 	eta = calloc(1, sizeof(*eta));
275 	asprintf(&name, "%s+%s", cipher->name, mac->name);
276 	eta->name = name;
277 	eta->cipher = cipher->cipher;
278 	eta->mac = mac->mac;
279 	eta->type = T_ETA;
280 	eta->evp_cipher = cipher->evp_cipher;
281 	eta->evp_md = mac->evp_md;
282 	return (eta);
283 }
284 
285 static void
286 free_eta(struct alg *eta)
287 {
288 	free(__DECONST(char *, eta->name));
289 	free(eta);
290 }
291 
292 static struct alg *
293 build_eta_name(const char *name)
294 {
295 	const struct alg *cipher, *mac;
296 	const char *mac_name;
297 	char *cp, *cipher_name;
298 
299 	cp = strchr(name, '+');
300 	cipher_name = strndup(name, cp - name);
301 	mac_name = cp + 1;
302 	cipher = find_alg(cipher_name);
303 	free(cipher_name);
304 	if (cipher == NULL || cipher->type != T_CIPHER)
305 		errx(1, "Invalid cipher %s", cipher_name);
306 	mac = find_alg(mac_name);
307 	if (mac == NULL || mac->type != T_HMAC)
308 		errx(1, "Invalid hmac %s", mac_name);
309 	return (build_eta(cipher, mac));
310 }
311 
312 static int
313 devcrypto(void)
314 {
315 	static int fd = -1;
316 
317 	if (fd < 0) {
318 		fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0);
319 		if (fd < 0)
320 			err(1, "/dev/crypto");
321 	}
322 	return (fd);
323 }
324 
325 /*
326  * Called on exit to change kern.cryptodevallowsoft back to 0
327  */
328 #define CRYPT_SOFT_ALLOW	"kern.cryptodevallowsoft"
329 
330 static void
331 reset_user_soft(void)
332 {
333 	int off = 0;
334 	sysctlbyname(CRYPT_SOFT_ALLOW, NULL, NULL, &off, sizeof(off));
335 }
336 
337 static void
338 enable_user_soft(void)
339 {
340 	int curstate;
341 	int on = 1;
342 	size_t cursize = sizeof(curstate);
343 
344 	if (sysctlbyname(CRYPT_SOFT_ALLOW, &curstate, &cursize,
345 		&on, sizeof(on)) == 0) {
346 		if (curstate == 0)
347 			atexit(reset_user_soft);
348 	}
349 }
350 
351 static int
352 crlookup(const char *devname)
353 {
354 	struct crypt_find_op find;
355 
356 	if (strncmp(devname, "soft", 4) == 0) {
357 		enable_user_soft();
358 		return CRYPTO_FLAG_SOFTWARE;
359 	}
360 
361 	find.crid = -1;
362 	strlcpy(find.name, devname, sizeof(find.name));
363 	if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
364 		err(1, "ioctl(CIOCFINDDEV)");
365 	return (find.crid);
366 }
367 
368 static const char *
369 crfind(int crid)
370 {
371 	static struct crypt_find_op find;
372 
373 	if (crid == CRYPTO_FLAG_SOFTWARE)
374 		return ("soft");
375 	else if (crid == CRYPTO_FLAG_HARDWARE)
376 		return ("unknown");
377 
378 	bzero(&find, sizeof(find));
379 	find.crid = crid;
380 	if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
381 		err(1, "ioctl(CIOCFINDDEV): crid %d", crid);
382 	return (find.name);
383 }
384 
385 static char
386 rdigit(void)
387 {
388 	const char a[] = {
389 		0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41,
390 		0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01
391 	};
392 	return 0x20+a[random()%nitems(a)];
393 }
394 
395 static char *
396 alloc_buffer(size_t len)
397 {
398 	char *buf;
399 	size_t i;
400 
401 	buf = malloc(len);
402 	for (i = 0; i < len; i++)
403 		buf[i] = rdigit();
404 	return (buf);
405 }
406 
407 static char *
408 generate_iv(size_t len, const struct alg *alg)
409 {
410 	char *iv;
411 
412 	iv = alloc_buffer(len);
413 	switch (alg->cipher) {
414 	case CRYPTO_AES_ICM:
415 		/* Clear the low 32 bits of the IV to hold the counter. */
416 		iv[len - 4] = 0;
417 		iv[len - 3] = 0;
418 		iv[len - 2] = 0;
419 		iv[len - 1] = 0;
420 		break;
421 	case CRYPTO_AES_XTS:
422 		/*
423 		 * Clear the low 64-bits to only store a 64-bit block
424 		 * number.
425 		 */
426 		iv[len - 8] = 0;
427 		iv[len - 7] = 0;
428 		iv[len - 6] = 0;
429 		iv[len - 5] = 0;
430 		iv[len - 4] = 0;
431 		iv[len - 3] = 0;
432 		iv[len - 2] = 0;
433 		iv[len - 1] = 0;
434 		break;
435 	}
436 	return (iv);
437 }
438 
439 static void
440 ocf_init_sop(struct session2_op *sop)
441 {
442 	memset(sop, 0, sizeof(*sop));
443 	sop->crid = requested_crid;
444 }
445 
446 static bool
447 ocf_init_session(struct session2_op *sop, const char *type, const char *name,
448     struct ocf_session *ses)
449 {
450 	int fd;
451 
452 	fd = devcrypto();
453 	if (ioctl(fd, CIOCGSESSION2, sop) < 0) {
454 		warn("cryptodev %s %s not supported for device %s",
455 		    type, name, crfind(sop->crid));
456 		ses->fd = -1;
457 		return (false);
458 	}
459 	ses->fd = fd;
460 	ses->ses = sop->ses;
461 	ses->crid = sop->crid;
462 	return (true);
463 }
464 
465 static void
466 ocf_destroy_session(struct ocf_session *ses)
467 {
468 	if (ses->fd == -1)
469 		return;
470 
471 	if (ioctl(ses->fd, CIOCFSESSION, &ses->ses) < 0)
472 		warn("ioctl(CIOCFSESSION)");
473 }
474 
475 static void
476 ocf_init_cop(const struct ocf_session *ses, struct crypt_op *cop)
477 {
478 	memset(cop, 0, sizeof(*cop));
479 	cop->ses = ses->ses;
480 }
481 
482 static void
483 ocf_init_caead(const struct ocf_session *ses, struct crypt_aead *caead)
484 {
485 	memset(caead, 0, sizeof(*caead));
486 	caead->ses = ses->ses;
487 }
488 
489 static bool
490 ocf_hash(const struct alg *alg, const char *buffer, size_t size, char *digest,
491     int *cridp)
492 {
493 	struct ocf_session ses;
494 	struct session2_op sop;
495 	struct crypt_op cop;
496 
497 	ocf_init_sop(&sop);
498 	sop.mac = alg->mac;
499 	if (!ocf_init_session(&sop, "HASH", alg->name, &ses))
500 		return (false);
501 
502 	ocf_init_cop(&ses, &cop);
503 	cop.op = 0;
504 	cop.len = size;
505 	cop.src = buffer;
506 	cop.mac = digest;
507 
508 	if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
509 		warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
510 		    size, crfind(ses.crid));
511 		ocf_destroy_session(&ses);
512 		return (false);
513 	}
514 
515 	*cridp = ses.crid;
516 	ocf_destroy_session(&ses);
517 	return (true);
518 }
519 
520 static void
521 openssl_hash(const struct alg *alg, const EVP_MD *md, const void *buffer,
522     size_t size, void *digest_out, unsigned *digest_sz_out)
523 {
524 	EVP_MD_CTX *mdctx;
525 	const char *errs;
526 	int rc;
527 
528 	errs = "";
529 
530 	mdctx = EVP_MD_CTX_create();
531 	if (mdctx == NULL)
532 		goto err_out;
533 
534 	rc = EVP_DigestInit_ex(mdctx, md, NULL);
535 	if (rc != 1)
536 		goto err_out;
537 
538 	rc = EVP_DigestUpdate(mdctx, buffer, size);
539 	if (rc != 1)
540 		goto err_out;
541 
542 	rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out);
543 	if (rc != 1)
544 		goto err_out;
545 
546 	EVP_MD_CTX_destroy(mdctx);
547 	return;
548 
549 err_out:
550 	errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs,
551 	    ERR_error_string(ERR_get_error(), NULL));
552 }
553 
554 static void
555 run_hash_test(const struct alg *alg, size_t size)
556 {
557 	const EVP_MD *md;
558 	char *buffer;
559 	u_int digest_len;
560 	int crid;
561 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
562 
563 	memset(control_digest, 0x3c, sizeof(control_digest));
564 	memset(test_digest, 0x3c, sizeof(test_digest));
565 
566 	md = alg->evp_md();
567 	assert((size_t)EVP_MD_size(md) <= sizeof(control_digest));
568 
569 	buffer = alloc_buffer(size);
570 
571 	/* OpenSSL HASH. */
572 	digest_len = sizeof(control_digest);
573 	openssl_hash(alg, md, buffer, size, control_digest, &digest_len);
574 
575 	/* cryptodev HASH. */
576 	if (!ocf_hash(alg, buffer, size, test_digest, &crid))
577 		goto out;
578 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
579 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
580 			printf("%s (%zu) mismatch in trailer:\n",
581 			    alg->name, size);
582 		else
583 			printf("%s (%zu) mismatch:\n", alg->name, size);
584 		printf("control:\n");
585 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
586 		printf("test (cryptodev device %s):\n", crfind(crid));
587 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
588 		goto out;
589 	}
590 
591 	if (verbose)
592 		printf("%s (%zu) matched (cryptodev device %s)\n",
593 		    alg->name, size, crfind(crid));
594 
595 out:
596 	free(buffer);
597 }
598 
599 static bool
600 ocf_hmac(const struct alg *alg, const char *buffer, size_t size,
601     const char *key, size_t key_len, char *digest, int *cridp)
602 {
603 	struct ocf_session ses;
604 	struct session2_op sop;
605 	struct crypt_op cop;
606 
607 	ocf_init_sop(&sop);
608 	sop.mackeylen = key_len;
609 	sop.mackey = key;
610 	sop.mac = alg->mac;
611 	if (!ocf_init_session(&sop, "HMAC", alg->name, &ses))
612 		return (false);
613 
614 	ocf_init_cop(&ses, &cop);
615 	cop.op = 0;
616 	cop.len = size;
617 	cop.src = buffer;
618 	cop.mac = digest;
619 
620 	if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
621 		warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name,
622 		    size, crfind(ses.crid));
623 		ocf_destroy_session(&ses);
624 		return (false);
625 	}
626 
627 	*cridp = ses.crid;
628 	ocf_destroy_session(&ses);
629 	return (true);
630 }
631 
632 static void
633 run_hmac_test(const struct alg *alg, size_t size)
634 {
635 	const EVP_MD *md;
636 	char *key, *buffer;
637 	u_int key_len, digest_len;
638 	int crid;
639 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
640 
641 	memset(control_digest, 0x3c, sizeof(control_digest));
642 	memset(test_digest, 0x3c, sizeof(test_digest));
643 
644 	md = alg->evp_md();
645 	key_len = EVP_MD_size(md);
646 	assert((size_t)EVP_MD_size(md) <= sizeof(control_digest));
647 
648 	key = alloc_buffer(key_len);
649 	buffer = alloc_buffer(size);
650 
651 	/* OpenSSL HMAC. */
652 	digest_len = sizeof(control_digest);
653 	if (HMAC(md, key, key_len, (u_char *)buffer, size,
654 	    (u_char *)control_digest, &digest_len) == NULL)
655 		errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
656 		    size, ERR_error_string(ERR_get_error(), NULL));
657 
658 	/* cryptodev HMAC. */
659 	if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid))
660 		goto out;
661 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
662 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
663 			printf("%s (%zu) mismatch in trailer:\n",
664 			    alg->name, size);
665 		else
666 			printf("%s (%zu) mismatch:\n", alg->name, size);
667 		printf("control:\n");
668 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
669 		printf("test (cryptodev device %s):\n", crfind(crid));
670 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
671 		goto out;
672 	}
673 
674 	if (verbose)
675 		printf("%s (%zu) matched (cryptodev device %s)\n",
676 		    alg->name, size, crfind(crid));
677 
678 out:
679 	free(buffer);
680 	free(key);
681 }
682 
683 static void
684 openssl_cipher(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
685     const char *iv, const char *input, char *output, size_t size, int enc)
686 {
687 	EVP_CIPHER_CTX *ctx;
688 	int outl, total;
689 
690 	ctx = EVP_CIPHER_CTX_new();
691 	if (ctx == NULL)
692 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
693 		    size, ERR_error_string(ERR_get_error(), NULL));
694 	if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
695 	    (const u_char *)iv, enc) != 1)
696 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
697 		    size, ERR_error_string(ERR_get_error(), NULL));
698 	EVP_CIPHER_CTX_set_padding(ctx, 0);
699 	if (EVP_CipherUpdate(ctx, (u_char *)output, &outl,
700 	    (const u_char *)input, size) != 1)
701 		errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name,
702 		    size, ERR_error_string(ERR_get_error(), NULL));
703 	total = outl;
704 	if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
705 		errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name,
706 		    size, ERR_error_string(ERR_get_error(), NULL));
707 	total += outl;
708 	if ((size_t)total != size)
709 		errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name,
710 		    size, total);
711 	EVP_CIPHER_CTX_free(ctx);
712 }
713 
714 static bool
715 ocf_init_cipher_session(const struct alg *alg, const char *key, size_t key_len,
716     struct ocf_session *ses)
717 {
718 	struct session2_op sop;
719 
720 	ocf_init_sop(&sop);
721 	sop.keylen = key_len;
722 	sop.key = key;
723 	sop.cipher = alg->cipher;
724 	return (ocf_init_session(&sop, "cipher", alg->name, ses));
725 }
726 
727 static bool
728 ocf_cipher(const struct ocf_session *ses, const struct alg *alg, const char *iv,
729     const char *input, char *output, size_t size, int op)
730 {
731 	struct crypt_op cop;
732 
733 	ocf_init_cop(ses, &cop);
734 	cop.op = op;
735 	cop.len = size;
736 	cop.src = input;
737 	cop.dst = output;
738 	cop.iv = iv;
739 
740 	if (ioctl(ses->fd, CIOCCRYPT, &cop) < 0) {
741 		warn("cryptodev %s (%zu) cipher failed for device %s",
742 		    alg->name, size, crfind(ses->crid));
743 		return (false);
744 	}
745 
746 	return (true);
747 }
748 
749 static void
750 run_cipher_test(const struct alg *alg, size_t size)
751 {
752 	struct ocf_session ses;
753 	const EVP_CIPHER *cipher;
754 	char *buffer, *cleartext, *ciphertext;
755 	char *iv, *key;
756 	u_int iv_len, key_len;
757 
758 	cipher = alg->evp_cipher();
759 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
760 		if (verbose)
761 			printf(
762 			    "%s (%zu): invalid buffer size (block size %d)\n",
763 			    alg->name, size, EVP_CIPHER_block_size(cipher));
764 		return;
765 	}
766 
767 	/*
768 	 * XTS requires at least one full block so that any partial
769 	 * block at the end has cipher text to steal.  Hardcoding the
770 	 * AES block size isn't ideal, but OpenSSL doesn't have a
771 	 * notion of a "native" block size.
772 	 */
773 	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
774 	    size < AES_BLOCK_LEN) {
775 		if (verbose)
776 			printf("%s (%zu): invalid buffer size\n", alg->name,
777 			    size);
778 		return;
779 	}
780 
781 	key_len = EVP_CIPHER_key_length(cipher);
782 	iv_len = EVP_CIPHER_iv_length(cipher);
783 
784 	key = alloc_buffer(key_len);
785 	iv = generate_iv(iv_len, alg);
786 	cleartext = alloc_buffer(size);
787 	buffer = malloc(size);
788 	ciphertext = malloc(size);
789 
790 	/* OpenSSL cipher. */
791 	openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1);
792 	if (size > 0 && memcmp(cleartext, ciphertext, size) == 0)
793 		warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name,
794 		    size);
795 	openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0);
796 	if (memcmp(cleartext, buffer, size) != 0) {
797 		printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size);
798 		printf("original:\n");
799 		hexdump(cleartext, size, NULL, 0);
800 		printf("decrypted:\n");
801 		hexdump(buffer, size, NULL, 0);
802 		exit(1);
803 	}
804 
805 	if (!ocf_init_cipher_session(alg, key, key_len, &ses))
806 		goto out;
807 
808 	/* OCF encrypt. */
809 	if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT))
810 		goto out;
811 	if (memcmp(ciphertext, buffer, size) != 0) {
812 		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
813 		printf("control:\n");
814 		hexdump(ciphertext, size, NULL, 0);
815 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
816 		hexdump(buffer, size, NULL, 0);
817 		goto out;
818 	}
819 
820 	/* OCF decrypt. */
821 	if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT))
822 		goto out;
823 	if (memcmp(cleartext, buffer, size) != 0) {
824 		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
825 		printf("control:\n");
826 		hexdump(cleartext, size, NULL, 0);
827 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
828 		hexdump(buffer, size, NULL, 0);
829 		goto out;
830 	}
831 
832 	if (verbose)
833 		printf("%s (%zu) matched (cryptodev device %s)\n",
834 		    alg->name, size, crfind(ses.crid));
835 
836 out:
837 	ocf_destroy_session(&ses);
838 	free(ciphertext);
839 	free(buffer);
840 	free(cleartext);
841 	free(iv);
842 	free(key);
843 }
844 
845 static bool
846 ocf_init_eta_session(const struct alg *alg, const char *cipher_key,
847     size_t cipher_key_len, const char *auth_key, size_t auth_key_len,
848     struct ocf_session *ses)
849 {
850 	struct session2_op sop;
851 
852 	ocf_init_sop(&sop);
853 	sop.keylen = cipher_key_len;
854 	sop.key = cipher_key;
855 	sop.cipher = alg->cipher;
856 	sop.mackeylen = auth_key_len;
857 	sop.mackey = auth_key;
858 	sop.mac = alg->mac;
859 	return (ocf_init_session(&sop, "ETA", alg->name, ses));
860 }
861 
862 static int
863 ocf_eta(const struct ocf_session *ses, const char *iv, size_t iv_len,
864     const char *aad, size_t aad_len, const char *input, char *output,
865     size_t size, char *digest, int op)
866 {
867 	int ret;
868 
869 	if (aad_len != 0) {
870 		struct crypt_aead caead;
871 
872 		ocf_init_caead(ses, &caead);
873 		caead.op = op;
874 		caead.len = size;
875 		caead.aadlen = aad_len;
876 		caead.ivlen = iv_len;
877 		caead.src = input;
878 		caead.dst = output;
879 		caead.aad = aad;
880 		caead.tag = digest;
881 		caead.iv = iv;
882 
883 		ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead);
884 	} else {
885 		struct crypt_op cop;
886 
887 		ocf_init_cop(ses, &cop);
888 		cop.op = op;
889 		cop.len = size;
890 		cop.src = input;
891 		cop.dst = output;
892 		cop.mac = digest;
893 		cop.iv = iv;
894 
895 		ret = ioctl(ses->fd, CIOCCRYPT, &cop);
896 	}
897 
898 	if (ret < 0)
899 		return (errno);
900 	return (0);
901 }
902 
903 static void
904 run_eta_test(const struct alg *alg, size_t aad_len, size_t size)
905 {
906 	struct ocf_session ses;
907 	const EVP_CIPHER *cipher;
908 	const EVP_MD *md;
909 	char *buffer, *cleartext, *ciphertext;
910 	char *iv, *auth_key, *cipher_key;
911 	u_int iv_len, auth_key_len, cipher_key_len, digest_len;
912 	int error;
913 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
914 
915 	cipher = alg->evp_cipher();
916 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
917 		if (verbose)
918 			printf(
919 		    "%s (%zu, %zu): invalid buffer size (block size %d)\n",
920 			    alg->name, aad_len, size,
921 			    EVP_CIPHER_block_size(cipher));
922 		return;
923 	}
924 
925 	/* See comment in run_cipher_test. */
926 	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
927 	    size < AES_BLOCK_LEN) {
928 		if (verbose)
929 			printf("%s (%zu): invalid buffer size\n", alg->name,
930 			    size);
931 		return;
932 	}
933 
934 	memset(control_digest, 0x3c, sizeof(control_digest));
935 	memset(test_digest, 0x3c, sizeof(test_digest));
936 
937 	md = alg->evp_md();
938 
939 	cipher_key_len = EVP_CIPHER_key_length(cipher);
940 	iv_len = EVP_CIPHER_iv_length(cipher);
941 	auth_key_len = EVP_MD_size(md);
942 
943 	cipher_key = alloc_buffer(cipher_key_len);
944 	iv = generate_iv(iv_len, alg);
945 	auth_key = alloc_buffer(auth_key_len);
946 	cleartext = alloc_buffer(aad_len + size);
947 	buffer = malloc(aad_len + size);
948 	ciphertext = malloc(aad_len + size);
949 
950 	/* OpenSSL encrypt + HMAC. */
951 	if (aad_len != 0)
952 		memcpy(ciphertext, cleartext, aad_len);
953 	openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len,
954 	    ciphertext + aad_len, size, 1);
955 	if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
956 	    size) == 0)
957 		warnx("OpenSSL %s (%zu, %zu): cipher text unchanged",
958 		    alg->name, aad_len, size);
959 	digest_len = sizeof(control_digest);
960 	if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
961 	    aad_len + size, (u_char *)control_digest, &digest_len) == NULL)
962 		errx(1, "OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name,
963 		    aad_len, size, ERR_error_string(ERR_get_error(), NULL));
964 
965 	if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key,
966 	    auth_key_len, &ses))
967 		goto out;
968 
969 	/* OCF encrypt + HMAC. */
970 	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? cleartext : NULL,
971 	    aad_len, cleartext + aad_len, buffer + aad_len, size, test_digest,
972 	    COP_ENCRYPT);
973 	if (error != 0) {
974 		warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
975 		    alg->name, aad_len, size, crfind(ses.crid));
976 		goto out;
977 	}
978 	if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
979 		printf("%s (%zu, %zu) encryption mismatch:\n", alg->name,
980 		    aad_len, size);
981 		printf("control:\n");
982 		hexdump(ciphertext + aad_len, size, NULL, 0);
983 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
984 		hexdump(buffer + aad_len, size, NULL, 0);
985 		goto out;
986 	}
987 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
988 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
989 			printf("%s (%zu, %zu) enc hash mismatch in trailer:\n",
990 			    alg->name, aad_len, size);
991 		else
992 			printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name,
993 			    aad_len, size);
994 		printf("control:\n");
995 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
996 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
997 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
998 		goto out;
999 	}
1000 
1001 	/* OCF HMAC + decrypt. */
1002 	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1003 	    aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1004 	    COP_DECRYPT);
1005 	if (error != 0) {
1006 		warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
1007 		    alg->name, aad_len, size, crfind(ses.crid));
1008 		goto out;
1009 	}
1010 	if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
1011 		printf("%s (%zu, %zu) decryption mismatch:\n", alg->name,
1012 		    aad_len, size);
1013 		printf("control:\n");
1014 		hexdump(cleartext, size, NULL, 0);
1015 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1016 		hexdump(buffer, size, NULL, 0);
1017 		goto out;
1018 	}
1019 
1020 	/* Verify OCF HMAC + decrypt fails with busted MAC. */
1021 	test_digest[0] ^= 0x1;
1022 	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1023 	    aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1024 	    COP_DECRYPT);
1025 	if (error != EBADMSG) {
1026 		if (error != 0)
1027 			warnc(error,
1028 		    "cryptodev %s (%zu, %zu) corrupt tag failed for device %s",
1029 			    alg->name, aad_len, size, crfind(ses.crid));
1030 		else
1031 			warnx(
1032 	    "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s",
1033 			    alg->name, aad_len, size, crfind(ses.crid));
1034 		goto out;
1035 	}
1036 
1037 	if (verbose)
1038 		printf("%s (%zu, %zu) matched (cryptodev device %s)\n",
1039 		    alg->name, aad_len, size, crfind(ses.crid));
1040 
1041 out:
1042 	ocf_destroy_session(&ses);
1043 	free(ciphertext);
1044 	free(buffer);
1045 	free(cleartext);
1046 	free(auth_key);
1047 	free(iv);
1048 	free(cipher_key);
1049 }
1050 
1051 static void
1052 openssl_gmac(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1053     const char *iv, const char *input, size_t size, char *tag)
1054 {
1055 	EVP_CIPHER_CTX *ctx;
1056 	int outl;
1057 
1058 	ctx = EVP_CIPHER_CTX_new();
1059 	if (ctx == NULL)
1060 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1061 		    size, ERR_error_string(ERR_get_error(), NULL));
1062 	if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1063 	    (const u_char *)iv) != 1)
1064 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1065 		    size, ERR_error_string(ERR_get_error(), NULL));
1066 	EVP_CIPHER_CTX_set_padding(ctx, 0);
1067 	if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)input,
1068 		size) != 1)
1069 		errx(1, "OpenSSL %s (%zu) update failed: %s",
1070 		    alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1071 	if (EVP_EncryptFinal_ex(ctx, NULL, &outl) != 1)
1072 		errx(1, "OpenSSL %s (%zu) final failed: %s", alg->name,
1073 		    size, ERR_error_string(ERR_get_error(), NULL));
1074 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1075 	    tag) != 1)
1076 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1077 		    size, ERR_error_string(ERR_get_error(), NULL));
1078 	EVP_CIPHER_CTX_free(ctx);
1079 }
1080 
1081 static bool
1082 ocf_mac(const struct alg *alg, const char *input, size_t size, const char *key,
1083     size_t key_len, const char *iv, char *tag, int *cridp)
1084 {
1085 	struct ocf_session ses;
1086 	struct session2_op sop;
1087 	struct crypt_op cop;
1088 
1089 	ocf_init_sop(&sop);
1090 	sop.mackeylen = key_len;
1091 	sop.mackey = key;
1092 	sop.mac = alg->mac;
1093 	if (!ocf_init_session(&sop, "MAC", alg->name, &ses))
1094 		return (false);
1095 
1096 	ocf_init_cop(&ses, &cop);
1097 	cop.op = 0;
1098 	cop.len = size;
1099 	cop.src = input;
1100 	cop.mac = tag;
1101 	cop.iv = iv;
1102 
1103 	if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
1104 		warn("cryptodev %s (%zu) failed for device %s", alg->name,
1105 		    size, crfind(ses.crid));
1106 		ocf_destroy_session(&ses);
1107 		return (false);
1108 	}
1109 
1110 	*cridp = ses.crid;
1111 	ocf_destroy_session(&ses);
1112 	return (true);
1113 }
1114 
1115 static void
1116 run_gmac_test(const struct alg *alg, size_t size)
1117 {
1118 	const EVP_CIPHER *cipher;
1119 	char *iv, *key, *buffer;
1120 	u_int iv_len, key_len;
1121 	int crid;
1122 	char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
1123 
1124 	cipher = alg->evp_cipher();
1125 
1126 	memset(control_tag, 0x3c, sizeof(control_tag));
1127 	memset(test_tag, 0x3c, sizeof(test_tag));
1128 
1129 	key_len = EVP_CIPHER_key_length(cipher);
1130 	iv_len = EVP_CIPHER_iv_length(cipher);
1131 
1132 	key = alloc_buffer(key_len);
1133 	iv = generate_iv(iv_len, alg);
1134 	buffer = alloc_buffer(size);
1135 
1136 	/* OpenSSL GMAC. */
1137 	openssl_gmac(alg, cipher, key, iv, buffer, size, control_tag);
1138 
1139 	/* OCF GMAC. */
1140 	if (!ocf_mac(alg, buffer, size, key, key_len, iv, test_tag, &crid))
1141 		goto out;
1142 	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1143 		printf("%s (%zu) mismatch:\n", alg->name, size);
1144 		printf("control:\n");
1145 		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1146 		printf("test (cryptodev device %s):\n", crfind(crid));
1147 		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1148 		goto out;
1149 	}
1150 
1151 	if (verbose)
1152 		printf("%s (%zu) matched (cryptodev device %s)\n",
1153 		    alg->name, size, crfind(crid));
1154 
1155 out:
1156 	free(buffer);
1157 	free(iv);
1158 	free(key);
1159 }
1160 
1161 static void
1162 openssl_digest(const struct alg *alg, const char *key, u_int key_len,
1163     const char *input, size_t size, char *tag, u_int tag_len)
1164 {
1165 	EVP_MD_CTX *mdctx;
1166 	EVP_PKEY *pkey;
1167 	size_t len;
1168 
1169 	pkey = EVP_PKEY_new_raw_private_key(alg->pkey, NULL, key, key_len);
1170 	if (pkey == NULL)
1171 		errx(1, "OpenSSL %s (%zu) pkey new failed: %s", alg->name,
1172 		    size, ERR_error_string(ERR_get_error(), NULL));
1173 	mdctx = EVP_MD_CTX_new();
1174 	if (mdctx == NULL)
1175 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1176 		    size, ERR_error_string(ERR_get_error(), NULL));
1177 	if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1)
1178 		errx(1, "OpenSSL %s (%zu) digest sign init failed: %s",
1179 		    alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1180 	if (EVP_DigestSignUpdate(mdctx, input, size) != 1)
1181 		errx(1, "OpenSSL %s (%zu) digest update failed: %s", alg->name,
1182 		    size, ERR_error_string(ERR_get_error(), NULL));
1183 	len = tag_len;
1184 	if (EVP_DigestSignFinal(mdctx, tag, &len) != 1)
1185 		errx(1, "OpenSSL %s (%zu) digest final failed: %s", alg->name,
1186 		    size, ERR_error_string(ERR_get_error(), NULL));
1187 	EVP_MD_CTX_free(mdctx);
1188 	EVP_PKEY_free(pkey);
1189 }
1190 
1191 static void
1192 run_digest_test(const struct alg *alg, size_t size)
1193 {
1194 	char *key, *buffer;
1195 	u_int key_len;
1196 	int crid;
1197 	char control_tag[EVP_MAX_MD_SIZE], test_tag[EVP_MAX_MD_SIZE];
1198 
1199 	memset(control_tag, 0x3c, sizeof(control_tag));
1200 	memset(test_tag, 0x3c, sizeof(test_tag));
1201 
1202 	key_len = alg->key_len;
1203 
1204 	key = alloc_buffer(key_len);
1205 	buffer = alloc_buffer(size);
1206 
1207 	/* OpenSSL Poly1305. */
1208 	openssl_digest(alg, key, key_len, buffer, size, control_tag,
1209 	    sizeof(control_tag));
1210 
1211 	/* OCF Poly1305. */
1212 	if (!ocf_mac(alg, buffer, size, key, key_len, NULL, test_tag, &crid))
1213 		goto out;
1214 	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1215 		printf("%s (%zu) mismatch:\n", alg->name, size);
1216 		printf("control:\n");
1217 		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1218 		printf("test (cryptodev device %s):\n", crfind(crid));
1219 		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1220 		goto out;
1221 	}
1222 
1223 	if (verbose)
1224 		printf("%s (%zu) matched (cryptodev device %s)\n",
1225 		    alg->name, size, crfind(crid));
1226 
1227 out:
1228 	free(buffer);
1229 	free(key);
1230 }
1231 
1232 static void
1233 openssl_aead_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1234     const char *key, const char *iv, size_t iv_len, const char *aad,
1235     size_t aad_len, const char *input, char *output, size_t size, char *tag)
1236 {
1237 	EVP_CIPHER_CTX *ctx;
1238 	int outl, total;
1239 
1240 	ctx = EVP_CIPHER_CTX_new();
1241 	if (ctx == NULL)
1242 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1243 		    size, ERR_error_string(ERR_get_error(), NULL));
1244 	if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
1245 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1246 		    size, ERR_error_string(ERR_get_error(), NULL));
1247 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1)
1248 		errx(1, "OpenSSL %s (%zu) setting iv length failed: %s", alg->name,
1249 		    size, ERR_error_string(ERR_get_error(), NULL));
1250 	if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1251 	    (const u_char *)iv) != 1)
1252 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1253 		    size, ERR_error_string(ERR_get_error(), NULL));
1254 	EVP_CIPHER_CTX_set_padding(ctx, 0);
1255 	if (aad != NULL) {
1256 		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1257 		    aad_len) != 1)
1258 			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1259 			    alg->name, size,
1260 			    ERR_error_string(ERR_get_error(), NULL));
1261 	}
1262 	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1263 	    (const u_char *)input, size) != 1)
1264 		errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
1265 		    size, ERR_error_string(ERR_get_error(), NULL));
1266 	total = outl;
1267 	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
1268 		errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
1269 		    size, ERR_error_string(ERR_get_error(), NULL));
1270 	total += outl;
1271 	if ((size_t)total != size)
1272 		errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
1273 		    size, total);
1274 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1275 	    tag) != 1)
1276 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1277 		    size, ERR_error_string(ERR_get_error(), NULL));
1278 	EVP_CIPHER_CTX_free(ctx);
1279 }
1280 
1281 #ifdef notused
1282 static bool
1283 openssl_aead_decrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1284     const char *key, const char *iv, const char *aad, size_t aad_len,
1285     const char *input, char *output, size_t size, char *tag)
1286 {
1287 	EVP_CIPHER_CTX *ctx;
1288 	int outl, total;
1289 	bool valid;
1290 
1291 	ctx = EVP_CIPHER_CTX_new();
1292 	if (ctx == NULL)
1293 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1294 		    size, ERR_error_string(ERR_get_error(), NULL));
1295 	if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1296 	    (const u_char *)iv) != 1)
1297 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1298 		    size, ERR_error_string(ERR_get_error(), NULL));
1299 	EVP_CIPHER_CTX_set_padding(ctx, 0);
1300 	if (aad != NULL) {
1301 		if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1302 		    aad_len) != 1)
1303 			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1304 			    alg->name, size,
1305 			    ERR_error_string(ERR_get_error(), NULL));
1306 	}
1307 	if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl,
1308 	    (const u_char *)input, size) != 1)
1309 		errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name,
1310 		    size, ERR_error_string(ERR_get_error(), NULL));
1311 	total = outl;
1312 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, alg->tag_len,
1313 	    tag) != 1)
1314 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1315 		    size, ERR_error_string(ERR_get_error(), NULL));
1316 	valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1);
1317 	total += outl;
1318 	if (total != size)
1319 		errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name,
1320 		    size, total);
1321 	EVP_CIPHER_CTX_free(ctx);
1322 	return (valid);
1323 }
1324 #endif
1325 
1326 static void
1327 openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1328     const char *key, const char *iv, size_t iv_len, const char *aad,
1329     size_t aad_len, const char *input, char *output, size_t size, char *tag)
1330 {
1331 	EVP_CIPHER_CTX *ctx;
1332 	int outl, total;
1333 
1334 	ctx = EVP_CIPHER_CTX_new();
1335 	if (ctx == NULL)
1336 		errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx new failed: %s",
1337 		    alg->name, iv_len, aad_len, size,
1338 		    ERR_error_string(ERR_get_error(), NULL));
1339 	if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
1340 		errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1341 		    alg->name, iv_len, aad_len, size,
1342 		    ERR_error_string(ERR_get_error(), NULL));
1343 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1)
1344 		errx(1,
1345 		    "OpenSSL %s/%zu (%zu, %zu) setting iv length failed: %s",
1346 		    alg->name, iv_len, aad_len, size,
1347 		    ERR_error_string(ERR_get_error(), NULL));
1348 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AES_CBC_MAC_HASH_LEN, NULL) != 1)
1349 		errx(1,
1350 		    "OpenSSL %s/%zu (%zu, %zu) setting tag length failed: %s",
1351 		    alg->name, iv_len, aad_len, size,
1352 		    ERR_error_string(ERR_get_error(), NULL));
1353 	if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1354 	    (const u_char *)iv) != 1)
1355 		errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1356 		    alg->name, iv_len, aad_len, size,
1357 		    ERR_error_string(ERR_get_error(), NULL));
1358 	if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1)
1359 		errx(1,
1360 		    "OpenSSL %s/%zu (%zu, %zu) unable to set data length: %s",
1361 		    alg->name, iv_len, aad_len, size,
1362 		    ERR_error_string(ERR_get_error(), NULL));
1363 
1364 	if (aad != NULL) {
1365 		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1366 		    aad_len) != 1)
1367 			errx(1,
1368 			    "OpenSSL %s/%zu (%zu, %zu) aad update failed: %s",
1369 			    alg->name, iv_len, aad_len, size,
1370 			    ERR_error_string(ERR_get_error(), NULL));
1371 	}
1372 	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1373 	    (const u_char *)input, size) != 1)
1374 		errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt update failed: %s",
1375 		    alg->name, iv_len, aad_len, size,
1376 		    ERR_error_string(ERR_get_error(), NULL));
1377 	total = outl;
1378 	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
1379 		errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt final failed: %s",
1380 		    alg->name, iv_len, aad_len, size,
1381 		    ERR_error_string(ERR_get_error(), NULL));
1382 	total += outl;
1383 	if ((size_t)total != size)
1384 		errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt size mismatch: %d",
1385 		    alg->name, iv_len, aad_len, size, total);
1386 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_CBC_MAC_HASH_LEN,
1387 	    tag) != 1)
1388 		errx(1, "OpenSSL %s/%zu (%zu, %zu) get tag failed: %s",
1389 		    alg->name, iv_len, aad_len, size,
1390 		    ERR_error_string(ERR_get_error(), NULL));
1391 	EVP_CIPHER_CTX_free(ctx);
1392 }
1393 
1394 static bool
1395 ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len,
1396     size_t iv_len, struct ocf_session *ses)
1397 {
1398 	struct session2_op sop;
1399 
1400 	ocf_init_sop(&sop);
1401 	sop.keylen = key_len;
1402 	sop.key = key;
1403 	sop.cipher = alg->cipher;
1404 	sop.ivlen = iv_len;
1405 	return (ocf_init_session(&sop, "AEAD", alg->name, ses));
1406 }
1407 
1408 static int
1409 ocf_aead(const struct ocf_session *ses, const char *iv, size_t iv_len,
1410     const char *aad, size_t aad_len, const char *input, char *output,
1411     size_t size, char *tag, int op)
1412 {
1413 	struct crypt_aead caead;
1414 
1415 	ocf_init_caead(ses, &caead);
1416 	caead.op = op;
1417 	caead.len = size;
1418 	caead.aadlen = aad_len;
1419 	caead.ivlen = iv_len;
1420 	caead.src = input;
1421 	caead.dst = output;
1422 	caead.aad = aad;
1423 	caead.tag = tag;
1424 	caead.iv = iv;
1425 
1426 	if (ioctl(ses->fd, CIOCCRYPTAEAD, &caead) < 0)
1427 		return (errno);
1428 	return (0);
1429 }
1430 
1431 #define	AEAD_MAX_TAG_LEN				\
1432 	MAX(MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN), POLY1305_HASH_LEN)
1433 
1434 static size_t
1435 max_ccm_buffer_length(size_t iv_len)
1436 {
1437 	const u_int L = 15 - iv_len;
1438 
1439 	switch (L) {
1440 	case 2:
1441 		return (0xffff);
1442 	case 3:
1443 		return (0xffffff);
1444 #ifdef __LP64__
1445 	case 4:
1446 		return (0xffffffff);
1447 	case 5:
1448 		return (0xffffffffff);
1449 	case 6:
1450 		return (0xffffffffffff);
1451 	case 7:
1452 		return (0xffffffffffffff);
1453 	default:
1454 		return (0xffffffffffffffff);
1455 #else
1456 	default:
1457 		return (0xffffffff);
1458 #endif
1459 	}
1460 }
1461 
1462 static void
1463 run_aead_test(const struct alg *alg, size_t aad_len, size_t size,
1464     size_t iv_len)
1465 {
1466 	struct ocf_session ses;
1467 	const EVP_CIPHER *cipher;
1468 	char *aad, *buffer, *cleartext, *ciphertext;
1469 	char *iv, *key;
1470 	u_int key_len;
1471 	int error;
1472 	char control_tag[AEAD_MAX_TAG_LEN], test_tag[AEAD_MAX_TAG_LEN];
1473 
1474 	cipher = alg->evp_cipher();
1475 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
1476 		if (verbose)
1477 			printf(
1478 		    "%s/%zu (%zu, %zu): invalid buffer size (block size %d)\n",
1479 			    alg->name, iv_len, aad_len, size,
1480 			    EVP_CIPHER_block_size(cipher));
1481 		return;
1482 	}
1483 
1484 	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE &&
1485 	    size > max_ccm_buffer_length(iv_len)) {
1486 		if (verbose)
1487 			printf("%s/%zu (%zu, %zu): invalid buffer size\n",
1488 			    alg->name, iv_len, aad_len, size);
1489 		return;
1490 	}
1491 
1492 	memset(control_tag, 0x3c, sizeof(control_tag));
1493 	memset(test_tag, 0x3c, sizeof(test_tag));
1494 
1495 	key_len = EVP_CIPHER_key_length(cipher);
1496 
1497 	key = alloc_buffer(key_len);
1498 	iv = generate_iv(iv_len, alg);
1499 	cleartext = alloc_buffer(size);
1500 	buffer = malloc(size);
1501 	ciphertext = malloc(size);
1502 	if (aad_len != 0)
1503 		aad = alloc_buffer(aad_len);
1504 	else
1505 		aad = NULL;
1506 
1507 	/* OpenSSL encrypt */
1508 	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE)
1509 		openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad,
1510 		    aad_len, cleartext, ciphertext, size, control_tag);
1511 	else
1512 		openssl_aead_encrypt(alg, cipher, key, iv, iv_len, aad,
1513 		    aad_len, cleartext, ciphertext, size, control_tag);
1514 
1515 	if (!ocf_init_aead_session(alg, key, key_len, iv_len, &ses))
1516 		goto out;
1517 
1518 	/* OCF encrypt */
1519 	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, cleartext, buffer,
1520 	    size, test_tag, COP_ENCRYPT);
1521 	if (error != 0) {
1522 		warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1523 		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1524 		goto out;
1525 	}
1526 	if (memcmp(ciphertext, buffer, size) != 0) {
1527 		printf("%s/%zu (%zu, %zu) encryption mismatch:\n", alg->name,
1528 		    iv_len, aad_len, size);
1529 		printf("control:\n");
1530 		hexdump(ciphertext, size, NULL, 0);
1531 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1532 		hexdump(buffer, size, NULL, 0);
1533 		goto out;
1534 	}
1535 	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1536 		printf("%s/%zu (%zu, %zu) enc tag mismatch:\n", alg->name,
1537 		    iv_len, aad_len, size);
1538 		printf("control:\n");
1539 		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1540 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1541 		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1542 		goto out;
1543 	}
1544 
1545 	/* OCF decrypt */
1546 	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1547 	    buffer, size, control_tag, COP_DECRYPT);
1548 	if (error != 0) {
1549 		warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1550 		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1551 		goto out;
1552 	}
1553 	if (memcmp(cleartext, buffer, size) != 0) {
1554 		printf("%s/%zu (%zu, %zu) decryption mismatch:\n", alg->name,
1555 		    iv_len, aad_len, size);
1556 		printf("control:\n");
1557 		hexdump(cleartext, size, NULL, 0);
1558 		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1559 		hexdump(buffer, size, NULL, 0);
1560 		goto out;
1561 	}
1562 
1563 	/* Verify OCF decrypt fails with busted tag. */
1564 	test_tag[0] ^= 0x1;
1565 	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1566 	    buffer, size, test_tag, COP_DECRYPT);
1567 	if (error != EBADMSG) {
1568 		if (error != 0)
1569 			warnc(error,
1570 		    "cryptodev %s/%zu (%zu, %zu) corrupt tag failed for device %s",
1571 			    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1572 		else
1573 			warnx(
1574 	    "cryptodev %s/%zu (%zu, %zu) corrupt tag didn't fail for device %s",
1575 			    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1576 		goto out;
1577 	}
1578 
1579 	if (verbose)
1580 		printf("%s/%zu (%zu, %zu) matched (cryptodev device %s)\n",
1581 		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1582 
1583 out:
1584 	ocf_destroy_session(&ses);
1585 	free(aad);
1586 	free(ciphertext);
1587 	free(buffer);
1588 	free(cleartext);
1589 	free(iv);
1590 	free(key);
1591 }
1592 
1593 static void
1594 run_test(const struct alg *alg, size_t aad_len, size_t size, size_t iv_len)
1595 {
1596 
1597 	switch (alg->type) {
1598 	case T_HASH:
1599 		run_hash_test(alg, size);
1600 		break;
1601 	case T_HMAC:
1602 		run_hmac_test(alg, size);
1603 		break;
1604 	case T_GMAC:
1605 		run_gmac_test(alg, size);
1606 		break;
1607 	case T_DIGEST:
1608 		run_digest_test(alg, size);
1609 		break;
1610 	case T_CIPHER:
1611 		run_cipher_test(alg, size);
1612 		break;
1613 	case T_ETA:
1614 		run_eta_test(alg, aad_len, size);
1615 		break;
1616 	case T_AEAD:
1617 		run_aead_test(alg, aad_len, size, iv_len);
1618 		break;
1619 	}
1620 }
1621 
1622 static void
1623 run_test_sizes(const struct alg *alg)
1624 {
1625 	u_int i, j, k;
1626 
1627 	switch (alg->type) {
1628 	default:
1629 		for (i = 0; i < nsizes; i++)
1630 			run_test(alg, 0, sizes[i], 0);
1631 		break;
1632 	case T_ETA:
1633 		for (i = 0; i < naad_sizes; i++)
1634 			for (j = 0; j < nsizes; j++)
1635 				run_test(alg, aad_sizes[i], sizes[j], 0);
1636 		break;
1637 	case T_AEAD:
1638 		for (i = 0; i < naad_sizes; i++) {
1639 			for (j = 0; j < nsizes; j++) {
1640 				if (iv_size != 0)
1641 					run_test(alg, aad_sizes[i], sizes[j],
1642 					    iv_size);
1643 				else if (testall) {
1644 					for (k = 0; alg->iv_sizes[k] != 0; k++)
1645 						run_test(alg, aad_sizes[i],
1646 						    sizes[j], alg->iv_sizes[k]);
1647 				} else
1648 					run_test(alg, aad_sizes[i], sizes[j],
1649 					    alg->iv_sizes[0]);
1650 			}
1651 		}
1652 		break;
1653 	}
1654 }
1655 
1656 static void
1657 run_hash_tests(void)
1658 {
1659 	u_int i;
1660 
1661 	for (i = 0; i < nitems(algs); i++)
1662 		if (algs[i].type == T_HASH)
1663 			run_test_sizes(&algs[i]);
1664 }
1665 
1666 static void
1667 run_mac_tests(void)
1668 {
1669 	u_int i;
1670 
1671 	for (i = 0; i < nitems(algs); i++)
1672 		if (algs[i].type == T_HMAC || algs[i].type == T_GMAC ||
1673 		    algs[i].type == T_DIGEST)
1674 			run_test_sizes(&algs[i]);
1675 }
1676 
1677 static void
1678 run_cipher_tests(void)
1679 {
1680 	u_int i;
1681 
1682 	for (i = 0; i < nitems(algs); i++)
1683 		if (algs[i].type == T_CIPHER)
1684 			run_test_sizes(&algs[i]);
1685 }
1686 
1687 static void
1688 run_eta_tests(void)
1689 {
1690 	const struct alg *cipher, *mac;
1691 	struct alg *eta;
1692 	u_int i, j;
1693 
1694 	for (i = 0; i < nitems(algs); i++) {
1695 		cipher = &algs[i];
1696 		if (cipher->type != T_CIPHER)
1697 			continue;
1698 		for (j = 0; j < nitems(algs); j++) {
1699 			mac = &algs[j];
1700 			if (mac->type != T_HMAC)
1701 				continue;
1702 			eta = build_eta(cipher, mac);
1703 			run_test_sizes(eta);
1704 			free_eta(eta);
1705 		}
1706 	}
1707 }
1708 
1709 static void
1710 run_aead_tests(void)
1711 {
1712 	u_int i;
1713 
1714 	for (i = 0; i < nitems(algs); i++)
1715 		if (algs[i].type == T_AEAD)
1716 			run_test_sizes(&algs[i]);
1717 }
1718 
1719 int
1720 main(int ac, char **av)
1721 {
1722 	const char *algname;
1723 	const struct alg *alg;
1724 	struct alg *eta;
1725 	char *cp;
1726 	size_t base_size;
1727 	u_int i;
1728 	int ch;
1729 
1730 	algname = NULL;
1731 	requested_crid = CRYPTO_FLAG_HARDWARE;
1732 	testall = false;
1733 	verbose = false;
1734 	iv_size = 0;
1735 	while ((ch = getopt(ac, av, "A:a:d:I:vz")) != -1)
1736 		switch (ch) {
1737 		case 'A':
1738 			if (naad_sizes >= nitems(aad_sizes)) {
1739 				warnx("Too many AAD sizes, ignoring extras");
1740 				break;
1741 			}
1742 			aad_sizes[naad_sizes] = strtol(optarg, &cp, 0);
1743 			if (*cp != '\0')
1744 				errx(1, "Bad AAD size %s", optarg);
1745 			naad_sizes++;
1746 			break;
1747 		case 'a':
1748 			algname = optarg;
1749 			break;
1750 		case 'd':
1751 			requested_crid = crlookup(optarg);
1752 			break;
1753 		case 'I':
1754 			iv_size = strtol(optarg, &cp, 0);
1755 			if (*cp != '\0')
1756 				errx(1, "Bad IV size %s", optarg);
1757 			break;
1758 		case 'v':
1759 			verbose = true;
1760 			break;
1761 		case 'z':
1762 			testall = true;
1763 			break;
1764 		default:
1765 			usage();
1766 		}
1767 	ac -= optind;
1768 	av += optind;
1769 	nsizes = 0;
1770 	while (ac > 0) {
1771 		if (nsizes >= nitems(sizes)) {
1772 			warnx("Too many sizes, ignoring extras");
1773 			break;
1774 		}
1775 		sizes[nsizes] = strtol(av[0], &cp, 0);
1776 		if (*cp != '\0')
1777 			errx(1, "Bad size %s", av[0]);
1778 		nsizes++;
1779 		ac--;
1780 		av++;
1781 	}
1782 
1783 	if (algname == NULL)
1784 		errx(1, "Algorithm required");
1785 
1786 	if (naad_sizes == 0) {
1787 		if (testall) {
1788 			for (i = 0; i <= 32; i++) {
1789 				aad_sizes[naad_sizes] = i;
1790 				naad_sizes++;
1791 			}
1792 
1793 			base_size = 32;
1794 			while (base_size * 2 < 512) {
1795 				base_size *= 2;
1796 				assert(naad_sizes < nitems(aad_sizes));
1797 				aad_sizes[naad_sizes] = base_size;
1798 				naad_sizes++;
1799 			}
1800 		} else {
1801 			aad_sizes[0] = 0;
1802 			naad_sizes = 1;
1803 		}
1804 	}
1805 
1806 	if (nsizes == 0) {
1807 		if (testall) {
1808 			for (i = 1; i <= EALG_MAX_BLOCK_LEN; i++) {
1809 				sizes[nsizes] = i;
1810 				nsizes++;
1811 			}
1812 
1813 			for (i = EALG_MAX_BLOCK_LEN + 8;
1814 			     i <= EALG_MAX_BLOCK_LEN * 2; i += 8) {
1815 				sizes[nsizes] = i;
1816 				nsizes++;
1817 			}
1818 
1819 			base_size = EALG_MAX_BLOCK_LEN * 2;
1820 			while (base_size * 2 < 240 * 1024) {
1821 				base_size *= 2;
1822 				assert(nsizes < nitems(sizes));
1823 				sizes[nsizes] = base_size;
1824 				nsizes++;
1825 			}
1826 
1827 			if (sizes[nsizes - 1] < 240 * 1024) {
1828 				assert(nsizes < nitems(sizes));
1829 				sizes[nsizes] = 240 * 1024;
1830 				nsizes++;
1831 			}
1832 		} else {
1833 			sizes[0] = 16;
1834 			nsizes = 1;
1835 		}
1836 	}
1837 
1838 	if (strcasecmp(algname, "hash") == 0)
1839 		run_hash_tests();
1840 	else if (strcasecmp(algname, "mac") == 0)
1841 		run_mac_tests();
1842 	else if (strcasecmp(algname, "cipher") == 0)
1843 		run_cipher_tests();
1844 	else if (strcasecmp(algname, "eta") == 0)
1845 		run_eta_tests();
1846 	else if (strcasecmp(algname, "aead") == 0)
1847 		run_aead_tests();
1848 	else if (strcasecmp(algname, "all") == 0) {
1849 		run_hash_tests();
1850 		run_mac_tests();
1851 		run_cipher_tests();
1852 		run_eta_tests();
1853 		run_aead_tests();
1854 	} else if (strchr(algname, '+') != NULL) {
1855 		eta = build_eta_name(algname);
1856 		run_test_sizes(eta);
1857 		free_eta(eta);
1858 	} else {
1859 		alg = find_alg(algname);
1860 		if (alg == NULL)
1861 			errx(1, "Invalid algorithm %s", algname);
1862 		run_test_sizes(alg);
1863 	}
1864 
1865 	return (0);
1866 }
1867