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