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