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 (96 bit nonce) 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
158struct ocf_session {
159	int fd;
160	int ses;
161	int crid;
162};
163
164static 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 },
257	  .evp_cipher = EVP_chacha20_poly1305 },
258};
259
260static bool testall, verbose;
261static int requested_crid;
262static size_t aad_sizes[48], sizes[EALG_MAX_BLOCK_LEN * 2];
263static u_int naad_sizes, nsizes;
264static u_int iv_size;
265
266static void
267usage(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
275static const struct alg *
276find_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
286static struct alg *
287build_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
305static void
306free_eta(struct alg *eta)
307{
308	free(__DECONST(char *, eta->name));
309	free(eta);
310}
311
312static struct alg *
313build_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
332static int
333devcrypto(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
350static void
351reset_user_soft(void)
352{
353	int off = 0;
354	sysctlbyname(CRYPT_SOFT_ALLOW, NULL, NULL, &off, sizeof(off));
355}
356
357static void
358enable_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
371static int
372crlookup(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
388static const char *
389crfind(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
405static char
406rdigit(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
415static char *
416alloc_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
427static char *
428generate_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
459static void
460ocf_init_sop(struct session2_op *sop)
461{
462	memset(sop, 0, sizeof(*sop));
463	sop->crid = requested_crid;
464}
465
466static bool
467ocf_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
485static void
486ocf_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
495static void
496ocf_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
502static void
503ocf_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
509static bool
510ocf_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
540static bool
541openssl_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 (true);
568
569err_out:
570	warnx("OpenSSL %s HASH failed%s: %s", alg->name, errs,
571	    ERR_error_string(ERR_get_error(), NULL));
572	return (false);
573}
574
575static void
576run_hash_test(const struct alg *alg, size_t size)
577{
578	const EVP_MD *md;
579	char *buffer;
580	u_int digest_len;
581	int crid;
582	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
583
584	memset(control_digest, 0x3c, sizeof(control_digest));
585	memset(test_digest, 0x3c, sizeof(test_digest));
586
587	md = alg->evp_md();
588	assert((size_t)EVP_MD_size(md) <= sizeof(control_digest));
589
590	buffer = alloc_buffer(size);
591
592	/* OpenSSL HASH. */
593	digest_len = sizeof(control_digest);
594	if (!openssl_hash(alg, md, buffer, size, control_digest, &digest_len))
595		goto out;
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
617out:
618	free(buffer);
619}
620
621static bool
622ocf_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
654static void
655run_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		warnx("OpenSSL %s (%zu) HMAC failed: %s", alg->name,
678		    size, ERR_error_string(ERR_get_error(), NULL));
679		goto out;
680	}
681
682	/* cryptodev HMAC. */
683	if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid))
684		goto out;
685	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
686		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
687			printf("%s (%zu) mismatch in trailer:\n",
688			    alg->name, size);
689		else
690			printf("%s (%zu) mismatch:\n", alg->name, size);
691		printf("control:\n");
692		hexdump(control_digest, sizeof(control_digest), NULL, 0);
693		printf("test (cryptodev device %s):\n", crfind(crid));
694		hexdump(test_digest, sizeof(test_digest), NULL, 0);
695		goto out;
696	}
697
698	if (verbose)
699		printf("%s (%zu) matched (cryptodev device %s)\n",
700		    alg->name, size, crfind(crid));
701
702out:
703	free(buffer);
704	free(key);
705}
706
707static bool
708openssl_cipher(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
709    const char *iv, const char *input, char *output, size_t size, int enc)
710{
711	EVP_CIPHER_CTX *ctx;
712	int outl, total;
713
714	ctx = EVP_CIPHER_CTX_new();
715	if (ctx == NULL) {
716		warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name,
717		    size, ERR_error_string(ERR_get_error(), NULL));
718		return (false);
719	}
720	if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
721	    (const u_char *)iv, enc) != 1) {
722		warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name,
723		    size, ERR_error_string(ERR_get_error(), NULL));
724		goto error;
725	}
726	EVP_CIPHER_CTX_set_padding(ctx, 0);
727	if (EVP_CipherUpdate(ctx, (u_char *)output, &outl,
728	    (const u_char *)input, size) != 1) {
729		warnx("OpenSSL %s (%zu) cipher update failed: %s", alg->name,
730		    size, ERR_error_string(ERR_get_error(), NULL));
731		goto error;
732	}
733	total = outl;
734	if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) {
735		warnx("OpenSSL %s (%zu) cipher final failed: %s", alg->name,
736		    size, ERR_error_string(ERR_get_error(), NULL));
737		goto error;
738	}
739	total += outl;
740	if ((size_t)total != size) {
741		warnx("OpenSSL %s (%zu) cipher size mismatch: %d", alg->name,
742		    size, total);
743		goto error;
744	}
745	EVP_CIPHER_CTX_free(ctx);
746	return (true);
747
748error:
749	EVP_CIPHER_CTX_free(ctx);
750	return (false);
751}
752
753static bool
754ocf_init_cipher_session(const struct alg *alg, const char *key, size_t key_len,
755    struct ocf_session *ses)
756{
757	struct session2_op sop;
758
759	ocf_init_sop(&sop);
760	sop.keylen = key_len;
761	sop.key = key;
762	sop.cipher = alg->cipher;
763	return (ocf_init_session(&sop, "cipher", alg->name, ses));
764}
765
766static bool
767ocf_cipher(const struct ocf_session *ses, const struct alg *alg, const char *iv,
768    const char *input, char *output, size_t size, int op)
769{
770	struct crypt_op cop;
771
772	ocf_init_cop(ses, &cop);
773	cop.op = op;
774	cop.len = size;
775	cop.src = input;
776	cop.dst = output;
777	cop.iv = iv;
778
779	if (ioctl(ses->fd, CIOCCRYPT, &cop) < 0) {
780		warn("cryptodev %s (%zu) cipher failed for device %s",
781		    alg->name, size, crfind(ses->crid));
782		return (false);
783	}
784
785	return (true);
786}
787
788static void
789run_cipher_test(const struct alg *alg, size_t size)
790{
791	struct ocf_session ses;
792	const EVP_CIPHER *cipher;
793	char *buffer, *cleartext, *ciphertext;
794	char *iv, *key;
795	u_int iv_len, key_len;
796
797	cipher = alg->evp_cipher();
798	if (size % EVP_CIPHER_block_size(cipher) != 0) {
799		if (verbose)
800			printf(
801			    "%s (%zu): invalid buffer size (block size %d)\n",
802			    alg->name, size, EVP_CIPHER_block_size(cipher));
803		return;
804	}
805
806	/*
807	 * XTS requires at least one full block so that any partial
808	 * block at the end has cipher text to steal.  Hardcoding the
809	 * AES block size isn't ideal, but OpenSSL doesn't have a
810	 * notion of a "native" block size.
811	 */
812	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
813	    size < AES_BLOCK_LEN) {
814		if (verbose)
815			printf("%s (%zu): invalid buffer size\n", alg->name,
816			    size);
817		return;
818	}
819
820	key_len = EVP_CIPHER_key_length(cipher);
821	iv_len = EVP_CIPHER_iv_length(cipher);
822
823	key = alloc_buffer(key_len);
824	iv = generate_iv(iv_len, alg);
825	cleartext = alloc_buffer(size);
826	buffer = malloc(size);
827	ciphertext = malloc(size);
828
829	/* OpenSSL cipher. */
830	if (!openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size,
831	    1))
832		goto out_noocf;
833	if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) {
834		warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name,
835		    size);
836		goto out_noocf;
837	}
838	if (!openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0))
839		goto out_noocf;
840	if (memcmp(cleartext, buffer, size) != 0) {
841		printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size);
842		printf("original:\n");
843		hexdump(cleartext, size, NULL, 0);
844		printf("decrypted:\n");
845		hexdump(buffer, size, NULL, 0);
846		goto out_noocf;
847	}
848
849	if (!ocf_init_cipher_session(alg, key, key_len, &ses))
850		goto out_noocf;
851
852	/* OCF encrypt. */
853	if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT))
854		goto out;
855	if (memcmp(ciphertext, buffer, size) != 0) {
856		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
857		printf("control:\n");
858		hexdump(ciphertext, size, NULL, 0);
859		printf("test (cryptodev device %s):\n", crfind(ses.crid));
860		hexdump(buffer, size, NULL, 0);
861		goto out;
862	}
863
864	/* OCF decrypt. */
865	if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT))
866		goto out;
867	if (memcmp(cleartext, buffer, size) != 0) {
868		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
869		printf("control:\n");
870		hexdump(cleartext, size, NULL, 0);
871		printf("test (cryptodev device %s):\n", crfind(ses.crid));
872		hexdump(buffer, size, NULL, 0);
873		goto out;
874	}
875
876	if (verbose)
877		printf("%s (%zu) matched (cryptodev device %s)\n",
878		    alg->name, size, crfind(ses.crid));
879
880out:
881	ocf_destroy_session(&ses);
882out_noocf:
883	free(ciphertext);
884	free(buffer);
885	free(cleartext);
886	free(iv);
887	free(key);
888}
889
890static bool
891ocf_init_eta_session(const struct alg *alg, const char *cipher_key,
892    size_t cipher_key_len, const char *auth_key, size_t auth_key_len,
893    struct ocf_session *ses)
894{
895	struct session2_op sop;
896
897	ocf_init_sop(&sop);
898	sop.keylen = cipher_key_len;
899	sop.key = cipher_key;
900	sop.cipher = alg->cipher;
901	sop.mackeylen = auth_key_len;
902	sop.mackey = auth_key;
903	sop.mac = alg->mac;
904	return (ocf_init_session(&sop, "ETA", alg->name, ses));
905}
906
907static int
908ocf_eta(const struct ocf_session *ses, const char *iv, size_t iv_len,
909    const char *aad, size_t aad_len, const char *input, char *output,
910    size_t size, char *digest, int op)
911{
912	int ret;
913
914	if (aad_len != 0) {
915		struct crypt_aead caead;
916
917		ocf_init_caead(ses, &caead);
918		caead.op = op;
919		caead.len = size;
920		caead.aadlen = aad_len;
921		caead.ivlen = iv_len;
922		caead.src = input;
923		caead.dst = output;
924		caead.aad = aad;
925		caead.tag = digest;
926		caead.iv = iv;
927
928		ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead);
929	} else {
930		struct crypt_op cop;
931
932		ocf_init_cop(ses, &cop);
933		cop.op = op;
934		cop.len = size;
935		cop.src = input;
936		cop.dst = output;
937		cop.mac = digest;
938		cop.iv = iv;
939
940		ret = ioctl(ses->fd, CIOCCRYPT, &cop);
941	}
942
943	if (ret < 0)
944		return (errno);
945	return (0);
946}
947
948static void
949run_eta_test(const struct alg *alg, size_t aad_len, size_t size)
950{
951	struct ocf_session ses;
952	const EVP_CIPHER *cipher;
953	const EVP_MD *md;
954	char *buffer, *cleartext, *ciphertext;
955	char *iv, *auth_key, *cipher_key;
956	u_int iv_len, auth_key_len, cipher_key_len, digest_len;
957	int error;
958	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
959
960	cipher = alg->evp_cipher();
961	if (size % EVP_CIPHER_block_size(cipher) != 0) {
962		if (verbose)
963			printf(
964		    "%s (%zu, %zu): invalid buffer size (block size %d)\n",
965			    alg->name, aad_len, size,
966			    EVP_CIPHER_block_size(cipher));
967		return;
968	}
969
970	/* See comment in run_cipher_test. */
971	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
972	    size < AES_BLOCK_LEN) {
973		if (verbose)
974			printf("%s (%zu): invalid buffer size\n", alg->name,
975			    size);
976		return;
977	}
978
979	memset(control_digest, 0x3c, sizeof(control_digest));
980	memset(test_digest, 0x3c, sizeof(test_digest));
981
982	md = alg->evp_md();
983
984	cipher_key_len = EVP_CIPHER_key_length(cipher);
985	iv_len = EVP_CIPHER_iv_length(cipher);
986	auth_key_len = EVP_MD_size(md);
987
988	cipher_key = alloc_buffer(cipher_key_len);
989	iv = generate_iv(iv_len, alg);
990	auth_key = alloc_buffer(auth_key_len);
991	cleartext = alloc_buffer(aad_len + size);
992	buffer = malloc(aad_len + size);
993	ciphertext = malloc(aad_len + size);
994
995	/* OpenSSL encrypt + HMAC. */
996	if (aad_len != 0)
997		memcpy(ciphertext, cleartext, aad_len);
998	if (!openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len,
999	    ciphertext + aad_len, size, 1))
1000		goto out_noocf;
1001	if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
1002	    size) == 0) {
1003		warnx("OpenSSL %s (%zu, %zu): cipher text unchanged",
1004		    alg->name, aad_len, size);
1005		goto out_noocf;
1006	}
1007	digest_len = sizeof(control_digest);
1008	if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
1009	    aad_len + size, (u_char *)control_digest, &digest_len) == NULL) {
1010		warnx("OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name,
1011		    aad_len, size, ERR_error_string(ERR_get_error(), NULL));
1012		goto out_noocf;
1013	}
1014
1015	if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key,
1016	    auth_key_len, &ses))
1017		goto out_noocf;
1018
1019	/* OCF encrypt + HMAC. */
1020	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? cleartext : NULL,
1021	    aad_len, cleartext + aad_len, buffer + aad_len, size, test_digest,
1022	    COP_ENCRYPT);
1023	if (error != 0) {
1024		warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
1025		    alg->name, aad_len, size, crfind(ses.crid));
1026		goto out;
1027	}
1028	if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
1029		printf("%s (%zu, %zu) encryption mismatch:\n", alg->name,
1030		    aad_len, size);
1031		printf("control:\n");
1032		hexdump(ciphertext + aad_len, size, NULL, 0);
1033		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1034		hexdump(buffer + aad_len, size, NULL, 0);
1035		goto out;
1036	}
1037	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
1038		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
1039			printf("%s (%zu, %zu) enc hash mismatch in trailer:\n",
1040			    alg->name, aad_len, size);
1041		else
1042			printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name,
1043			    aad_len, size);
1044		printf("control:\n");
1045		hexdump(control_digest, sizeof(control_digest), NULL, 0);
1046		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1047		hexdump(test_digest, sizeof(test_digest), NULL, 0);
1048		goto out;
1049	}
1050
1051	/* OCF HMAC + decrypt. */
1052	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1053	    aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1054	    COP_DECRYPT);
1055	if (error != 0) {
1056		warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
1057		    alg->name, aad_len, size, crfind(ses.crid));
1058		goto out;
1059	}
1060	if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
1061		printf("%s (%zu, %zu) decryption mismatch:\n", alg->name,
1062		    aad_len, size);
1063		printf("control:\n");
1064		hexdump(cleartext, size, NULL, 0);
1065		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1066		hexdump(buffer, size, NULL, 0);
1067		goto out;
1068	}
1069
1070	/* Verify OCF HMAC + decrypt fails with busted MAC. */
1071	test_digest[0] ^= 0x1;
1072	error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1073	    aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1074	    COP_DECRYPT);
1075	if (error != EBADMSG) {
1076		if (error != 0)
1077			warnc(error,
1078		    "cryptodev %s (%zu, %zu) corrupt tag failed for device %s",
1079			    alg->name, aad_len, size, crfind(ses.crid));
1080		else
1081			warnx(
1082	    "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s",
1083			    alg->name, aad_len, size, crfind(ses.crid));
1084		goto out;
1085	}
1086
1087	if (verbose)
1088		printf("%s (%zu, %zu) matched (cryptodev device %s)\n",
1089		    alg->name, aad_len, size, crfind(ses.crid));
1090
1091out:
1092	ocf_destroy_session(&ses);
1093out_noocf:
1094	free(ciphertext);
1095	free(buffer);
1096	free(cleartext);
1097	free(auth_key);
1098	free(iv);
1099	free(cipher_key);
1100}
1101
1102static bool
1103openssl_gmac(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1104    const char *iv, const char *input, size_t size, char *tag)
1105{
1106	EVP_CIPHER_CTX *ctx;
1107	int outl;
1108
1109	ctx = EVP_CIPHER_CTX_new();
1110	if (ctx == NULL) {
1111		warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1112		    size, ERR_error_string(ERR_get_error(), NULL));
1113		return (false);
1114	}
1115	if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1116	    (const u_char *)iv) != 1) {
1117		warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1118		    size, ERR_error_string(ERR_get_error(), NULL));
1119		goto error;
1120	}
1121	EVP_CIPHER_CTX_set_padding(ctx, 0);
1122	if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)input,
1123	    size) != 1) {
1124		warnx("OpenSSL %s (%zu) update failed: %s",
1125		    alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1126		goto error;
1127	}
1128	if (EVP_EncryptFinal_ex(ctx, NULL, &outl) != 1) {
1129		warnx("OpenSSL %s (%zu) final failed: %s", alg->name,
1130		    size, ERR_error_string(ERR_get_error(), NULL));
1131		goto error;
1132	}
1133	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1134	    tag) != 1) {
1135		warnx("OpenSSL %s (%zu) get tag failed: %s", alg->name,
1136		    size, ERR_error_string(ERR_get_error(), NULL));
1137		goto error;
1138	}
1139	EVP_CIPHER_CTX_free(ctx);
1140	return (true);
1141
1142error:
1143	EVP_CIPHER_CTX_free(ctx);
1144	return (false);
1145}
1146
1147static bool
1148ocf_mac(const struct alg *alg, const char *input, size_t size, const char *key,
1149    size_t key_len, const char *iv, char *tag, int *cridp)
1150{
1151	struct ocf_session ses;
1152	struct session2_op sop;
1153	struct crypt_op cop;
1154
1155	ocf_init_sop(&sop);
1156	sop.mackeylen = key_len;
1157	sop.mackey = key;
1158	sop.mac = alg->mac;
1159	if (!ocf_init_session(&sop, "MAC", alg->name, &ses))
1160		return (false);
1161
1162	ocf_init_cop(&ses, &cop);
1163	cop.op = 0;
1164	cop.len = size;
1165	cop.src = input;
1166	cop.mac = tag;
1167	cop.iv = iv;
1168
1169	if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
1170		warn("cryptodev %s (%zu) failed for device %s", alg->name,
1171		    size, crfind(ses.crid));
1172		ocf_destroy_session(&ses);
1173		return (false);
1174	}
1175
1176	*cridp = ses.crid;
1177	ocf_destroy_session(&ses);
1178	return (true);
1179}
1180
1181static void
1182run_gmac_test(const struct alg *alg, size_t size)
1183{
1184	const EVP_CIPHER *cipher;
1185	char *iv, *key, *buffer;
1186	u_int iv_len, key_len;
1187	int crid;
1188	char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
1189
1190	cipher = alg->evp_cipher();
1191
1192	memset(control_tag, 0x3c, sizeof(control_tag));
1193	memset(test_tag, 0x3c, sizeof(test_tag));
1194
1195	key_len = EVP_CIPHER_key_length(cipher);
1196	iv_len = EVP_CIPHER_iv_length(cipher);
1197
1198	key = alloc_buffer(key_len);
1199	iv = generate_iv(iv_len, alg);
1200	buffer = alloc_buffer(size);
1201
1202	/* OpenSSL GMAC. */
1203	if (!openssl_gmac(alg, cipher, key, iv, buffer, size, control_tag))
1204		goto out;
1205
1206	/* OCF GMAC. */
1207	if (!ocf_mac(alg, buffer, size, key, key_len, iv, test_tag, &crid))
1208		goto out;
1209	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1210		printf("%s (%zu) mismatch:\n", alg->name, size);
1211		printf("control:\n");
1212		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1213		printf("test (cryptodev device %s):\n", crfind(crid));
1214		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1215		goto out;
1216	}
1217
1218	if (verbose)
1219		printf("%s (%zu) matched (cryptodev device %s)\n",
1220		    alg->name, size, crfind(crid));
1221
1222out:
1223	free(buffer);
1224	free(iv);
1225	free(key);
1226}
1227
1228static bool
1229openssl_digest(const struct alg *alg, const char *key, u_int key_len,
1230    const char *input, size_t size, char *tag, u_int tag_len)
1231{
1232	EVP_MD_CTX *mdctx;
1233	EVP_PKEY *pkey;
1234	size_t len;
1235
1236	pkey = EVP_PKEY_new_raw_private_key(alg->pkey, NULL, key, key_len);
1237	if (pkey == NULL) {
1238		warnx("OpenSSL %s (%zu) pkey new failed: %s", alg->name,
1239		    size, ERR_error_string(ERR_get_error(), NULL));
1240		return (false);
1241	}
1242	mdctx = EVP_MD_CTX_new();
1243	if (mdctx == NULL) {
1244		warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1245		    size, ERR_error_string(ERR_get_error(), NULL));
1246		EVP_PKEY_free(pkey);
1247		return (false);
1248	}
1249	if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
1250		warnx("OpenSSL %s (%zu) digest sign init failed: %s",
1251		    alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1252		goto error;
1253	}
1254	if (EVP_DigestSignUpdate(mdctx, input, size) != 1) {
1255		warnx("OpenSSL %s (%zu) digest update failed: %s", alg->name,
1256		    size, ERR_error_string(ERR_get_error(), NULL));
1257		goto error;
1258	}
1259	len = tag_len;
1260	if (EVP_DigestSignFinal(mdctx, tag, &len) != 1) {
1261		warnx("OpenSSL %s (%zu) digest final failed: %s", alg->name,
1262		    size, ERR_error_string(ERR_get_error(), NULL));
1263		goto error;
1264	}
1265	EVP_MD_CTX_free(mdctx);
1266	EVP_PKEY_free(pkey);
1267	return (true);
1268
1269error:
1270	EVP_MD_CTX_free(mdctx);
1271	EVP_PKEY_free(pkey);
1272	return (false);
1273}
1274
1275static void
1276run_digest_test(const struct alg *alg, size_t size)
1277{
1278	char *key, *buffer;
1279	u_int key_len;
1280	int crid;
1281	char control_tag[EVP_MAX_MD_SIZE], test_tag[EVP_MAX_MD_SIZE];
1282
1283	memset(control_tag, 0x3c, sizeof(control_tag));
1284	memset(test_tag, 0x3c, sizeof(test_tag));
1285
1286	key_len = alg->key_len;
1287
1288	key = alloc_buffer(key_len);
1289	buffer = alloc_buffer(size);
1290
1291	/* OpenSSL Poly1305. */
1292	if (!openssl_digest(alg, key, key_len, buffer, size, control_tag,
1293	    sizeof(control_tag)))
1294		goto out;
1295
1296	/* OCF Poly1305. */
1297	if (!ocf_mac(alg, buffer, size, key, key_len, NULL, test_tag, &crid))
1298		goto out;
1299	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1300		printf("%s (%zu) mismatch:\n", alg->name, size);
1301		printf("control:\n");
1302		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1303		printf("test (cryptodev device %s):\n", crfind(crid));
1304		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1305		goto out;
1306	}
1307
1308	if (verbose)
1309		printf("%s (%zu) matched (cryptodev device %s)\n",
1310		    alg->name, size, crfind(crid));
1311
1312out:
1313	free(buffer);
1314	free(key);
1315}
1316
1317static bool
1318openssl_aead_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1319    const char *key, const char *iv, size_t iv_len, const char *aad,
1320    size_t aad_len, const char *input, char *output, size_t size, char *tag)
1321{
1322	EVP_CIPHER_CTX *ctx;
1323	int outl, total;
1324
1325	ctx = EVP_CIPHER_CTX_new();
1326	if (ctx == NULL) {
1327		warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1328		    size, ERR_error_string(ERR_get_error(), NULL));
1329		return (false);
1330	}
1331	if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
1332		warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1333		    size, ERR_error_string(ERR_get_error(), NULL));
1334		goto error;
1335	}
1336	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) !=
1337	    1) {
1338		warnx("OpenSSL %s (%zu) setting iv length failed: %s", alg->name,
1339		    size, ERR_error_string(ERR_get_error(), NULL));
1340		goto error;
1341	}
1342	if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1343	    (const u_char *)iv) != 1) {
1344		warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1345		    size, ERR_error_string(ERR_get_error(), NULL));
1346		goto error;
1347	}
1348	EVP_CIPHER_CTX_set_padding(ctx, 0);
1349	if (aad != NULL) {
1350		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1351		    aad_len) != 1) {
1352			warnx("OpenSSL %s (%zu) aad update failed: %s",
1353			    alg->name, size,
1354			    ERR_error_string(ERR_get_error(), NULL));
1355			goto error;
1356		}
1357	}
1358	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1359	    (const u_char *)input, size) != 1) {
1360		warnx("OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
1361		    size, ERR_error_string(ERR_get_error(), NULL));
1362		goto error;
1363	}
1364	total = outl;
1365	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) {
1366		warnx("OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
1367		    size, ERR_error_string(ERR_get_error(), NULL));
1368		goto error;
1369	}
1370	total += outl;
1371	if ((size_t)total != size) {
1372		warnx("OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
1373		    size, total);
1374		goto error;
1375	}
1376	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1377	    tag) != 1) {
1378		warnx("OpenSSL %s (%zu) get tag failed: %s", alg->name,
1379		    size, ERR_error_string(ERR_get_error(), NULL));
1380		goto error;
1381	}
1382	EVP_CIPHER_CTX_free(ctx);
1383	return (true);
1384
1385error:
1386	EVP_CIPHER_CTX_free(ctx);
1387	return (false);
1388}
1389
1390#ifdef notused
1391static bool
1392openssl_aead_decrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1393    const char *key, const char *iv, const char *aad, size_t aad_len,
1394    const char *input, char *output, size_t size, char *tag)
1395{
1396	EVP_CIPHER_CTX *ctx;
1397	int outl, total;
1398	bool valid;
1399
1400	ctx = EVP_CIPHER_CTX_new();
1401	if (ctx == NULL)
1402		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1403		    size, ERR_error_string(ERR_get_error(), NULL));
1404	if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1405	    (const u_char *)iv) != 1)
1406		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1407		    size, ERR_error_string(ERR_get_error(), NULL));
1408	EVP_CIPHER_CTX_set_padding(ctx, 0);
1409	if (aad != NULL) {
1410		if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1411		    aad_len) != 1)
1412			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1413			    alg->name, size,
1414			    ERR_error_string(ERR_get_error(), NULL));
1415	}
1416	if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl,
1417	    (const u_char *)input, size) != 1)
1418		errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name,
1419		    size, ERR_error_string(ERR_get_error(), NULL));
1420	total = outl;
1421	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, alg->tag_len,
1422	    tag) != 1)
1423		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1424		    size, ERR_error_string(ERR_get_error(), NULL));
1425	valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1);
1426	total += outl;
1427	if (total != size)
1428		errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name,
1429		    size, total);
1430	EVP_CIPHER_CTX_free(ctx);
1431	return (valid);
1432}
1433#endif
1434
1435static bool
1436openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1437    const char *key, const char *iv, size_t iv_len, const char *aad,
1438    size_t aad_len, const char *input, char *output, size_t size, char *tag)
1439{
1440	EVP_CIPHER_CTX *ctx;
1441	int outl, total;
1442
1443	ctx = EVP_CIPHER_CTX_new();
1444	if (ctx == NULL) {
1445		warnx("OpenSSL %s/%zu (%zu, %zu) ctx new failed: %s",
1446		    alg->name, iv_len, aad_len, size,
1447		    ERR_error_string(ERR_get_error(), NULL));
1448		return (false);
1449	}
1450	if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
1451		warnx("OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1452		    alg->name, iv_len, aad_len, size,
1453		    ERR_error_string(ERR_get_error(), NULL));
1454		goto error;
1455	}
1456	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) !=
1457	    1) {
1458		warnx("OpenSSL %s/%zu (%zu, %zu) setting iv length failed: %s",
1459		    alg->name, iv_len, aad_len, size,
1460		    ERR_error_string(ERR_get_error(), NULL));
1461		goto error;
1462	}
1463	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AES_CBC_MAC_HASH_LEN,
1464	    NULL) != 1) {
1465		warnx("OpenSSL %s/%zu (%zu, %zu) setting tag length failed: %s",
1466		    alg->name, iv_len, aad_len, size,
1467		    ERR_error_string(ERR_get_error(), NULL));
1468		goto error;
1469	}
1470	if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1471	    (const u_char *)iv) != 1) {
1472		warnx("OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1473		    alg->name, iv_len, aad_len, size,
1474		    ERR_error_string(ERR_get_error(), NULL));
1475		goto error;
1476	}
1477	if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1) {
1478		warnx("OpenSSL %s/%zu (%zu, %zu) unable to set data length: %s",
1479		    alg->name, iv_len, aad_len, size,
1480		    ERR_error_string(ERR_get_error(), NULL));
1481		goto error;
1482	}
1483
1484	if (aad != NULL) {
1485		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1486		    aad_len) != 1) {
1487			warnx("OpenSSL %s/%zu (%zu, %zu) aad update failed: %s",
1488			    alg->name, iv_len, aad_len, size,
1489			    ERR_error_string(ERR_get_error(), NULL));
1490			goto error;
1491		}
1492	}
1493	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1494	    (const u_char *)input, size) != 1) {
1495		warnx("OpenSSL %s/%zu (%zu, %zu) encrypt update failed: %s",
1496		    alg->name, iv_len, aad_len, size,
1497		    ERR_error_string(ERR_get_error(), NULL));
1498		goto error;
1499	}
1500	total = outl;
1501	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) {
1502		warnx("OpenSSL %s/%zu (%zu, %zu) encrypt final failed: %s",
1503		    alg->name, iv_len, aad_len, size,
1504		    ERR_error_string(ERR_get_error(), NULL));
1505		goto error;
1506	}
1507	total += outl;
1508	if ((size_t)total != size) {
1509		warnx("OpenSSL %s/%zu (%zu, %zu) encrypt size mismatch: %d",
1510		    alg->name, iv_len, aad_len, size, total);
1511		goto error;
1512	}
1513	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_CBC_MAC_HASH_LEN,
1514	    tag) != 1) {
1515		warnx("OpenSSL %s/%zu (%zu, %zu) get tag failed: %s",
1516		    alg->name, iv_len, aad_len, size,
1517		    ERR_error_string(ERR_get_error(), NULL));
1518		goto error;
1519	}
1520	EVP_CIPHER_CTX_free(ctx);
1521	return (true);
1522
1523error:
1524	EVP_CIPHER_CTX_free(ctx);
1525	return (false);
1526}
1527
1528static bool
1529ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len,
1530    size_t iv_len, struct ocf_session *ses)
1531{
1532	struct session2_op sop;
1533
1534	ocf_init_sop(&sop);
1535	sop.keylen = key_len;
1536	sop.key = key;
1537	sop.cipher = alg->cipher;
1538	sop.ivlen = iv_len;
1539	return (ocf_init_session(&sop, "AEAD", alg->name, ses));
1540}
1541
1542static int
1543ocf_aead(const struct ocf_session *ses, const char *iv, size_t iv_len,
1544    const char *aad, size_t aad_len, const char *input, char *output,
1545    size_t size, char *tag, int op)
1546{
1547	struct crypt_aead caead;
1548
1549	ocf_init_caead(ses, &caead);
1550	caead.op = op;
1551	caead.len = size;
1552	caead.aadlen = aad_len;
1553	caead.ivlen = iv_len;
1554	caead.src = input;
1555	caead.dst = output;
1556	caead.aad = aad;
1557	caead.tag = tag;
1558	caead.iv = iv;
1559
1560	if (ioctl(ses->fd, CIOCCRYPTAEAD, &caead) < 0)
1561		return (errno);
1562	return (0);
1563}
1564
1565#define	AEAD_MAX_TAG_LEN				\
1566	MAX(MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN), POLY1305_HASH_LEN)
1567
1568static size_t
1569max_ccm_buffer_length(size_t iv_len)
1570{
1571	const u_int L = 15 - iv_len;
1572
1573	switch (L) {
1574	case 2:
1575		return (0xffff);
1576	case 3:
1577		return (0xffffff);
1578#ifdef __LP64__
1579	case 4:
1580		return (0xffffffff);
1581	case 5:
1582		return (0xffffffffff);
1583	case 6:
1584		return (0xffffffffffff);
1585	case 7:
1586		return (0xffffffffffffff);
1587	default:
1588		return (0xffffffffffffffff);
1589#else
1590	default:
1591		return (0xffffffff);
1592#endif
1593	}
1594}
1595
1596static void
1597run_aead_test(const struct alg *alg, size_t aad_len, size_t size,
1598    size_t iv_len)
1599{
1600	struct ocf_session ses;
1601	const EVP_CIPHER *cipher;
1602	char *aad, *buffer, *cleartext, *ciphertext;
1603	char *iv, *key;
1604	u_int key_len;
1605	int error;
1606	char control_tag[AEAD_MAX_TAG_LEN], test_tag[AEAD_MAX_TAG_LEN];
1607	bool ok;
1608
1609	cipher = alg->evp_cipher();
1610	if (size % EVP_CIPHER_block_size(cipher) != 0) {
1611		if (verbose)
1612			printf(
1613		    "%s/%zu (%zu, %zu): invalid buffer size (block size %d)\n",
1614			    alg->name, iv_len, aad_len, size,
1615			    EVP_CIPHER_block_size(cipher));
1616		return;
1617	}
1618
1619	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE &&
1620	    size > max_ccm_buffer_length(iv_len)) {
1621		if (verbose)
1622			printf("%s/%zu (%zu, %zu): invalid buffer size\n",
1623			    alg->name, iv_len, aad_len, size);
1624		return;
1625	}
1626
1627	memset(control_tag, 0x3c, sizeof(control_tag));
1628	memset(test_tag, 0x3c, sizeof(test_tag));
1629
1630	key_len = EVP_CIPHER_key_length(cipher);
1631
1632	key = alloc_buffer(key_len);
1633	iv = generate_iv(iv_len, alg);
1634	cleartext = alloc_buffer(size);
1635	buffer = malloc(size);
1636	ciphertext = malloc(size);
1637	if (aad_len != 0)
1638		aad = alloc_buffer(aad_len);
1639	else
1640		aad = NULL;
1641
1642	/* OpenSSL encrypt */
1643	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE)
1644		ok = openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad,
1645		    aad_len, cleartext, ciphertext, size, control_tag);
1646	else
1647		ok = openssl_aead_encrypt(alg, cipher, key, iv, iv_len, aad,
1648		    aad_len, cleartext, ciphertext, size, control_tag);
1649	if (!ok)
1650		goto out_noocf;
1651
1652	if (!ocf_init_aead_session(alg, key, key_len, iv_len, &ses))
1653		goto out_noocf;
1654
1655	/* OCF encrypt */
1656	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, cleartext, buffer,
1657	    size, test_tag, COP_ENCRYPT);
1658	if (error != 0) {
1659		warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1660		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1661		goto out;
1662	}
1663	if (memcmp(ciphertext, buffer, size) != 0) {
1664		printf("%s/%zu (%zu, %zu) encryption mismatch:\n", alg->name,
1665		    iv_len, aad_len, size);
1666		printf("control:\n");
1667		hexdump(ciphertext, size, NULL, 0);
1668		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1669		hexdump(buffer, size, NULL, 0);
1670		goto out;
1671	}
1672	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1673		printf("%s/%zu (%zu, %zu) enc tag mismatch:\n", alg->name,
1674		    iv_len, aad_len, size);
1675		printf("control:\n");
1676		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1677		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1678		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1679		goto out;
1680	}
1681
1682	/* OCF decrypt */
1683	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1684	    buffer, size, control_tag, COP_DECRYPT);
1685	if (error != 0) {
1686		warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1687		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1688		goto out;
1689	}
1690	if (memcmp(cleartext, buffer, size) != 0) {
1691		printf("%s/%zu (%zu, %zu) decryption mismatch:\n", alg->name,
1692		    iv_len, aad_len, size);
1693		printf("control:\n");
1694		hexdump(cleartext, size, NULL, 0);
1695		printf("test (cryptodev device %s):\n", crfind(ses.crid));
1696		hexdump(buffer, size, NULL, 0);
1697		goto out;
1698	}
1699
1700	/* Verify OCF decrypt fails with busted tag. */
1701	test_tag[0] ^= 0x1;
1702	error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1703	    buffer, size, test_tag, COP_DECRYPT);
1704	if (error != EBADMSG) {
1705		if (error != 0)
1706			warnc(error,
1707		    "cryptodev %s/%zu (%zu, %zu) corrupt tag failed for device %s",
1708			    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1709		else
1710			warnx(
1711	    "cryptodev %s/%zu (%zu, %zu) corrupt tag didn't fail for device %s",
1712			    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1713		goto out;
1714	}
1715
1716	if (verbose)
1717		printf("%s/%zu (%zu, %zu) matched (cryptodev device %s)\n",
1718		    alg->name, iv_len, aad_len, size, crfind(ses.crid));
1719
1720out:
1721	ocf_destroy_session(&ses);
1722out_noocf:
1723	free(aad);
1724	free(ciphertext);
1725	free(buffer);
1726	free(cleartext);
1727	free(iv);
1728	free(key);
1729}
1730
1731static void
1732run_test(const struct alg *alg, size_t aad_len, size_t size, size_t iv_len)
1733{
1734
1735	switch (alg->type) {
1736	case T_HASH:
1737		run_hash_test(alg, size);
1738		break;
1739	case T_HMAC:
1740		run_hmac_test(alg, size);
1741		break;
1742	case T_GMAC:
1743		run_gmac_test(alg, size);
1744		break;
1745	case T_DIGEST:
1746		run_digest_test(alg, size);
1747		break;
1748	case T_CIPHER:
1749		run_cipher_test(alg, size);
1750		break;
1751	case T_ETA:
1752		run_eta_test(alg, aad_len, size);
1753		break;
1754	case T_AEAD:
1755		run_aead_test(alg, aad_len, size, iv_len);
1756		break;
1757	}
1758}
1759
1760static void
1761run_test_sizes(const struct alg *alg)
1762{
1763	u_int i, j, k;
1764
1765	switch (alg->type) {
1766	default:
1767		for (i = 0; i < nsizes; i++)
1768			run_test(alg, 0, sizes[i], 0);
1769		break;
1770	case T_ETA:
1771		for (i = 0; i < naad_sizes; i++)
1772			for (j = 0; j < nsizes; j++)
1773				run_test(alg, aad_sizes[i], sizes[j], 0);
1774		break;
1775	case T_AEAD:
1776		for (i = 0; i < naad_sizes; i++) {
1777			for (j = 0; j < nsizes; j++) {
1778				if (iv_size != 0)
1779					run_test(alg, aad_sizes[i], sizes[j],
1780					    iv_size);
1781				else if (testall) {
1782					for (k = 0; alg->iv_sizes[k] != 0; k++)
1783						run_test(alg, aad_sizes[i],
1784						    sizes[j], alg->iv_sizes[k]);
1785				} else
1786					run_test(alg, aad_sizes[i], sizes[j],
1787					    alg->iv_sizes[0]);
1788			}
1789		}
1790		break;
1791	}
1792}
1793
1794static void
1795run_hash_tests(void)
1796{
1797	u_int i;
1798
1799	for (i = 0; i < nitems(algs); i++)
1800		if (algs[i].type == T_HASH)
1801			run_test_sizes(&algs[i]);
1802}
1803
1804static void
1805run_mac_tests(void)
1806{
1807	u_int i;
1808
1809	for (i = 0; i < nitems(algs); i++)
1810		if (algs[i].type == T_HMAC || algs[i].type == T_GMAC ||
1811		    algs[i].type == T_DIGEST)
1812			run_test_sizes(&algs[i]);
1813}
1814
1815static void
1816run_cipher_tests(void)
1817{
1818	u_int i;
1819
1820	for (i = 0; i < nitems(algs); i++)
1821		if (algs[i].type == T_CIPHER)
1822			run_test_sizes(&algs[i]);
1823}
1824
1825static void
1826run_eta_tests(void)
1827{
1828	const struct alg *cipher, *mac;
1829	struct alg *eta;
1830	u_int i, j;
1831
1832	for (i = 0; i < nitems(algs); i++) {
1833		cipher = &algs[i];
1834		if (cipher->type != T_CIPHER)
1835			continue;
1836		for (j = 0; j < nitems(algs); j++) {
1837			mac = &algs[j];
1838			if (mac->type != T_HMAC)
1839				continue;
1840			eta = build_eta(cipher, mac);
1841			run_test_sizes(eta);
1842			free_eta(eta);
1843		}
1844	}
1845}
1846
1847static void
1848run_aead_tests(void)
1849{
1850	u_int i;
1851
1852	for (i = 0; i < nitems(algs); i++)
1853		if (algs[i].type == T_AEAD)
1854			run_test_sizes(&algs[i]);
1855}
1856
1857static void
1858run_prefix_tests(const char *prefix)
1859{
1860	size_t prefix_len;
1861	u_int i;
1862
1863	prefix_len = strlen(prefix);
1864	for (i = 0; i < nitems(algs); i++)
1865		if (strlen(algs[i].name) >= prefix_len &&
1866		    memcmp(algs[i].name, prefix, prefix_len) == 0)
1867			run_test_sizes(&algs[i]);
1868}
1869
1870int
1871main(int ac, char **av)
1872{
1873	const char *algname;
1874	const struct alg *alg;
1875	struct alg *eta;
1876	char *cp;
1877	size_t base_size;
1878	u_int i;
1879	int ch;
1880
1881	algname = NULL;
1882	requested_crid = CRYPTO_FLAG_HARDWARE;
1883	testall = false;
1884	verbose = false;
1885	iv_size = 0;
1886	while ((ch = getopt(ac, av, "A:a:d:I:vz")) != -1)
1887		switch (ch) {
1888		case 'A':
1889			if (naad_sizes >= nitems(aad_sizes)) {
1890				warnx("Too many AAD sizes, ignoring extras");
1891				break;
1892			}
1893			aad_sizes[naad_sizes] = strtol(optarg, &cp, 0);
1894			if (*cp != '\0')
1895				errx(1, "Bad AAD size %s", optarg);
1896			naad_sizes++;
1897			break;
1898		case 'a':
1899			algname = optarg;
1900			break;
1901		case 'd':
1902			requested_crid = crlookup(optarg);
1903			break;
1904		case 'I':
1905			iv_size = strtol(optarg, &cp, 0);
1906			if (*cp != '\0')
1907				errx(1, "Bad IV size %s", optarg);
1908			break;
1909		case 'v':
1910			verbose = true;
1911			break;
1912		case 'z':
1913			testall = true;
1914			break;
1915		default:
1916			usage();
1917		}
1918	ac -= optind;
1919	av += optind;
1920	nsizes = 0;
1921	while (ac > 0) {
1922		if (nsizes >= nitems(sizes)) {
1923			warnx("Too many sizes, ignoring extras");
1924			break;
1925		}
1926		sizes[nsizes] = strtol(av[0], &cp, 0);
1927		if (*cp != '\0')
1928			errx(1, "Bad size %s", av[0]);
1929		nsizes++;
1930		ac--;
1931		av++;
1932	}
1933
1934	if (algname == NULL)
1935		errx(1, "Algorithm required");
1936
1937	if (naad_sizes == 0) {
1938		if (testall) {
1939			for (i = 0; i <= 32; i++) {
1940				aad_sizes[naad_sizes] = i;
1941				naad_sizes++;
1942			}
1943
1944			base_size = 32;
1945			while (base_size * 2 < 512) {
1946				base_size *= 2;
1947				assert(naad_sizes < nitems(aad_sizes));
1948				aad_sizes[naad_sizes] = base_size;
1949				naad_sizes++;
1950			}
1951		} else {
1952			aad_sizes[0] = 0;
1953			naad_sizes = 1;
1954		}
1955	}
1956
1957	if (nsizes == 0) {
1958		if (testall) {
1959			for (i = 1; i <= EALG_MAX_BLOCK_LEN; i++) {
1960				sizes[nsizes] = i;
1961				nsizes++;
1962			}
1963
1964			for (i = EALG_MAX_BLOCK_LEN + 8;
1965			     i <= EALG_MAX_BLOCK_LEN * 2; i += 8) {
1966				sizes[nsizes] = i;
1967				nsizes++;
1968			}
1969
1970			base_size = EALG_MAX_BLOCK_LEN * 2;
1971			while (base_size * 2 < 240 * 1024) {
1972				base_size *= 2;
1973				assert(nsizes < nitems(sizes));
1974				sizes[nsizes] = base_size;
1975				nsizes++;
1976			}
1977
1978			if (sizes[nsizes - 1] < 240 * 1024) {
1979				assert(nsizes < nitems(sizes));
1980				sizes[nsizes] = 240 * 1024;
1981				nsizes++;
1982			}
1983		} else {
1984			sizes[0] = 16;
1985			nsizes = 1;
1986		}
1987	}
1988
1989	if (strcasecmp(algname, "hash") == 0)
1990		run_hash_tests();
1991	else if (strcasecmp(algname, "mac") == 0)
1992		run_mac_tests();
1993	else if (strcasecmp(algname, "cipher") == 0)
1994		run_cipher_tests();
1995	else if (strcasecmp(algname, "eta") == 0)
1996		run_eta_tests();
1997	else if (strcasecmp(algname, "aead") == 0)
1998		run_aead_tests();
1999	else if (strcasecmp(algname, "gmac") == 0 ||
2000	    strcasecmp(algname, "aes-cbc") == 0 ||
2001	    strcasecmp(algname, "aes-ctr") == 0 ||
2002	    strcasecmp(algname, "aes-xts") == 0 ||
2003	    strcasecmp(algname, "camellia-cbc") == 0 ||
2004	    strcasecmp(algname, "aes-gcm") == 0 ||
2005	    strcasecmp(algname, "aes-ccm") == 0)
2006		run_prefix_tests(algname);
2007	else if (strcasecmp(algname, "all") == 0) {
2008		run_hash_tests();
2009		run_mac_tests();
2010		run_cipher_tests();
2011		run_eta_tests();
2012		run_aead_tests();
2013	} else if (strchr(algname, '+') != NULL) {
2014		eta = build_eta_name(algname);
2015		run_test_sizes(eta);
2016		free_eta(eta);
2017	} else {
2018		alg = find_alg(algname);
2019		if (alg == NULL)
2020			errx(1, "Invalid algorithm %s", algname);
2021		run_test_sizes(alg);
2022	}
2023
2024	return (0);
2025}
2026