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