2 * Copyright (c) 2017 Chelsio Communications, Inc.
4 * Copyright (c) 2021 The FreeBSD Foundation
5 * Written by: John Baldwin <jhb@FreeBSD.org>
7 * Portions of this software were developed by Ararat River
8 * Consulting, LLC under sponsorship of the FreeBSD Foundation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
32 * Copyright (c) 2004 Sam Leffler, Errno Consulting
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
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.
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.
66 * A different tool for checking hardware crypto support. Whereas
67 * cryptotest is focused on simple performance numbers, this tool is
68 * focused on correctness. For each crypto operation, it performs the
69 * operation once in software via OpenSSL and a second time via
70 * OpenCrypto and compares the results.
72 * cryptocheck [-vz] [-A aad length] [-a algorithm] [-d dev] [-I IV length]
77 * -z Run all algorithms on a variety of buffer sizes.
79 * Supported algorithms:
81 * hash Run all hash tests
82 * mac Run all mac tests
83 * cipher Run all cipher tests
84 * eta Run all encrypt-then-authenticate tests
85 * aead Run all authenticated encryption with associated data
89 * ripemd160 160-bit RIPEMD
91 * sha224 224-bit SHA-2
92 * sha256 256-bit SHA-2
93 * sha384 384-bit SHA-2
94 * sha512 512-bit SHA-2
99 * ripemd160hmac 160-bit RIPEMD HMAC
100 * sha1hmac SHA-1 HMAC
101 * sha224hmac 224-bit SHA-2 HMAC
102 * sha256hmac 256-bit SHA-2 HMAC
103 * sha384hmac 384-bit SHA-2 HMAC
104 * sha512hmac 512-bit SHA-2 HMAC
105 * gmac 128/192/256-bit GMAC
106 * gmac128 128-bit GMAC
107 * gmac192 192-bit GMAC
108 * gmac256 256-bit GMAC
112 * aes-cbc 128/192/256-bit AES-CBC
113 * aes-cbc128 128-bit AES-CBC
114 * aes-cbc192 192-bit AES-CBC
115 * aes-cbc256 256-bit AES-CBC
116 * aes-ctr 128/192/256-bit AES-CTR
117 * aes-ctr128 128-bit AES-CTR
118 * aes-ctr192 192-bit AES-CTR
119 * aes-ctr256 256-bit AES-CTR
120 * aes-xts 128/256-bit AES-XTS
121 * aes-xts128 128-bit AES-XTS
122 * aes-xts256 256-bit AES-XTS
123 * camellia-cbc 128/192/256-bit Camellia-CBC
124 * camellia-cbc128 128-bit Camellia-CBC
125 * camellia-cbc192 192-bit Camellia-CBC
126 * camellia-cbc256 256-bit Camellia-CBC
129 * Encrypt then Authenticate:
132 * Authenticated Encryption with Associated Data:
133 * aes-gcm 128/192/256-bit AES-GCM
134 * aes-gcm128 128-bit AES-GCM
135 * aes-gcm192 192-bit AES-GCM
136 * aes-gcm256 256-bit AES-GCM
137 * aes-ccm 128/192/256-bit AES-CCM
138 * aes-ccm128 128-bit AES-CCM
139 * aes-ccm192 192-bit AES-CCM
140 * aes-ccm256 256-bit AES-CCM
141 * chacha20-poly1305 Chacha20 with Poly1305 per RFC 8439
144 #include <sys/param.h>
145 #include <sys/sysctl.h>
155 #include <openssl/err.h>
156 #include <openssl/hmac.h>
158 #include <crypto/cryptodev.h>
166 static const struct alg {
170 enum { T_HASH, T_HMAC, T_GMAC, T_DIGEST, T_CIPHER, T_ETA, T_AEAD } type;
174 const EVP_CIPHER *(*evp_cipher)(void);
175 const EVP_MD *(*evp_md)(void);
178 { .name = "ripemd160", .mac = CRYPTO_RIPEMD160, .type = T_HASH,
179 .evp_md = EVP_ripemd160 },
180 { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH,
181 .evp_md = EVP_sha1 },
182 { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH,
183 .evp_md = EVP_sha224 },
184 { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH,
185 .evp_md = EVP_sha256 },
186 { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH,
187 .evp_md = EVP_sha384 },
188 { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH,
189 .evp_md = EVP_sha512 },
190 { .name = "ripemd160hmac", .mac = CRYPTO_RIPEMD160_HMAC, .type = T_HMAC,
191 .evp_md = EVP_ripemd160 },
192 { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
193 .evp_md = EVP_sha1 },
194 { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
195 .evp_md = EVP_sha224 },
196 { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
197 .evp_md = EVP_sha256 },
198 { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
199 .evp_md = EVP_sha384 },
200 { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
201 .evp_md = EVP_sha512 },
202 { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH,
203 .evp_md = EVP_blake2b512 },
204 { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH,
205 .evp_md = EVP_blake2s256 },
206 { .name = "gmac128", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
207 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_128_gcm },
208 { .name = "gmac192", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
209 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_192_gcm },
210 { .name = "gmac256", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC,
211 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_256_gcm },
212 { .name = "poly1305", .mac = CRYPTO_POLY1305, .type = T_DIGEST,
213 .key_len = POLY1305_KEY_LEN, .pkey = EVP_PKEY_POLY1305 },
214 { .name = "aes-cbc128", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
215 .evp_cipher = EVP_aes_128_cbc },
216 { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
217 .evp_cipher = EVP_aes_192_cbc },
218 { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER,
219 .evp_cipher = EVP_aes_256_cbc },
220 { .name = "aes-ctr128", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
221 .evp_cipher = EVP_aes_128_ctr },
222 { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
223 .evp_cipher = EVP_aes_192_ctr },
224 { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER,
225 .evp_cipher = EVP_aes_256_ctr },
226 { .name = "aes-xts128", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
227 .evp_cipher = EVP_aes_128_xts },
228 { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER,
229 .evp_cipher = EVP_aes_256_xts },
230 { .name = "camellia-cbc128", .cipher = CRYPTO_CAMELLIA_CBC,
231 .type = T_CIPHER, .evp_cipher = EVP_camellia_128_cbc },
232 { .name = "camellia-cbc192", .cipher = CRYPTO_CAMELLIA_CBC,
233 .type = T_CIPHER, .evp_cipher = EVP_camellia_192_cbc },
234 { .name = "camellia-cbc256", .cipher = CRYPTO_CAMELLIA_CBC,
235 .type = T_CIPHER, .evp_cipher = EVP_camellia_256_cbc },
236 { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_CIPHER,
237 .evp_cipher = EVP_chacha20 },
238 { .name = "aes-gcm128", .cipher = CRYPTO_AES_NIST_GCM_16,
239 .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN,
240 .iv_sizes = { AES_GCM_IV_LEN }, .evp_cipher = EVP_aes_128_gcm },
241 { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16,
242 .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN,
243 .iv_sizes = { AES_GCM_IV_LEN }, .evp_cipher = EVP_aes_192_gcm },
244 { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16,
245 .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN,
246 .iv_sizes = { AES_GCM_IV_LEN }, .evp_cipher = EVP_aes_256_gcm },
247 { .name = "aes-ccm128", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
248 .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
249 .evp_cipher = EVP_aes_128_ccm },
250 { .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
251 .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
252 .evp_cipher = EVP_aes_192_ccm },
253 { .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD,
254 .tag_len = AES_CBC_MAC_HASH_LEN, .iv_sizes = { 12, 7, 8, 9, 10, 11, 13 },
255 .evp_cipher = EVP_aes_256_ccm },
256 { .name = "chacha20-poly1305", .cipher = CRYPTO_CHACHA20_POLY1305,
257 .type = T_AEAD, .tag_len = POLY1305_HASH_LEN,
258 .iv_sizes = { CHACHA20_POLY1305_IV_LEN, 8 },
259 .evp_cipher = EVP_chacha20_poly1305 },
262 static bool testall, verbose;
263 static int requested_crid;
264 static size_t aad_sizes[48], sizes[EALG_MAX_BLOCK_LEN * 2];
265 static u_int naad_sizes, nsizes;
266 static u_int iv_size;
272 "usage: cryptocheck [-vz] [-A aad size] [-a algorithm]\n"
273 " [-d dev] [-I IV size] [size ...]\n");
277 static const struct alg *
278 find_alg(const char *name)
282 for (i = 0; i < nitems(algs); i++)
283 if (strcasecmp(algs[i].name, name) == 0)
289 build_eta(const struct alg *cipher, const struct alg *mac)
294 assert(cipher->type == T_CIPHER);
295 assert(mac->type == T_HMAC);
296 eta = calloc(1, sizeof(*eta));
297 asprintf(&name, "%s+%s", cipher->name, mac->name);
299 eta->cipher = cipher->cipher;
302 eta->evp_cipher = cipher->evp_cipher;
303 eta->evp_md = mac->evp_md;
308 free_eta(struct alg *eta)
310 free(__DECONST(char *, eta->name));
315 build_eta_name(const char *name)
317 const struct alg *cipher, *mac;
318 const char *mac_name;
319 char *cp, *cipher_name;
321 cp = strchr(name, '+');
322 cipher_name = strndup(name, cp - name);
324 cipher = find_alg(cipher_name);
326 if (cipher == NULL || cipher->type != T_CIPHER)
327 errx(1, "Invalid cipher %s", cipher_name);
328 mac = find_alg(mac_name);
329 if (mac == NULL || mac->type != T_HMAC)
330 errx(1, "Invalid hmac %s", mac_name);
331 return (build_eta(cipher, mac));
340 fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0);
342 err(1, "/dev/crypto");
348 * Called on exit to change kern.cryptodevallowsoft back to 0
350 #define CRYPT_SOFT_ALLOW "kern.cryptodevallowsoft"
353 reset_user_soft(void)
356 sysctlbyname(CRYPT_SOFT_ALLOW, NULL, NULL, &off, sizeof(off));
360 enable_user_soft(void)
364 size_t cursize = sizeof(curstate);
366 if (sysctlbyname(CRYPT_SOFT_ALLOW, &curstate, &cursize,
367 &on, sizeof(on)) == 0) {
369 atexit(reset_user_soft);
374 crlookup(const char *devname)
376 struct crypt_find_op find;
378 if (strncmp(devname, "soft", 4) == 0) {
380 return CRYPTO_FLAG_SOFTWARE;
384 strlcpy(find.name, devname, sizeof(find.name));
385 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
386 err(1, "ioctl(CIOCFINDDEV)");
393 static struct crypt_find_op find;
395 if (crid == CRYPTO_FLAG_SOFTWARE)
397 else if (crid == CRYPTO_FLAG_HARDWARE)
400 bzero(&find, sizeof(find));
402 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
403 err(1, "ioctl(CIOCFINDDEV): crid %d", crid);
411 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41,
412 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01
414 return 0x20+a[random()%nitems(a)];
418 alloc_buffer(size_t len)
424 for (i = 0; i < len; i++)
430 generate_iv(size_t len, const struct alg *alg)
434 iv = alloc_buffer(len);
435 switch (alg->cipher) {
437 /* Clear the low 32 bits of the IV to hold the counter. */
445 * Clear the low 64-bits to only store a 64-bit block
462 ocf_init_sop(struct session2_op *sop)
464 memset(sop, 0, sizeof(*sop));
465 sop->crid = requested_crid;
469 ocf_init_session(struct session2_op *sop, const char *type, const char *name,
470 struct ocf_session *ses)
475 if (ioctl(fd, CIOCGSESSION2, sop) < 0) {
476 warn("cryptodev %s %s not supported for device %s",
477 type, name, crfind(sop->crid));
483 ses->crid = sop->crid;
488 ocf_destroy_session(struct ocf_session *ses)
493 if (ioctl(ses->fd, CIOCFSESSION, &ses->ses) < 0)
494 warn("ioctl(CIOCFSESSION)");
498 ocf_init_cop(const struct ocf_session *ses, struct crypt_op *cop)
500 memset(cop, 0, sizeof(*cop));
505 ocf_init_caead(const struct ocf_session *ses, struct crypt_aead *caead)
507 memset(caead, 0, sizeof(*caead));
508 caead->ses = ses->ses;
512 ocf_hash(const struct alg *alg, const char *buffer, size_t size, char *digest,
515 struct ocf_session ses;
516 struct session2_op sop;
521 if (!ocf_init_session(&sop, "HASH", alg->name, &ses))
524 ocf_init_cop(&ses, &cop);
530 if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
531 warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
532 size, crfind(ses.crid));
533 ocf_destroy_session(&ses);
538 ocf_destroy_session(&ses);
543 openssl_hash(const struct alg *alg, const EVP_MD *md, const void *buffer,
544 size_t size, void *digest_out, unsigned *digest_sz_out)
552 mdctx = EVP_MD_CTX_create();
556 rc = EVP_DigestInit_ex(mdctx, md, NULL);
560 rc = EVP_DigestUpdate(mdctx, buffer, size);
564 rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out);
568 EVP_MD_CTX_destroy(mdctx);
572 errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs,
573 ERR_error_string(ERR_get_error(), NULL));
577 run_hash_test(const struct alg *alg, size_t size)
583 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
585 memset(control_digest, 0x3c, sizeof(control_digest));
586 memset(test_digest, 0x3c, sizeof(test_digest));
589 assert((size_t)EVP_MD_size(md) <= sizeof(control_digest));
591 buffer = alloc_buffer(size);
594 digest_len = sizeof(control_digest);
595 openssl_hash(alg, md, buffer, size, control_digest, &digest_len);
597 /* cryptodev HASH. */
598 if (!ocf_hash(alg, buffer, size, test_digest, &crid))
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",
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);
614 printf("%s (%zu) matched (cryptodev device %s)\n",
615 alg->name, size, crfind(crid));
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)
625 struct ocf_session ses;
626 struct session2_op sop;
630 sop.mackeylen = key_len;
633 if (!ocf_init_session(&sop, "HMAC", alg->name, &ses))
636 ocf_init_cop(&ses, &cop);
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);
650 ocf_destroy_session(&ses);
655 run_hmac_test(const struct alg *alg, size_t size)
659 u_int key_len, digest_len;
661 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
663 memset(control_digest, 0x3c, sizeof(control_digest));
664 memset(test_digest, 0x3c, sizeof(test_digest));
667 key_len = EVP_MD_size(md);
668 assert((size_t)EVP_MD_size(md) <= sizeof(control_digest));
670 key = alloc_buffer(key_len);
671 buffer = alloc_buffer(size);
674 digest_len = sizeof(control_digest);
675 if (HMAC(md, key, key_len, (u_char *)buffer, size,
676 (u_char *)control_digest, &digest_len) == NULL)
677 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
678 size, ERR_error_string(ERR_get_error(), NULL));
680 /* cryptodev HMAC. */
681 if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid))
683 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
684 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
685 printf("%s (%zu) mismatch in trailer:\n",
688 printf("%s (%zu) mismatch:\n", alg->name, size);
689 printf("control:\n");
690 hexdump(control_digest, sizeof(control_digest), NULL, 0);
691 printf("test (cryptodev device %s):\n", crfind(crid));
692 hexdump(test_digest, sizeof(test_digest), NULL, 0);
697 printf("%s (%zu) matched (cryptodev device %s)\n",
698 alg->name, size, crfind(crid));
706 openssl_cipher(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
707 const char *iv, const char *input, char *output, size_t size, int enc)
712 ctx = EVP_CIPHER_CTX_new();
714 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
715 size, ERR_error_string(ERR_get_error(), NULL));
716 if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
717 (const u_char *)iv, enc) != 1)
718 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
719 size, ERR_error_string(ERR_get_error(), NULL));
720 EVP_CIPHER_CTX_set_padding(ctx, 0);
721 if (EVP_CipherUpdate(ctx, (u_char *)output, &outl,
722 (const u_char *)input, size) != 1)
723 errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name,
724 size, ERR_error_string(ERR_get_error(), NULL));
726 if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
727 errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name,
728 size, ERR_error_string(ERR_get_error(), NULL));
730 if ((size_t)total != size)
731 errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name,
733 EVP_CIPHER_CTX_free(ctx);
737 ocf_init_cipher_session(const struct alg *alg, const char *key, size_t key_len,
738 struct ocf_session *ses)
740 struct session2_op sop;
743 sop.keylen = key_len;
745 sop.cipher = alg->cipher;
746 return (ocf_init_session(&sop, "cipher", alg->name, ses));
750 ocf_cipher(const struct ocf_session *ses, const struct alg *alg, const char *iv,
751 const char *input, char *output, size_t size, int op)
755 ocf_init_cop(ses, &cop);
762 if (ioctl(ses->fd, CIOCCRYPT, &cop) < 0) {
763 warn("cryptodev %s (%zu) cipher failed for device %s",
764 alg->name, size, crfind(ses->crid));
772 run_cipher_test(const struct alg *alg, size_t size)
774 struct ocf_session ses;
775 const EVP_CIPHER *cipher;
776 char *buffer, *cleartext, *ciphertext;
778 u_int iv_len, key_len;
780 cipher = alg->evp_cipher();
781 if (size % EVP_CIPHER_block_size(cipher) != 0) {
784 "%s (%zu): invalid buffer size (block size %d)\n",
785 alg->name, size, EVP_CIPHER_block_size(cipher));
790 * XTS requires at least one full block so that any partial
791 * block at the end has cipher text to steal. Hardcoding the
792 * AES block size isn't ideal, but OpenSSL doesn't have a
793 * notion of a "native" block size.
795 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
796 size < AES_BLOCK_LEN) {
798 printf("%s (%zu): invalid buffer size\n", alg->name,
803 key_len = EVP_CIPHER_key_length(cipher);
804 iv_len = EVP_CIPHER_iv_length(cipher);
806 key = alloc_buffer(key_len);
807 iv = generate_iv(iv_len, alg);
808 cleartext = alloc_buffer(size);
809 buffer = malloc(size);
810 ciphertext = malloc(size);
812 /* OpenSSL cipher. */
813 openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1);
814 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0)
815 warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name,
817 openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0);
818 if (memcmp(cleartext, buffer, size) != 0) {
819 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size);
820 printf("original:\n");
821 hexdump(cleartext, size, NULL, 0);
822 printf("decrypted:\n");
823 hexdump(buffer, size, NULL, 0);
827 if (!ocf_init_cipher_session(alg, key, key_len, &ses))
831 if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT))
833 if (memcmp(ciphertext, buffer, size) != 0) {
834 printf("%s (%zu) encryption mismatch:\n", alg->name, size);
835 printf("control:\n");
836 hexdump(ciphertext, size, NULL, 0);
837 printf("test (cryptodev device %s):\n", crfind(ses.crid));
838 hexdump(buffer, size, NULL, 0);
843 if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT))
845 if (memcmp(cleartext, buffer, size) != 0) {
846 printf("%s (%zu) decryption mismatch:\n", alg->name, size);
847 printf("control:\n");
848 hexdump(cleartext, size, NULL, 0);
849 printf("test (cryptodev device %s):\n", crfind(ses.crid));
850 hexdump(buffer, size, NULL, 0);
855 printf("%s (%zu) matched (cryptodev device %s)\n",
856 alg->name, size, crfind(ses.crid));
859 ocf_destroy_session(&ses);
868 ocf_init_eta_session(const struct alg *alg, const char *cipher_key,
869 size_t cipher_key_len, const char *auth_key, size_t auth_key_len,
870 struct ocf_session *ses)
872 struct session2_op sop;
875 sop.keylen = cipher_key_len;
876 sop.key = cipher_key;
877 sop.cipher = alg->cipher;
878 sop.mackeylen = auth_key_len;
879 sop.mackey = auth_key;
881 return (ocf_init_session(&sop, "ETA", alg->name, ses));
885 ocf_eta(const struct ocf_session *ses, const char *iv, size_t iv_len,
886 const char *aad, size_t aad_len, const char *input, char *output,
887 size_t size, char *digest, int op)
892 struct crypt_aead caead;
894 ocf_init_caead(ses, &caead);
897 caead.aadlen = aad_len;
898 caead.ivlen = iv_len;
905 ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead);
909 ocf_init_cop(ses, &cop);
917 ret = ioctl(ses->fd, CIOCCRYPT, &cop);
926 run_eta_test(const struct alg *alg, size_t aad_len, size_t size)
928 struct ocf_session ses;
929 const EVP_CIPHER *cipher;
931 char *buffer, *cleartext, *ciphertext;
932 char *iv, *auth_key, *cipher_key;
933 u_int iv_len, auth_key_len, cipher_key_len, digest_len;
935 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
937 cipher = alg->evp_cipher();
938 if (size % EVP_CIPHER_block_size(cipher) != 0) {
941 "%s (%zu, %zu): invalid buffer size (block size %d)\n",
942 alg->name, aad_len, size,
943 EVP_CIPHER_block_size(cipher));
947 /* See comment in run_cipher_test. */
948 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
949 size < AES_BLOCK_LEN) {
951 printf("%s (%zu): invalid buffer size\n", alg->name,
956 memset(control_digest, 0x3c, sizeof(control_digest));
957 memset(test_digest, 0x3c, sizeof(test_digest));
961 cipher_key_len = EVP_CIPHER_key_length(cipher);
962 iv_len = EVP_CIPHER_iv_length(cipher);
963 auth_key_len = EVP_MD_size(md);
965 cipher_key = alloc_buffer(cipher_key_len);
966 iv = generate_iv(iv_len, alg);
967 auth_key = alloc_buffer(auth_key_len);
968 cleartext = alloc_buffer(aad_len + size);
969 buffer = malloc(aad_len + size);
970 ciphertext = malloc(aad_len + size);
972 /* OpenSSL encrypt + HMAC. */
974 memcpy(ciphertext, cleartext, aad_len);
975 openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len,
976 ciphertext + aad_len, size, 1);
977 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
979 warnx("OpenSSL %s (%zu, %zu): cipher text unchanged",
980 alg->name, aad_len, size);
981 digest_len = sizeof(control_digest);
982 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
983 aad_len + size, (u_char *)control_digest, &digest_len) == NULL)
984 errx(1, "OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name,
985 aad_len, size, ERR_error_string(ERR_get_error(), NULL));
987 if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key,
991 /* OCF encrypt + HMAC. */
992 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? cleartext : NULL,
993 aad_len, cleartext + aad_len, buffer + aad_len, size, test_digest,
996 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
997 alg->name, aad_len, size, crfind(ses.crid));
1000 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
1001 printf("%s (%zu, %zu) encryption mismatch:\n", alg->name,
1003 printf("control:\n");
1004 hexdump(ciphertext + aad_len, size, NULL, 0);
1005 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1006 hexdump(buffer + aad_len, size, NULL, 0);
1009 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
1010 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
1011 printf("%s (%zu, %zu) enc hash mismatch in trailer:\n",
1012 alg->name, aad_len, size);
1014 printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name,
1016 printf("control:\n");
1017 hexdump(control_digest, sizeof(control_digest), NULL, 0);
1018 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1019 hexdump(test_digest, sizeof(test_digest), NULL, 0);
1023 /* OCF HMAC + decrypt. */
1024 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1025 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1028 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
1029 alg->name, aad_len, size, crfind(ses.crid));
1032 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
1033 printf("%s (%zu, %zu) decryption mismatch:\n", alg->name,
1035 printf("control:\n");
1036 hexdump(cleartext, size, NULL, 0);
1037 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1038 hexdump(buffer, size, NULL, 0);
1042 /* Verify OCF HMAC + decrypt fails with busted MAC. */
1043 test_digest[0] ^= 0x1;
1044 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL,
1045 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest,
1047 if (error != EBADMSG) {
1050 "cryptodev %s (%zu, %zu) corrupt tag failed for device %s",
1051 alg->name, aad_len, size, crfind(ses.crid));
1054 "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s",
1055 alg->name, aad_len, size, crfind(ses.crid));
1060 printf("%s (%zu, %zu) matched (cryptodev device %s)\n",
1061 alg->name, aad_len, size, crfind(ses.crid));
1064 ocf_destroy_session(&ses);
1074 openssl_gmac(const struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1075 const char *iv, const char *input, size_t size, char *tag)
1077 EVP_CIPHER_CTX *ctx;
1080 ctx = EVP_CIPHER_CTX_new();
1082 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1083 size, ERR_error_string(ERR_get_error(), NULL));
1084 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1085 (const u_char *)iv) != 1)
1086 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1087 size, ERR_error_string(ERR_get_error(), NULL));
1088 EVP_CIPHER_CTX_set_padding(ctx, 0);
1089 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)input,
1091 errx(1, "OpenSSL %s (%zu) update failed: %s",
1092 alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1093 if (EVP_EncryptFinal_ex(ctx, NULL, &outl) != 1)
1094 errx(1, "OpenSSL %s (%zu) final failed: %s", alg->name,
1095 size, ERR_error_string(ERR_get_error(), NULL));
1096 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1098 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1099 size, ERR_error_string(ERR_get_error(), NULL));
1100 EVP_CIPHER_CTX_free(ctx);
1104 ocf_mac(const struct alg *alg, const char *input, size_t size, const char *key,
1105 size_t key_len, const char *iv, char *tag, int *cridp)
1107 struct ocf_session ses;
1108 struct session2_op sop;
1109 struct crypt_op cop;
1112 sop.mackeylen = key_len;
1115 if (!ocf_init_session(&sop, "MAC", alg->name, &ses))
1118 ocf_init_cop(&ses, &cop);
1125 if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) {
1126 warn("cryptodev %s (%zu) failed for device %s", alg->name,
1127 size, crfind(ses.crid));
1128 ocf_destroy_session(&ses);
1133 ocf_destroy_session(&ses);
1138 run_gmac_test(const struct alg *alg, size_t size)
1140 const EVP_CIPHER *cipher;
1141 char *iv, *key, *buffer;
1142 u_int iv_len, key_len;
1144 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
1146 cipher = alg->evp_cipher();
1148 memset(control_tag, 0x3c, sizeof(control_tag));
1149 memset(test_tag, 0x3c, sizeof(test_tag));
1151 key_len = EVP_CIPHER_key_length(cipher);
1152 iv_len = EVP_CIPHER_iv_length(cipher);
1154 key = alloc_buffer(key_len);
1155 iv = generate_iv(iv_len, alg);
1156 buffer = alloc_buffer(size);
1159 openssl_gmac(alg, cipher, key, iv, buffer, size, control_tag);
1162 if (!ocf_mac(alg, buffer, size, key, key_len, iv, test_tag, &crid))
1164 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1165 printf("%s (%zu) mismatch:\n", alg->name, size);
1166 printf("control:\n");
1167 hexdump(control_tag, sizeof(control_tag), NULL, 0);
1168 printf("test (cryptodev device %s):\n", crfind(crid));
1169 hexdump(test_tag, sizeof(test_tag), NULL, 0);
1174 printf("%s (%zu) matched (cryptodev device %s)\n",
1175 alg->name, size, crfind(crid));
1184 openssl_digest(const struct alg *alg, const char *key, u_int key_len,
1185 const char *input, size_t size, char *tag, u_int tag_len)
1191 pkey = EVP_PKEY_new_raw_private_key(alg->pkey, NULL, key, key_len);
1193 errx(1, "OpenSSL %s (%zu) pkey new failed: %s", alg->name,
1194 size, ERR_error_string(ERR_get_error(), NULL));
1195 mdctx = EVP_MD_CTX_new();
1197 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1198 size, ERR_error_string(ERR_get_error(), NULL));
1199 if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1)
1200 errx(1, "OpenSSL %s (%zu) digest sign init failed: %s",
1201 alg->name, size, ERR_error_string(ERR_get_error(), NULL));
1202 if (EVP_DigestSignUpdate(mdctx, input, size) != 1)
1203 errx(1, "OpenSSL %s (%zu) digest update failed: %s", alg->name,
1204 size, ERR_error_string(ERR_get_error(), NULL));
1206 if (EVP_DigestSignFinal(mdctx, tag, &len) != 1)
1207 errx(1, "OpenSSL %s (%zu) digest final failed: %s", alg->name,
1208 size, ERR_error_string(ERR_get_error(), NULL));
1209 EVP_MD_CTX_free(mdctx);
1210 EVP_PKEY_free(pkey);
1214 run_digest_test(const struct alg *alg, size_t size)
1219 char control_tag[EVP_MAX_MD_SIZE], test_tag[EVP_MAX_MD_SIZE];
1221 memset(control_tag, 0x3c, sizeof(control_tag));
1222 memset(test_tag, 0x3c, sizeof(test_tag));
1224 key_len = alg->key_len;
1226 key = alloc_buffer(key_len);
1227 buffer = alloc_buffer(size);
1229 /* OpenSSL Poly1305. */
1230 openssl_digest(alg, key, key_len, buffer, size, control_tag,
1231 sizeof(control_tag));
1234 if (!ocf_mac(alg, buffer, size, key, key_len, NULL, test_tag, &crid))
1236 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1237 printf("%s (%zu) mismatch:\n", alg->name, size);
1238 printf("control:\n");
1239 hexdump(control_tag, sizeof(control_tag), NULL, 0);
1240 printf("test (cryptodev device %s):\n", crfind(crid));
1241 hexdump(test_tag, sizeof(test_tag), NULL, 0);
1246 printf("%s (%zu) matched (cryptodev device %s)\n",
1247 alg->name, size, crfind(crid));
1255 openssl_aead_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1256 const char *key, const char *iv, size_t iv_len, const char *aad,
1257 size_t aad_len, const char *input, char *output, size_t size, char *tag)
1259 EVP_CIPHER_CTX *ctx;
1262 ctx = EVP_CIPHER_CTX_new();
1264 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1265 size, ERR_error_string(ERR_get_error(), NULL));
1266 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
1267 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1268 size, ERR_error_string(ERR_get_error(), NULL));
1269 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1)
1270 errx(1, "OpenSSL %s (%zu) setting iv length failed: %s", alg->name,
1271 size, ERR_error_string(ERR_get_error(), NULL));
1272 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1273 (const u_char *)iv) != 1)
1274 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1275 size, ERR_error_string(ERR_get_error(), NULL));
1276 EVP_CIPHER_CTX_set_padding(ctx, 0);
1278 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1280 errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1282 ERR_error_string(ERR_get_error(), NULL));
1284 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1285 (const u_char *)input, size) != 1)
1286 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
1287 size, ERR_error_string(ERR_get_error(), NULL));
1289 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
1290 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
1291 size, ERR_error_string(ERR_get_error(), NULL));
1293 if ((size_t)total != size)
1294 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
1296 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len,
1298 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1299 size, ERR_error_string(ERR_get_error(), NULL));
1300 EVP_CIPHER_CTX_free(ctx);
1305 openssl_aead_decrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1306 const char *key, const char *iv, const char *aad, size_t aad_len,
1307 const char *input, char *output, size_t size, char *tag)
1309 EVP_CIPHER_CTX *ctx;
1313 ctx = EVP_CIPHER_CTX_new();
1315 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1316 size, ERR_error_string(ERR_get_error(), NULL));
1317 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1318 (const u_char *)iv) != 1)
1319 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1320 size, ERR_error_string(ERR_get_error(), NULL));
1321 EVP_CIPHER_CTX_set_padding(ctx, 0);
1323 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1325 errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1327 ERR_error_string(ERR_get_error(), NULL));
1329 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl,
1330 (const u_char *)input, size) != 1)
1331 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name,
1332 size, ERR_error_string(ERR_get_error(), NULL));
1334 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, alg->tag_len,
1336 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1337 size, ERR_error_string(ERR_get_error(), NULL));
1338 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1);
1341 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name,
1343 EVP_CIPHER_CTX_free(ctx);
1349 openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher,
1350 const char *key, const char *iv, size_t iv_len, const char *aad,
1351 size_t aad_len, const char *input, char *output, size_t size, char *tag)
1353 EVP_CIPHER_CTX *ctx;
1356 ctx = EVP_CIPHER_CTX_new();
1358 errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx new failed: %s",
1359 alg->name, iv_len, aad_len, size,
1360 ERR_error_string(ERR_get_error(), NULL));
1361 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
1362 errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1363 alg->name, iv_len, aad_len, size,
1364 ERR_error_string(ERR_get_error(), NULL));
1365 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1)
1367 "OpenSSL %s/%zu (%zu, %zu) setting iv length failed: %s",
1368 alg->name, iv_len, aad_len, size,
1369 ERR_error_string(ERR_get_error(), NULL));
1370 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AES_CBC_MAC_HASH_LEN, NULL) != 1)
1372 "OpenSSL %s/%zu (%zu, %zu) setting tag length failed: %s",
1373 alg->name, iv_len, aad_len, size,
1374 ERR_error_string(ERR_get_error(), NULL));
1375 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key,
1376 (const u_char *)iv) != 1)
1377 errx(1, "OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s",
1378 alg->name, iv_len, aad_len, size,
1379 ERR_error_string(ERR_get_error(), NULL));
1380 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1)
1382 "OpenSSL %s/%zu (%zu, %zu) unable to set data length: %s",
1383 alg->name, iv_len, aad_len, size,
1384 ERR_error_string(ERR_get_error(), NULL));
1387 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1390 "OpenSSL %s/%zu (%zu, %zu) aad update failed: %s",
1391 alg->name, iv_len, aad_len, size,
1392 ERR_error_string(ERR_get_error(), NULL));
1394 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
1395 (const u_char *)input, size) != 1)
1396 errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt update failed: %s",
1397 alg->name, iv_len, aad_len, size,
1398 ERR_error_string(ERR_get_error(), NULL));
1400 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
1401 errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt final failed: %s",
1402 alg->name, iv_len, aad_len, size,
1403 ERR_error_string(ERR_get_error(), NULL));
1405 if ((size_t)total != size)
1406 errx(1, "OpenSSL %s/%zu (%zu, %zu) encrypt size mismatch: %d",
1407 alg->name, iv_len, aad_len, size, total);
1408 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_CBC_MAC_HASH_LEN,
1410 errx(1, "OpenSSL %s/%zu (%zu, %zu) get tag failed: %s",
1411 alg->name, iv_len, aad_len, size,
1412 ERR_error_string(ERR_get_error(), NULL));
1413 EVP_CIPHER_CTX_free(ctx);
1417 ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len,
1418 size_t iv_len, struct ocf_session *ses)
1420 struct session2_op sop;
1423 sop.keylen = key_len;
1425 sop.cipher = alg->cipher;
1427 return (ocf_init_session(&sop, "AEAD", alg->name, ses));
1431 ocf_aead(const struct ocf_session *ses, const char *iv, size_t iv_len,
1432 const char *aad, size_t aad_len, const char *input, char *output,
1433 size_t size, char *tag, int op)
1435 struct crypt_aead caead;
1437 ocf_init_caead(ses, &caead);
1440 caead.aadlen = aad_len;
1441 caead.ivlen = iv_len;
1448 if (ioctl(ses->fd, CIOCCRYPTAEAD, &caead) < 0)
1453 #define AEAD_MAX_TAG_LEN \
1454 MAX(MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN), POLY1305_HASH_LEN)
1457 max_ccm_buffer_length(size_t iv_len)
1459 const u_int L = 15 - iv_len;
1468 return (0xffffffff);
1470 return (0xffffffffff);
1472 return (0xffffffffffff);
1474 return (0xffffffffffffff);
1476 return (0xffffffffffffffff);
1479 return (0xffffffff);
1485 run_aead_test(const struct alg *alg, size_t aad_len, size_t size,
1488 struct ocf_session ses;
1489 const EVP_CIPHER *cipher;
1490 char *aad, *buffer, *cleartext, *ciphertext;
1494 char control_tag[AEAD_MAX_TAG_LEN], test_tag[AEAD_MAX_TAG_LEN];
1496 cipher = alg->evp_cipher();
1497 if (size % EVP_CIPHER_block_size(cipher) != 0) {
1500 "%s/%zu (%zu, %zu): invalid buffer size (block size %d)\n",
1501 alg->name, iv_len, aad_len, size,
1502 EVP_CIPHER_block_size(cipher));
1506 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE &&
1507 size > max_ccm_buffer_length(iv_len)) {
1509 printf("%s/%zu (%zu, %zu): invalid buffer size\n",
1510 alg->name, iv_len, aad_len, size);
1514 memset(control_tag, 0x3c, sizeof(control_tag));
1515 memset(test_tag, 0x3c, sizeof(test_tag));
1517 key_len = EVP_CIPHER_key_length(cipher);
1519 key = alloc_buffer(key_len);
1520 iv = generate_iv(iv_len, alg);
1521 cleartext = alloc_buffer(size);
1522 buffer = malloc(size);
1523 ciphertext = malloc(size);
1525 aad = alloc_buffer(aad_len);
1529 /* OpenSSL encrypt */
1530 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE)
1531 openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad,
1532 aad_len, cleartext, ciphertext, size, control_tag);
1534 openssl_aead_encrypt(alg, cipher, key, iv, iv_len, aad,
1535 aad_len, cleartext, ciphertext, size, control_tag);
1537 if (!ocf_init_aead_session(alg, key, key_len, iv_len, &ses))
1541 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, cleartext, buffer,
1542 size, test_tag, COP_ENCRYPT);
1544 warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1545 alg->name, iv_len, aad_len, size, crfind(ses.crid));
1548 if (memcmp(ciphertext, buffer, size) != 0) {
1549 printf("%s/%zu (%zu, %zu) encryption mismatch:\n", alg->name,
1550 iv_len, aad_len, size);
1551 printf("control:\n");
1552 hexdump(ciphertext, size, NULL, 0);
1553 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1554 hexdump(buffer, size, NULL, 0);
1557 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1558 printf("%s/%zu (%zu, %zu) enc tag mismatch:\n", alg->name,
1559 iv_len, aad_len, size);
1560 printf("control:\n");
1561 hexdump(control_tag, sizeof(control_tag), NULL, 0);
1562 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1563 hexdump(test_tag, sizeof(test_tag), NULL, 0);
1568 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1569 buffer, size, control_tag, COP_DECRYPT);
1571 warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s",
1572 alg->name, iv_len, aad_len, size, crfind(ses.crid));
1575 if (memcmp(cleartext, buffer, size) != 0) {
1576 printf("%s/%zu (%zu, %zu) decryption mismatch:\n", alg->name,
1577 iv_len, aad_len, size);
1578 printf("control:\n");
1579 hexdump(cleartext, size, NULL, 0);
1580 printf("test (cryptodev device %s):\n", crfind(ses.crid));
1581 hexdump(buffer, size, NULL, 0);
1585 /* Verify OCF decrypt fails with busted tag. */
1587 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext,
1588 buffer, size, test_tag, COP_DECRYPT);
1589 if (error != EBADMSG) {
1592 "cryptodev %s/%zu (%zu, %zu) corrupt tag failed for device %s",
1593 alg->name, iv_len, aad_len, size, crfind(ses.crid));
1596 "cryptodev %s/%zu (%zu, %zu) corrupt tag didn't fail for device %s",
1597 alg->name, iv_len, aad_len, size, crfind(ses.crid));
1602 printf("%s/%zu (%zu, %zu) matched (cryptodev device %s)\n",
1603 alg->name, iv_len, aad_len, size, crfind(ses.crid));
1606 ocf_destroy_session(&ses);
1616 run_test(const struct alg *alg, size_t aad_len, size_t size, size_t iv_len)
1619 switch (alg->type) {
1621 run_hash_test(alg, size);
1624 run_hmac_test(alg, size);
1627 run_gmac_test(alg, size);
1630 run_digest_test(alg, size);
1633 run_cipher_test(alg, size);
1636 run_eta_test(alg, aad_len, size);
1639 run_aead_test(alg, aad_len, size, iv_len);
1645 run_test_sizes(const struct alg *alg)
1649 switch (alg->type) {
1651 for (i = 0; i < nsizes; i++)
1652 run_test(alg, 0, sizes[i], 0);
1655 for (i = 0; i < naad_sizes; i++)
1656 for (j = 0; j < nsizes; j++)
1657 run_test(alg, aad_sizes[i], sizes[j], 0);
1660 for (i = 0; i < naad_sizes; i++) {
1661 for (j = 0; j < nsizes; j++) {
1663 run_test(alg, aad_sizes[i], sizes[j],
1666 for (k = 0; alg->iv_sizes[k] != 0; k++)
1667 run_test(alg, aad_sizes[i],
1668 sizes[j], alg->iv_sizes[k]);
1670 run_test(alg, aad_sizes[i], sizes[j],
1679 run_hash_tests(void)
1683 for (i = 0; i < nitems(algs); i++)
1684 if (algs[i].type == T_HASH)
1685 run_test_sizes(&algs[i]);
1693 for (i = 0; i < nitems(algs); i++)
1694 if (algs[i].type == T_HMAC || algs[i].type == T_GMAC ||
1695 algs[i].type == T_DIGEST)
1696 run_test_sizes(&algs[i]);
1700 run_cipher_tests(void)
1704 for (i = 0; i < nitems(algs); i++)
1705 if (algs[i].type == T_CIPHER)
1706 run_test_sizes(&algs[i]);
1712 const struct alg *cipher, *mac;
1716 for (i = 0; i < nitems(algs); i++) {
1718 if (cipher->type != T_CIPHER)
1720 for (j = 0; j < nitems(algs); j++) {
1722 if (mac->type != T_HMAC)
1724 eta = build_eta(cipher, mac);
1725 run_test_sizes(eta);
1732 run_aead_tests(void)
1736 for (i = 0; i < nitems(algs); i++)
1737 if (algs[i].type == T_AEAD)
1738 run_test_sizes(&algs[i]);
1742 run_prefix_tests(const char *prefix)
1747 prefix_len = strlen(prefix);
1748 for (i = 0; i < nitems(algs); i++)
1749 if (strlen(algs[i].name) >= prefix_len &&
1750 memcmp(algs[i].name, prefix, prefix_len) == 0)
1751 run_test_sizes(&algs[i]);
1755 main(int ac, char **av)
1757 const char *algname;
1758 const struct alg *alg;
1766 requested_crid = CRYPTO_FLAG_HARDWARE;
1770 while ((ch = getopt(ac, av, "A:a:d:I:vz")) != -1)
1773 if (naad_sizes >= nitems(aad_sizes)) {
1774 warnx("Too many AAD sizes, ignoring extras");
1777 aad_sizes[naad_sizes] = strtol(optarg, &cp, 0);
1779 errx(1, "Bad AAD size %s", optarg);
1786 requested_crid = crlookup(optarg);
1789 iv_size = strtol(optarg, &cp, 0);
1791 errx(1, "Bad IV size %s", optarg);
1806 if (nsizes >= nitems(sizes)) {
1807 warnx("Too many sizes, ignoring extras");
1810 sizes[nsizes] = strtol(av[0], &cp, 0);
1812 errx(1, "Bad size %s", av[0]);
1818 if (algname == NULL)
1819 errx(1, "Algorithm required");
1821 if (naad_sizes == 0) {
1823 for (i = 0; i <= 32; i++) {
1824 aad_sizes[naad_sizes] = i;
1829 while (base_size * 2 < 512) {
1831 assert(naad_sizes < nitems(aad_sizes));
1832 aad_sizes[naad_sizes] = base_size;
1843 for (i = 1; i <= EALG_MAX_BLOCK_LEN; i++) {
1848 for (i = EALG_MAX_BLOCK_LEN + 8;
1849 i <= EALG_MAX_BLOCK_LEN * 2; i += 8) {
1854 base_size = EALG_MAX_BLOCK_LEN * 2;
1855 while (base_size * 2 < 240 * 1024) {
1857 assert(nsizes < nitems(sizes));
1858 sizes[nsizes] = base_size;
1862 if (sizes[nsizes - 1] < 240 * 1024) {
1863 assert(nsizes < nitems(sizes));
1864 sizes[nsizes] = 240 * 1024;
1873 if (strcasecmp(algname, "hash") == 0)
1875 else if (strcasecmp(algname, "mac") == 0)
1877 else if (strcasecmp(algname, "cipher") == 0)
1879 else if (strcasecmp(algname, "eta") == 0)
1881 else if (strcasecmp(algname, "aead") == 0)
1883 else if (strcasecmp(algname, "gmac") == 0 ||
1884 strcasecmp(algname, "aes-cbc") == 0 ||
1885 strcasecmp(algname, "aes-ctr") == 0 ||
1886 strcasecmp(algname, "aes-xts") == 0 ||
1887 strcasecmp(algname, "camellia-cbc") == 0 ||
1888 strcasecmp(algname, "aes-gcm") == 0 ||
1889 strcasecmp(algname, "aes-ccm") == 0)
1890 run_prefix_tests(algname);
1891 else if (strcasecmp(algname, "all") == 0) {
1897 } else if (strchr(algname, '+') != NULL) {
1898 eta = build_eta_name(algname);
1899 run_test_sizes(eta);
1902 alg = find_alg(algname);
1904 errx(1, "Invalid algorithm %s", algname);
1905 run_test_sizes(alg);