xref: /freebsd/tools/tools/crypto/cryptocheck.c (revision 0957b409)
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  *	hmac		Run all hmac tests
77  *	blkcipher	Run all block cipher tests
78  *	authenc		Run all authenticated encryption tests
79  *	aead		Run all authenticated encryption with associated data
80  *			tests
81  *
82  * HMACs:
83  *	sha1		sha1 hmac
84  *	sha256		256-bit sha2 hmac
85  *	sha384		384-bit sha2 hmac
86  *	sha512		512-bit	sha2 hmac
87  *	blake2b		Blake2-B
88  *	blake2s		Blake2-S
89  *
90  * Block Ciphers:
91  *	aes-cbc		128-bit aes cbc
92  *	aes-cbc192	192-bit	aes cbc
93  *	aes-cbc256	256-bit aes cbc
94  *	aes-ctr		128-bit aes ctr
95  *	aes-ctr192	192-bit aes ctr
96  *	aes-ctr256	256-bit aes ctr
97  *	aes-xts		128-bit aes xts
98  *	aes-xts256	256-bit aes xts
99  *	chacha20
100  *
101  * Authenticated Encryption:
102  *	<block cipher>+<hmac>
103  *
104  * Authenticated Encryption with Associated Data:
105  *	aes-gcm		128-bit aes gcm
106  *	aes-gcm192	192-bit aes gcm
107  *	aes-gcm256	256-bit aes gcm
108  *	aes-ccm		128-bit aes ccm
109  *	aes-ccm192	192-bit aes ccm
110  *	aes-ccm256	256-bit aes ccm
111  */
112 
113 #include <sys/param.h>
114 #include <assert.h>
115 #include <err.h>
116 #include <fcntl.h>
117 #include <libutil.h>
118 #include <stdbool.h>
119 #include <stdio.h>
120 #include <string.h>
121 #include <unistd.h>
122 
123 #include <openssl/err.h>
124 #include <openssl/hmac.h>
125 
126 #include <crypto/cryptodev.h>
127 
128 /* XXX: Temporary hack */
129 #ifndef COP_F_CIPHER_FIRST
130 #define	COP_F_CIPHER_FIRST	0x0001	/* Cipher before MAC. */
131 #endif
132 
133 struct alg {
134 	const char *name;
135 	int cipher;
136 	int mac;
137 	enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM, T_CCM } type;
138 	const EVP_CIPHER *(*evp_cipher)(void);
139 	const EVP_MD *(*evp_md)(void);
140 } algs[] = {
141 	{ .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH,
142 	  .evp_md = EVP_sha1 },
143 	{ .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH,
144 	  .evp_md = EVP_sha224 },
145 	{ .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH,
146 	  .evp_md = EVP_sha256 },
147 	{ .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH,
148 	  .evp_md = EVP_sha384 },
149 	{ .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH,
150 	  .evp_md = EVP_sha512 },
151 	{ .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
152 	  .evp_md = EVP_sha1 },
153 	{ .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
154 	  .evp_md = EVP_sha224 },
155 	{ .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
156 	  .evp_md = EVP_sha256 },
157 	{ .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
158 	  .evp_md = EVP_sha384 },
159 	{ .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
160 	  .evp_md = EVP_sha512 },
161 	{ .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH,
162 	  .evp_md = EVP_blake2b512 },
163 	{ .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH,
164 	  .evp_md = EVP_blake2s256 },
165 	{ .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
166 	  .evp_cipher = EVP_aes_128_cbc },
167 	{ .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
168 	  .evp_cipher = EVP_aes_192_cbc },
169 	{ .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
170 	  .evp_cipher = EVP_aes_256_cbc },
171 	{ .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
172 	  .evp_cipher = EVP_aes_128_ctr },
173 	{ .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
174 	  .evp_cipher = EVP_aes_192_ctr },
175 	{ .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
176 	  .evp_cipher = EVP_aes_256_ctr },
177 	{ .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
178 	  .evp_cipher = EVP_aes_128_xts },
179 	{ .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
180 	  .evp_cipher = EVP_aes_256_xts },
181 	{ .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_BLKCIPHER,
182 	  .evp_cipher = EVP_chacha20 },
183 	{ .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16,
184 	  .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_GCM,
185 	  .evp_cipher = EVP_aes_128_gcm },
186 	{ .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16,
187 	  .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_GCM,
188 	  .evp_cipher = EVP_aes_192_gcm },
189 	{ .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16,
190 	  .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_GCM,
191 	  .evp_cipher = EVP_aes_256_gcm },
192 	{ .name = "aes-ccm", .cipher = CRYPTO_AES_CCM_16,
193 	  .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
194 	  .evp_cipher = EVP_aes_128_ccm },
195 	{ .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16,
196 	  .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
197 	  .evp_cipher = EVP_aes_192_ccm },
198 	{ .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16,
199 	  .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM,
200 	  .evp_cipher = EVP_aes_256_ccm },
201 };
202 
203 static bool verbose;
204 static int crid;
205 static size_t aad_len;
206 
207 static void
208 usage(void)
209 {
210 	fprintf(stderr,
211 	    "usage: cryptocheck [-z] [-a algorithm] [-d dev] [size ...]\n");
212 	exit(1);
213 }
214 
215 static struct alg *
216 find_alg(const char *name)
217 {
218 	u_int i;
219 
220 	for (i = 0; i < nitems(algs); i++)
221 		if (strcasecmp(algs[i].name, name) == 0)
222 			return (&algs[i]);
223 	return (NULL);
224 }
225 
226 static struct alg *
227 build_authenc(struct alg *cipher, struct alg *hmac)
228 {
229 	static struct alg authenc;
230 	char *name;
231 
232 	assert(cipher->type == T_BLKCIPHER);
233 	assert(hmac->type == T_HMAC);
234 	memset(&authenc, 0, sizeof(authenc));
235 	asprintf(&name, "%s+%s", cipher->name, hmac->name);
236 	authenc.name = name;
237 	authenc.cipher = cipher->cipher;
238 	authenc.mac = hmac->mac;
239 	authenc.type = T_AUTHENC;
240 	authenc.evp_cipher = cipher->evp_cipher;
241 	authenc.evp_md = hmac->evp_md;
242 	return (&authenc);
243 }
244 
245 static struct alg *
246 build_authenc_name(const char *name)
247 {
248 	struct alg *cipher, *hmac;
249 	const char *hmac_name;
250 	char *cp, *cipher_name;
251 
252 	cp = strchr(name, '+');
253 	cipher_name = strndup(name, cp - name);
254 	hmac_name = cp + 1;
255 	cipher = find_alg(cipher_name);
256 	free(cipher_name);
257 	if (cipher == NULL)
258 		errx(1, "Invalid cipher %s", cipher_name);
259 	hmac = find_alg(hmac_name);
260 	if (hmac == NULL)
261 		errx(1, "Invalid hash %s", hmac_name);
262 	return (build_authenc(cipher, hmac));
263 }
264 
265 static int
266 devcrypto(void)
267 {
268 	static int fd = -1;
269 
270 	if (fd < 0) {
271 		fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0);
272 		if (fd < 0)
273 			err(1, "/dev/crypto");
274 	}
275 	return (fd);
276 }
277 
278 static int
279 crlookup(const char *devname)
280 {
281 	struct crypt_find_op find;
282 
283 	if (strncmp(devname, "soft", 4) == 0)
284 		return CRYPTO_FLAG_SOFTWARE;
285 
286 	find.crid = -1;
287 	strlcpy(find.name, devname, sizeof(find.name));
288 	if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
289 		err(1, "ioctl(CIOCFINDDEV)");
290 	return (find.crid);
291 }
292 
293 const char *
294 crfind(int crid)
295 {
296 	static struct crypt_find_op find;
297 
298 	if (crid == CRYPTO_FLAG_SOFTWARE)
299 		return ("soft");
300 	else if (crid == CRYPTO_FLAG_HARDWARE)
301 		return ("unknown");
302 
303 	bzero(&find, sizeof(find));
304 	find.crid = crid;
305 	if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1)
306 		err(1, "ioctl(CIOCFINDDEV): crid %d", crid);
307 	return (find.name);
308 }
309 
310 static int
311 crget(void)
312 {
313 	int fd;
314 
315 	if (ioctl(devcrypto(), CRIOGET, &fd) == -1)
316 		err(1, "ioctl(CRIOGET)");
317 	if (fcntl(fd, F_SETFD, 1) == -1)
318 		err(1, "fcntl(F_SETFD) (crget)");
319 	return fd;
320 }
321 
322 static char
323 rdigit(void)
324 {
325 	const char a[] = {
326 		0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41,
327 		0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01
328 	};
329 	return 0x20+a[random()%nitems(a)];
330 }
331 
332 static char *
333 alloc_buffer(size_t len)
334 {
335 	char *buf;
336 	size_t i;
337 
338 	buf = malloc(len);
339 	for (i = 0; i < len; i++)
340 		buf[i] = rdigit();
341 	return (buf);
342 }
343 
344 static char *
345 generate_iv(size_t len, struct alg *alg)
346 {
347 	char *iv;
348 
349 	iv = alloc_buffer(len);
350 	switch (alg->cipher) {
351 	case CRYPTO_AES_ICM:
352 		/* Clear the low 32 bits of the IV to hold the counter. */
353 		iv[len - 4] = 0;
354 		iv[len - 3] = 0;
355 		iv[len - 2] = 0;
356 		iv[len - 1] = 0;
357 		break;
358 	case CRYPTO_AES_XTS:
359 		/*
360 		 * Clear the low 64-bits to only store a 64-bit block
361 		 * number.
362 		 */
363 		iv[len - 8] = 0;
364 		iv[len - 7] = 0;
365 		iv[len - 6] = 0;
366 		iv[len - 5] = 0;
367 		iv[len - 4] = 0;
368 		iv[len - 3] = 0;
369 		iv[len - 2] = 0;
370 		iv[len - 1] = 0;
371 		break;
372 	}
373 	return (iv);
374 }
375 
376 static bool
377 ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest,
378     int *cridp)
379 {
380 	struct session2_op sop;
381 	struct crypt_op cop;
382 	int fd;
383 
384 	memset(&sop, 0, sizeof(sop));
385 	memset(&cop, 0, sizeof(cop));
386 	sop.crid = crid;
387 	sop.mac = alg->mac;
388 	fd = crget();
389 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
390 		warn("cryptodev %s HASH not supported for device %s",
391 		    alg->name, crfind(crid));
392 		close(fd);
393 		return (false);
394 	}
395 
396 	cop.ses = sop.ses;
397 	cop.op = 0;
398 	cop.len = size;
399 	cop.src = (char *)buffer;
400 	cop.dst = NULL;
401 	cop.mac = digest;
402 	cop.iv = NULL;
403 
404 	if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
405 		warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
406 		    size, crfind(crid));
407 		close(fd);
408 		return (false);
409 	}
410 
411 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
412 		warn("ioctl(CIOCFSESSION)");
413 
414 	close(fd);
415 	*cridp = sop.crid;
416 	return (true);
417 }
418 
419 static void
420 openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer,
421     size_t size, void *digest_out, unsigned *digest_sz_out)
422 {
423 	EVP_MD_CTX *mdctx;
424 	const char *errs;
425 	int rc;
426 
427 	errs = "";
428 
429 	mdctx = EVP_MD_CTX_create();
430 	if (mdctx == NULL)
431 		goto err_out;
432 
433 	rc = EVP_DigestInit_ex(mdctx, md, NULL);
434 	if (rc != 1)
435 		goto err_out;
436 
437 	rc = EVP_DigestUpdate(mdctx, buffer, size);
438 	if (rc != 1)
439 		goto err_out;
440 
441 	rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out);
442 	if (rc != 1)
443 		goto err_out;
444 
445 	EVP_MD_CTX_destroy(mdctx);
446 	return;
447 
448 err_out:
449 	errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs,
450 	    ERR_error_string(ERR_get_error(), NULL));
451 }
452 
453 static void
454 run_hash_test(struct alg *alg, size_t size)
455 {
456 	const EVP_MD *md;
457 	char *buffer;
458 	u_int digest_len;
459 	int crid;
460 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
461 
462 	memset(control_digest, 0x3c, sizeof(control_digest));
463 	memset(test_digest, 0x3c, sizeof(test_digest));
464 
465 	md = alg->evp_md();
466 	assert(EVP_MD_size(md) <= sizeof(control_digest));
467 
468 	buffer = alloc_buffer(size);
469 
470 	/* OpenSSL HASH. */
471 	digest_len = sizeof(control_digest);
472 	openssl_hash(alg, md, buffer, size, control_digest, &digest_len);
473 
474 	/* cryptodev HASH. */
475 	if (!ocf_hash(alg, buffer, size, test_digest, &crid))
476 		goto out;
477 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
478 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
479 			printf("%s (%zu) mismatch in trailer:\n",
480 			    alg->name, size);
481 		else
482 			printf("%s (%zu) mismatch:\n", alg->name, size);
483 		printf("control:\n");
484 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
485 		printf("test (cryptodev device %s):\n", crfind(crid));
486 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
487 		goto out;
488 	}
489 
490 	if (verbose)
491 		printf("%s (%zu) matched (cryptodev device %s)\n",
492 		    alg->name, size, crfind(crid));
493 
494 out:
495 	free(buffer);
496 }
497 
498 static bool
499 ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key,
500     size_t key_len, char *digest, int *cridp)
501 {
502 	struct session2_op sop;
503 	struct crypt_op cop;
504 	int fd;
505 
506 	memset(&sop, 0, sizeof(sop));
507 	memset(&cop, 0, sizeof(cop));
508 	sop.crid = crid;
509 	sop.mackeylen = key_len;
510 	sop.mackey = (char *)key;
511 	sop.mac = alg->mac;
512 	fd = crget();
513 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
514 		warn("cryptodev %s HMAC not supported for device %s",
515 		    alg->name, crfind(crid));
516 		close(fd);
517 		return (false);
518 	}
519 
520 	cop.ses = sop.ses;
521 	cop.op = 0;
522 	cop.len = size;
523 	cop.src = (char *)buffer;
524 	cop.dst = NULL;
525 	cop.mac = digest;
526 	cop.iv = NULL;
527 
528 	if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
529 		warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name,
530 		    size, crfind(crid));
531 		close(fd);
532 		return (false);
533 	}
534 
535 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
536 		warn("ioctl(CIOCFSESSION)");
537 
538 	close(fd);
539 	*cridp = sop.crid;
540 	return (true);
541 }
542 
543 static void
544 run_hmac_test(struct alg *alg, size_t size)
545 {
546 	const EVP_MD *md;
547 	char *key, *buffer;
548 	u_int key_len, digest_len;
549 	int crid;
550 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
551 
552 	memset(control_digest, 0x3c, sizeof(control_digest));
553 	memset(test_digest, 0x3c, sizeof(test_digest));
554 
555 	md = alg->evp_md();
556 	key_len = EVP_MD_size(md);
557 	assert(EVP_MD_size(md) <= sizeof(control_digest));
558 
559 	key = alloc_buffer(key_len);
560 	buffer = alloc_buffer(size);
561 
562 	/* OpenSSL HMAC. */
563 	digest_len = sizeof(control_digest);
564 	if (HMAC(md, key, key_len, (u_char *)buffer, size,
565 	    (u_char *)control_digest, &digest_len) == NULL)
566 		errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
567 		    size, ERR_error_string(ERR_get_error(), NULL));
568 
569 	/* cryptodev HMAC. */
570 	if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid))
571 		goto out;
572 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
573 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
574 			printf("%s (%zu) mismatch in trailer:\n",
575 			    alg->name, size);
576 		else
577 			printf("%s (%zu) mismatch:\n", alg->name, size);
578 		printf("control:\n");
579 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
580 		printf("test (cryptodev device %s):\n", crfind(crid));
581 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
582 		goto out;
583 	}
584 
585 	if (verbose)
586 		printf("%s (%zu) matched (cryptodev device %s)\n",
587 		    alg->name, size, crfind(crid));
588 
589 out:
590 	free(buffer);
591 	free(key);
592 }
593 
594 static void
595 openssl_cipher(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
596     const char *iv, const char *input, char *output, size_t size, int enc)
597 {
598 	EVP_CIPHER_CTX *ctx;
599 	int outl, total;
600 
601 	ctx = EVP_CIPHER_CTX_new();
602 	if (ctx == NULL)
603 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
604 		    size, ERR_error_string(ERR_get_error(), NULL));
605 	if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
606 	    (const u_char *)iv, enc) != 1)
607 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
608 		    size, ERR_error_string(ERR_get_error(), NULL));
609 	EVP_CIPHER_CTX_set_padding(ctx, 0);
610 	if (EVP_CipherUpdate(ctx, (u_char *)output, &outl,
611 	    (const u_char *)input, size) != 1)
612 		errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name,
613 		    size, ERR_error_string(ERR_get_error(), NULL));
614 	total = outl;
615 	if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
616 		errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name,
617 		    size, ERR_error_string(ERR_get_error(), NULL));
618 	total += outl;
619 	if (total != size)
620 		errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name,
621 		    size, total);
622 	EVP_CIPHER_CTX_free(ctx);
623 }
624 
625 static bool
626 ocf_cipher(struct alg *alg, const char *key, size_t key_len,
627     const char *iv, const char *input, char *output, size_t size, int enc,
628     int *cridp)
629 {
630 	struct session2_op sop;
631 	struct crypt_op cop;
632 	int fd;
633 
634 	memset(&sop, 0, sizeof(sop));
635 	memset(&cop, 0, sizeof(cop));
636 	sop.crid = crid;
637 	sop.keylen = key_len;
638 	sop.key = (char *)key;
639 	sop.cipher = alg->cipher;
640 	fd = crget();
641 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
642 		warn("cryptodev %s block cipher not supported for device %s",
643 		    alg->name, crfind(crid));
644 		close(fd);
645 		return (false);
646 	}
647 
648 	cop.ses = sop.ses;
649 	cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
650 	cop.len = size;
651 	cop.src = (char *)input;
652 	cop.dst = output;
653 	cop.mac = NULL;
654 	cop.iv = (char *)iv;
655 
656 	if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
657 		warn("cryptodev %s (%zu) block cipher failed for device %s",
658 		    alg->name, size, crfind(crid));
659 		close(fd);
660 		return (false);
661 	}
662 
663 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
664 		warn("ioctl(CIOCFSESSION)");
665 
666 	close(fd);
667 	*cridp = sop.crid;
668 	return (true);
669 }
670 
671 static void
672 run_blkcipher_test(struct alg *alg, size_t size)
673 {
674 	const EVP_CIPHER *cipher;
675 	char *buffer, *cleartext, *ciphertext;
676 	char *iv, *key;
677 	u_int iv_len, key_len;
678 	int crid;
679 
680 	cipher = alg->evp_cipher();
681 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
682 		if (verbose)
683 			printf(
684 			    "%s (%zu): invalid buffer size (block size %d)\n",
685 			    alg->name, size, EVP_CIPHER_block_size(cipher));
686 		return;
687 	}
688 
689 	key_len = EVP_CIPHER_key_length(cipher);
690 	iv_len = EVP_CIPHER_iv_length(cipher);
691 
692 	key = alloc_buffer(key_len);
693 	iv = generate_iv(iv_len, alg);
694 	cleartext = alloc_buffer(size);
695 	buffer = malloc(size);
696 	ciphertext = malloc(size);
697 
698 	/* OpenSSL cipher. */
699 	openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1);
700 	if (size > 0 && memcmp(cleartext, ciphertext, size) == 0)
701 		errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name,
702 		    size);
703 	openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0);
704 	if (memcmp(cleartext, buffer, size) != 0) {
705 		printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size);
706 		printf("original:\n");
707 		hexdump(cleartext, size, NULL, 0);
708 		printf("decrypted:\n");
709 		hexdump(buffer, size, NULL, 0);
710 		exit(1);
711 	}
712 
713 	/* OCF encrypt. */
714 	if (!ocf_cipher(alg, key, key_len, iv, cleartext, buffer, size, 1,
715 	    &crid))
716 		goto out;
717 	if (memcmp(ciphertext, buffer, size) != 0) {
718 		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
719 		printf("control:\n");
720 		hexdump(ciphertext, size, NULL, 0);
721 		printf("test (cryptodev device %s):\n", crfind(crid));
722 		hexdump(buffer, size, NULL, 0);
723 		goto out;
724 	}
725 
726 	/* OCF decrypt. */
727 	if (!ocf_cipher(alg, key, key_len, iv, ciphertext, buffer, size, 0,
728 	    &crid))
729 		goto out;
730 	if (memcmp(cleartext, buffer, size) != 0) {
731 		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
732 		printf("control:\n");
733 		hexdump(cleartext, size, NULL, 0);
734 		printf("test (cryptodev device %s):\n", crfind(crid));
735 		hexdump(buffer, size, NULL, 0);
736 		goto out;
737 	}
738 
739 	if (verbose)
740 		printf("%s (%zu) matched (cryptodev device %s)\n",
741 		    alg->name, size, crfind(crid));
742 
743 out:
744 	free(ciphertext);
745 	free(buffer);
746 	free(cleartext);
747 	free(iv);
748 	free(key);
749 }
750 
751 static bool
752 ocf_authenc(struct alg *alg, const char *cipher_key, size_t cipher_key_len,
753     const char *iv, size_t iv_len, const char *auth_key, size_t auth_key_len,
754     const char *aad, size_t aad_len, const char *input, char *output,
755     size_t size, char *digest, int enc, int *cridp)
756 {
757 	struct session2_op sop;
758 	int fd;
759 
760 	memset(&sop, 0, sizeof(sop));
761 	sop.crid = crid;
762 	sop.keylen = cipher_key_len;
763 	sop.key = (char *)cipher_key;
764 	sop.cipher = alg->cipher;
765 	sop.mackeylen = auth_key_len;
766 	sop.mackey = (char *)auth_key;
767 	sop.mac = alg->mac;
768 	fd = crget();
769 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
770 		warn("cryptodev %s AUTHENC not supported for device %s",
771 		    alg->name, crfind(crid));
772 		close(fd);
773 		return (false);
774 	}
775 
776 	if (aad_len != 0) {
777 		struct crypt_aead caead;
778 
779 		memset(&caead, 0, sizeof(caead));
780 		caead.ses = sop.ses;
781 		caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
782 		caead.flags = enc ? COP_F_CIPHER_FIRST : 0;
783 		caead.len = size;
784 		caead.aadlen = aad_len;
785 		caead.ivlen = iv_len;
786 		caead.src = (char *)input;
787 		caead.dst = output;
788 		caead.aad = (char *)aad;
789 		caead.tag = digest;
790 		caead.iv = (char *)iv;
791 
792 		if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
793 			warn("cryptodev %s (%zu) failed for device %s",
794 			    alg->name, size, crfind(crid));
795 			close(fd);
796 			return (false);
797 		}
798 	} else {
799 		struct crypt_op cop;
800 
801 		memset(&cop, 0, sizeof(cop));
802 		cop.ses = sop.ses;
803 		cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
804 		cop.flags = enc ? COP_F_CIPHER_FIRST : 0;
805 		cop.len = size;
806 		cop.src = (char *)input;
807 		cop.dst = output;
808 		cop.mac = digest;
809 		cop.iv = (char *)iv;
810 
811 		if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
812 			warn("cryptodev %s (%zu) AUTHENC failed for device %s",
813 			    alg->name, size, crfind(crid));
814 			close(fd);
815 			return (false);
816 		}
817 	}
818 
819 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
820 		warn("ioctl(CIOCFSESSION)");
821 
822 	close(fd);
823 	*cridp = sop.crid;
824 	return (true);
825 }
826 
827 static void
828 run_authenc_test(struct alg *alg, size_t size)
829 {
830 	const EVP_CIPHER *cipher;
831 	const EVP_MD *md;
832 	char *aad, *buffer, *cleartext, *ciphertext;
833 	char *iv, *auth_key, *cipher_key;
834 	u_int iv_len, auth_key_len, cipher_key_len, digest_len;
835 	int crid;
836 	char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
837 
838 	cipher = alg->evp_cipher();
839 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
840 		if (verbose)
841 			printf(
842 			    "%s (%zu): invalid buffer size (block size %d)\n",
843 			    alg->name, size, EVP_CIPHER_block_size(cipher));
844 		return;
845 	}
846 
847 	memset(control_digest, 0x3c, sizeof(control_digest));
848 	memset(test_digest, 0x3c, sizeof(test_digest));
849 
850 	md = alg->evp_md();
851 
852 	cipher_key_len = EVP_CIPHER_key_length(cipher);
853 	iv_len = EVP_CIPHER_iv_length(cipher);
854 	auth_key_len = EVP_MD_size(md);
855 
856 	cipher_key = alloc_buffer(cipher_key_len);
857 	iv = generate_iv(iv_len, alg);
858 	auth_key = alloc_buffer(auth_key_len);
859 	cleartext = alloc_buffer(aad_len + size);
860 	buffer = malloc(aad_len + size);
861 	ciphertext = malloc(aad_len + size);
862 
863 	/* OpenSSL encrypt + HMAC. */
864 	if (aad_len != 0)
865 		memcpy(ciphertext, cleartext, aad_len);
866 	openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len,
867 	    ciphertext + aad_len, size, 1);
868 	if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
869 	    size) == 0)
870 		errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name,
871 		    size);
872 	digest_len = sizeof(control_digest);
873 	if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
874 	    aad_len + size, (u_char *)control_digest, &digest_len) == NULL)
875 		errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
876 		    size, ERR_error_string(ERR_get_error(), NULL));
877 
878 	/* OCF encrypt + HMAC. */
879 	if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
880 	    auth_key_len, aad_len != 0 ? cleartext : NULL, aad_len,
881 	    cleartext + aad_len, buffer + aad_len, size, test_digest, 1, &crid))
882 		goto out;
883 	if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
884 		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
885 		printf("control:\n");
886 		hexdump(ciphertext + aad_len, size, NULL, 0);
887 		printf("test (cryptodev device %s):\n", crfind(crid));
888 		hexdump(buffer + aad_len, size, NULL, 0);
889 		goto out;
890 	}
891 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
892 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
893 			printf("%s (%zu) enc hash mismatch in trailer:\n",
894 			    alg->name, size);
895 		else
896 			printf("%s (%zu) enc hash mismatch:\n", alg->name,
897 			    size);
898 		printf("control:\n");
899 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
900 		printf("test (cryptodev device %s):\n", crfind(crid));
901 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
902 		goto out;
903 	}
904 
905 	/* OCF HMAC + decrypt. */
906 	memset(test_digest, 0x3c, sizeof(test_digest));
907 	if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
908 	    auth_key_len, aad_len != 0 ? ciphertext : NULL, aad_len,
909 	    ciphertext + aad_len, buffer + aad_len, size, test_digest, 0,
910 	    &crid))
911 		goto out;
912 	if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
913 		if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
914 			printf("%s (%zu) dec hash mismatch in trailer:\n",
915 			    alg->name, size);
916 		else
917 			printf("%s (%zu) dec hash mismatch:\n", alg->name,
918 			    size);
919 		printf("control:\n");
920 		hexdump(control_digest, sizeof(control_digest), NULL, 0);
921 		printf("test (cryptodev device %s):\n", crfind(crid));
922 		hexdump(test_digest, sizeof(test_digest), NULL, 0);
923 		goto out;
924 	}
925 	if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
926 		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
927 		printf("control:\n");
928 		hexdump(cleartext, size, NULL, 0);
929 		printf("test (cryptodev device %s):\n", crfind(crid));
930 		hexdump(buffer, size, NULL, 0);
931 		goto out;
932 	}
933 
934 	if (verbose)
935 		printf("%s (%zu) matched (cryptodev device %s)\n",
936 		    alg->name, size, crfind(crid));
937 
938 out:
939 	free(ciphertext);
940 	free(buffer);
941 	free(cleartext);
942 	free(auth_key);
943 	free(iv);
944 	free(cipher_key);
945 }
946 
947 static void
948 openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
949     const char *iv, const char *aad, size_t aad_len, const char *input,
950     char *output, size_t size, char *tag)
951 {
952 	EVP_CIPHER_CTX *ctx;
953 	int outl, total;
954 
955 	ctx = EVP_CIPHER_CTX_new();
956 	if (ctx == NULL)
957 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
958 		    size, ERR_error_string(ERR_get_error(), NULL));
959 	if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
960 	    (const u_char *)iv) != 1)
961 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
962 		    size, ERR_error_string(ERR_get_error(), NULL));
963 	EVP_CIPHER_CTX_set_padding(ctx, 0);
964 	if (aad != NULL) {
965 		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
966 		    aad_len) != 1)
967 			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
968 			    alg->name, size,
969 			    ERR_error_string(ERR_get_error(), NULL));
970 	}
971 	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
972 	    (const u_char *)input, size) != 1)
973 		errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
974 		    size, ERR_error_string(ERR_get_error(), NULL));
975 	total = outl;
976 	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
977 		errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
978 		    size, ERR_error_string(ERR_get_error(), NULL));
979 	total += outl;
980 	if (total != size)
981 		errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
982 		    size, total);
983 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GMAC_HASH_LEN,
984 	    tag) != 1)
985 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
986 		    size, ERR_error_string(ERR_get_error(), NULL));
987 	EVP_CIPHER_CTX_free(ctx);
988 }
989 
990 static bool
991 ocf_gcm(struct alg *alg, const char *key, size_t key_len, const char *iv,
992     size_t iv_len, const char *aad, size_t aad_len, const char *input,
993     char *output, size_t size, char *tag, int enc, int *cridp)
994 {
995 	struct session2_op sop;
996 	struct crypt_aead caead;
997 	int fd;
998 
999 	memset(&sop, 0, sizeof(sop));
1000 	memset(&caead, 0, sizeof(caead));
1001 	sop.crid = crid;
1002 	sop.keylen = key_len;
1003 	sop.key = (char *)key;
1004 	sop.cipher = alg->cipher;
1005 	sop.mackeylen = key_len;
1006 	sop.mackey = (char *)key;
1007 	sop.mac = alg->mac;
1008 	fd = crget();
1009 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
1010 		warn("cryptodev %s not supported for device %s",
1011 		    alg->name, crfind(crid));
1012 		close(fd);
1013 		return (false);
1014 	}
1015 
1016 	caead.ses = sop.ses;
1017 	caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
1018 	caead.len = size;
1019 	caead.aadlen = aad_len;
1020 	caead.ivlen = iv_len;
1021 	caead.src = (char *)input;
1022 	caead.dst = output;
1023 	caead.aad = (char *)aad;
1024 	caead.tag = tag;
1025 	caead.iv = (char *)iv;
1026 
1027 	if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
1028 		warn("cryptodev %s (%zu) failed for device %s",
1029 		    alg->name, size, crfind(crid));
1030 		close(fd);
1031 		return (false);
1032 	}
1033 
1034 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
1035 		warn("ioctl(CIOCFSESSION)");
1036 
1037 	close(fd);
1038 	*cridp = sop.crid;
1039 	return (true);
1040 }
1041 
1042 #ifdef notused
1043 static bool
1044 openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1045     const char *iv, const char *aad, size_t aad_len, const char *input,
1046     char *output, size_t size, char *tag)
1047 {
1048 	EVP_CIPHER_CTX *ctx;
1049 	int outl, total;
1050 	bool valid;
1051 
1052 	ctx = EVP_CIPHER_CTX_new();
1053 	if (ctx == NULL)
1054 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1055 		    size, ERR_error_string(ERR_get_error(), NULL));
1056 	if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1057 	    (const u_char *)iv) != 1)
1058 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1059 		    size, ERR_error_string(ERR_get_error(), NULL));
1060 	EVP_CIPHER_CTX_set_padding(ctx, 0);
1061 	if (aad != NULL) {
1062 		if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1063 		    aad_len) != 1)
1064 			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1065 			    alg->name, size,
1066 			    ERR_error_string(ERR_get_error(), NULL));
1067 	}
1068 	if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl,
1069 	    (const u_char *)input, size) != 1)
1070 		errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name,
1071 		    size, ERR_error_string(ERR_get_error(), NULL));
1072 	total = outl;
1073 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GMAC_HASH_LEN,
1074 	    tag) != 1)
1075 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1076 		    size, ERR_error_string(ERR_get_error(), NULL));
1077 	valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1);
1078 	total += outl;
1079 	if (total != size)
1080 		errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name,
1081 		    size, total);
1082 	EVP_CIPHER_CTX_free(ctx);
1083 	return (valid);
1084 }
1085 #endif
1086 
1087 static void
1088 run_gcm_test(struct alg *alg, size_t size)
1089 {
1090 	const EVP_CIPHER *cipher;
1091 	char *aad, *buffer, *cleartext, *ciphertext;
1092 	char *iv, *key;
1093 	u_int iv_len, key_len;
1094 	int crid;
1095 	char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
1096 
1097 	cipher = alg->evp_cipher();
1098 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
1099 		if (verbose)
1100 			printf(
1101 			    "%s (%zu): invalid buffer size (block size %d)\n",
1102 			    alg->name, size, EVP_CIPHER_block_size(cipher));
1103 		return;
1104 	}
1105 
1106 	memset(control_tag, 0x3c, sizeof(control_tag));
1107 	memset(test_tag, 0x3c, sizeof(test_tag));
1108 
1109 	key_len = EVP_CIPHER_key_length(cipher);
1110 	iv_len = EVP_CIPHER_iv_length(cipher);
1111 
1112 	key = alloc_buffer(key_len);
1113 	iv = generate_iv(iv_len, alg);
1114 	cleartext = alloc_buffer(size);
1115 	buffer = malloc(size);
1116 	ciphertext = malloc(size);
1117 	if (aad_len != 0)
1118 		aad = alloc_buffer(aad_len);
1119 	else
1120 		aad = NULL;
1121 
1122 	/* OpenSSL encrypt */
1123 	openssl_gcm_encrypt(alg, cipher, key, iv, aad, aad_len, cleartext,
1124 	    ciphertext, size, control_tag);
1125 
1126 	/* OCF encrypt */
1127 	if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext,
1128 	    buffer, size, test_tag, 1, &crid))
1129 		goto out;
1130 	if (memcmp(ciphertext, buffer, size) != 0) {
1131 		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
1132 		printf("control:\n");
1133 		hexdump(ciphertext, size, NULL, 0);
1134 		printf("test (cryptodev device %s):\n", crfind(crid));
1135 		hexdump(buffer, size, NULL, 0);
1136 		goto out;
1137 	}
1138 	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1139 		printf("%s (%zu) enc tag mismatch:\n", alg->name, size);
1140 		printf("control:\n");
1141 		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1142 		printf("test (cryptodev device %s):\n", crfind(crid));
1143 		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1144 		goto out;
1145 	}
1146 
1147 	/* OCF decrypt */
1148 	if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext,
1149 	    buffer, size, control_tag, 0, &crid))
1150 		goto out;
1151 	if (memcmp(cleartext, buffer, size) != 0) {
1152 		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
1153 		printf("control:\n");
1154 		hexdump(cleartext, size, NULL, 0);
1155 		printf("test (cryptodev device %s):\n", crfind(crid));
1156 		hexdump(buffer, size, NULL, 0);
1157 		goto out;
1158 	}
1159 
1160 	if (verbose)
1161 		printf("%s (%zu) matched (cryptodev device %s)\n",
1162 		    alg->name, size, crfind(crid));
1163 
1164 out:
1165 	free(aad);
1166 	free(ciphertext);
1167 	free(buffer);
1168 	free(cleartext);
1169 	free(iv);
1170 	free(key);
1171 }
1172 
1173 static void
1174 openssl_ccm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1175     const char *iv, size_t iv_len, const char *aad, size_t aad_len,
1176 		    const char *input, char *output, size_t size, char *tag)
1177 {
1178 	EVP_CIPHER_CTX *ctx;
1179 	int outl, total;
1180 
1181 	ctx = EVP_CIPHER_CTX_new();
1182 	if (ctx == NULL)
1183 		errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1184 		    size, ERR_error_string(ERR_get_error(), NULL));
1185 	if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
1186 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1187 		    size, ERR_error_string(ERR_get_error(), NULL));
1188 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_len, NULL) != 1)
1189 		errx(1, "OpenSSL %s (%zu) setting iv length failed: %s", alg->name,
1190 		    size, ERR_error_string(ERR_get_error(), NULL));
1191 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, AES_CBC_MAC_HASH_LEN, NULL) != 1)
1192 		errx(1, "OpenSSL %s (%zu) setting tag length failed: %s", alg->name,
1193 		     size, ERR_error_string(ERR_get_error(), NULL));
1194 	if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1195 	    (const u_char *)iv) != 1)
1196 		errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1197 		    size, ERR_error_string(ERR_get_error(), NULL));
1198 	if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1)
1199 		errx(1, "OpenSSL %s (%zu) unable to set data length: %s", alg->name,
1200 		     size, ERR_error_string(ERR_get_error(), NULL));
1201 
1202 	if (aad != NULL) {
1203 		if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1204 		    aad_len) != 1)
1205 			errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1206 			    alg->name, size,
1207 			    ERR_error_string(ERR_get_error(), NULL));
1208 	}
1209 	if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1210 	    (const u_char *)input, size) != 1)
1211 		errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
1212 		    size, ERR_error_string(ERR_get_error(), NULL));
1213 	total = outl;
1214 	if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
1215 		errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
1216 		    size, ERR_error_string(ERR_get_error(), NULL));
1217 	total += outl;
1218 	if (total != size)
1219 		errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
1220 		    size, total);
1221 	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, AES_CBC_MAC_HASH_LEN,
1222 	    tag) != 1)
1223 		errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1224 		    size, ERR_error_string(ERR_get_error(), NULL));
1225 	EVP_CIPHER_CTX_free(ctx);
1226 }
1227 
1228 static bool
1229 ocf_ccm(struct alg *alg, const char *key, size_t key_len, const char *iv,
1230     size_t iv_len, const char *aad, size_t aad_len, const char *input,
1231     char *output, size_t size, char *tag, int enc, int *cridp)
1232 {
1233 	struct session2_op sop;
1234 	struct crypt_aead caead;
1235 	int fd;
1236 	bool rv;
1237 
1238 	memset(&sop, 0, sizeof(sop));
1239 	memset(&caead, 0, sizeof(caead));
1240 	sop.crid = crid;
1241 	sop.keylen = key_len;
1242 	sop.key = (char *)key;
1243 	sop.cipher = alg->cipher;
1244 	sop.mackeylen = key_len;
1245 	sop.mackey = (char *)key;
1246 	sop.mac = alg->mac;
1247 	fd = crget();
1248 	if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
1249 		warn("cryptodev %s not supported for device %s",
1250 		    alg->name, crfind(crid));
1251 		close(fd);
1252 		return (false);
1253 	}
1254 
1255 	caead.ses = sop.ses;
1256 	caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
1257 	caead.len = size;
1258 	caead.aadlen = aad_len;
1259 	caead.ivlen = iv_len;
1260 	caead.src = (char *)input;
1261 	caead.dst = output;
1262 	caead.aad = (char *)aad;
1263 	caead.tag = tag;
1264 	caead.iv = (char *)iv;
1265 
1266 	if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
1267 		warn("cryptodev %s (%zu) failed for device %s",
1268 		    alg->name, size, crfind(crid));
1269 		rv = false;
1270 	} else
1271 		rv = true;
1272 
1273 	if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
1274 		warn("ioctl(CIOCFSESSION)");
1275 
1276 	close(fd);
1277 	*cridp = sop.crid;
1278 	return (rv);
1279 }
1280 
1281 static void
1282 run_ccm_test(struct alg *alg, size_t size)
1283 {
1284 	const EVP_CIPHER *cipher;
1285 	char *aad, *buffer, *cleartext, *ciphertext;
1286 	char *iv, *key;
1287 	u_int iv_len, key_len;
1288 	int crid;
1289 	char control_tag[AES_CBC_MAC_HASH_LEN], test_tag[AES_CBC_MAC_HASH_LEN];
1290 
1291 	cipher = alg->evp_cipher();
1292 	if (size % EVP_CIPHER_block_size(cipher) != 0) {
1293 		if (verbose)
1294 			printf(
1295 			    "%s (%zu): invalid buffer size (block size %d)\n",
1296 			    alg->name, size, EVP_CIPHER_block_size(cipher));
1297 		return;
1298 	}
1299 
1300 	memset(control_tag, 0x3c, sizeof(control_tag));
1301 	memset(test_tag, 0x3c, sizeof(test_tag));
1302 
1303 	/*
1304 	 * We only have one algorithm constant for CBC-MAC; however, the
1305 	 * alg structure uses the different openssl types, which gives us
1306 	 * the key length.  We need that for the OCF code.
1307 	 */
1308 	key_len = EVP_CIPHER_key_length(cipher);
1309 
1310 	/*
1311 	 * AES-CCM can have varying IV lengths; however, for the moment
1312 	 * we only support AES_CCM_IV_LEN (12).  So if the sizes are
1313 	 * different, we'll fail.
1314 	 */
1315 	iv_len = EVP_CIPHER_iv_length(cipher);
1316 	if (iv_len != AES_CCM_IV_LEN) {
1317 		if (verbose)
1318 			printf("OpenSSL CCM IV length (%d) != AES_CCM_IV_LEN",
1319 			    iv_len);
1320 		return;
1321 	}
1322 
1323 	key = alloc_buffer(key_len);
1324 	iv = generate_iv(iv_len, alg);
1325 	cleartext = alloc_buffer(size);
1326 	buffer = malloc(size);
1327 	ciphertext = malloc(size);
1328 	if (aad_len != 0)
1329 		aad = alloc_buffer(aad_len);
1330 	else
1331 		aad = NULL;
1332 
1333 	/* OpenSSL encrypt */
1334 	openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad, aad_len, cleartext,
1335 	    ciphertext, size, control_tag);
1336 
1337 	/* OCF encrypt */
1338 	if (!ocf_ccm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext,
1339 	    buffer, size, test_tag, 1, &crid))
1340 		goto out;
1341 	if (memcmp(ciphertext, buffer, size) != 0) {
1342 		printf("%s (%zu) encryption mismatch:\n", alg->name, size);
1343 		printf("control:\n");
1344 		hexdump(ciphertext, size, NULL, 0);
1345 		printf("test (cryptodev device %s):\n", crfind(crid));
1346 		hexdump(buffer, size, NULL, 0);
1347 		goto out;
1348 	}
1349 	if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1350 		printf("%s (%zu) enc tag mismatch:\n", alg->name, size);
1351 		printf("control:\n");
1352 		hexdump(control_tag, sizeof(control_tag), NULL, 0);
1353 		printf("test (cryptodev device %s):\n", crfind(crid));
1354 		hexdump(test_tag, sizeof(test_tag), NULL, 0);
1355 		goto out;
1356 	}
1357 
1358 	/* OCF decrypt */
1359 	if (!ocf_ccm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext,
1360 	    buffer, size, control_tag, 0, &crid))
1361 		goto out;
1362 	if (memcmp(cleartext, buffer, size) != 0) {
1363 		printf("%s (%zu) decryption mismatch:\n", alg->name, size);
1364 		printf("control:\n");
1365 		hexdump(cleartext, size, NULL, 0);
1366 		printf("test (cryptodev device %s):\n", crfind(crid));
1367 		hexdump(buffer, size, NULL, 0);
1368 		goto out;
1369 	}
1370 
1371 	if (verbose)
1372 		printf("%s (%zu) matched (cryptodev device %s)\n",
1373 		    alg->name, size, crfind(crid));
1374 
1375 out:
1376 	free(aad);
1377 	free(ciphertext);
1378 	free(buffer);
1379 	free(cleartext);
1380 	free(iv);
1381 	free(key);
1382 }
1383 
1384 static void
1385 run_test(struct alg *alg, size_t size)
1386 {
1387 
1388 	switch (alg->type) {
1389 	case T_HASH:
1390 		run_hash_test(alg, size);
1391 		break;
1392 	case T_HMAC:
1393 		run_hmac_test(alg, size);
1394 		break;
1395 	case T_BLKCIPHER:
1396 		run_blkcipher_test(alg, size);
1397 		break;
1398 	case T_AUTHENC:
1399 		run_authenc_test(alg, size);
1400 		break;
1401 	case T_GCM:
1402 		run_gcm_test(alg, size);
1403 		break;
1404 	case T_CCM:
1405 		run_ccm_test(alg, size);
1406 		break;
1407 	}
1408 }
1409 
1410 static void
1411 run_test_sizes(struct alg *alg, size_t *sizes, u_int nsizes)
1412 {
1413 	u_int i;
1414 
1415 	for (i = 0; i < nsizes; i++)
1416 		run_test(alg, sizes[i]);
1417 }
1418 
1419 static void
1420 run_hash_tests(size_t *sizes, u_int nsizes)
1421 {
1422 	u_int i;
1423 
1424 	for (i = 0; i < nitems(algs); i++)
1425 		if (algs[i].type == T_HASH)
1426 			run_test_sizes(&algs[i], sizes, nsizes);
1427 }
1428 
1429 static void
1430 run_hmac_tests(size_t *sizes, u_int nsizes)
1431 {
1432 	u_int i;
1433 
1434 	for (i = 0; i < nitems(algs); i++)
1435 		if (algs[i].type == T_HMAC)
1436 			run_test_sizes(&algs[i], sizes, nsizes);
1437 }
1438 
1439 static void
1440 run_blkcipher_tests(size_t *sizes, u_int nsizes)
1441 {
1442 	u_int i;
1443 
1444 	for (i = 0; i < nitems(algs); i++)
1445 		if (algs[i].type == T_BLKCIPHER)
1446 			run_test_sizes(&algs[i], sizes, nsizes);
1447 }
1448 
1449 static void
1450 run_authenc_tests(size_t *sizes, u_int nsizes)
1451 {
1452 	struct alg *authenc, *cipher, *hmac;
1453 	u_int i, j;
1454 
1455 	for (i = 0; i < nitems(algs); i++) {
1456 		cipher = &algs[i];
1457 		if (cipher->type != T_BLKCIPHER)
1458 			continue;
1459 		for (j = 0; j < nitems(algs); j++) {
1460 			hmac = &algs[j];
1461 			if (hmac->type != T_HMAC)
1462 				continue;
1463 			authenc = build_authenc(cipher, hmac);
1464 			run_test_sizes(authenc, sizes, nsizes);
1465 			free((char *)authenc->name);
1466 		}
1467 	}
1468 }
1469 
1470 static void
1471 run_aead_tests(size_t *sizes, u_int nsizes)
1472 {
1473 	u_int i;
1474 
1475 	for (i = 0; i < nitems(algs); i++)
1476 		if (algs[i].type == T_GCM ||
1477 		    algs[i].type == T_CCM)
1478 			run_test_sizes(&algs[i], sizes, nsizes);
1479 }
1480 
1481 int
1482 main(int ac, char **av)
1483 {
1484 	const char *algname;
1485 	struct alg *alg;
1486 	size_t sizes[128];
1487 	u_int i, nsizes;
1488 	bool testall;
1489 	int ch;
1490 
1491 	algname = NULL;
1492 	crid = CRYPTO_FLAG_HARDWARE;
1493 	testall = false;
1494 	verbose = false;
1495 	while ((ch = getopt(ac, av, "A:a:d:vz")) != -1)
1496 		switch (ch) {
1497 		case 'A':
1498 			aad_len = atoi(optarg);
1499 			break;
1500 		case 'a':
1501 			algname = optarg;
1502 			break;
1503 		case 'd':
1504 			crid = crlookup(optarg);
1505 			break;
1506 		case 'v':
1507 			verbose = true;
1508 			break;
1509 		case 'z':
1510 			testall = true;
1511 			break;
1512 		default:
1513 			usage();
1514 		}
1515 	ac -= optind;
1516 	av += optind;
1517 	nsizes = 0;
1518 	while (ac > 0) {
1519 		char *cp;
1520 
1521 		if (nsizes >= nitems(sizes)) {
1522 			warnx("Too many sizes, ignoring extras");
1523 			break;
1524 		}
1525 		sizes[nsizes] = strtol(av[0], &cp, 0);
1526 		if (*cp != '\0')
1527 			errx(1, "Bad size %s", av[0]);
1528 		nsizes++;
1529 		ac--;
1530 		av++;
1531 	}
1532 
1533 	if (algname == NULL)
1534 		errx(1, "Algorithm required");
1535 	if (nsizes == 0) {
1536 		sizes[0] = 16;
1537 		nsizes++;
1538 		if (testall) {
1539 			while (sizes[nsizes - 1] * 2 < 240 * 1024) {
1540 				assert(nsizes < nitems(sizes));
1541 				sizes[nsizes] = sizes[nsizes - 1] * 2;
1542 				nsizes++;
1543 			}
1544 			if (sizes[nsizes - 1] < 240 * 1024) {
1545 				assert(nsizes < nitems(sizes));
1546 				sizes[nsizes] = 240 * 1024;
1547 				nsizes++;
1548 			}
1549 		}
1550 	}
1551 
1552 	if (strcasecmp(algname, "hash") == 0)
1553 		run_hash_tests(sizes, nsizes);
1554 	else if (strcasecmp(algname, "hmac") == 0)
1555 		run_hmac_tests(sizes, nsizes);
1556 	else if (strcasecmp(algname, "blkcipher") == 0)
1557 		run_blkcipher_tests(sizes, nsizes);
1558 	else if (strcasecmp(algname, "authenc") == 0)
1559 		run_authenc_tests(sizes, nsizes);
1560 	else if (strcasecmp(algname, "aead") == 0)
1561 		run_aead_tests(sizes, nsizes);
1562 	else if (strcasecmp(algname, "all") == 0) {
1563 		run_hash_tests(sizes, nsizes);
1564 		run_hmac_tests(sizes, nsizes);
1565 		run_blkcipher_tests(sizes, nsizes);
1566 		run_authenc_tests(sizes, nsizes);
1567 		run_aead_tests(sizes, nsizes);
1568 	} else if (strchr(algname, '+') != NULL) {
1569 		alg = build_authenc_name(algname);
1570 		run_test_sizes(alg, sizes, nsizes);
1571 	} else {
1572 		alg = find_alg(algname);
1573 		if (alg == NULL)
1574 			errx(1, "Invalid algorithm %s", algname);
1575 		run_test_sizes(alg, sizes, nsizes);
1576 	}
1577 
1578 	return (0);
1579 }
1580