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