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