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