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