2 * Copyright (c) 2017 Chelsio Communications, Inc.
4 * Written by: John Baldwin <jhb@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Copyright (c) 2004 Sam Leffler, Errno Consulting
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer,
36 * without modification.
37 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
38 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
39 * redistribution must be conditioned upon including a substantially
40 * similar Disclaimer requirement for further binary redistribution.
41 * 3. Neither the names of the above-listed copyright holders nor the names
42 * of any contributors may be used to endorse or promote products derived
43 * from this software without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
49 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
50 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
51 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
54 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
56 * THE POSSIBILITY OF SUCH DAMAGES.
62 * A different tool for checking hardware crypto support. Whereas
63 * cryptotest is focused on simple performance numbers, this tool is
64 * focused on correctness. For each crypto operation, it performs the
65 * operation once in software via OpenSSL and a second time via
66 * OpenCrypto and compares the results.
68 * cryptocheck [-vz] [-A aad length] [-a algorithm] [-d dev] [size ...]
72 * -z Run all algorithms on a variety of buffer sizes.
74 * Supported algorithms:
76 * hmac Run all hmac tests
77 * blkcipher Run all block cipher tests
78 * authenc Run all authenticated encryption tests
79 * aead Run all authenticated encryption with associated data
84 * sha256 256-bit sha2 hmac
85 * sha384 384-bit sha2 hmac
86 * sha512 512-bit sha2 hmac
91 * aes-cbc 128-bit aes cbc
92 * aes-cbc192 192-bit aes cbc
93 * aes-cbc256 256-bit aes cbc
94 * aes-ctr 128-bit aes ctr
95 * aes-ctr192 192-bit aes ctr
96 * aes-ctr256 256-bit aes ctr
97 * aes-xts 128-bit aes xts
98 * aes-xts256 256-bit aes xts
101 * Authenticated Encryption:
102 * <block cipher>+<hmac>
104 * Authenticated Encryption with Associated Data:
105 * aes-gcm 128-bit aes gcm
106 * aes-gcm192 192-bit aes gcm
107 * aes-gcm256 256-bit aes gcm
110 #include <sys/param.h>
120 #include <openssl/err.h>
121 #include <openssl/hmac.h>
123 #include <crypto/cryptodev.h>
125 /* XXX: Temporary hack */
126 #ifndef COP_F_CIPHER_FIRST
127 #define COP_F_CIPHER_FIRST 0x0001 /* Cipher before MAC. */
134 enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM } type;
135 const EVP_CIPHER *(*evp_cipher)(void);
136 const EVP_MD *(*evp_md)(void);
138 { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH,
139 .evp_md = EVP_sha1 },
140 { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH,
141 .evp_md = EVP_sha224 },
142 { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH,
143 .evp_md = EVP_sha256 },
144 { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH,
145 .evp_md = EVP_sha384 },
146 { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH,
147 .evp_md = EVP_sha512 },
148 { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC,
149 .evp_md = EVP_sha1 },
150 { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC,
151 .evp_md = EVP_sha224 },
152 { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC,
153 .evp_md = EVP_sha256 },
154 { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC,
155 .evp_md = EVP_sha384 },
156 { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC,
157 .evp_md = EVP_sha512 },
158 { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH,
159 .evp_md = EVP_blake2b512 },
160 { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH,
161 .evp_md = EVP_blake2s256 },
162 { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
163 .evp_cipher = EVP_aes_128_cbc },
164 { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
165 .evp_cipher = EVP_aes_192_cbc },
166 { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER,
167 .evp_cipher = EVP_aes_256_cbc },
168 { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
169 .evp_cipher = EVP_aes_128_ctr },
170 { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
171 .evp_cipher = EVP_aes_192_ctr },
172 { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER,
173 .evp_cipher = EVP_aes_256_ctr },
174 { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
175 .evp_cipher = EVP_aes_128_xts },
176 { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER,
177 .evp_cipher = EVP_aes_256_xts },
178 { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_BLKCIPHER,
179 .evp_cipher = EVP_chacha20 },
180 { .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16,
181 .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_GCM,
182 .evp_cipher = EVP_aes_128_gcm },
183 { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16,
184 .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_GCM,
185 .evp_cipher = EVP_aes_192_gcm },
186 { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16,
187 .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_GCM,
188 .evp_cipher = EVP_aes_256_gcm },
193 static size_t aad_len;
199 "usage: cryptocheck [-z] [-a algorithm] [-d dev] [size ...]\n");
204 find_alg(const char *name)
208 for (i = 0; i < nitems(algs); i++)
209 if (strcasecmp(algs[i].name, name) == 0)
215 build_authenc(struct alg *cipher, struct alg *hmac)
217 static struct alg authenc;
220 assert(cipher->type == T_BLKCIPHER);
221 assert(hmac->type == T_HMAC);
222 memset(&authenc, 0, sizeof(authenc));
223 asprintf(&name, "%s+%s", cipher->name, hmac->name);
225 authenc.cipher = cipher->cipher;
226 authenc.mac = hmac->mac;
227 authenc.type = T_AUTHENC;
228 authenc.evp_cipher = cipher->evp_cipher;
229 authenc.evp_md = hmac->evp_md;
234 build_authenc_name(const char *name)
236 struct alg *cipher, *hmac;
237 const char *hmac_name;
238 char *cp, *cipher_name;
240 cp = strchr(name, '+');
241 cipher_name = strndup(name, cp - name);
243 cipher = find_alg(cipher_name);
246 errx(1, "Invalid cipher %s", cipher_name);
247 hmac = find_alg(hmac_name);
249 errx(1, "Invalid hash %s", hmac_name);
250 return (build_authenc(cipher, hmac));
259 fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0);
261 err(1, "/dev/crypto");
267 crlookup(const char *devname)
269 struct crypt_find_op find;
271 if (strncmp(devname, "soft", 4) == 0)
272 return CRYPTO_FLAG_SOFTWARE;
275 strlcpy(find.name, devname, sizeof(find.name));
276 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
277 err(1, "ioctl(CIOCFINDDEV)");
284 static struct crypt_find_op find;
286 if (crid == CRYPTO_FLAG_SOFTWARE)
288 else if (crid == CRYPTO_FLAG_HARDWARE)
291 bzero(&find, sizeof(find));
293 if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1)
294 err(1, "ioctl(CIOCFINDDEV): crid %d", crid);
303 if (ioctl(devcrypto(), CRIOGET, &fd) == -1)
304 err(1, "ioctl(CRIOGET)");
305 if (fcntl(fd, F_SETFD, 1) == -1)
306 err(1, "fcntl(F_SETFD) (crget)");
314 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41,
315 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01
317 return 0x20+a[random()%nitems(a)];
321 alloc_buffer(size_t len)
327 for (i = 0; i < len; i++)
333 generate_iv(size_t len, struct alg *alg)
337 iv = alloc_buffer(len);
338 switch (alg->cipher) {
340 /* Clear the low 32 bits of the IV to hold the counter. */
348 * Clear the low 64-bits to only store a 64-bit block
365 ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest,
368 struct session2_op sop;
372 memset(&sop, 0, sizeof(sop));
373 memset(&cop, 0, sizeof(cop));
377 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
378 warn("cryptodev %s HASH not supported for device %s",
379 alg->name, crfind(crid));
387 cop.src = (char *)buffer;
392 if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
393 warn("cryptodev %s (%zu) HASH failed for device %s", alg->name,
399 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
400 warn("ioctl(CIOCFSESSION)");
408 openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer,
409 size_t size, void *digest_out, unsigned *digest_sz_out)
417 mdctx = EVP_MD_CTX_create();
421 rc = EVP_DigestInit_ex(mdctx, md, NULL);
425 rc = EVP_DigestUpdate(mdctx, buffer, size);
429 rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out);
433 EVP_MD_CTX_destroy(mdctx);
437 errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs,
438 ERR_error_string(ERR_get_error(), NULL));
442 run_hash_test(struct alg *alg, size_t size)
448 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
450 memset(control_digest, 0x3c, sizeof(control_digest));
451 memset(test_digest, 0x3c, sizeof(test_digest));
454 assert(EVP_MD_size(md) <= sizeof(control_digest));
456 buffer = alloc_buffer(size);
459 digest_len = sizeof(control_digest);
460 openssl_hash(alg, md, buffer, size, control_digest, &digest_len);
462 /* cryptodev HASH. */
463 if (!ocf_hash(alg, buffer, size, test_digest, &crid))
465 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
466 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
467 printf("%s (%zu) mismatch in trailer:\n",
470 printf("%s (%zu) mismatch:\n", alg->name, size);
471 printf("control:\n");
472 hexdump(control_digest, sizeof(control_digest), NULL, 0);
473 printf("test (cryptodev device %s):\n", crfind(crid));
474 hexdump(test_digest, sizeof(test_digest), NULL, 0);
479 printf("%s (%zu) matched (cryptodev device %s)\n",
480 alg->name, size, crfind(crid));
487 ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key,
488 size_t key_len, char *digest, int *cridp)
490 struct session2_op sop;
494 memset(&sop, 0, sizeof(sop));
495 memset(&cop, 0, sizeof(cop));
497 sop.mackeylen = key_len;
498 sop.mackey = (char *)key;
501 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
502 warn("cryptodev %s HMAC not supported for device %s",
503 alg->name, crfind(crid));
511 cop.src = (char *)buffer;
516 if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
517 warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name,
523 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
524 warn("ioctl(CIOCFSESSION)");
532 run_hmac_test(struct alg *alg, size_t size)
536 u_int key_len, digest_len;
538 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
540 memset(control_digest, 0x3c, sizeof(control_digest));
541 memset(test_digest, 0x3c, sizeof(test_digest));
544 key_len = EVP_MD_size(md);
545 assert(EVP_MD_size(md) <= sizeof(control_digest));
547 key = alloc_buffer(key_len);
548 buffer = alloc_buffer(size);
551 digest_len = sizeof(control_digest);
552 if (HMAC(md, key, key_len, (u_char *)buffer, size,
553 (u_char *)control_digest, &digest_len) == NULL)
554 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
555 size, ERR_error_string(ERR_get_error(), NULL));
557 /* cryptodev HMAC. */
558 if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid))
560 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
561 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
562 printf("%s (%zu) mismatch in trailer:\n",
565 printf("%s (%zu) mismatch:\n", alg->name, size);
566 printf("control:\n");
567 hexdump(control_digest, sizeof(control_digest), NULL, 0);
568 printf("test (cryptodev device %s):\n", crfind(crid));
569 hexdump(test_digest, sizeof(test_digest), NULL, 0);
574 printf("%s (%zu) matched (cryptodev device %s)\n",
575 alg->name, size, crfind(crid));
583 openssl_cipher(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
584 const char *iv, const char *input, char *output, size_t size, int enc)
589 ctx = EVP_CIPHER_CTX_new();
591 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
592 size, ERR_error_string(ERR_get_error(), NULL));
593 if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key,
594 (const u_char *)iv, enc) != 1)
595 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
596 size, ERR_error_string(ERR_get_error(), NULL));
597 EVP_CIPHER_CTX_set_padding(ctx, 0);
598 if (EVP_CipherUpdate(ctx, (u_char *)output, &outl,
599 (const u_char *)input, size) != 1)
600 errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name,
601 size, ERR_error_string(ERR_get_error(), NULL));
603 if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
604 errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name,
605 size, ERR_error_string(ERR_get_error(), NULL));
608 errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name,
610 EVP_CIPHER_CTX_free(ctx);
614 ocf_cipher(struct alg *alg, const char *key, size_t key_len,
615 const char *iv, const char *input, char *output, size_t size, int enc,
618 struct session2_op sop;
622 memset(&sop, 0, sizeof(sop));
623 memset(&cop, 0, sizeof(cop));
625 sop.keylen = key_len;
626 sop.key = (char *)key;
627 sop.cipher = alg->cipher;
629 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
630 warn("cryptodev %s block cipher not supported for device %s",
631 alg->name, crfind(crid));
637 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
639 cop.src = (char *)input;
644 if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
645 warn("cryptodev %s (%zu) block cipher failed for device %s",
646 alg->name, size, crfind(crid));
651 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
652 warn("ioctl(CIOCFSESSION)");
660 run_blkcipher_test(struct alg *alg, size_t size)
662 const EVP_CIPHER *cipher;
663 char *buffer, *cleartext, *ciphertext;
665 u_int iv_len, key_len;
668 cipher = alg->evp_cipher();
669 if (size % EVP_CIPHER_block_size(cipher) != 0) {
672 "%s (%zu): invalid buffer size (block size %d)\n",
673 alg->name, size, EVP_CIPHER_block_size(cipher));
677 key_len = EVP_CIPHER_key_length(cipher);
678 iv_len = EVP_CIPHER_iv_length(cipher);
680 key = alloc_buffer(key_len);
681 iv = generate_iv(iv_len, alg);
682 cleartext = alloc_buffer(size);
683 buffer = malloc(size);
684 ciphertext = malloc(size);
686 /* OpenSSL cipher. */
687 openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1);
688 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0)
689 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name,
691 openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0);
692 if (memcmp(cleartext, buffer, size) != 0) {
693 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size);
694 printf("original:\n");
695 hexdump(cleartext, size, NULL, 0);
696 printf("decrypted:\n");
697 hexdump(buffer, size, NULL, 0);
702 if (!ocf_cipher(alg, key, key_len, iv, cleartext, buffer, size, 1,
705 if (memcmp(ciphertext, buffer, size) != 0) {
706 printf("%s (%zu) encryption mismatch:\n", alg->name, size);
707 printf("control:\n");
708 hexdump(ciphertext, size, NULL, 0);
709 printf("test (cryptodev device %s):\n", crfind(crid));
710 hexdump(buffer, size, NULL, 0);
715 if (!ocf_cipher(alg, key, key_len, iv, ciphertext, buffer, size, 0,
718 if (memcmp(cleartext, buffer, size) != 0) {
719 printf("%s (%zu) decryption mismatch:\n", alg->name, size);
720 printf("control:\n");
721 hexdump(cleartext, size, NULL, 0);
722 printf("test (cryptodev device %s):\n", crfind(crid));
723 hexdump(buffer, size, NULL, 0);
728 printf("%s (%zu) matched (cryptodev device %s)\n",
729 alg->name, size, crfind(crid));
740 ocf_authenc(struct alg *alg, const char *cipher_key, size_t cipher_key_len,
741 const char *iv, size_t iv_len, const char *auth_key, size_t auth_key_len,
742 const char *aad, size_t aad_len, const char *input, char *output,
743 size_t size, char *digest, int enc, int *cridp)
745 struct session2_op sop;
748 memset(&sop, 0, sizeof(sop));
750 sop.keylen = cipher_key_len;
751 sop.key = (char *)cipher_key;
752 sop.cipher = alg->cipher;
753 sop.mackeylen = auth_key_len;
754 sop.mackey = (char *)auth_key;
757 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
758 warn("cryptodev %s AUTHENC not supported for device %s",
759 alg->name, crfind(crid));
765 struct crypt_aead caead;
767 memset(&caead, 0, sizeof(caead));
769 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
770 caead.flags = enc ? COP_F_CIPHER_FIRST : 0;
772 caead.aadlen = aad_len;
773 caead.ivlen = iv_len;
774 caead.src = (char *)input;
776 caead.aad = (char *)aad;
778 caead.iv = (char *)iv;
780 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
781 warn("cryptodev %s (%zu) failed for device %s",
782 alg->name, size, crfind(crid));
789 memset(&cop, 0, sizeof(cop));
791 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT;
792 cop.flags = enc ? COP_F_CIPHER_FIRST : 0;
794 cop.src = (char *)input;
799 if (ioctl(fd, CIOCCRYPT, &cop) < 0) {
800 warn("cryptodev %s (%zu) AUTHENC failed for device %s",
801 alg->name, size, crfind(crid));
807 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
808 warn("ioctl(CIOCFSESSION)");
816 run_authenc_test(struct alg *alg, size_t size)
818 const EVP_CIPHER *cipher;
820 char *aad, *buffer, *cleartext, *ciphertext;
821 char *iv, *auth_key, *cipher_key;
822 u_int iv_len, auth_key_len, cipher_key_len, digest_len;
824 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE];
826 cipher = alg->evp_cipher();
827 if (size % EVP_CIPHER_block_size(cipher) != 0) {
830 "%s (%zu): invalid buffer size (block size %d)\n",
831 alg->name, size, EVP_CIPHER_block_size(cipher));
835 memset(control_digest, 0x3c, sizeof(control_digest));
836 memset(test_digest, 0x3c, sizeof(test_digest));
840 cipher_key_len = EVP_CIPHER_key_length(cipher);
841 iv_len = EVP_CIPHER_iv_length(cipher);
842 auth_key_len = EVP_MD_size(md);
844 cipher_key = alloc_buffer(cipher_key_len);
845 iv = generate_iv(iv_len, alg);
846 auth_key = alloc_buffer(auth_key_len);
847 cleartext = alloc_buffer(aad_len + size);
848 buffer = malloc(aad_len + size);
849 ciphertext = malloc(aad_len + size);
851 /* OpenSSL encrypt + HMAC. */
853 memcpy(ciphertext, cleartext, aad_len);
854 openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len,
855 ciphertext + aad_len, size, 1);
856 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
858 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name,
860 digest_len = sizeof(control_digest);
861 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
862 aad_len + size, (u_char *)control_digest, &digest_len) == NULL)
863 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name,
864 size, ERR_error_string(ERR_get_error(), NULL));
866 /* OCF encrypt + HMAC. */
867 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
868 auth_key_len, aad_len != 0 ? cleartext : NULL, aad_len,
869 cleartext + aad_len, buffer + aad_len, size, test_digest, 1, &crid))
871 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
872 printf("%s (%zu) encryption mismatch:\n", alg->name, size);
873 printf("control:\n");
874 hexdump(ciphertext + aad_len, size, NULL, 0);
875 printf("test (cryptodev device %s):\n", crfind(crid));
876 hexdump(buffer + aad_len, size, NULL, 0);
879 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
880 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
881 printf("%s (%zu) enc hash mismatch in trailer:\n",
884 printf("%s (%zu) enc hash mismatch:\n", alg->name,
886 printf("control:\n");
887 hexdump(control_digest, sizeof(control_digest), NULL, 0);
888 printf("test (cryptodev device %s):\n", crfind(crid));
889 hexdump(test_digest, sizeof(test_digest), NULL, 0);
893 /* OCF HMAC + decrypt. */
894 memset(test_digest, 0x3c, sizeof(test_digest));
895 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key,
896 auth_key_len, aad_len != 0 ? ciphertext : NULL, aad_len,
897 ciphertext + aad_len, buffer + aad_len, size, test_digest, 0,
900 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
901 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
902 printf("%s (%zu) dec hash mismatch in trailer:\n",
905 printf("%s (%zu) dec hash mismatch:\n", alg->name,
907 printf("control:\n");
908 hexdump(control_digest, sizeof(control_digest), NULL, 0);
909 printf("test (cryptodev device %s):\n", crfind(crid));
910 hexdump(test_digest, sizeof(test_digest), NULL, 0);
913 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
914 printf("%s (%zu) decryption mismatch:\n", alg->name, size);
915 printf("control:\n");
916 hexdump(cleartext, size, NULL, 0);
917 printf("test (cryptodev device %s):\n", crfind(crid));
918 hexdump(buffer, size, NULL, 0);
923 printf("%s (%zu) matched (cryptodev device %s)\n",
924 alg->name, size, crfind(crid));
936 openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
937 const char *iv, const char *aad, size_t aad_len, const char *input,
938 char *output, size_t size, char *tag)
943 ctx = EVP_CIPHER_CTX_new();
945 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
946 size, ERR_error_string(ERR_get_error(), NULL));
947 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
948 (const u_char *)iv) != 1)
949 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
950 size, ERR_error_string(ERR_get_error(), NULL));
951 EVP_CIPHER_CTX_set_padding(ctx, 0);
953 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
955 errx(1, "OpenSSL %s (%zu) aad update failed: %s",
957 ERR_error_string(ERR_get_error(), NULL));
959 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl,
960 (const u_char *)input, size) != 1)
961 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name,
962 size, ERR_error_string(ERR_get_error(), NULL));
964 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1)
965 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name,
966 size, ERR_error_string(ERR_get_error(), NULL));
969 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name,
971 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GMAC_HASH_LEN,
973 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
974 size, ERR_error_string(ERR_get_error(), NULL));
975 EVP_CIPHER_CTX_free(ctx);
979 ocf_gcm(struct alg *alg, const char *key, size_t key_len, const char *iv,
980 size_t iv_len, const char *aad, size_t aad_len, const char *input,
981 char *output, size_t size, char *tag, int enc, int *cridp)
983 struct session2_op sop;
984 struct crypt_aead caead;
987 memset(&sop, 0, sizeof(sop));
988 memset(&caead, 0, sizeof(caead));
990 sop.keylen = key_len;
991 sop.key = (char *)key;
992 sop.cipher = alg->cipher;
993 sop.mackeylen = key_len;
994 sop.mackey = (char *)key;
997 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) {
998 warn("cryptodev %s not supported for device %s",
999 alg->name, crfind(crid));
1004 caead.ses = sop.ses;
1005 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT;
1007 caead.aadlen = aad_len;
1008 caead.ivlen = iv_len;
1009 caead.src = (char *)input;
1011 caead.aad = (char *)aad;
1013 caead.iv = (char *)iv;
1015 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) {
1016 warn("cryptodev %s (%zu) failed for device %s",
1017 alg->name, size, crfind(crid));
1022 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0)
1023 warn("ioctl(CIOCFSESSION)");
1032 openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key,
1033 const char *iv, const char *aad, size_t aad_len, const char *input,
1034 char *output, size_t size, char *tag)
1036 EVP_CIPHER_CTX *ctx;
1040 ctx = EVP_CIPHER_CTX_new();
1042 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name,
1043 size, ERR_error_string(ERR_get_error(), NULL));
1044 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key,
1045 (const u_char *)iv) != 1)
1046 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name,
1047 size, ERR_error_string(ERR_get_error(), NULL));
1048 EVP_CIPHER_CTX_set_padding(ctx, 0);
1050 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad,
1052 errx(1, "OpenSSL %s (%zu) aad update failed: %s",
1054 ERR_error_string(ERR_get_error(), NULL));
1056 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl,
1057 (const u_char *)input, size) != 1)
1058 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name,
1059 size, ERR_error_string(ERR_get_error(), NULL));
1061 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GMAC_HASH_LEN,
1063 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name,
1064 size, ERR_error_string(ERR_get_error(), NULL));
1065 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1);
1068 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name,
1070 EVP_CIPHER_CTX_free(ctx);
1076 run_gcm_test(struct alg *alg, size_t size)
1078 const EVP_CIPHER *cipher;
1079 char *aad, *buffer, *cleartext, *ciphertext;
1081 u_int iv_len, key_len;
1083 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN];
1085 cipher = alg->evp_cipher();
1086 if (size % EVP_CIPHER_block_size(cipher) != 0) {
1089 "%s (%zu): invalid buffer size (block size %d)\n",
1090 alg->name, size, EVP_CIPHER_block_size(cipher));
1094 memset(control_tag, 0x3c, sizeof(control_tag));
1095 memset(test_tag, 0x3c, sizeof(test_tag));
1097 key_len = EVP_CIPHER_key_length(cipher);
1098 iv_len = EVP_CIPHER_iv_length(cipher);
1100 key = alloc_buffer(key_len);
1101 iv = generate_iv(iv_len, alg);
1102 cleartext = alloc_buffer(size);
1103 buffer = malloc(size);
1104 ciphertext = malloc(size);
1106 aad = alloc_buffer(aad_len);
1110 /* OpenSSL encrypt */
1111 openssl_gcm_encrypt(alg, cipher, key, iv, aad, aad_len, cleartext,
1112 ciphertext, size, control_tag);
1115 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext,
1116 buffer, size, test_tag, 1, &crid))
1118 if (memcmp(ciphertext, buffer, size) != 0) {
1119 printf("%s (%zu) encryption mismatch:\n", alg->name, size);
1120 printf("control:\n");
1121 hexdump(ciphertext, size, NULL, 0);
1122 printf("test (cryptodev device %s):\n", crfind(crid));
1123 hexdump(buffer, size, NULL, 0);
1126 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
1127 printf("%s (%zu) enc tag mismatch:\n", alg->name, size);
1128 printf("control:\n");
1129 hexdump(control_tag, sizeof(control_tag), NULL, 0);
1130 printf("test (cryptodev device %s):\n", crfind(crid));
1131 hexdump(test_tag, sizeof(test_tag), NULL, 0);
1136 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext,
1137 buffer, size, control_tag, 0, &crid))
1139 if (memcmp(cleartext, buffer, size) != 0) {
1140 printf("%s (%zu) decryption mismatch:\n", alg->name, size);
1141 printf("control:\n");
1142 hexdump(cleartext, size, NULL, 0);
1143 printf("test (cryptodev device %s):\n", crfind(crid));
1144 hexdump(buffer, size, NULL, 0);
1149 printf("%s (%zu) matched (cryptodev device %s)\n",
1150 alg->name, size, crfind(crid));
1162 run_test(struct alg *alg, size_t size)
1165 switch (alg->type) {
1167 run_hash_test(alg, size);
1170 run_hmac_test(alg, size);
1173 run_blkcipher_test(alg, size);
1176 run_authenc_test(alg, size);
1179 run_gcm_test(alg, size);
1185 run_test_sizes(struct alg *alg, size_t *sizes, u_int nsizes)
1189 for (i = 0; i < nsizes; i++)
1190 run_test(alg, sizes[i]);
1194 run_hash_tests(size_t *sizes, u_int nsizes)
1198 for (i = 0; i < nitems(algs); i++)
1199 if (algs[i].type == T_HASH)
1200 run_test_sizes(&algs[i], sizes, nsizes);
1204 run_hmac_tests(size_t *sizes, u_int nsizes)
1208 for (i = 0; i < nitems(algs); i++)
1209 if (algs[i].type == T_HMAC)
1210 run_test_sizes(&algs[i], sizes, nsizes);
1214 run_blkcipher_tests(size_t *sizes, u_int nsizes)
1218 for (i = 0; i < nitems(algs); i++)
1219 if (algs[i].type == T_BLKCIPHER)
1220 run_test_sizes(&algs[i], sizes, nsizes);
1224 run_authenc_tests(size_t *sizes, u_int nsizes)
1226 struct alg *authenc, *cipher, *hmac;
1229 for (i = 0; i < nitems(algs); i++) {
1231 if (cipher->type != T_BLKCIPHER)
1233 for (j = 0; j < nitems(algs); j++) {
1235 if (hmac->type != T_HMAC)
1237 authenc = build_authenc(cipher, hmac);
1238 run_test_sizes(authenc, sizes, nsizes);
1239 free((char *)authenc->name);
1245 run_aead_tests(size_t *sizes, u_int nsizes)
1249 for (i = 0; i < nitems(algs); i++)
1250 if (algs[i].type == T_GCM)
1251 run_test_sizes(&algs[i], sizes, nsizes);
1255 main(int ac, char **av)
1257 const char *algname;
1265 crid = CRYPTO_FLAG_HARDWARE;
1268 while ((ch = getopt(ac, av, "A:a:d:vz")) != -1)
1271 aad_len = atoi(optarg);
1277 crid = crlookup(optarg);
1294 if (nsizes >= nitems(sizes)) {
1295 warnx("Too many sizes, ignoring extras");
1298 sizes[nsizes] = strtol(av[0], &cp, 0);
1300 errx(1, "Bad size %s", av[0]);
1306 if (algname == NULL)
1307 errx(1, "Algorithm required");
1312 while (sizes[nsizes - 1] * 2 < 240 * 1024) {
1313 assert(nsizes < nitems(sizes));
1314 sizes[nsizes] = sizes[nsizes - 1] * 2;
1317 if (sizes[nsizes - 1] < 240 * 1024) {
1318 assert(nsizes < nitems(sizes));
1319 sizes[nsizes] = 240 * 1024;
1325 if (strcasecmp(algname, "hash") == 0)
1326 run_hash_tests(sizes, nsizes);
1327 else if (strcasecmp(algname, "hmac") == 0)
1328 run_hmac_tests(sizes, nsizes);
1329 else if (strcasecmp(algname, "blkcipher") == 0)
1330 run_blkcipher_tests(sizes, nsizes);
1331 else if (strcasecmp(algname, "authenc") == 0)
1332 run_authenc_tests(sizes, nsizes);
1333 else if (strcasecmp(algname, "aead") == 0)
1334 run_aead_tests(sizes, nsizes);
1335 else if (strcasecmp(algname, "all") == 0) {
1336 run_hash_tests(sizes, nsizes);
1337 run_hmac_tests(sizes, nsizes);
1338 run_blkcipher_tests(sizes, nsizes);
1339 run_authenc_tests(sizes, nsizes);
1340 run_aead_tests(sizes, nsizes);
1341 } else if (strchr(algname, '+') != NULL) {
1342 alg = build_authenc_name(algname);
1343 run_test_sizes(alg, sizes, nsizes);
1345 alg = find_alg(algname);
1347 errx(1, "Invalid algorithm %s", algname);
1348 run_test_sizes(alg, sizes, nsizes);