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