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