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