1/*- 2 * Copyright (c) 2017 Chelsio Communications, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 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. 14 * 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 25 * SUCH DAMAGE. 26 */ 27/*- 28 * Copyright (c) 2004 Sam Leffler, Errno Consulting 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 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. 44 * 45 * NO WARRANTY 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. 57 * 58 * $FreeBSD$ 59 */ 60 61/* 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. 67 * 68 * cryptocheck [-vz] [-A aad length] [-a algorithm] [-d dev] [size ...] 69 * 70 * Options: 71 * -v Verbose. 72 * -z Run all algorithms on a variety of buffer sizes. 73 * 74 * Supported algorithms: 75 * all Run all tests 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 80 * tests 81 * 82 * HMACs: 83 * sha1 sha1 hmac 84 * sha256 256-bit sha2 hmac 85 * sha384 384-bit sha2 hmac 86 * sha512 512-bit sha2 hmac 87 * blake2b Blake2-B 88 * blake2s Blake2-S 89 * 90 * Block Ciphers: 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 99 * chacha20 100 * 101 * Authenticated Encryption: 102 * <block cipher>+<hmac> 103 * 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 108 * aes-ccm 128-bit aes ccm 109 * aes-ccm192 192-bit aes ccm 110 * aes-ccm256 256-bit aes ccm 111 */ 112 113#include <sys/param.h> 114#include <assert.h> 115#include <err.h> 116#include <fcntl.h> 117#include <libutil.h> 118#include <stdbool.h> 119#include <stdio.h> 120#include <string.h> 121#include <unistd.h> 122 123#include <openssl/err.h> 124#include <openssl/hmac.h> 125 126#include <crypto/cryptodev.h> 127 128/* XXX: Temporary hack */ 129#ifndef COP_F_CIPHER_FIRST 130#define COP_F_CIPHER_FIRST 0x0001 /* Cipher before MAC. */ 131#endif 132 133struct alg { 134 const char *name; 135 int cipher; 136 int mac; 137 enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM, T_CCM } type; 138 const EVP_CIPHER *(*evp_cipher)(void); 139 const EVP_MD *(*evp_md)(void); 140} algs[] = { 141 { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH, 142 .evp_md = EVP_sha1 }, 143 { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH, 144 .evp_md = EVP_sha224 }, 145 { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH, 146 .evp_md = EVP_sha256 }, 147 { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH, 148 .evp_md = EVP_sha384 }, 149 { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH, 150 .evp_md = EVP_sha512 }, 151 { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC, 152 .evp_md = EVP_sha1 }, 153 { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC, 154 .evp_md = EVP_sha224 }, 155 { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC, 156 .evp_md = EVP_sha256 }, 157 { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC, 158 .evp_md = EVP_sha384 }, 159 { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC, 160 .evp_md = EVP_sha512 }, 161 { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH, 162 .evp_md = EVP_blake2b512 }, 163 { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH, 164 .evp_md = EVP_blake2s256 }, 165 { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 166 .evp_cipher = EVP_aes_128_cbc }, 167 { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 168 .evp_cipher = EVP_aes_192_cbc }, 169 { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 170 .evp_cipher = EVP_aes_256_cbc }, 171 { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 172 .evp_cipher = EVP_aes_128_ctr }, 173 { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 174 .evp_cipher = EVP_aes_192_ctr }, 175 { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 176 .evp_cipher = EVP_aes_256_ctr }, 177 { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER, 178 .evp_cipher = EVP_aes_128_xts }, 179 { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER, 180 .evp_cipher = EVP_aes_256_xts }, 181 { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_BLKCIPHER, 182 .evp_cipher = EVP_chacha20 }, 183 { .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16, 184 .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_GCM, 185 .evp_cipher = EVP_aes_128_gcm }, 186 { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16, 187 .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_GCM, 188 .evp_cipher = EVP_aes_192_gcm }, 189 { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16, 190 .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_GCM, 191 .evp_cipher = EVP_aes_256_gcm }, 192 { .name = "aes-ccm", .cipher = CRYPTO_AES_CCM_16, 193 .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM, 194 .evp_cipher = EVP_aes_128_ccm }, 195 { .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16, 196 .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM, 197 .evp_cipher = EVP_aes_192_ccm }, 198 { .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16, 199 .mac = CRYPTO_AES_CCM_CBC_MAC, .type = T_CCM, 200 .evp_cipher = EVP_aes_256_ccm }, 201}; 202 203static bool verbose; 204static int crid; 205static size_t aad_len; 206 207static void 208usage(void) 209{ 210 fprintf(stderr, 211 "usage: cryptocheck [-z] [-a algorithm] [-d dev] [size ...]\n"); 212 exit(1); 213} 214 215static struct alg * 216find_alg(const char *name) 217{ 218 u_int i; 219 220 for (i = 0; i < nitems(algs); i++) 221 if (strcasecmp(algs[i].name, name) == 0) 222 return (&algs[i]); 223 return (NULL); 224} 225 226static struct alg * 227build_authenc(struct alg *cipher, struct alg *hmac) 228{ 229 static struct alg authenc; 230 char *name; 231 232 assert(cipher->type == T_BLKCIPHER); 233 assert(hmac->type == T_HMAC); 234 memset(&authenc, 0, sizeof(authenc)); 235 asprintf(&name, "%s+%s", cipher->name, hmac->name); 236 authenc.name = name; 237 authenc.cipher = cipher->cipher; 238 authenc.mac = hmac->mac; 239 authenc.type = T_AUTHENC; 240 authenc.evp_cipher = cipher->evp_cipher; 241 authenc.evp_md = hmac->evp_md; 242 return (&authenc); 243} 244 245static struct alg * 246build_authenc_name(const char *name) 247{ 248 struct alg *cipher, *hmac; 249 const char *hmac_name; 250 char *cp, *cipher_name; 251 252 cp = strchr(name, '+'); 253 cipher_name = strndup(name, cp - name); 254 hmac_name = cp + 1; 255 cipher = find_alg(cipher_name); 256 free(cipher_name); 257 if (cipher == NULL) 258 errx(1, "Invalid cipher %s", cipher_name); 259 hmac = find_alg(hmac_name); 260 if (hmac == NULL) 261 errx(1, "Invalid hash %s", hmac_name); 262 return (build_authenc(cipher, hmac)); 263} 264 265static int 266devcrypto(void) 267{ 268 static int fd = -1; 269 270 if (fd < 0) { 271 fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0); 272 if (fd < 0) 273 err(1, "/dev/crypto"); 274 } 275 return (fd); 276} 277 278static int 279crlookup(const char *devname) 280{ 281 struct crypt_find_op find; 282 283 if (strncmp(devname, "soft", 4) == 0) 284 return CRYPTO_FLAG_SOFTWARE; 285 286 find.crid = -1; 287 strlcpy(find.name, devname, sizeof(find.name)); 288 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) 289 err(1, "ioctl(CIOCFINDDEV)"); 290 return (find.crid); 291} 292 293const char * 294crfind(int crid) 295{ 296 static struct crypt_find_op find; 297 298 if (crid == CRYPTO_FLAG_SOFTWARE) 299 return ("soft"); 300 else if (crid == CRYPTO_FLAG_HARDWARE) 301 return ("unknown"); 302 303 bzero(&find, sizeof(find)); 304 find.crid = crid; 305 if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1) 306 err(1, "ioctl(CIOCFINDDEV): crid %d", crid); 307 return (find.name); 308} 309 310static int 311crget(void) 312{ 313 int fd; 314 315 if (ioctl(devcrypto(), CRIOGET, &fd) == -1) 316 err(1, "ioctl(CRIOGET)"); 317 if (fcntl(fd, F_SETFD, 1) == -1) 318 err(1, "fcntl(F_SETFD) (crget)"); 319 return fd; 320} 321 322static char 323rdigit(void) 324{ 325 const char a[] = { 326 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41, 327 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01 328 }; 329 return 0x20+a[random()%nitems(a)]; 330} 331 332static char * 333alloc_buffer(size_t len) 334{ 335 char *buf; 336 size_t i; 337 338 buf = malloc(len); 339 for (i = 0; i < len; i++) 340 buf[i] = rdigit(); 341 return (buf); 342} 343 344static char * 345generate_iv(size_t len, struct alg *alg) 346{ 347 char *iv; 348 349 iv = alloc_buffer(len); 350 switch (alg->cipher) { 351 case CRYPTO_AES_ICM: 352 /* Clear the low 32 bits of the IV to hold the counter. */ 353 iv[len - 4] = 0; 354 iv[len - 3] = 0; 355 iv[len - 2] = 0; 356 iv[len - 1] = 0; 357 break; 358 case CRYPTO_AES_XTS: 359 /* 360 * Clear the low 64-bits to only store a 64-bit block 361 * number. 362 */ 363 iv[len - 8] = 0; 364 iv[len - 7] = 0; 365 iv[len - 6] = 0; 366 iv[len - 5] = 0; 367 iv[len - 4] = 0; 368 iv[len - 3] = 0; 369 iv[len - 2] = 0; 370 iv[len - 1] = 0; 371 break; 372 } 373 return (iv); 374} 375 376static bool 377ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest, 378 int *cridp) 379{ 380 struct session2_op sop; 381 struct crypt_op cop; 382 int fd; 383 384 memset(&sop, 0, sizeof(sop)); 385 memset(&cop, 0, sizeof(cop)); 386 sop.crid = crid; 387 sop.mac = alg->mac; 388 fd = crget(); 389 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 390 warn("cryptodev %s HASH not supported for device %s", 391 alg->name, crfind(crid)); 392 close(fd); 393 return (false); 394 } 395 396 cop.ses = sop.ses; 397 cop.op = 0; 398 cop.len = size; 399 cop.src = (char *)buffer; 400 cop.dst = NULL; 401 cop.mac = digest; 402 cop.iv = NULL; 403 404 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 405 warn("cryptodev %s (%zu) HASH failed for device %s", alg->name, 406 size, crfind(crid)); 407 close(fd); 408 return (false); 409 } 410 411 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 412 warn("ioctl(CIOCFSESSION)"); 413 414 close(fd); 415 *cridp = sop.crid; 416 return (true); 417} 418 419static void 420openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer, 421 size_t size, void *digest_out, unsigned *digest_sz_out) 422{ 423 EVP_MD_CTX *mdctx; 424 const char *errs; 425 int rc; 426 427 errs = ""; 428 429 mdctx = EVP_MD_CTX_create(); 430 if (mdctx == NULL) 431 goto err_out; 432 433 rc = EVP_DigestInit_ex(mdctx, md, NULL); 434 if (rc != 1) 435 goto err_out; 436 437 rc = EVP_DigestUpdate(mdctx, buffer, size); 438 if (rc != 1) 439 goto err_out; 440 441 rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out); 442 if (rc != 1) 443 goto err_out; 444 445 EVP_MD_CTX_destroy(mdctx); 446 return; 447 448err_out: 449 errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs, 450 ERR_error_string(ERR_get_error(), NULL)); 451} 452 453static void 454run_hash_test(struct alg *alg, size_t size) 455{ 456 const EVP_MD *md; 457 char *buffer; 458 u_int digest_len; 459 int crid; 460 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 461 462 memset(control_digest, 0x3c, sizeof(control_digest)); 463 memset(test_digest, 0x3c, sizeof(test_digest)); 464 465 md = alg->evp_md(); 466 assert(EVP_MD_size(md) <= sizeof(control_digest)); 467 468 buffer = alloc_buffer(size); 469 470 /* OpenSSL HASH. */ 471 digest_len = sizeof(control_digest); 472 openssl_hash(alg, md, buffer, size, control_digest, &digest_len); 473 474 /* cryptodev HASH. */ 475 if (!ocf_hash(alg, buffer, size, test_digest, &crid)) 476 goto out; 477 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 478 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 479 printf("%s (%zu) mismatch in trailer:\n", 480 alg->name, size); 481 else 482 printf("%s (%zu) mismatch:\n", alg->name, size); 483 printf("control:\n"); 484 hexdump(control_digest, sizeof(control_digest), NULL, 0); 485 printf("test (cryptodev device %s):\n", crfind(crid)); 486 hexdump(test_digest, sizeof(test_digest), NULL, 0); 487 goto out; 488 } 489 490 if (verbose) 491 printf("%s (%zu) matched (cryptodev device %s)\n", 492 alg->name, size, crfind(crid)); 493 494out: 495 free(buffer); 496} 497 498static bool 499ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key, 500 size_t key_len, char *digest, int *cridp) 501{ 502 struct session2_op sop; 503 struct crypt_op cop; 504 int fd; 505 506 memset(&sop, 0, sizeof(sop)); 507 memset(&cop, 0, sizeof(cop)); 508 sop.crid = crid; 509 sop.mackeylen = key_len; 510 sop.mackey = (char *)key; 511 sop.mac = alg->mac; 512 fd = crget(); 513 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 514 warn("cryptodev %s HMAC not supported for device %s", 515 alg->name, crfind(crid)); 516 close(fd); 517 return (false); 518 } 519 520 cop.ses = sop.ses; 521 cop.op = 0; 522 cop.len = size; 523 cop.src = (char *)buffer; 524 cop.dst = NULL; 525 cop.mac = digest; 526 cop.iv = NULL; 527 528 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 529 warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name, 530 size, crfind(crid)); 531 close(fd); 532 return (false); 533 } 534 535 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 536 warn("ioctl(CIOCFSESSION)"); 537 538 close(fd); 539 *cridp = sop.crid; 540 return (true); 541} 542 543static void 544run_hmac_test(struct alg *alg, size_t size) 545{ 546 const EVP_MD *md; 547 char *key, *buffer; 548 u_int key_len, digest_len; 549 int crid; 550 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 551 552 memset(control_digest, 0x3c, sizeof(control_digest)); 553 memset(test_digest, 0x3c, sizeof(test_digest)); 554 555 md = alg->evp_md(); 556 key_len = EVP_MD_size(md); 557 assert(EVP_MD_size(md) <= sizeof(control_digest)); 558 559 key = alloc_buffer(key_len); 560 buffer = alloc_buffer(size); 561 562 /* OpenSSL HMAC. */ 563 digest_len = sizeof(control_digest); 564 if (HMAC(md, key, key_len, (u_char *)buffer, size, 565 (u_char *)control_digest, &digest_len) == NULL) 566 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name, 567 size, ERR_error_string(ERR_get_error(), NULL)); 568 569 /* cryptodev HMAC. */ 570 if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid)) 571 goto out; 572 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 573 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 574 printf("%s (%zu) mismatch in trailer:\n", 575 alg->name, size); 576 else 577 printf("%s (%zu) mismatch:\n", alg->name, size); 578 printf("control:\n"); 579 hexdump(control_digest, sizeof(control_digest), NULL, 0); 580 printf("test (cryptodev device %s):\n", crfind(crid)); 581 hexdump(test_digest, sizeof(test_digest), NULL, 0); 582 goto out; 583 } 584 585 if (verbose) 586 printf("%s (%zu) matched (cryptodev device %s)\n", 587 alg->name, size, crfind(crid)); 588 589out: 590 free(buffer); 591 free(key); 592} 593 594static void 595openssl_cipher(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 596 const char *iv, const char *input, char *output, size_t size, int enc) 597{ 598 EVP_CIPHER_CTX *ctx; 599 int outl, total; 600 601 ctx = EVP_CIPHER_CTX_new(); 602 if (ctx == NULL) 603 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 604 size, ERR_error_string(ERR_get_error(), NULL)); 605 if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key, 606 (const u_char *)iv, enc) != 1) 607 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 608 size, ERR_error_string(ERR_get_error(), NULL)); 609 EVP_CIPHER_CTX_set_padding(ctx, 0); 610 if (EVP_CipherUpdate(ctx, (u_char *)output, &outl, 611 (const u_char *)input, size) != 1) 612 errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name, 613 size, ERR_error_string(ERR_get_error(), NULL)); 614 total = outl; 615 if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 616 errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name, 617 size, ERR_error_string(ERR_get_error(), NULL)); 618 total += outl; 619 if (total != size) 620 errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name, 621 size, total); 622 EVP_CIPHER_CTX_free(ctx); 623} 624 625static bool 626ocf_cipher(struct alg *alg, const char *key, size_t key_len, 627 const char *iv, const char *input, char *output, size_t size, int enc, 628 int *cridp) 629{ 630 struct session2_op sop; 631 struct crypt_op cop; 632 int fd; 633 634 memset(&sop, 0, sizeof(sop)); 635 memset(&cop, 0, sizeof(cop)); 636 sop.crid = crid; 637 sop.keylen = key_len; 638 sop.key = (char *)key; 639 sop.cipher = alg->cipher; 640 fd = crget(); 641 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 642 warn("cryptodev %s block cipher not supported for device %s", 643 alg->name, crfind(crid)); 644 close(fd); 645 return (false); 646 } 647 648 cop.ses = sop.ses; 649 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT; 650 cop.len = size; 651 cop.src = (char *)input; 652 cop.dst = output; 653 cop.mac = NULL; 654 cop.iv = (char *)iv; 655 656 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 657 warn("cryptodev %s (%zu) block cipher failed for device %s", 658 alg->name, size, crfind(crid)); 659 close(fd); 660 return (false); 661 } 662 663 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 664 warn("ioctl(CIOCFSESSION)"); 665 666 close(fd); 667 *cridp = sop.crid; 668 return (true); 669} 670 671static void 672run_blkcipher_test(struct alg *alg, size_t size) 673{ 674 const EVP_CIPHER *cipher; 675 char *buffer, *cleartext, *ciphertext; 676 char *iv, *key; 677 u_int iv_len, key_len; 678 int crid; 679 680 cipher = alg->evp_cipher(); 681 if (size % EVP_CIPHER_block_size(cipher) != 0) { 682 if (verbose) 683 printf( 684 "%s (%zu): invalid buffer size (block size %d)\n", 685 alg->name, size, EVP_CIPHER_block_size(cipher)); 686 return; 687 } 688 689 key_len = EVP_CIPHER_key_length(cipher); 690 iv_len = EVP_CIPHER_iv_length(cipher); 691 692 key = alloc_buffer(key_len); 693 iv = generate_iv(iv_len, alg); 694 cleartext = alloc_buffer(size); 695 buffer = malloc(size); 696 ciphertext = malloc(size); 697 698 /* OpenSSL cipher. */ 699 openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1); 700 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) 701 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, 702 size); 703 openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0); 704 if (memcmp(cleartext, buffer, size) != 0) { 705 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size); 706 printf("original:\n"); 707 hexdump(cleartext, size, NULL, 0); 708 printf("decrypted:\n"); 709 hexdump(buffer, size, NULL, 0); 710 exit(1); 711 } 712 713 /* OCF encrypt. */ 714 if (!ocf_cipher(alg, key, key_len, iv, cleartext, buffer, size, 1, 715 &crid)) 716 goto out; 717 if (memcmp(ciphertext, buffer, size) != 0) { 718 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 719 printf("control:\n"); 720 hexdump(ciphertext, size, NULL, 0); 721 printf("test (cryptodev device %s):\n", crfind(crid)); 722 hexdump(buffer, size, NULL, 0); 723 goto out; 724 } 725 726 /* OCF decrypt. */ 727 if (!ocf_cipher(alg, key, key_len, iv, ciphertext, buffer, size, 0, 728 &crid)) 729 goto out; 730 if (memcmp(cleartext, buffer, size) != 0) { 731 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 732 printf("control:\n"); 733 hexdump(cleartext, size, NULL, 0); 734 printf("test (cryptodev device %s):\n", crfind(crid)); 735 hexdump(buffer, size, NULL, 0); 736 goto out; 737 } 738 739 if (verbose) 740 printf("%s (%zu) matched (cryptodev device %s)\n", 741 alg->name, size, crfind(crid)); 742 743out: 744 free(ciphertext); 745 free(buffer); 746 free(cleartext); 747 free(iv); 748 free(key); 749} 750 751static bool 752ocf_authenc(struct alg *alg, const char *cipher_key, size_t cipher_key_len, 753 const char *iv, size_t iv_len, const char *auth_key, size_t auth_key_len, 754 const char *aad, size_t aad_len, const char *input, char *output, 755 size_t size, char *digest, int enc, int *cridp) 756{ 757 struct session2_op sop; 758 int fd; 759 760 memset(&sop, 0, sizeof(sop)); 761 sop.crid = crid; 762 sop.keylen = cipher_key_len; 763 sop.key = (char *)cipher_key; 764 sop.cipher = alg->cipher; 765 sop.mackeylen = auth_key_len; 766 sop.mackey = (char *)auth_key; 767 sop.mac = alg->mac; 768 fd = crget(); 769 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 770 warn("cryptodev %s AUTHENC not supported for device %s", 771 alg->name, crfind(crid)); 772 close(fd); 773 return (false); 774 } 775 776 if (aad_len != 0) { 777 struct crypt_aead caead; 778 779 memset(&caead, 0, sizeof(caead)); 780 caead.ses = sop.ses; 781 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT; 782 caead.flags = enc ? COP_F_CIPHER_FIRST : 0; 783 caead.len = size; 784 caead.aadlen = aad_len; 785 caead.ivlen = iv_len; 786 caead.src = (char *)input; 787 caead.dst = output; 788 caead.aad = (char *)aad; 789 caead.tag = digest; 790 caead.iv = (char *)iv; 791 792 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) { 793 warn("cryptodev %s (%zu) failed for device %s", 794 alg->name, size, crfind(crid)); 795 close(fd); 796 return (false); 797 } 798 } else { 799 struct crypt_op cop; 800 801 memset(&cop, 0, sizeof(cop)); 802 cop.ses = sop.ses; 803 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT; 804 cop.flags = enc ? COP_F_CIPHER_FIRST : 0; 805 cop.len = size; 806 cop.src = (char *)input; 807 cop.dst = output; 808 cop.mac = digest; 809 cop.iv = (char *)iv; 810 811 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 812 warn("cryptodev %s (%zu) AUTHENC failed for device %s", 813 alg->name, size, crfind(crid)); 814 close(fd); 815 return (false); 816 } 817 } 818 819 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 820 warn("ioctl(CIOCFSESSION)"); 821 822 close(fd); 823 *cridp = sop.crid; 824 return (true); 825} 826 827static void 828run_authenc_test(struct alg *alg, size_t size) 829{ 830 const EVP_CIPHER *cipher; 831 const EVP_MD *md; 832 char *aad, *buffer, *cleartext, *ciphertext; 833 char *iv, *auth_key, *cipher_key; 834 u_int iv_len, auth_key_len, cipher_key_len, digest_len; 835 int crid; 836 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 837 838 cipher = alg->evp_cipher(); 839 if (size % EVP_CIPHER_block_size(cipher) != 0) { 840 if (verbose) 841 printf( 842 "%s (%zu): invalid buffer size (block size %d)\n", 843 alg->name, size, EVP_CIPHER_block_size(cipher)); 844 return; 845 } 846 847 memset(control_digest, 0x3c, sizeof(control_digest)); 848 memset(test_digest, 0x3c, sizeof(test_digest)); 849 850 md = alg->evp_md(); 851 852 cipher_key_len = EVP_CIPHER_key_length(cipher); 853 iv_len = EVP_CIPHER_iv_length(cipher); 854 auth_key_len = EVP_MD_size(md); 855 856 cipher_key = alloc_buffer(cipher_key_len); 857 iv = generate_iv(iv_len, alg); 858 auth_key = alloc_buffer(auth_key_len); 859 cleartext = alloc_buffer(aad_len + size); 860 buffer = malloc(aad_len + size); 861 ciphertext = malloc(aad_len + size); 862 863 /* OpenSSL encrypt + HMAC. */ 864 if (aad_len != 0) 865 memcpy(ciphertext, cleartext, aad_len); 866 openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len, 867 ciphertext + aad_len, size, 1); 868 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len, 869 size) == 0) 870 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, 871 size); 872 digest_len = sizeof(control_digest); 873 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext, 874 aad_len + size, (u_char *)control_digest, &digest_len) == NULL) 875 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name, 876 size, ERR_error_string(ERR_get_error(), NULL)); 877 878 /* OCF encrypt + HMAC. */ 879 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key, 880 auth_key_len, aad_len != 0 ? cleartext : NULL, aad_len, 881 cleartext + aad_len, buffer + aad_len, size, test_digest, 1, &crid)) 882 goto out; 883 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) { 884 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 885 printf("control:\n"); 886 hexdump(ciphertext + aad_len, size, NULL, 0); 887 printf("test (cryptodev device %s):\n", crfind(crid)); 888 hexdump(buffer + aad_len, size, NULL, 0); 889 goto out; 890 } 891 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 892 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 893 printf("%s (%zu) enc hash mismatch in trailer:\n", 894 alg->name, size); 895 else 896 printf("%s (%zu) enc hash mismatch:\n", alg->name, 897 size); 898 printf("control:\n"); 899 hexdump(control_digest, sizeof(control_digest), NULL, 0); 900 printf("test (cryptodev device %s):\n", crfind(crid)); 901 hexdump(test_digest, sizeof(test_digest), NULL, 0); 902 goto out; 903 } 904 905 /* OCF HMAC + decrypt. */ 906 memset(test_digest, 0x3c, sizeof(test_digest)); 907 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key, 908 auth_key_len, aad_len != 0 ? ciphertext : NULL, aad_len, 909 ciphertext + aad_len, buffer + aad_len, size, test_digest, 0, 910 &crid)) 911 goto out; 912 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 913 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 914 printf("%s (%zu) dec hash mismatch in trailer:\n", 915 alg->name, size); 916 else 917 printf("%s (%zu) dec hash mismatch:\n", alg->name, 918 size); 919 printf("control:\n"); 920 hexdump(control_digest, sizeof(control_digest), NULL, 0); 921 printf("test (cryptodev device %s):\n", crfind(crid)); 922 hexdump(test_digest, sizeof(test_digest), NULL, 0); 923 goto out; 924 } 925 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) { 926 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 927 printf("control:\n"); 928 hexdump(cleartext, size, NULL, 0); 929 printf("test (cryptodev device %s):\n", crfind(crid)); 930 hexdump(buffer, size, NULL, 0); 931 goto out; 932 } 933 934 if (verbose) 935 printf("%s (%zu) matched (cryptodev device %s)\n", 936 alg->name, size, crfind(crid)); 937 938out: 939 free(ciphertext); 940 free(buffer); 941 free(cleartext); 942 free(auth_key); 943 free(iv); 944 free(cipher_key); 945} 946 947static void 948openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 949 const char *iv, const char *aad, size_t aad_len, const char *input, 950 char *output, size_t size, char *tag) 951{ 952 EVP_CIPHER_CTX *ctx; 953 int outl, total; 954 955 ctx = EVP_CIPHER_CTX_new(); 956 if (ctx == NULL) 957 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 958 size, ERR_error_string(ERR_get_error(), NULL)); 959 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 960 (const u_char *)iv) != 1) 961 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 962 size, ERR_error_string(ERR_get_error(), NULL)); 963 EVP_CIPHER_CTX_set_padding(ctx, 0); 964 if (aad != NULL) { 965 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 966 aad_len) != 1) 967 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 968 alg->name, size, 969 ERR_error_string(ERR_get_error(), NULL)); 970 } 971 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 972 (const u_char *)input, size) != 1) 973 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 974 size, ERR_error_string(ERR_get_error(), NULL)); 975 total = outl; 976 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 977 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 978 size, ERR_error_string(ERR_get_error(), NULL)); 979 total += outl; 980 if (total != size) 981 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 982 size, total); 983 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GMAC_HASH_LEN, 984 tag) != 1) 985 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 986 size, ERR_error_string(ERR_get_error(), NULL)); 987 EVP_CIPHER_CTX_free(ctx); 988} 989 990static bool 991ocf_gcm(struct alg *alg, const char *key, size_t key_len, const char *iv, 992 size_t iv_len, const char *aad, size_t aad_len, const char *input, 993 char *output, size_t size, char *tag, int enc, int *cridp) 994{ 995 struct session2_op sop; 996 struct crypt_aead caead; 997 int fd; 998 999 memset(&sop, 0, sizeof(sop)); 1000 memset(&caead, 0, sizeof(caead)); 1001 sop.crid = crid; 1002 sop.keylen = key_len; 1003 sop.key = (char *)key; 1004 sop.cipher = alg->cipher; 1005 sop.mackeylen = key_len; 1006 sop.mackey = (char *)key; 1007 sop.mac = alg->mac; 1008 fd = crget(); 1009 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 1010 warn("cryptodev %s not supported for device %s", 1011 alg->name, crfind(crid)); 1012 close(fd); 1013 return (false); 1014 } 1015 1016 caead.ses = sop.ses; 1017 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT; 1018 caead.len = size; 1019 caead.aadlen = aad_len; 1020 caead.ivlen = iv_len; 1021 caead.src = (char *)input; 1022 caead.dst = output; 1023 caead.aad = (char *)aad; 1024 caead.tag = tag; 1025 caead.iv = (char *)iv; 1026 1027 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) { 1028 warn("cryptodev %s (%zu) failed for device %s", 1029 alg->name, size, crfind(crid)); 1030 close(fd); 1031 return (false); 1032 } 1033 1034 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 1035 warn("ioctl(CIOCFSESSION)"); 1036 1037 close(fd); 1038 *cridp = sop.crid; 1039 return (true); 1040} 1041 1042#ifdef notused 1043static bool 1044openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 1045 const char *iv, const char *aad, size_t aad_len, const char *input, 1046 char *output, size_t size, char *tag) 1047{ 1048 EVP_CIPHER_CTX *ctx; 1049 int outl, total; 1050 bool valid; 1051 1052 ctx = EVP_CIPHER_CTX_new(); 1053 if (ctx == NULL) 1054 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1055 size, ERR_error_string(ERR_get_error(), NULL)); 1056 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1057 (const u_char *)iv) != 1) 1058 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1059 size, ERR_error_string(ERR_get_error(), NULL)); 1060 EVP_CIPHER_CTX_set_padding(ctx, 0); 1061 if (aad != NULL) { 1062 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1063 aad_len) != 1) 1064 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1065 alg->name, size, 1066 ERR_error_string(ERR_get_error(), NULL)); 1067 } 1068 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl, 1069 (const u_char *)input, size) != 1) 1070 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name, 1071 size, ERR_error_string(ERR_get_error(), NULL)); 1072 total = outl; 1073 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GMAC_HASH_LEN, 1074 tag) != 1) 1075 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1076 size, ERR_error_string(ERR_get_error(), NULL)); 1077 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1); 1078 total += outl; 1079 if (total != size) 1080 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name, 1081 size, total); 1082 EVP_CIPHER_CTX_free(ctx); 1083 return (valid); 1084} 1085#endif 1086 1087static void 1088run_gcm_test(struct alg *alg, size_t size) 1089{ 1090 const EVP_CIPHER *cipher; 1091 char *aad, *buffer, *cleartext, *ciphertext; 1092 char *iv, *key; 1093 u_int iv_len, key_len; 1094 int crid; 1095 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN]; 1096 1097 cipher = alg->evp_cipher(); 1098 if (size % EVP_CIPHER_block_size(cipher) != 0) { 1099 if (verbose) 1100 printf( 1101 "%s (%zu): invalid buffer size (block size %d)\n", 1102 alg->name, size, EVP_CIPHER_block_size(cipher)); 1103 return; 1104 } 1105 1106 memset(control_tag, 0x3c, sizeof(control_tag)); 1107 memset(test_tag, 0x3c, sizeof(test_tag)); 1108 1109 key_len = EVP_CIPHER_key_length(cipher); 1110 iv_len = EVP_CIPHER_iv_length(cipher); 1111 1112 key = alloc_buffer(key_len); 1113 iv = generate_iv(iv_len, alg); 1114 cleartext = alloc_buffer(size); 1115 buffer = malloc(size); 1116 ciphertext = malloc(size); 1117 if (aad_len != 0) 1118 aad = alloc_buffer(aad_len); 1119 else 1120 aad = NULL; 1121 1122 /* OpenSSL encrypt */ 1123 openssl_gcm_encrypt(alg, cipher, key, iv, aad, aad_len, cleartext, 1124 ciphertext, size, control_tag); 1125 1126 /* OCF encrypt */ 1127 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext, 1128 buffer, size, test_tag, 1, &crid)) 1129 goto out; 1130 if (memcmp(ciphertext, buffer, size) != 0) { 1131 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 1132 printf("control:\n"); 1133 hexdump(ciphertext, size, NULL, 0); 1134 printf("test (cryptodev device %s):\n", crfind(crid)); 1135 hexdump(buffer, size, NULL, 0); 1136 goto out; 1137 } 1138 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1139 printf("%s (%zu) enc tag mismatch:\n", alg->name, size); 1140 printf("control:\n"); 1141 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1142 printf("test (cryptodev device %s):\n", crfind(crid)); 1143 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1144 goto out; 1145 } 1146 1147 /* OCF decrypt */ 1148 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext, 1149 buffer, size, control_tag, 0, &crid)) 1150 goto out; 1151 if (memcmp(cleartext, buffer, size) != 0) { 1152 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 1153 printf("control:\n"); 1154 hexdump(cleartext, size, NULL, 0); 1155 printf("test (cryptodev device %s):\n", crfind(crid)); 1156 hexdump(buffer, size, NULL, 0); 1157 goto out; 1158 } 1159 1160 if (verbose) 1161 printf("%s (%zu) matched (cryptodev device %s)\n", 1162 alg->name, size, crfind(crid)); 1163 1164out: 1165 free(aad); 1166 free(ciphertext); 1167 free(buffer); 1168 free(cleartext); 1169 free(iv); 1170 free(key); 1171} 1172 1173static void 1174openssl_ccm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 1175 const char *iv, size_t iv_len, const char *aad, size_t aad_len, 1176 const char *input, char *output, size_t size, char *tag) 1177{ 1178 EVP_CIPHER_CTX *ctx; 1179 int outl, total; 1180 1181 ctx = EVP_CIPHER_CTX_new(); 1182 if (ctx == NULL) 1183 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1184 size, ERR_error_string(ERR_get_error(), NULL)); 1185 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) 1186 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1187 size, ERR_error_string(ERR_get_error(), NULL)); 1188 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_len, NULL) != 1) 1189 errx(1, "OpenSSL %s (%zu) setting iv length failed: %s", alg->name, 1190 size, ERR_error_string(ERR_get_error(), NULL)); 1191 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, AES_CBC_MAC_HASH_LEN, NULL) != 1) 1192 errx(1, "OpenSSL %s (%zu) setting tag length failed: %s", alg->name, 1193 size, ERR_error_string(ERR_get_error(), NULL)); 1194 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key, 1195 (const u_char *)iv) != 1) 1196 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1197 size, ERR_error_string(ERR_get_error(), NULL)); 1198 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1) 1199 errx(1, "OpenSSL %s (%zu) unable to set data length: %s", alg->name, 1200 size, ERR_error_string(ERR_get_error(), NULL)); 1201 1202 if (aad != NULL) { 1203 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1204 aad_len) != 1) 1205 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1206 alg->name, size, 1207 ERR_error_string(ERR_get_error(), NULL)); 1208 } 1209 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 1210 (const u_char *)input, size) != 1) 1211 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 1212 size, ERR_error_string(ERR_get_error(), NULL)); 1213 total = outl; 1214 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 1215 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 1216 size, ERR_error_string(ERR_get_error(), NULL)); 1217 total += outl; 1218 if (total != size) 1219 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 1220 size, total); 1221 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, AES_CBC_MAC_HASH_LEN, 1222 tag) != 1) 1223 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1224 size, ERR_error_string(ERR_get_error(), NULL)); 1225 EVP_CIPHER_CTX_free(ctx); 1226} 1227 1228static bool 1229ocf_ccm(struct alg *alg, const char *key, size_t key_len, const char *iv, 1230 size_t iv_len, const char *aad, size_t aad_len, const char *input, 1231 char *output, size_t size, char *tag, int enc, int *cridp) 1232{ 1233 struct session2_op sop; 1234 struct crypt_aead caead; 1235 int fd; 1236 bool rv; 1237 1238 memset(&sop, 0, sizeof(sop)); 1239 memset(&caead, 0, sizeof(caead)); 1240 sop.crid = crid; 1241 sop.keylen = key_len; 1242 sop.key = (char *)key; 1243 sop.cipher = alg->cipher; 1244 sop.mackeylen = key_len; 1245 sop.mackey = (char *)key; 1246 sop.mac = alg->mac; 1247 fd = crget(); 1248 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 1249 warn("cryptodev %s not supported for device %s", 1250 alg->name, crfind(crid)); 1251 close(fd); 1252 return (false); 1253 } 1254 1255 caead.ses = sop.ses; 1256 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT; 1257 caead.len = size; 1258 caead.aadlen = aad_len; 1259 caead.ivlen = iv_len; 1260 caead.src = (char *)input; 1261 caead.dst = output; 1262 caead.aad = (char *)aad; 1263 caead.tag = tag; 1264 caead.iv = (char *)iv; 1265 1266 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) { 1267 warn("cryptodev %s (%zu) failed for device %s", 1268 alg->name, size, crfind(crid)); 1269 rv = false; 1270 } else 1271 rv = true; 1272 1273 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 1274 warn("ioctl(CIOCFSESSION)"); 1275 1276 close(fd); 1277 *cridp = sop.crid; 1278 return (rv); 1279} 1280 1281static void 1282run_ccm_test(struct alg *alg, size_t size) 1283{ 1284 const EVP_CIPHER *cipher; 1285 char *aad, *buffer, *cleartext, *ciphertext; 1286 char *iv, *key; 1287 u_int iv_len, key_len; 1288 int crid; 1289 char control_tag[AES_CBC_MAC_HASH_LEN], test_tag[AES_CBC_MAC_HASH_LEN]; 1290 1291 cipher = alg->evp_cipher(); 1292 if (size % EVP_CIPHER_block_size(cipher) != 0) { 1293 if (verbose) 1294 printf( 1295 "%s (%zu): invalid buffer size (block size %d)\n", 1296 alg->name, size, EVP_CIPHER_block_size(cipher)); 1297 return; 1298 } 1299 1300 memset(control_tag, 0x3c, sizeof(control_tag)); 1301 memset(test_tag, 0x3c, sizeof(test_tag)); 1302 1303 /* 1304 * We only have one algorithm constant for CBC-MAC; however, the 1305 * alg structure uses the different openssl types, which gives us 1306 * the key length. We need that for the OCF code. 1307 */ 1308 key_len = EVP_CIPHER_key_length(cipher); 1309 1310 /* 1311 * AES-CCM can have varying IV lengths; however, for the moment 1312 * we only support AES_CCM_IV_LEN (12). So if the sizes are 1313 * different, we'll fail. 1314 */ 1315 iv_len = EVP_CIPHER_iv_length(cipher); 1316 if (iv_len != AES_CCM_IV_LEN) { 1317 if (verbose) 1318 printf("OpenSSL CCM IV length (%d) != AES_CCM_IV_LEN", 1319 iv_len); 1320 return; 1321 } 1322 1323 key = alloc_buffer(key_len); 1324 iv = generate_iv(iv_len, alg); 1325 cleartext = alloc_buffer(size); 1326 buffer = malloc(size); 1327 ciphertext = malloc(size); 1328 if (aad_len != 0) 1329 aad = alloc_buffer(aad_len); 1330 else 1331 aad = NULL; 1332 1333 /* OpenSSL encrypt */ 1334 openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad, aad_len, cleartext, 1335 ciphertext, size, control_tag); 1336 1337 /* OCF encrypt */ 1338 if (!ocf_ccm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext, 1339 buffer, size, test_tag, 1, &crid)) 1340 goto out; 1341 if (memcmp(ciphertext, buffer, size) != 0) { 1342 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 1343 printf("control:\n"); 1344 hexdump(ciphertext, size, NULL, 0); 1345 printf("test (cryptodev device %s):\n", crfind(crid)); 1346 hexdump(buffer, size, NULL, 0); 1347 goto out; 1348 } 1349 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1350 printf("%s (%zu) enc tag mismatch:\n", alg->name, size); 1351 printf("control:\n"); 1352 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1353 printf("test (cryptodev device %s):\n", crfind(crid)); 1354 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1355 goto out; 1356 } 1357 1358 /* OCF decrypt */ 1359 if (!ocf_ccm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext, 1360 buffer, size, control_tag, 0, &crid)) 1361 goto out; 1362 if (memcmp(cleartext, buffer, size) != 0) { 1363 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 1364 printf("control:\n"); 1365 hexdump(cleartext, size, NULL, 0); 1366 printf("test (cryptodev device %s):\n", crfind(crid)); 1367 hexdump(buffer, size, NULL, 0); 1368 goto out; 1369 } 1370 1371 if (verbose) 1372 printf("%s (%zu) matched (cryptodev device %s)\n", 1373 alg->name, size, crfind(crid)); 1374 1375out: 1376 free(aad); 1377 free(ciphertext); 1378 free(buffer); 1379 free(cleartext); 1380 free(iv); 1381 free(key); 1382} 1383 1384static void 1385run_test(struct alg *alg, size_t size) 1386{ 1387 1388 switch (alg->type) { 1389 case T_HASH: 1390 run_hash_test(alg, size); 1391 break; 1392 case T_HMAC: 1393 run_hmac_test(alg, size); 1394 break; 1395 case T_BLKCIPHER: 1396 run_blkcipher_test(alg, size); 1397 break; 1398 case T_AUTHENC: 1399 run_authenc_test(alg, size); 1400 break; 1401 case T_GCM: 1402 run_gcm_test(alg, size); 1403 break; 1404 case T_CCM: 1405 run_ccm_test(alg, size); 1406 break; 1407 } 1408} 1409 1410static void 1411run_test_sizes(struct alg *alg, size_t *sizes, u_int nsizes) 1412{ 1413 u_int i; 1414 1415 for (i = 0; i < nsizes; i++) 1416 run_test(alg, sizes[i]); 1417} 1418 1419static void 1420run_hash_tests(size_t *sizes, u_int nsizes) 1421{ 1422 u_int i; 1423 1424 for (i = 0; i < nitems(algs); i++) 1425 if (algs[i].type == T_HASH) 1426 run_test_sizes(&algs[i], sizes, nsizes); 1427} 1428 1429static void 1430run_hmac_tests(size_t *sizes, u_int nsizes) 1431{ 1432 u_int i; 1433 1434 for (i = 0; i < nitems(algs); i++) 1435 if (algs[i].type == T_HMAC) 1436 run_test_sizes(&algs[i], sizes, nsizes); 1437} 1438 1439static void 1440run_blkcipher_tests(size_t *sizes, u_int nsizes) 1441{ 1442 u_int i; 1443 1444 for (i = 0; i < nitems(algs); i++) 1445 if (algs[i].type == T_BLKCIPHER) 1446 run_test_sizes(&algs[i], sizes, nsizes); 1447} 1448 1449static void 1450run_authenc_tests(size_t *sizes, u_int nsizes) 1451{ 1452 struct alg *authenc, *cipher, *hmac; 1453 u_int i, j; 1454 1455 for (i = 0; i < nitems(algs); i++) { 1456 cipher = &algs[i]; 1457 if (cipher->type != T_BLKCIPHER) 1458 continue; 1459 for (j = 0; j < nitems(algs); j++) { 1460 hmac = &algs[j]; 1461 if (hmac->type != T_HMAC) 1462 continue; 1463 authenc = build_authenc(cipher, hmac); 1464 run_test_sizes(authenc, sizes, nsizes); 1465 free((char *)authenc->name); 1466 } 1467 } 1468} 1469 1470static void 1471run_aead_tests(size_t *sizes, u_int nsizes) 1472{ 1473 u_int i; 1474 1475 for (i = 0; i < nitems(algs); i++) 1476 if (algs[i].type == T_GCM || 1477 algs[i].type == T_CCM) 1478 run_test_sizes(&algs[i], sizes, nsizes); 1479} 1480 1481int 1482main(int ac, char **av) 1483{ 1484 const char *algname; 1485 struct alg *alg; 1486 size_t sizes[128]; 1487 u_int i, nsizes; 1488 bool testall; 1489 int ch; 1490 1491 algname = NULL; 1492 crid = CRYPTO_FLAG_HARDWARE; 1493 testall = false; 1494 verbose = false; 1495 while ((ch = getopt(ac, av, "A:a:d:vz")) != -1) 1496 switch (ch) { 1497 case 'A': 1498 aad_len = atoi(optarg); 1499 break; 1500 case 'a': 1501 algname = optarg; 1502 break; 1503 case 'd': 1504 crid = crlookup(optarg); 1505 break; 1506 case 'v': 1507 verbose = true; 1508 break; 1509 case 'z': 1510 testall = true; 1511 break; 1512 default: 1513 usage(); 1514 } 1515 ac -= optind; 1516 av += optind; 1517 nsizes = 0; 1518 while (ac > 0) { 1519 char *cp; 1520 1521 if (nsizes >= nitems(sizes)) { 1522 warnx("Too many sizes, ignoring extras"); 1523 break; 1524 } 1525 sizes[nsizes] = strtol(av[0], &cp, 0); 1526 if (*cp != '\0') 1527 errx(1, "Bad size %s", av[0]); 1528 nsizes++; 1529 ac--; 1530 av++; 1531 } 1532 1533 if (algname == NULL) 1534 errx(1, "Algorithm required"); 1535 if (nsizes == 0) { 1536 sizes[0] = 16; 1537 nsizes++; 1538 if (testall) { 1539 while (sizes[nsizes - 1] * 2 < 240 * 1024) { 1540 assert(nsizes < nitems(sizes)); 1541 sizes[nsizes] = sizes[nsizes - 1] * 2; 1542 nsizes++; 1543 } 1544 if (sizes[nsizes - 1] < 240 * 1024) { 1545 assert(nsizes < nitems(sizes)); 1546 sizes[nsizes] = 240 * 1024; 1547 nsizes++; 1548 } 1549 } 1550 } 1551 1552 if (strcasecmp(algname, "hash") == 0) 1553 run_hash_tests(sizes, nsizes); 1554 else if (strcasecmp(algname, "hmac") == 0) 1555 run_hmac_tests(sizes, nsizes); 1556 else if (strcasecmp(algname, "blkcipher") == 0) 1557 run_blkcipher_tests(sizes, nsizes); 1558 else if (strcasecmp(algname, "authenc") == 0) 1559 run_authenc_tests(sizes, nsizes); 1560 else if (strcasecmp(algname, "aead") == 0) 1561 run_aead_tests(sizes, nsizes); 1562 else if (strcasecmp(algname, "all") == 0) { 1563 run_hash_tests(sizes, nsizes); 1564 run_hmac_tests(sizes, nsizes); 1565 run_blkcipher_tests(sizes, nsizes); 1566 run_authenc_tests(sizes, nsizes); 1567 run_aead_tests(sizes, nsizes); 1568 } else if (strchr(algname, '+') != NULL) { 1569 alg = build_authenc_name(algname); 1570 run_test_sizes(alg, sizes, nsizes); 1571 } else { 1572 alg = find_alg(algname); 1573 if (alg == NULL) 1574 errx(1, "Invalid algorithm %s", algname); 1575 run_test_sizes(alg, sizes, nsizes); 1576 } 1577 1578 return (0); 1579} 1580