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