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