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