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