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