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 * poly1305 102 * 103 * Ciphers: 104 * aes-cbc 128-bit AES-CBC 105 * aes-cbc192 192-bit AES-CBC 106 * aes-cbc256 256-bit AES-CBC 107 * aes-ctr 128-bit AES-CTR 108 * aes-ctr192 192-bit AES-CTR 109 * aes-ctr256 256-bit AES-CTR 110 * aes-xts 128-bit AES-XTS 111 * aes-xts256 256-bit AES-XTS 112 * chacha20 113 * 114 * Encrypt then Authenticate: 115 * <cipher>+<mac> 116 * 117 * Authenticated Encryption with Associated Data: 118 * aes-gcm 128-bit AES-GCM 119 * aes-gcm192 192-bit AES-GCM 120 * aes-gcm256 256-bit AES-GCM 121 * aes-ccm 128-bit AES-CCM 122 * aes-ccm192 192-bit AES-CCM 123 * aes-ccm256 256-bit AES-CCM 124 * chacha20-poly1305 Chacha20 (96 bit nonce) with Poly1305 per RFC 8439 125 */ 126 127 #include <sys/param.h> 128 #include <sys/sysctl.h> 129 #include <assert.h> 130 #include <err.h> 131 #include <fcntl.h> 132 #include <libutil.h> 133 #include <stdbool.h> 134 #include <stdio.h> 135 #include <string.h> 136 #include <unistd.h> 137 138 #include <openssl/err.h> 139 #include <openssl/hmac.h> 140 141 #include <crypto/cryptodev.h> 142 143 struct ocf_session { 144 int fd; 145 int ses; 146 int crid; 147 }; 148 149 static const struct alg { 150 const char *name; 151 int cipher; 152 int mac; 153 enum { T_HASH, T_HMAC, T_GMAC, T_DIGEST, T_CIPHER, T_ETA, T_AEAD } type; 154 int key_len; 155 int tag_len; 156 const EVP_CIPHER *(*evp_cipher)(void); 157 const EVP_MD *(*evp_md)(void); 158 int pkey; 159 } algs[] = { 160 { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH, 161 .evp_md = EVP_sha1 }, 162 { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH, 163 .evp_md = EVP_sha224 }, 164 { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH, 165 .evp_md = EVP_sha256 }, 166 { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH, 167 .evp_md = EVP_sha384 }, 168 { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH, 169 .evp_md = EVP_sha512 }, 170 { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC, 171 .evp_md = EVP_sha1 }, 172 { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC, 173 .evp_md = EVP_sha224 }, 174 { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC, 175 .evp_md = EVP_sha256 }, 176 { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC, 177 .evp_md = EVP_sha384 }, 178 { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC, 179 .evp_md = EVP_sha512 }, 180 { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH, 181 .evp_md = EVP_blake2b512 }, 182 { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH, 183 .evp_md = EVP_blake2s256 }, 184 { .name = "gmac", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC, 185 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_128_gcm }, 186 { .name = "gmac192", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC, 187 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_192_gcm }, 188 { .name = "gmac256", .mac = CRYPTO_AES_NIST_GMAC, .type = T_GMAC, 189 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_256_gcm }, 190 { .name = "poly1305", .mac = CRYPTO_POLY1305, .type = T_DIGEST, 191 .key_len = POLY1305_KEY_LEN, .pkey = EVP_PKEY_POLY1305 }, 192 { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER, 193 .evp_cipher = EVP_aes_128_cbc }, 194 { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER, 195 .evp_cipher = EVP_aes_192_cbc }, 196 { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_CIPHER, 197 .evp_cipher = EVP_aes_256_cbc }, 198 { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER, 199 .evp_cipher = EVP_aes_128_ctr }, 200 { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER, 201 .evp_cipher = EVP_aes_192_ctr }, 202 { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_CIPHER, 203 .evp_cipher = EVP_aes_256_ctr }, 204 { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER, 205 .evp_cipher = EVP_aes_128_xts }, 206 { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_CIPHER, 207 .evp_cipher = EVP_aes_256_xts }, 208 { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_CIPHER, 209 .evp_cipher = EVP_chacha20 }, 210 { .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16, .type = T_AEAD, 211 .tag_len = AES_GMAC_HASH_LEN, .evp_cipher = EVP_aes_128_gcm }, 212 { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16, 213 .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN, 214 .evp_cipher = EVP_aes_192_gcm }, 215 { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16, 216 .type = T_AEAD, .tag_len = AES_GMAC_HASH_LEN, 217 .evp_cipher = EVP_aes_256_gcm }, 218 { .name = "aes-ccm", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD, 219 .evp_cipher = EVP_aes_128_ccm, .tag_len = AES_CBC_MAC_HASH_LEN }, 220 { .name = "aes-ccm192", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD, 221 .evp_cipher = EVP_aes_192_ccm, .tag_len = AES_CBC_MAC_HASH_LEN }, 222 { .name = "aes-ccm256", .cipher = CRYPTO_AES_CCM_16, .type = T_AEAD, 223 .evp_cipher = EVP_aes_256_ccm, .tag_len = AES_CBC_MAC_HASH_LEN }, 224 { .name = "chacha20-poly1305", .cipher = CRYPTO_CHACHA20_POLY1305, 225 .type = T_AEAD, .tag_len = POLY1305_HASH_LEN, 226 .evp_cipher = EVP_chacha20_poly1305 }, 227 }; 228 229 static bool verbose; 230 static int requested_crid; 231 static size_t aad_sizes[48], sizes[EALG_MAX_BLOCK_LEN * 2]; 232 static u_int naad_sizes, nsizes; 233 234 static void 235 usage(void) 236 { 237 fprintf(stderr, 238 "usage: cryptocheck [-z] [-a algorithm] [-d dev] [size ...]\n"); 239 exit(1); 240 } 241 242 static const struct alg * 243 find_alg(const char *name) 244 { 245 u_int i; 246 247 for (i = 0; i < nitems(algs); i++) 248 if (strcasecmp(algs[i].name, name) == 0) 249 return (&algs[i]); 250 return (NULL); 251 } 252 253 static struct alg * 254 build_eta(const struct alg *cipher, const struct alg *mac) 255 { 256 struct alg *eta; 257 char *name; 258 259 assert(cipher->type == T_CIPHER); 260 assert(mac->type == T_HMAC); 261 eta = calloc(1, sizeof(*eta)); 262 asprintf(&name, "%s+%s", cipher->name, mac->name); 263 eta->name = name; 264 eta->cipher = cipher->cipher; 265 eta->mac = mac->mac; 266 eta->type = T_ETA; 267 eta->evp_cipher = cipher->evp_cipher; 268 eta->evp_md = mac->evp_md; 269 return (eta); 270 } 271 272 static void 273 free_eta(struct alg *eta) 274 { 275 free(__DECONST(char *, eta->name)); 276 free(eta); 277 } 278 279 static struct alg * 280 build_eta_name(const char *name) 281 { 282 const struct alg *cipher, *mac; 283 const char *mac_name; 284 char *cp, *cipher_name; 285 286 cp = strchr(name, '+'); 287 cipher_name = strndup(name, cp - name); 288 mac_name = cp + 1; 289 cipher = find_alg(cipher_name); 290 free(cipher_name); 291 if (cipher == NULL || cipher->type != T_CIPHER) 292 errx(1, "Invalid cipher %s", cipher_name); 293 mac = find_alg(mac_name); 294 if (mac == NULL || mac->type != T_HMAC) 295 errx(1, "Invalid hmac %s", mac_name); 296 return (build_eta(cipher, mac)); 297 } 298 299 static int 300 devcrypto(void) 301 { 302 static int fd = -1; 303 304 if (fd < 0) { 305 fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0); 306 if (fd < 0) 307 err(1, "/dev/crypto"); 308 } 309 return (fd); 310 } 311 312 /* 313 * Called on exit to change kern.cryptodevallowsoft back to 0 314 */ 315 #define CRYPT_SOFT_ALLOW "kern.cryptodevallowsoft" 316 317 static void 318 reset_user_soft(void) 319 { 320 int off = 0; 321 sysctlbyname(CRYPT_SOFT_ALLOW, NULL, NULL, &off, sizeof(off)); 322 } 323 324 static void 325 enable_user_soft(void) 326 { 327 int curstate; 328 int on = 1; 329 size_t cursize = sizeof(curstate); 330 331 if (sysctlbyname(CRYPT_SOFT_ALLOW, &curstate, &cursize, 332 &on, sizeof(on)) == 0) { 333 if (curstate == 0) 334 atexit(reset_user_soft); 335 } 336 } 337 338 static int 339 crlookup(const char *devname) 340 { 341 struct crypt_find_op find; 342 343 if (strncmp(devname, "soft", 4) == 0) { 344 enable_user_soft(); 345 return CRYPTO_FLAG_SOFTWARE; 346 } 347 348 find.crid = -1; 349 strlcpy(find.name, devname, sizeof(find.name)); 350 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) 351 err(1, "ioctl(CIOCFINDDEV)"); 352 return (find.crid); 353 } 354 355 static const char * 356 crfind(int crid) 357 { 358 static struct crypt_find_op find; 359 360 if (crid == CRYPTO_FLAG_SOFTWARE) 361 return ("soft"); 362 else if (crid == CRYPTO_FLAG_HARDWARE) 363 return ("unknown"); 364 365 bzero(&find, sizeof(find)); 366 find.crid = crid; 367 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) 368 err(1, "ioctl(CIOCFINDDEV): crid %d", crid); 369 return (find.name); 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 = requested_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 = devcrypto(); 440 if (ioctl(fd, CIOCGSESSION2, sop) < 0) { 441 warn("cryptodev %s %s not supported for device %s", 442 type, name, crfind(sop->crid)); 443 ses->fd = -1; 444 return (false); 445 } 446 ses->fd = fd; 447 ses->ses = sop->ses; 448 ses->crid = sop->crid; 449 return (true); 450 } 451 452 static void 453 ocf_destroy_session(struct ocf_session *ses) 454 { 455 if (ses->fd == -1) 456 return; 457 458 if (ioctl(ses->fd, CIOCFSESSION, &ses->ses) < 0) 459 warn("ioctl(CIOCFSESSION)"); 460 } 461 462 static void 463 ocf_init_cop(const struct ocf_session *ses, struct crypt_op *cop) 464 { 465 memset(cop, 0, sizeof(*cop)); 466 cop->ses = ses->ses; 467 } 468 469 static void 470 ocf_init_caead(const struct ocf_session *ses, struct crypt_aead *caead) 471 { 472 memset(caead, 0, sizeof(*caead)); 473 caead->ses = ses->ses; 474 } 475 476 static bool 477 ocf_hash(const struct alg *alg, const char *buffer, size_t size, char *digest, 478 int *cridp) 479 { 480 struct ocf_session ses; 481 struct session2_op sop; 482 struct crypt_op cop; 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 = 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(ses.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((size_t)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 = 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 = 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(ses.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((size_t)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 ((size_t)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 = 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 = input; 724 cop.dst = output; 725 cop.iv = 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(ses->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 /* 755 * XTS requires at least one full block so that any partial 756 * block at the end has cipher text to steal. Hardcoding the 757 * AES block size isn't ideal, but OpenSSL doesn't have a 758 * notion of a "native" block size. 759 */ 760 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE && 761 size < AES_BLOCK_LEN) { 762 if (verbose) 763 printf("%s (%zu): invalid buffer size\n", alg->name, 764 size); 765 return; 766 } 767 768 key_len = EVP_CIPHER_key_length(cipher); 769 iv_len = EVP_CIPHER_iv_length(cipher); 770 771 key = alloc_buffer(key_len); 772 iv = generate_iv(iv_len, alg); 773 cleartext = alloc_buffer(size); 774 buffer = malloc(size); 775 ciphertext = malloc(size); 776 777 /* OpenSSL cipher. */ 778 openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1); 779 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) 780 warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name, 781 size); 782 openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0); 783 if (memcmp(cleartext, buffer, size) != 0) { 784 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size); 785 printf("original:\n"); 786 hexdump(cleartext, size, NULL, 0); 787 printf("decrypted:\n"); 788 hexdump(buffer, size, NULL, 0); 789 exit(1); 790 } 791 792 if (!ocf_init_cipher_session(alg, key, key_len, &ses)) 793 goto out; 794 795 /* OCF encrypt. */ 796 if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT)) 797 goto out; 798 if (memcmp(ciphertext, buffer, size) != 0) { 799 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 800 printf("control:\n"); 801 hexdump(ciphertext, size, NULL, 0); 802 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 803 hexdump(buffer, size, NULL, 0); 804 goto out; 805 } 806 807 /* OCF decrypt. */ 808 if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT)) 809 goto out; 810 if (memcmp(cleartext, buffer, size) != 0) { 811 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 812 printf("control:\n"); 813 hexdump(cleartext, size, NULL, 0); 814 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 815 hexdump(buffer, size, NULL, 0); 816 goto out; 817 } 818 819 if (verbose) 820 printf("%s (%zu) matched (cryptodev device %s)\n", 821 alg->name, size, crfind(ses.crid)); 822 823 out: 824 ocf_destroy_session(&ses); 825 free(ciphertext); 826 free(buffer); 827 free(cleartext); 828 free(iv); 829 free(key); 830 } 831 832 static bool 833 ocf_init_eta_session(const struct alg *alg, const char *cipher_key, 834 size_t cipher_key_len, const char *auth_key, size_t auth_key_len, 835 struct ocf_session *ses) 836 { 837 struct session2_op sop; 838 839 ocf_init_sop(&sop); 840 sop.keylen = cipher_key_len; 841 sop.key = cipher_key; 842 sop.cipher = alg->cipher; 843 sop.mackeylen = auth_key_len; 844 sop.mackey = auth_key; 845 sop.mac = alg->mac; 846 return (ocf_init_session(&sop, "ETA", alg->name, ses)); 847 } 848 849 static int 850 ocf_eta(const struct ocf_session *ses, const char *iv, size_t iv_len, 851 const char *aad, size_t aad_len, const char *input, char *output, 852 size_t size, char *digest, int op) 853 { 854 int ret; 855 856 if (aad_len != 0) { 857 struct crypt_aead caead; 858 859 ocf_init_caead(ses, &caead); 860 caead.op = op; 861 caead.len = size; 862 caead.aadlen = aad_len; 863 caead.ivlen = iv_len; 864 caead.src = input; 865 caead.dst = output; 866 caead.aad = aad; 867 caead.tag = digest; 868 caead.iv = iv; 869 870 ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead); 871 } else { 872 struct crypt_op cop; 873 874 ocf_init_cop(ses, &cop); 875 cop.op = op; 876 cop.len = size; 877 cop.src = input; 878 cop.dst = output; 879 cop.mac = digest; 880 cop.iv = iv; 881 882 ret = ioctl(ses->fd, CIOCCRYPT, &cop); 883 } 884 885 if (ret < 0) 886 return (errno); 887 return (0); 888 } 889 890 static void 891 run_eta_test(const struct alg *alg, size_t aad_len, size_t size) 892 { 893 struct ocf_session ses; 894 const EVP_CIPHER *cipher; 895 const EVP_MD *md; 896 char *buffer, *cleartext, *ciphertext; 897 char *iv, *auth_key, *cipher_key; 898 u_int iv_len, auth_key_len, cipher_key_len, digest_len; 899 int error; 900 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 901 902 cipher = alg->evp_cipher(); 903 if (size % EVP_CIPHER_block_size(cipher) != 0) { 904 if (verbose) 905 printf( 906 "%s (%zu, %zu): invalid buffer size (block size %d)\n", 907 alg->name, aad_len, size, 908 EVP_CIPHER_block_size(cipher)); 909 return; 910 } 911 912 /* See comment in run_cipher_test. */ 913 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE && 914 size < AES_BLOCK_LEN) { 915 if (verbose) 916 printf("%s (%zu): invalid buffer size\n", alg->name, 917 size); 918 return; 919 } 920 921 memset(control_digest, 0x3c, sizeof(control_digest)); 922 memset(test_digest, 0x3c, sizeof(test_digest)); 923 924 md = alg->evp_md(); 925 926 cipher_key_len = EVP_CIPHER_key_length(cipher); 927 iv_len = EVP_CIPHER_iv_length(cipher); 928 auth_key_len = EVP_MD_size(md); 929 930 cipher_key = alloc_buffer(cipher_key_len); 931 iv = generate_iv(iv_len, alg); 932 auth_key = alloc_buffer(auth_key_len); 933 cleartext = alloc_buffer(aad_len + size); 934 buffer = malloc(aad_len + size); 935 ciphertext = malloc(aad_len + size); 936 937 /* OpenSSL encrypt + HMAC. */ 938 if (aad_len != 0) 939 memcpy(ciphertext, cleartext, aad_len); 940 openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len, 941 ciphertext + aad_len, size, 1); 942 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len, 943 size) == 0) 944 warnx("OpenSSL %s (%zu, %zu): cipher text unchanged", 945 alg->name, aad_len, size); 946 digest_len = sizeof(control_digest); 947 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext, 948 aad_len + size, (u_char *)control_digest, &digest_len) == NULL) 949 errx(1, "OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name, 950 aad_len, size, ERR_error_string(ERR_get_error(), NULL)); 951 952 if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key, 953 auth_key_len, &ses)) 954 goto out; 955 956 /* OCF encrypt + HMAC. */ 957 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? cleartext : NULL, 958 aad_len, cleartext + aad_len, buffer + aad_len, size, test_digest, 959 COP_ENCRYPT); 960 if (error != 0) { 961 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s", 962 alg->name, aad_len, size, crfind(ses.crid)); 963 goto out; 964 } 965 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) { 966 printf("%s (%zu, %zu) encryption mismatch:\n", alg->name, 967 aad_len, size); 968 printf("control:\n"); 969 hexdump(ciphertext + aad_len, size, NULL, 0); 970 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 971 hexdump(buffer + aad_len, size, NULL, 0); 972 goto out; 973 } 974 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 975 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 976 printf("%s (%zu, %zu) enc hash mismatch in trailer:\n", 977 alg->name, aad_len, size); 978 else 979 printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name, 980 aad_len, size); 981 printf("control:\n"); 982 hexdump(control_digest, sizeof(control_digest), NULL, 0); 983 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 984 hexdump(test_digest, sizeof(test_digest), NULL, 0); 985 goto out; 986 } 987 988 /* OCF HMAC + decrypt. */ 989 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL, 990 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest, 991 COP_DECRYPT); 992 if (error != 0) { 993 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s", 994 alg->name, aad_len, size, crfind(ses.crid)); 995 goto out; 996 } 997 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) { 998 printf("%s (%zu, %zu) decryption mismatch:\n", alg->name, 999 aad_len, size); 1000 printf("control:\n"); 1001 hexdump(cleartext, size, NULL, 0); 1002 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1003 hexdump(buffer, size, NULL, 0); 1004 goto out; 1005 } 1006 1007 /* Verify OCF HMAC + decrypt fails with busted MAC. */ 1008 test_digest[0] ^= 0x1; 1009 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL, 1010 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest, 1011 COP_DECRYPT); 1012 if (error != EBADMSG) { 1013 if (error != 0) 1014 warnc(error, 1015 "cryptodev %s (%zu, %zu) corrupt tag failed for device %s", 1016 alg->name, aad_len, size, crfind(ses.crid)); 1017 else 1018 warnx( 1019 "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s", 1020 alg->name, aad_len, size, crfind(ses.crid)); 1021 goto out; 1022 } 1023 1024 if (verbose) 1025 printf("%s (%zu, %zu) matched (cryptodev device %s)\n", 1026 alg->name, aad_len, size, crfind(ses.crid)); 1027 1028 out: 1029 ocf_destroy_session(&ses); 1030 free(ciphertext); 1031 free(buffer); 1032 free(cleartext); 1033 free(auth_key); 1034 free(iv); 1035 free(cipher_key); 1036 } 1037 1038 static void 1039 openssl_gmac(const struct alg *alg, const EVP_CIPHER *cipher, const char *key, 1040 const char *iv, const char *input, size_t size, char *tag) 1041 { 1042 EVP_CIPHER_CTX *ctx; 1043 int outl; 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_EncryptInit_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 (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)input, 1055 size) != 1) 1056 errx(1, "OpenSSL %s (%zu) update failed: %s", 1057 alg->name, size, ERR_error_string(ERR_get_error(), NULL)); 1058 if (EVP_EncryptFinal_ex(ctx, NULL, &outl) != 1) 1059 errx(1, "OpenSSL %s (%zu) final failed: %s", alg->name, 1060 size, ERR_error_string(ERR_get_error(), NULL)); 1061 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len, 1062 tag) != 1) 1063 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1064 size, ERR_error_string(ERR_get_error(), NULL)); 1065 EVP_CIPHER_CTX_free(ctx); 1066 } 1067 1068 static bool 1069 ocf_mac(const struct alg *alg, const char *input, size_t size, const char *key, 1070 size_t key_len, const char *iv, char *tag, int *cridp) 1071 { 1072 struct ocf_session ses; 1073 struct session2_op sop; 1074 struct crypt_op cop; 1075 1076 ocf_init_sop(&sop); 1077 sop.mackeylen = key_len; 1078 sop.mackey = key; 1079 sop.mac = alg->mac; 1080 if (!ocf_init_session(&sop, "MAC", alg->name, &ses)) 1081 return (false); 1082 1083 ocf_init_cop(&ses, &cop); 1084 cop.op = 0; 1085 cop.len = size; 1086 cop.src = input; 1087 cop.mac = tag; 1088 cop.iv = iv; 1089 1090 if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) { 1091 warn("cryptodev %s (%zu) failed for device %s", alg->name, 1092 size, crfind(ses.crid)); 1093 ocf_destroy_session(&ses); 1094 return (false); 1095 } 1096 1097 *cridp = ses.crid; 1098 ocf_destroy_session(&ses); 1099 return (true); 1100 } 1101 1102 static void 1103 run_gmac_test(const struct alg *alg, size_t size) 1104 { 1105 const EVP_CIPHER *cipher; 1106 char *iv, *key, *buffer; 1107 u_int iv_len, key_len; 1108 int crid; 1109 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN]; 1110 1111 cipher = alg->evp_cipher(); 1112 1113 memset(control_tag, 0x3c, sizeof(control_tag)); 1114 memset(test_tag, 0x3c, sizeof(test_tag)); 1115 1116 key_len = EVP_CIPHER_key_length(cipher); 1117 iv_len = EVP_CIPHER_iv_length(cipher); 1118 1119 key = alloc_buffer(key_len); 1120 iv = generate_iv(iv_len, alg); 1121 buffer = alloc_buffer(size); 1122 1123 /* OpenSSL GMAC. */ 1124 openssl_gmac(alg, cipher, key, iv, buffer, size, control_tag); 1125 1126 /* OCF GMAC. */ 1127 if (!ocf_mac(alg, buffer, size, key, key_len, iv, test_tag, &crid)) 1128 goto out; 1129 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1130 printf("%s (%zu) mismatch:\n", alg->name, size); 1131 printf("control:\n"); 1132 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1133 printf("test (cryptodev device %s):\n", crfind(crid)); 1134 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1135 goto out; 1136 } 1137 1138 if (verbose) 1139 printf("%s (%zu) matched (cryptodev device %s)\n", 1140 alg->name, size, crfind(crid)); 1141 1142 out: 1143 free(buffer); 1144 free(iv); 1145 free(key); 1146 } 1147 1148 static void 1149 openssl_digest(const struct alg *alg, const char *key, u_int key_len, 1150 const char *input, size_t size, char *tag, u_int tag_len) 1151 { 1152 EVP_MD_CTX *mdctx; 1153 EVP_PKEY *pkey; 1154 size_t len; 1155 1156 pkey = EVP_PKEY_new_raw_private_key(alg->pkey, NULL, key, key_len); 1157 if (pkey == NULL) 1158 errx(1, "OpenSSL %s (%zu) pkey new failed: %s", alg->name, 1159 size, ERR_error_string(ERR_get_error(), NULL)); 1160 mdctx = EVP_MD_CTX_new(); 1161 if (mdctx == NULL) 1162 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1163 size, ERR_error_string(ERR_get_error(), NULL)); 1164 if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1) 1165 errx(1, "OpenSSL %s (%zu) digest sign init failed: %s", 1166 alg->name, size, ERR_error_string(ERR_get_error(), NULL)); 1167 if (EVP_DigestSignUpdate(mdctx, input, size) != 1) 1168 errx(1, "OpenSSL %s (%zu) digest update failed: %s", alg->name, 1169 size, ERR_error_string(ERR_get_error(), NULL)); 1170 len = tag_len; 1171 if (EVP_DigestSignFinal(mdctx, tag, &len) != 1) 1172 errx(1, "OpenSSL %s (%zu) digest final failed: %s", alg->name, 1173 size, ERR_error_string(ERR_get_error(), NULL)); 1174 EVP_MD_CTX_free(mdctx); 1175 EVP_PKEY_free(pkey); 1176 } 1177 1178 static void 1179 run_digest_test(const struct alg *alg, size_t size) 1180 { 1181 char *key, *buffer; 1182 u_int key_len; 1183 int crid; 1184 char control_tag[EVP_MAX_MD_SIZE], test_tag[EVP_MAX_MD_SIZE]; 1185 1186 memset(control_tag, 0x3c, sizeof(control_tag)); 1187 memset(test_tag, 0x3c, sizeof(test_tag)); 1188 1189 key_len = alg->key_len; 1190 1191 key = alloc_buffer(key_len); 1192 buffer = alloc_buffer(size); 1193 1194 /* OpenSSL Poly1305. */ 1195 openssl_digest(alg, key, key_len, buffer, size, control_tag, 1196 sizeof(control_tag)); 1197 1198 /* OCF Poly1305. */ 1199 if (!ocf_mac(alg, buffer, size, key, key_len, NULL, test_tag, &crid)) 1200 goto out; 1201 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1202 printf("%s (%zu) mismatch:\n", alg->name, size); 1203 printf("control:\n"); 1204 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1205 printf("test (cryptodev device %s):\n", crfind(crid)); 1206 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1207 goto out; 1208 } 1209 1210 if (verbose) 1211 printf("%s (%zu) matched (cryptodev device %s)\n", 1212 alg->name, size, crfind(crid)); 1213 1214 out: 1215 free(buffer); 1216 free(key); 1217 } 1218 1219 static void 1220 openssl_aead_encrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1221 const char *key, const char *iv, const char *aad, size_t aad_len, 1222 const char *input, char *output, size_t size, char *tag) 1223 { 1224 EVP_CIPHER_CTX *ctx; 1225 int outl, total; 1226 1227 ctx = EVP_CIPHER_CTX_new(); 1228 if (ctx == NULL) 1229 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1230 size, ERR_error_string(ERR_get_error(), NULL)); 1231 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1232 (const u_char *)iv) != 1) 1233 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1234 size, ERR_error_string(ERR_get_error(), NULL)); 1235 EVP_CIPHER_CTX_set_padding(ctx, 0); 1236 if (aad != NULL) { 1237 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1238 aad_len) != 1) 1239 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1240 alg->name, size, 1241 ERR_error_string(ERR_get_error(), NULL)); 1242 } 1243 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 1244 (const u_char *)input, size) != 1) 1245 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 1246 size, ERR_error_string(ERR_get_error(), NULL)); 1247 total = outl; 1248 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 1249 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 1250 size, ERR_error_string(ERR_get_error(), NULL)); 1251 total += outl; 1252 if ((size_t)total != size) 1253 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 1254 size, total); 1255 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len, 1256 tag) != 1) 1257 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1258 size, ERR_error_string(ERR_get_error(), NULL)); 1259 EVP_CIPHER_CTX_free(ctx); 1260 } 1261 1262 #ifdef notused 1263 static bool 1264 openssl_aead_decrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1265 const char *key, const char *iv, const char *aad, size_t aad_len, 1266 const char *input, char *output, size_t size, char *tag) 1267 { 1268 EVP_CIPHER_CTX *ctx; 1269 int outl, total; 1270 bool valid; 1271 1272 ctx = EVP_CIPHER_CTX_new(); 1273 if (ctx == NULL) 1274 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1275 size, ERR_error_string(ERR_get_error(), NULL)); 1276 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1277 (const u_char *)iv) != 1) 1278 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1279 size, ERR_error_string(ERR_get_error(), NULL)); 1280 EVP_CIPHER_CTX_set_padding(ctx, 0); 1281 if (aad != NULL) { 1282 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1283 aad_len) != 1) 1284 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1285 alg->name, size, 1286 ERR_error_string(ERR_get_error(), NULL)); 1287 } 1288 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl, 1289 (const u_char *)input, size) != 1) 1290 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name, 1291 size, ERR_error_string(ERR_get_error(), NULL)); 1292 total = outl; 1293 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, alg->tag_len, 1294 tag) != 1) 1295 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1296 size, ERR_error_string(ERR_get_error(), NULL)); 1297 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1); 1298 total += outl; 1299 if (total != size) 1300 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name, 1301 size, total); 1302 EVP_CIPHER_CTX_free(ctx); 1303 return (valid); 1304 } 1305 #endif 1306 1307 static void 1308 openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1309 const char *key, const char *iv, size_t iv_len, const char *aad, 1310 size_t aad_len, const char *input, char *output, size_t size, char *tag) 1311 { 1312 EVP_CIPHER_CTX *ctx; 1313 int outl, total; 1314 1315 ctx = EVP_CIPHER_CTX_new(); 1316 if (ctx == NULL) 1317 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1318 size, ERR_error_string(ERR_get_error(), NULL)); 1319 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) 1320 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1321 size, ERR_error_string(ERR_get_error(), NULL)); 1322 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1) 1323 errx(1, "OpenSSL %s (%zu) setting iv length failed: %s", alg->name, 1324 size, ERR_error_string(ERR_get_error(), NULL)); 1325 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AES_CBC_MAC_HASH_LEN, NULL) != 1) 1326 errx(1, "OpenSSL %s (%zu) setting tag length failed: %s", alg->name, 1327 size, ERR_error_string(ERR_get_error(), NULL)); 1328 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key, 1329 (const u_char *)iv) != 1) 1330 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1331 size, ERR_error_string(ERR_get_error(), NULL)); 1332 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1) 1333 errx(1, "OpenSSL %s (%zu) unable to set data length: %s", alg->name, 1334 size, ERR_error_string(ERR_get_error(), NULL)); 1335 1336 if (aad != NULL) { 1337 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1338 aad_len) != 1) 1339 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1340 alg->name, size, 1341 ERR_error_string(ERR_get_error(), NULL)); 1342 } 1343 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 1344 (const u_char *)input, size) != 1) 1345 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 1346 size, ERR_error_string(ERR_get_error(), NULL)); 1347 total = outl; 1348 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 1349 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 1350 size, ERR_error_string(ERR_get_error(), NULL)); 1351 total += outl; 1352 if ((size_t)total != size) 1353 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 1354 size, total); 1355 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_CBC_MAC_HASH_LEN, 1356 tag) != 1) 1357 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1358 size, ERR_error_string(ERR_get_error(), NULL)); 1359 EVP_CIPHER_CTX_free(ctx); 1360 } 1361 1362 static bool 1363 ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len, 1364 struct ocf_session *ses) 1365 { 1366 struct session2_op sop; 1367 1368 ocf_init_sop(&sop); 1369 sop.keylen = key_len; 1370 sop.key = key; 1371 sop.cipher = alg->cipher; 1372 return (ocf_init_session(&sop, "AEAD", alg->name, ses)); 1373 } 1374 1375 static int 1376 ocf_aead(const struct ocf_session *ses, const char *iv, size_t iv_len, 1377 const char *aad, size_t aad_len, const char *input, char *output, 1378 size_t size, char *tag, int op) 1379 { 1380 struct crypt_aead caead; 1381 1382 ocf_init_caead(ses, &caead); 1383 caead.op = op; 1384 caead.len = size; 1385 caead.aadlen = aad_len; 1386 caead.ivlen = iv_len; 1387 caead.src = input; 1388 caead.dst = output; 1389 caead.aad = aad; 1390 caead.tag = tag; 1391 caead.iv = iv; 1392 1393 if (ioctl(ses->fd, CIOCCRYPTAEAD, &caead) < 0) 1394 return (errno); 1395 return (0); 1396 } 1397 1398 #define AEAD_MAX_TAG_LEN \ 1399 MAX(MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN), POLY1305_HASH_LEN) 1400 1401 static void 1402 run_aead_test(const struct alg *alg, size_t aad_len, size_t size) 1403 { 1404 struct ocf_session ses; 1405 const EVP_CIPHER *cipher; 1406 char *aad, *buffer, *cleartext, *ciphertext; 1407 char *iv, *key; 1408 u_int iv_len, key_len; 1409 int error; 1410 char control_tag[AEAD_MAX_TAG_LEN], test_tag[AEAD_MAX_TAG_LEN]; 1411 1412 cipher = alg->evp_cipher(); 1413 if (size % EVP_CIPHER_block_size(cipher) != 0) { 1414 if (verbose) 1415 printf( 1416 "%s (%zu, %zu): invalid buffer size (block size %d)\n", 1417 alg->name, aad_len, size, 1418 EVP_CIPHER_block_size(cipher)); 1419 return; 1420 } 1421 1422 memset(control_tag, 0x3c, sizeof(control_tag)); 1423 memset(test_tag, 0x3c, sizeof(test_tag)); 1424 1425 key_len = EVP_CIPHER_key_length(cipher); 1426 iv_len = EVP_CIPHER_iv_length(cipher); 1427 1428 /* 1429 * AES-CCM can have varying IV lengths; however, for the moment 1430 * we only support AES_CCM_IV_LEN (12). So if the sizes are 1431 * different, we'll fail. 1432 */ 1433 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE && 1434 iv_len != AES_CCM_IV_LEN) { 1435 if (verbose) 1436 printf("OpenSSL CCM IV length (%d) != AES_CCM_IV_LEN", 1437 iv_len); 1438 return; 1439 } 1440 1441 key = alloc_buffer(key_len); 1442 iv = generate_iv(iv_len, alg); 1443 cleartext = alloc_buffer(size); 1444 buffer = malloc(size); 1445 ciphertext = malloc(size); 1446 if (aad_len != 0) 1447 aad = alloc_buffer(aad_len); 1448 else 1449 aad = NULL; 1450 1451 /* OpenSSL encrypt */ 1452 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE) 1453 openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad, 1454 aad_len, cleartext, ciphertext, size, control_tag); 1455 else 1456 openssl_aead_encrypt(alg, cipher, key, iv, aad, aad_len, 1457 cleartext, ciphertext, size, control_tag); 1458 1459 if (!ocf_init_aead_session(alg, key, key_len, &ses)) 1460 goto out; 1461 1462 /* OCF encrypt */ 1463 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, cleartext, buffer, 1464 size, test_tag, COP_ENCRYPT); 1465 if (error != 0) { 1466 warnc(error, "cryptodev %s (%zu, %zu) failed for device %s", 1467 alg->name, aad_len, size, crfind(ses.crid)); 1468 goto out; 1469 } 1470 if (memcmp(ciphertext, buffer, size) != 0) { 1471 printf("%s (%zu, %zu) encryption mismatch:\n", alg->name, 1472 aad_len, size); 1473 printf("control:\n"); 1474 hexdump(ciphertext, size, NULL, 0); 1475 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1476 hexdump(buffer, size, NULL, 0); 1477 goto out; 1478 } 1479 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1480 printf("%s (%zu, %zu) enc tag mismatch:\n", alg->name, aad_len, 1481 size); 1482 printf("control:\n"); 1483 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1484 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1485 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1486 goto out; 1487 } 1488 1489 /* OCF decrypt */ 1490 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext, 1491 buffer, size, control_tag, COP_DECRYPT); 1492 if (error != 0) { 1493 warnc(error, "cryptodev %s (%zu, %zu) failed for device %s", 1494 alg->name, aad_len, size, crfind(ses.crid)); 1495 goto out; 1496 } 1497 if (memcmp(cleartext, buffer, size) != 0) { 1498 printf("%s (%zu, %zu) decryption mismatch:\n", alg->name, 1499 aad_len, size); 1500 printf("control:\n"); 1501 hexdump(cleartext, size, NULL, 0); 1502 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1503 hexdump(buffer, size, NULL, 0); 1504 goto out; 1505 } 1506 1507 /* Verify OCF decrypt fails with busted tag. */ 1508 test_tag[0] ^= 0x1; 1509 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext, 1510 buffer, size, test_tag, COP_DECRYPT); 1511 if (error != EBADMSG) { 1512 if (error != 0) 1513 warnc(error, 1514 "cryptodev %s (%zu, %zu) corrupt tag failed for device %s", 1515 alg->name, aad_len, size, crfind(ses.crid)); 1516 else 1517 warnx( 1518 "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s", 1519 alg->name, aad_len, size, crfind(ses.crid)); 1520 goto out; 1521 } 1522 1523 if (verbose) 1524 printf("%s (%zu, %zu) matched (cryptodev device %s)\n", 1525 alg->name, aad_len, size, crfind(ses.crid)); 1526 1527 out: 1528 ocf_destroy_session(&ses); 1529 free(aad); 1530 free(ciphertext); 1531 free(buffer); 1532 free(cleartext); 1533 free(iv); 1534 free(key); 1535 } 1536 1537 static void 1538 run_test(const struct alg *alg, size_t aad_len, size_t size) 1539 { 1540 1541 switch (alg->type) { 1542 case T_HASH: 1543 run_hash_test(alg, size); 1544 break; 1545 case T_HMAC: 1546 run_hmac_test(alg, size); 1547 break; 1548 case T_GMAC: 1549 run_gmac_test(alg, size); 1550 break; 1551 case T_DIGEST: 1552 run_digest_test(alg, size); 1553 break; 1554 case T_CIPHER: 1555 run_cipher_test(alg, size); 1556 break; 1557 case T_ETA: 1558 run_eta_test(alg, aad_len, size); 1559 break; 1560 case T_AEAD: 1561 run_aead_test(alg, aad_len, size); 1562 break; 1563 } 1564 } 1565 1566 static void 1567 run_test_sizes(const struct alg *alg) 1568 { 1569 u_int i, j; 1570 1571 switch (alg->type) { 1572 default: 1573 for (i = 0; i < nsizes; i++) 1574 run_test(alg, 0, sizes[i]); 1575 break; 1576 case T_ETA: 1577 case T_AEAD: 1578 for (i = 0; i < naad_sizes; i++) 1579 for (j = 0; j < nsizes; j++) 1580 run_test(alg, aad_sizes[i], sizes[j]); 1581 break; 1582 } 1583 } 1584 1585 static void 1586 run_hash_tests(void) 1587 { 1588 u_int i; 1589 1590 for (i = 0; i < nitems(algs); i++) 1591 if (algs[i].type == T_HASH) 1592 run_test_sizes(&algs[i]); 1593 } 1594 1595 static void 1596 run_mac_tests(void) 1597 { 1598 u_int i; 1599 1600 for (i = 0; i < nitems(algs); i++) 1601 if (algs[i].type == T_HMAC || algs[i].type == T_GMAC || 1602 algs[i].type == T_DIGEST) 1603 run_test_sizes(&algs[i]); 1604 } 1605 1606 static void 1607 run_cipher_tests(void) 1608 { 1609 u_int i; 1610 1611 for (i = 0; i < nitems(algs); i++) 1612 if (algs[i].type == T_CIPHER) 1613 run_test_sizes(&algs[i]); 1614 } 1615 1616 static void 1617 run_eta_tests(void) 1618 { 1619 const struct alg *cipher, *mac; 1620 struct alg *eta; 1621 u_int i, j; 1622 1623 for (i = 0; i < nitems(algs); i++) { 1624 cipher = &algs[i]; 1625 if (cipher->type != T_CIPHER) 1626 continue; 1627 for (j = 0; j < nitems(algs); j++) { 1628 mac = &algs[j]; 1629 if (mac->type != T_HMAC) 1630 continue; 1631 eta = build_eta(cipher, mac); 1632 run_test_sizes(eta); 1633 free_eta(eta); 1634 } 1635 } 1636 } 1637 1638 static void 1639 run_aead_tests(void) 1640 { 1641 u_int i; 1642 1643 for (i = 0; i < nitems(algs); i++) 1644 if (algs[i].type == T_AEAD) 1645 run_test_sizes(&algs[i]); 1646 } 1647 1648 int 1649 main(int ac, char **av) 1650 { 1651 const char *algname; 1652 const struct alg *alg; 1653 struct alg *eta; 1654 char *cp; 1655 size_t base_size; 1656 u_int i; 1657 bool testall; 1658 int ch; 1659 1660 algname = NULL; 1661 requested_crid = CRYPTO_FLAG_HARDWARE; 1662 testall = false; 1663 verbose = false; 1664 while ((ch = getopt(ac, av, "A:a:d:vz")) != -1) 1665 switch (ch) { 1666 case 'A': 1667 if (naad_sizes >= nitems(aad_sizes)) { 1668 warnx("Too many AAD sizes, ignoring extras"); 1669 break; 1670 } 1671 aad_sizes[naad_sizes] = strtol(optarg, &cp, 0); 1672 if (*cp != '\0') 1673 errx(1, "Bad AAD size %s", optarg); 1674 naad_sizes++; 1675 break; 1676 case 'a': 1677 algname = optarg; 1678 break; 1679 case 'd': 1680 requested_crid = crlookup(optarg); 1681 break; 1682 case 'v': 1683 verbose = true; 1684 break; 1685 case 'z': 1686 testall = true; 1687 break; 1688 default: 1689 usage(); 1690 } 1691 ac -= optind; 1692 av += optind; 1693 nsizes = 0; 1694 while (ac > 0) { 1695 if (nsizes >= nitems(sizes)) { 1696 warnx("Too many sizes, ignoring extras"); 1697 break; 1698 } 1699 sizes[nsizes] = strtol(av[0], &cp, 0); 1700 if (*cp != '\0') 1701 errx(1, "Bad size %s", av[0]); 1702 nsizes++; 1703 ac--; 1704 av++; 1705 } 1706 1707 if (algname == NULL) 1708 errx(1, "Algorithm required"); 1709 1710 if (naad_sizes == 0) { 1711 if (testall) { 1712 for (i = 0; i <= 32; i++) { 1713 aad_sizes[naad_sizes] = i; 1714 naad_sizes++; 1715 } 1716 1717 base_size = 32; 1718 while (base_size * 2 < 512) { 1719 base_size *= 2; 1720 assert(naad_sizes < nitems(aad_sizes)); 1721 aad_sizes[naad_sizes] = base_size; 1722 naad_sizes++; 1723 } 1724 } else { 1725 aad_sizes[0] = 0; 1726 naad_sizes = 1; 1727 } 1728 } 1729 1730 if (nsizes == 0) { 1731 if (testall) { 1732 for (i = 1; i <= EALG_MAX_BLOCK_LEN; i++) { 1733 sizes[nsizes] = i; 1734 nsizes++; 1735 } 1736 1737 for (i = EALG_MAX_BLOCK_LEN + 8; 1738 i <= EALG_MAX_BLOCK_LEN * 2; i += 8) { 1739 sizes[nsizes] = i; 1740 nsizes++; 1741 } 1742 1743 base_size = EALG_MAX_BLOCK_LEN * 2; 1744 while (base_size * 2 < 240 * 1024) { 1745 base_size *= 2; 1746 assert(nsizes < nitems(sizes)); 1747 sizes[nsizes] = base_size; 1748 nsizes++; 1749 } 1750 1751 if (sizes[nsizes - 1] < 240 * 1024) { 1752 assert(nsizes < nitems(sizes)); 1753 sizes[nsizes] = 240 * 1024; 1754 nsizes++; 1755 } 1756 } else { 1757 sizes[0] = 16; 1758 nsizes = 1; 1759 } 1760 } 1761 1762 if (strcasecmp(algname, "hash") == 0) 1763 run_hash_tests(); 1764 else if (strcasecmp(algname, "mac") == 0) 1765 run_mac_tests(); 1766 else if (strcasecmp(algname, "cipher") == 0) 1767 run_cipher_tests(); 1768 else if (strcasecmp(algname, "eta") == 0) 1769 run_eta_tests(); 1770 else if (strcasecmp(algname, "aead") == 0) 1771 run_aead_tests(); 1772 else if (strcasecmp(algname, "all") == 0) { 1773 run_hash_tests(); 1774 run_mac_tests(); 1775 run_cipher_tests(); 1776 run_eta_tests(); 1777 run_aead_tests(); 1778 } else if (strchr(algname, '+') != NULL) { 1779 eta = build_eta_name(algname); 1780 run_test_sizes(eta); 1781 free_eta(eta); 1782 } else { 1783 alg = find_alg(algname); 1784 if (alg == NULL) 1785 errx(1, "Invalid algorithm %s", algname); 1786 run_test_sizes(alg); 1787 } 1788 1789 return (0); 1790 } 1791