1 /*- 2 * Copyright (c) 2017 Chelsio Communications, Inc. 3 * All rights reserved. 4 * Written by: John Baldwin <jhb@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 /*- 28 * Copyright (c) 2004 Sam Leffler, Errno Consulting 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 1. Redistributions of source code must retain the above copyright 35 * notice, this list of conditions and the following disclaimer, 36 * without modification. 37 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 38 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 39 * redistribution must be conditioned upon including a substantially 40 * similar Disclaimer requirement for further binary redistribution. 41 * 3. Neither the names of the above-listed copyright holders nor the names 42 * of any contributors may be used to endorse or promote products derived 43 * from this software without specific prior written permission. 44 * 45 * NO WARRANTY 46 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 48 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 49 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 50 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 51 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 54 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 56 * THE POSSIBILITY OF SUCH DAMAGES. 57 * 58 * $FreeBSD$ 59 */ 60 61 /* 62 * A different tool for checking hardware crypto support. Whereas 63 * cryptotest is focused on simple performance numbers, this tool is 64 * focused on correctness. For each crypto operation, it performs the 65 * operation once in software via OpenSSL and a second time via 66 * OpenCrypto and compares the results. 67 * 68 * cryptocheck [-vz] [-A aad length] [-a algorithm] [-d dev] [size ...] 69 * 70 * Options: 71 * -v Verbose. 72 * -z Run all algorithms on a variety of buffer sizes. 73 * 74 * Supported algorithms: 75 * all Run all tests 76 * hmac Run all hmac tests 77 * blkcipher Run all block cipher tests 78 * authenc Run all authenticated encryption tests 79 * aead Run all authenticated encryption with associated data 80 * tests 81 * 82 * HMACs: 83 * sha1 sha1 hmac 84 * sha256 256-bit sha2 hmac 85 * sha384 384-bit sha2 hmac 86 * sha512 512-bit sha2 hmac 87 * blake2b Blake2-B 88 * blake2s Blake2-S 89 * 90 * Block Ciphers: 91 * aes-cbc 128-bit aes cbc 92 * aes-cbc192 192-bit aes cbc 93 * aes-cbc256 256-bit aes cbc 94 * aes-ctr 128-bit aes ctr 95 * aes-ctr192 192-bit aes ctr 96 * aes-ctr256 256-bit aes ctr 97 * aes-xts 128-bit aes xts 98 * aes-xts256 256-bit aes xts 99 * chacha20 100 * 101 * Authenticated Encryption: 102 * <block cipher>+<hmac> 103 * 104 * Authenticated Encryption with Associated Data: 105 * aes-gcm 128-bit aes gcm 106 * aes-gcm192 192-bit aes gcm 107 * aes-gcm256 256-bit aes gcm 108 */ 109 110 #include <sys/param.h> 111 #include <assert.h> 112 #include <err.h> 113 #include <fcntl.h> 114 #include <libutil.h> 115 #include <stdbool.h> 116 #include <stdio.h> 117 #include <string.h> 118 #include <unistd.h> 119 120 #include <openssl/err.h> 121 #include <openssl/hmac.h> 122 123 #include <crypto/cryptodev.h> 124 125 /* XXX: Temporary hack */ 126 #ifndef COP_F_CIPHER_FIRST 127 #define COP_F_CIPHER_FIRST 0x0001 /* Cipher before MAC. */ 128 #endif 129 130 struct alg { 131 const char *name; 132 int cipher; 133 int mac; 134 enum { T_HASH, T_HMAC, T_BLKCIPHER, T_AUTHENC, T_GCM } type; 135 const EVP_CIPHER *(*evp_cipher)(void); 136 const EVP_MD *(*evp_md)(void); 137 } algs[] = { 138 { .name = "sha1", .mac = CRYPTO_SHA1, .type = T_HASH, 139 .evp_md = EVP_sha1 }, 140 { .name = "sha224", .mac = CRYPTO_SHA2_224, .type = T_HASH, 141 .evp_md = EVP_sha224 }, 142 { .name = "sha256", .mac = CRYPTO_SHA2_256, .type = T_HASH, 143 .evp_md = EVP_sha256 }, 144 { .name = "sha384", .mac = CRYPTO_SHA2_384, .type = T_HASH, 145 .evp_md = EVP_sha384 }, 146 { .name = "sha512", .mac = CRYPTO_SHA2_512, .type = T_HASH, 147 .evp_md = EVP_sha512 }, 148 { .name = "sha1hmac", .mac = CRYPTO_SHA1_HMAC, .type = T_HMAC, 149 .evp_md = EVP_sha1 }, 150 { .name = "sha224hmac", .mac = CRYPTO_SHA2_224_HMAC, .type = T_HMAC, 151 .evp_md = EVP_sha224 }, 152 { .name = "sha256hmac", .mac = CRYPTO_SHA2_256_HMAC, .type = T_HMAC, 153 .evp_md = EVP_sha256 }, 154 { .name = "sha384hmac", .mac = CRYPTO_SHA2_384_HMAC, .type = T_HMAC, 155 .evp_md = EVP_sha384 }, 156 { .name = "sha512hmac", .mac = CRYPTO_SHA2_512_HMAC, .type = T_HMAC, 157 .evp_md = EVP_sha512 }, 158 { .name = "blake2b", .mac = CRYPTO_BLAKE2B, .type = T_HASH, 159 .evp_md = EVP_blake2b512 }, 160 { .name = "blake2s", .mac = CRYPTO_BLAKE2S, .type = T_HASH, 161 .evp_md = EVP_blake2s256 }, 162 { .name = "aes-cbc", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 163 .evp_cipher = EVP_aes_128_cbc }, 164 { .name = "aes-cbc192", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 165 .evp_cipher = EVP_aes_192_cbc }, 166 { .name = "aes-cbc256", .cipher = CRYPTO_AES_CBC, .type = T_BLKCIPHER, 167 .evp_cipher = EVP_aes_256_cbc }, 168 { .name = "aes-ctr", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 169 .evp_cipher = EVP_aes_128_ctr }, 170 { .name = "aes-ctr192", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 171 .evp_cipher = EVP_aes_192_ctr }, 172 { .name = "aes-ctr256", .cipher = CRYPTO_AES_ICM, .type = T_BLKCIPHER, 173 .evp_cipher = EVP_aes_256_ctr }, 174 { .name = "aes-xts", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER, 175 .evp_cipher = EVP_aes_128_xts }, 176 { .name = "aes-xts256", .cipher = CRYPTO_AES_XTS, .type = T_BLKCIPHER, 177 .evp_cipher = EVP_aes_256_xts }, 178 { .name = "chacha20", .cipher = CRYPTO_CHACHA20, .type = T_BLKCIPHER, 179 .evp_cipher = EVP_chacha20 }, 180 { .name = "aes-gcm", .cipher = CRYPTO_AES_NIST_GCM_16, 181 .mac = CRYPTO_AES_128_NIST_GMAC, .type = T_GCM, 182 .evp_cipher = EVP_aes_128_gcm }, 183 { .name = "aes-gcm192", .cipher = CRYPTO_AES_NIST_GCM_16, 184 .mac = CRYPTO_AES_192_NIST_GMAC, .type = T_GCM, 185 .evp_cipher = EVP_aes_192_gcm }, 186 { .name = "aes-gcm256", .cipher = CRYPTO_AES_NIST_GCM_16, 187 .mac = CRYPTO_AES_256_NIST_GMAC, .type = T_GCM, 188 .evp_cipher = EVP_aes_256_gcm }, 189 }; 190 191 static bool verbose; 192 static int crid; 193 static size_t aad_len; 194 195 static void 196 usage(void) 197 { 198 fprintf(stderr, 199 "usage: cryptocheck [-z] [-a algorithm] [-d dev] [size ...]\n"); 200 exit(1); 201 } 202 203 static struct alg * 204 find_alg(const char *name) 205 { 206 u_int i; 207 208 for (i = 0; i < nitems(algs); i++) 209 if (strcasecmp(algs[i].name, name) == 0) 210 return (&algs[i]); 211 return (NULL); 212 } 213 214 static struct alg * 215 build_authenc(struct alg *cipher, struct alg *hmac) 216 { 217 static struct alg authenc; 218 char *name; 219 220 assert(cipher->type == T_BLKCIPHER); 221 assert(hmac->type == T_HMAC); 222 memset(&authenc, 0, sizeof(authenc)); 223 asprintf(&name, "%s+%s", cipher->name, hmac->name); 224 authenc.name = name; 225 authenc.cipher = cipher->cipher; 226 authenc.mac = hmac->mac; 227 authenc.type = T_AUTHENC; 228 authenc.evp_cipher = cipher->evp_cipher; 229 authenc.evp_md = hmac->evp_md; 230 return (&authenc); 231 } 232 233 static struct alg * 234 build_authenc_name(const char *name) 235 { 236 struct alg *cipher, *hmac; 237 const char *hmac_name; 238 char *cp, *cipher_name; 239 240 cp = strchr(name, '+'); 241 cipher_name = strndup(name, cp - name); 242 hmac_name = cp + 1; 243 cipher = find_alg(cipher_name); 244 free(cipher_name); 245 if (cipher == NULL) 246 errx(1, "Invalid cipher %s", cipher_name); 247 hmac = find_alg(hmac_name); 248 if (hmac == NULL) 249 errx(1, "Invalid hash %s", hmac_name); 250 return (build_authenc(cipher, hmac)); 251 } 252 253 static int 254 devcrypto(void) 255 { 256 static int fd = -1; 257 258 if (fd < 0) { 259 fd = open("/dev/crypto", O_RDWR | O_CLOEXEC, 0); 260 if (fd < 0) 261 err(1, "/dev/crypto"); 262 } 263 return (fd); 264 } 265 266 static int 267 crlookup(const char *devname) 268 { 269 struct crypt_find_op find; 270 271 if (strncmp(devname, "soft", 4) == 0) 272 return CRYPTO_FLAG_SOFTWARE; 273 274 find.crid = -1; 275 strlcpy(find.name, devname, sizeof(find.name)); 276 if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) 277 err(1, "ioctl(CIOCFINDDEV)"); 278 return (find.crid); 279 } 280 281 const char * 282 crfind(int crid) 283 { 284 static struct crypt_find_op find; 285 286 if (crid == CRYPTO_FLAG_SOFTWARE) 287 return ("soft"); 288 else if (crid == CRYPTO_FLAG_HARDWARE) 289 return ("unknown"); 290 291 bzero(&find, sizeof(find)); 292 find.crid = crid; 293 if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1) 294 err(1, "ioctl(CIOCFINDDEV): crid %d", crid); 295 return (find.name); 296 } 297 298 static int 299 crget(void) 300 { 301 int fd; 302 303 if (ioctl(devcrypto(), CRIOGET, &fd) == -1) 304 err(1, "ioctl(CRIOGET)"); 305 if (fcntl(fd, F_SETFD, 1) == -1) 306 err(1, "fcntl(F_SETFD) (crget)"); 307 return fd; 308 } 309 310 static char 311 rdigit(void) 312 { 313 const char a[] = { 314 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41, 315 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01 316 }; 317 return 0x20+a[random()%nitems(a)]; 318 } 319 320 static char * 321 alloc_buffer(size_t len) 322 { 323 char *buf; 324 size_t i; 325 326 buf = malloc(len); 327 for (i = 0; i < len; i++) 328 buf[i] = rdigit(); 329 return (buf); 330 } 331 332 static char * 333 generate_iv(size_t len, struct alg *alg) 334 { 335 char *iv; 336 337 iv = alloc_buffer(len); 338 switch (alg->cipher) { 339 case CRYPTO_AES_ICM: 340 /* Clear the low 32 bits of the IV to hold the counter. */ 341 iv[len - 4] = 0; 342 iv[len - 3] = 0; 343 iv[len - 2] = 0; 344 iv[len - 1] = 0; 345 break; 346 case CRYPTO_AES_XTS: 347 /* 348 * Clear the low 64-bits to only store a 64-bit block 349 * number. 350 */ 351 iv[len - 8] = 0; 352 iv[len - 7] = 0; 353 iv[len - 6] = 0; 354 iv[len - 5] = 0; 355 iv[len - 4] = 0; 356 iv[len - 3] = 0; 357 iv[len - 2] = 0; 358 iv[len - 1] = 0; 359 break; 360 } 361 return (iv); 362 } 363 364 static bool 365 ocf_hash(struct alg *alg, const char *buffer, size_t size, char *digest, 366 int *cridp) 367 { 368 struct session2_op sop; 369 struct crypt_op cop; 370 int fd; 371 372 memset(&sop, 0, sizeof(sop)); 373 memset(&cop, 0, sizeof(cop)); 374 sop.crid = crid; 375 sop.mac = alg->mac; 376 fd = crget(); 377 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 378 warn("cryptodev %s HASH not supported for device %s", 379 alg->name, crfind(crid)); 380 close(fd); 381 return (false); 382 } 383 384 cop.ses = sop.ses; 385 cop.op = 0; 386 cop.len = size; 387 cop.src = (char *)buffer; 388 cop.dst = NULL; 389 cop.mac = digest; 390 cop.iv = NULL; 391 392 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 393 warn("cryptodev %s (%zu) HASH failed for device %s", alg->name, 394 size, crfind(crid)); 395 close(fd); 396 return (false); 397 } 398 399 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 400 warn("ioctl(CIOCFSESSION)"); 401 402 close(fd); 403 *cridp = sop.crid; 404 return (true); 405 } 406 407 static void 408 openssl_hash(struct alg *alg, const EVP_MD *md, const void *buffer, 409 size_t size, void *digest_out, unsigned *digest_sz_out) 410 { 411 EVP_MD_CTX *mdctx; 412 const char *errs; 413 int rc; 414 415 errs = ""; 416 417 mdctx = EVP_MD_CTX_create(); 418 if (mdctx == NULL) 419 goto err_out; 420 421 rc = EVP_DigestInit_ex(mdctx, md, NULL); 422 if (rc != 1) 423 goto err_out; 424 425 rc = EVP_DigestUpdate(mdctx, buffer, size); 426 if (rc != 1) 427 goto err_out; 428 429 rc = EVP_DigestFinal_ex(mdctx, digest_out, digest_sz_out); 430 if (rc != 1) 431 goto err_out; 432 433 EVP_MD_CTX_destroy(mdctx); 434 return; 435 436 err_out: 437 errx(1, "OpenSSL %s HASH failed%s: %s", alg->name, errs, 438 ERR_error_string(ERR_get_error(), NULL)); 439 } 440 441 static void 442 run_hash_test(struct alg *alg, size_t size) 443 { 444 const EVP_MD *md; 445 char *buffer; 446 u_int digest_len; 447 int crid; 448 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 449 450 memset(control_digest, 0x3c, sizeof(control_digest)); 451 memset(test_digest, 0x3c, sizeof(test_digest)); 452 453 md = alg->evp_md(); 454 assert(EVP_MD_size(md) <= sizeof(control_digest)); 455 456 buffer = alloc_buffer(size); 457 458 /* OpenSSL HASH. */ 459 digest_len = sizeof(control_digest); 460 openssl_hash(alg, md, buffer, size, control_digest, &digest_len); 461 462 /* cryptodev HASH. */ 463 if (!ocf_hash(alg, buffer, size, test_digest, &crid)) 464 goto out; 465 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 466 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 467 printf("%s (%zu) mismatch in trailer:\n", 468 alg->name, size); 469 else 470 printf("%s (%zu) mismatch:\n", alg->name, size); 471 printf("control:\n"); 472 hexdump(control_digest, sizeof(control_digest), NULL, 0); 473 printf("test (cryptodev device %s):\n", crfind(crid)); 474 hexdump(test_digest, sizeof(test_digest), NULL, 0); 475 goto out; 476 } 477 478 if (verbose) 479 printf("%s (%zu) matched (cryptodev device %s)\n", 480 alg->name, size, crfind(crid)); 481 482 out: 483 free(buffer); 484 } 485 486 static bool 487 ocf_hmac(struct alg *alg, const char *buffer, size_t size, const char *key, 488 size_t key_len, char *digest, int *cridp) 489 { 490 struct session2_op sop; 491 struct crypt_op cop; 492 int fd; 493 494 memset(&sop, 0, sizeof(sop)); 495 memset(&cop, 0, sizeof(cop)); 496 sop.crid = crid; 497 sop.mackeylen = key_len; 498 sop.mackey = (char *)key; 499 sop.mac = alg->mac; 500 fd = crget(); 501 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 502 warn("cryptodev %s HMAC not supported for device %s", 503 alg->name, crfind(crid)); 504 close(fd); 505 return (false); 506 } 507 508 cop.ses = sop.ses; 509 cop.op = 0; 510 cop.len = size; 511 cop.src = (char *)buffer; 512 cop.dst = NULL; 513 cop.mac = digest; 514 cop.iv = NULL; 515 516 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 517 warn("cryptodev %s (%zu) HMAC failed for device %s", alg->name, 518 size, crfind(crid)); 519 close(fd); 520 return (false); 521 } 522 523 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 524 warn("ioctl(CIOCFSESSION)"); 525 526 close(fd); 527 *cridp = sop.crid; 528 return (true); 529 } 530 531 static void 532 run_hmac_test(struct alg *alg, size_t size) 533 { 534 const EVP_MD *md; 535 char *key, *buffer; 536 u_int key_len, digest_len; 537 int crid; 538 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 539 540 memset(control_digest, 0x3c, sizeof(control_digest)); 541 memset(test_digest, 0x3c, sizeof(test_digest)); 542 543 md = alg->evp_md(); 544 key_len = EVP_MD_size(md); 545 assert(EVP_MD_size(md) <= sizeof(control_digest)); 546 547 key = alloc_buffer(key_len); 548 buffer = alloc_buffer(size); 549 550 /* OpenSSL HMAC. */ 551 digest_len = sizeof(control_digest); 552 if (HMAC(md, key, key_len, (u_char *)buffer, size, 553 (u_char *)control_digest, &digest_len) == NULL) 554 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name, 555 size, ERR_error_string(ERR_get_error(), NULL)); 556 557 /* cryptodev HMAC. */ 558 if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid)) 559 goto out; 560 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 561 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 562 printf("%s (%zu) mismatch in trailer:\n", 563 alg->name, size); 564 else 565 printf("%s (%zu) mismatch:\n", alg->name, size); 566 printf("control:\n"); 567 hexdump(control_digest, sizeof(control_digest), NULL, 0); 568 printf("test (cryptodev device %s):\n", crfind(crid)); 569 hexdump(test_digest, sizeof(test_digest), NULL, 0); 570 goto out; 571 } 572 573 if (verbose) 574 printf("%s (%zu) matched (cryptodev device %s)\n", 575 alg->name, size, crfind(crid)); 576 577 out: 578 free(buffer); 579 free(key); 580 } 581 582 static void 583 openssl_cipher(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 584 const char *iv, const char *input, char *output, size_t size, int enc) 585 { 586 EVP_CIPHER_CTX *ctx; 587 int outl, total; 588 589 ctx = EVP_CIPHER_CTX_new(); 590 if (ctx == NULL) 591 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 592 size, ERR_error_string(ERR_get_error(), NULL)); 593 if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key, 594 (const u_char *)iv, enc) != 1) 595 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 596 size, ERR_error_string(ERR_get_error(), NULL)); 597 EVP_CIPHER_CTX_set_padding(ctx, 0); 598 if (EVP_CipherUpdate(ctx, (u_char *)output, &outl, 599 (const u_char *)input, size) != 1) 600 errx(1, "OpenSSL %s (%zu) cipher update failed: %s", alg->name, 601 size, ERR_error_string(ERR_get_error(), NULL)); 602 total = outl; 603 if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 604 errx(1, "OpenSSL %s (%zu) cipher final failed: %s", alg->name, 605 size, ERR_error_string(ERR_get_error(), NULL)); 606 total += outl; 607 if (total != size) 608 errx(1, "OpenSSL %s (%zu) cipher size mismatch: %d", alg->name, 609 size, total); 610 EVP_CIPHER_CTX_free(ctx); 611 } 612 613 static bool 614 ocf_cipher(struct alg *alg, const char *key, size_t key_len, 615 const char *iv, const char *input, char *output, size_t size, int enc, 616 int *cridp) 617 { 618 struct session2_op sop; 619 struct crypt_op cop; 620 int fd; 621 622 memset(&sop, 0, sizeof(sop)); 623 memset(&cop, 0, sizeof(cop)); 624 sop.crid = crid; 625 sop.keylen = key_len; 626 sop.key = (char *)key; 627 sop.cipher = alg->cipher; 628 fd = crget(); 629 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 630 warn("cryptodev %s block cipher not supported for device %s", 631 alg->name, crfind(crid)); 632 close(fd); 633 return (false); 634 } 635 636 cop.ses = sop.ses; 637 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT; 638 cop.len = size; 639 cop.src = (char *)input; 640 cop.dst = output; 641 cop.mac = NULL; 642 cop.iv = (char *)iv; 643 644 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 645 warn("cryptodev %s (%zu) block cipher failed for device %s", 646 alg->name, size, crfind(crid)); 647 close(fd); 648 return (false); 649 } 650 651 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 652 warn("ioctl(CIOCFSESSION)"); 653 654 close(fd); 655 *cridp = sop.crid; 656 return (true); 657 } 658 659 static void 660 run_blkcipher_test(struct alg *alg, size_t size) 661 { 662 const EVP_CIPHER *cipher; 663 char *buffer, *cleartext, *ciphertext; 664 char *iv, *key; 665 u_int iv_len, key_len; 666 int crid; 667 668 cipher = alg->evp_cipher(); 669 if (size % EVP_CIPHER_block_size(cipher) != 0) { 670 if (verbose) 671 printf( 672 "%s (%zu): invalid buffer size (block size %d)\n", 673 alg->name, size, EVP_CIPHER_block_size(cipher)); 674 return; 675 } 676 677 key_len = EVP_CIPHER_key_length(cipher); 678 iv_len = EVP_CIPHER_iv_length(cipher); 679 680 key = alloc_buffer(key_len); 681 iv = generate_iv(iv_len, alg); 682 cleartext = alloc_buffer(size); 683 buffer = malloc(size); 684 ciphertext = malloc(size); 685 686 /* OpenSSL cipher. */ 687 openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1); 688 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) 689 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, 690 size); 691 openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0); 692 if (memcmp(cleartext, buffer, size) != 0) { 693 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size); 694 printf("original:\n"); 695 hexdump(cleartext, size, NULL, 0); 696 printf("decrypted:\n"); 697 hexdump(buffer, size, NULL, 0); 698 exit(1); 699 } 700 701 /* OCF encrypt. */ 702 if (!ocf_cipher(alg, key, key_len, iv, cleartext, buffer, size, 1, 703 &crid)) 704 goto out; 705 if (memcmp(ciphertext, buffer, size) != 0) { 706 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 707 printf("control:\n"); 708 hexdump(ciphertext, size, NULL, 0); 709 printf("test (cryptodev device %s):\n", crfind(crid)); 710 hexdump(buffer, size, NULL, 0); 711 goto out; 712 } 713 714 /* OCF decrypt. */ 715 if (!ocf_cipher(alg, key, key_len, iv, ciphertext, buffer, size, 0, 716 &crid)) 717 goto out; 718 if (memcmp(cleartext, buffer, size) != 0) { 719 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 720 printf("control:\n"); 721 hexdump(cleartext, size, NULL, 0); 722 printf("test (cryptodev device %s):\n", crfind(crid)); 723 hexdump(buffer, size, NULL, 0); 724 goto out; 725 } 726 727 if (verbose) 728 printf("%s (%zu) matched (cryptodev device %s)\n", 729 alg->name, size, crfind(crid)); 730 731 out: 732 free(ciphertext); 733 free(buffer); 734 free(cleartext); 735 free(iv); 736 free(key); 737 } 738 739 static bool 740 ocf_authenc(struct alg *alg, const char *cipher_key, size_t cipher_key_len, 741 const char *iv, size_t iv_len, const char *auth_key, size_t auth_key_len, 742 const char *aad, size_t aad_len, const char *input, char *output, 743 size_t size, char *digest, int enc, int *cridp) 744 { 745 struct session2_op sop; 746 int fd; 747 748 memset(&sop, 0, sizeof(sop)); 749 sop.crid = crid; 750 sop.keylen = cipher_key_len; 751 sop.key = (char *)cipher_key; 752 sop.cipher = alg->cipher; 753 sop.mackeylen = auth_key_len; 754 sop.mackey = (char *)auth_key; 755 sop.mac = alg->mac; 756 fd = crget(); 757 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 758 warn("cryptodev %s AUTHENC not supported for device %s", 759 alg->name, crfind(crid)); 760 close(fd); 761 return (false); 762 } 763 764 if (aad_len != 0) { 765 struct crypt_aead caead; 766 767 memset(&caead, 0, sizeof(caead)); 768 caead.ses = sop.ses; 769 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT; 770 caead.flags = enc ? COP_F_CIPHER_FIRST : 0; 771 caead.len = size; 772 caead.aadlen = aad_len; 773 caead.ivlen = iv_len; 774 caead.src = (char *)input; 775 caead.dst = output; 776 caead.aad = (char *)aad; 777 caead.tag = digest; 778 caead.iv = (char *)iv; 779 780 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) { 781 warn("cryptodev %s (%zu) failed for device %s", 782 alg->name, size, crfind(crid)); 783 close(fd); 784 return (false); 785 } 786 } else { 787 struct crypt_op cop; 788 789 memset(&cop, 0, sizeof(cop)); 790 cop.ses = sop.ses; 791 cop.op = enc ? COP_ENCRYPT : COP_DECRYPT; 792 cop.flags = enc ? COP_F_CIPHER_FIRST : 0; 793 cop.len = size; 794 cop.src = (char *)input; 795 cop.dst = output; 796 cop.mac = digest; 797 cop.iv = (char *)iv; 798 799 if (ioctl(fd, CIOCCRYPT, &cop) < 0) { 800 warn("cryptodev %s (%zu) AUTHENC failed for device %s", 801 alg->name, size, crfind(crid)); 802 close(fd); 803 return (false); 804 } 805 } 806 807 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 808 warn("ioctl(CIOCFSESSION)"); 809 810 close(fd); 811 *cridp = sop.crid; 812 return (true); 813 } 814 815 static void 816 run_authenc_test(struct alg *alg, size_t size) 817 { 818 const EVP_CIPHER *cipher; 819 const EVP_MD *md; 820 char *aad, *buffer, *cleartext, *ciphertext; 821 char *iv, *auth_key, *cipher_key; 822 u_int iv_len, auth_key_len, cipher_key_len, digest_len; 823 int crid; 824 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 825 826 cipher = alg->evp_cipher(); 827 if (size % EVP_CIPHER_block_size(cipher) != 0) { 828 if (verbose) 829 printf( 830 "%s (%zu): invalid buffer size (block size %d)\n", 831 alg->name, size, EVP_CIPHER_block_size(cipher)); 832 return; 833 } 834 835 memset(control_digest, 0x3c, sizeof(control_digest)); 836 memset(test_digest, 0x3c, sizeof(test_digest)); 837 838 md = alg->evp_md(); 839 840 cipher_key_len = EVP_CIPHER_key_length(cipher); 841 iv_len = EVP_CIPHER_iv_length(cipher); 842 auth_key_len = EVP_MD_size(md); 843 844 cipher_key = alloc_buffer(cipher_key_len); 845 iv = generate_iv(iv_len, alg); 846 auth_key = alloc_buffer(auth_key_len); 847 cleartext = alloc_buffer(aad_len + size); 848 buffer = malloc(aad_len + size); 849 ciphertext = malloc(aad_len + size); 850 851 /* OpenSSL encrypt + HMAC. */ 852 if (aad_len != 0) 853 memcpy(ciphertext, cleartext, aad_len); 854 openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len, 855 ciphertext + aad_len, size, 1); 856 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len, 857 size) == 0) 858 errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, 859 size); 860 digest_len = sizeof(control_digest); 861 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext, 862 aad_len + size, (u_char *)control_digest, &digest_len) == NULL) 863 errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name, 864 size, ERR_error_string(ERR_get_error(), NULL)); 865 866 /* OCF encrypt + HMAC. */ 867 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key, 868 auth_key_len, aad_len != 0 ? cleartext : NULL, aad_len, 869 cleartext + aad_len, buffer + aad_len, size, test_digest, 1, &crid)) 870 goto out; 871 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) { 872 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 873 printf("control:\n"); 874 hexdump(ciphertext + aad_len, size, NULL, 0); 875 printf("test (cryptodev device %s):\n", crfind(crid)); 876 hexdump(buffer + aad_len, size, NULL, 0); 877 goto out; 878 } 879 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 880 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 881 printf("%s (%zu) enc hash mismatch in trailer:\n", 882 alg->name, size); 883 else 884 printf("%s (%zu) enc hash mismatch:\n", alg->name, 885 size); 886 printf("control:\n"); 887 hexdump(control_digest, sizeof(control_digest), NULL, 0); 888 printf("test (cryptodev device %s):\n", crfind(crid)); 889 hexdump(test_digest, sizeof(test_digest), NULL, 0); 890 goto out; 891 } 892 893 /* OCF HMAC + decrypt. */ 894 memset(test_digest, 0x3c, sizeof(test_digest)); 895 if (!ocf_authenc(alg, cipher_key, cipher_key_len, iv, iv_len, auth_key, 896 auth_key_len, aad_len != 0 ? ciphertext : NULL, aad_len, 897 ciphertext + aad_len, buffer + aad_len, size, test_digest, 0, 898 &crid)) 899 goto out; 900 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 901 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 902 printf("%s (%zu) dec hash mismatch in trailer:\n", 903 alg->name, size); 904 else 905 printf("%s (%zu) dec hash mismatch:\n", alg->name, 906 size); 907 printf("control:\n"); 908 hexdump(control_digest, sizeof(control_digest), NULL, 0); 909 printf("test (cryptodev device %s):\n", crfind(crid)); 910 hexdump(test_digest, sizeof(test_digest), NULL, 0); 911 goto out; 912 } 913 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) { 914 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 915 printf("control:\n"); 916 hexdump(cleartext, size, NULL, 0); 917 printf("test (cryptodev device %s):\n", crfind(crid)); 918 hexdump(buffer, size, NULL, 0); 919 goto out; 920 } 921 922 if (verbose) 923 printf("%s (%zu) matched (cryptodev device %s)\n", 924 alg->name, size, crfind(crid)); 925 926 out: 927 free(ciphertext); 928 free(buffer); 929 free(cleartext); 930 free(auth_key); 931 free(iv); 932 free(cipher_key); 933 } 934 935 static void 936 openssl_gcm_encrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 937 const char *iv, const char *aad, size_t aad_len, const char *input, 938 char *output, size_t size, char *tag) 939 { 940 EVP_CIPHER_CTX *ctx; 941 int outl, total; 942 943 ctx = EVP_CIPHER_CTX_new(); 944 if (ctx == NULL) 945 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 946 size, ERR_error_string(ERR_get_error(), NULL)); 947 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 948 (const u_char *)iv) != 1) 949 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 950 size, ERR_error_string(ERR_get_error(), NULL)); 951 EVP_CIPHER_CTX_set_padding(ctx, 0); 952 if (aad != NULL) { 953 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 954 aad_len) != 1) 955 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 956 alg->name, size, 957 ERR_error_string(ERR_get_error(), NULL)); 958 } 959 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 960 (const u_char *)input, size) != 1) 961 errx(1, "OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 962 size, ERR_error_string(ERR_get_error(), NULL)); 963 total = outl; 964 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) 965 errx(1, "OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 966 size, ERR_error_string(ERR_get_error(), NULL)); 967 total += outl; 968 if (total != size) 969 errx(1, "OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 970 size, total); 971 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GMAC_HASH_LEN, 972 tag) != 1) 973 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 974 size, ERR_error_string(ERR_get_error(), NULL)); 975 EVP_CIPHER_CTX_free(ctx); 976 } 977 978 static bool 979 ocf_gcm(struct alg *alg, const char *key, size_t key_len, const char *iv, 980 size_t iv_len, const char *aad, size_t aad_len, const char *input, 981 char *output, size_t size, char *tag, int enc, int *cridp) 982 { 983 struct session2_op sop; 984 struct crypt_aead caead; 985 int fd; 986 987 memset(&sop, 0, sizeof(sop)); 988 memset(&caead, 0, sizeof(caead)); 989 sop.crid = crid; 990 sop.keylen = key_len; 991 sop.key = (char *)key; 992 sop.cipher = alg->cipher; 993 sop.mackeylen = key_len; 994 sop.mackey = (char *)key; 995 sop.mac = alg->mac; 996 fd = crget(); 997 if (ioctl(fd, CIOCGSESSION2, &sop) < 0) { 998 warn("cryptodev %s not supported for device %s", 999 alg->name, crfind(crid)); 1000 close(fd); 1001 return (false); 1002 } 1003 1004 caead.ses = sop.ses; 1005 caead.op = enc ? COP_ENCRYPT : COP_DECRYPT; 1006 caead.len = size; 1007 caead.aadlen = aad_len; 1008 caead.ivlen = iv_len; 1009 caead.src = (char *)input; 1010 caead.dst = output; 1011 caead.aad = (char *)aad; 1012 caead.tag = tag; 1013 caead.iv = (char *)iv; 1014 1015 if (ioctl(fd, CIOCCRYPTAEAD, &caead) < 0) { 1016 warn("cryptodev %s (%zu) failed for device %s", 1017 alg->name, size, crfind(crid)); 1018 close(fd); 1019 return (false); 1020 } 1021 1022 if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 1023 warn("ioctl(CIOCFSESSION)"); 1024 1025 close(fd); 1026 *cridp = sop.crid; 1027 return (true); 1028 } 1029 1030 #ifdef notused 1031 static bool 1032 openssl_gcm_decrypt(struct alg *alg, const EVP_CIPHER *cipher, const char *key, 1033 const char *iv, const char *aad, size_t aad_len, const char *input, 1034 char *output, size_t size, char *tag) 1035 { 1036 EVP_CIPHER_CTX *ctx; 1037 int outl, total; 1038 bool valid; 1039 1040 ctx = EVP_CIPHER_CTX_new(); 1041 if (ctx == NULL) 1042 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1043 size, ERR_error_string(ERR_get_error(), NULL)); 1044 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1045 (const u_char *)iv) != 1) 1046 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1047 size, ERR_error_string(ERR_get_error(), NULL)); 1048 EVP_CIPHER_CTX_set_padding(ctx, 0); 1049 if (aad != NULL) { 1050 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1051 aad_len) != 1) 1052 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1053 alg->name, size, 1054 ERR_error_string(ERR_get_error(), NULL)); 1055 } 1056 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl, 1057 (const u_char *)input, size) != 1) 1058 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name, 1059 size, ERR_error_string(ERR_get_error(), NULL)); 1060 total = outl; 1061 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GMAC_HASH_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 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1); 1066 total += outl; 1067 if (total != size) 1068 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name, 1069 size, total); 1070 EVP_CIPHER_CTX_free(ctx); 1071 return (valid); 1072 } 1073 #endif 1074 1075 static void 1076 run_gcm_test(struct alg *alg, size_t size) 1077 { 1078 const EVP_CIPHER *cipher; 1079 char *aad, *buffer, *cleartext, *ciphertext; 1080 char *iv, *key; 1081 u_int iv_len, key_len; 1082 int crid; 1083 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN]; 1084 1085 cipher = alg->evp_cipher(); 1086 if (size % EVP_CIPHER_block_size(cipher) != 0) { 1087 if (verbose) 1088 printf( 1089 "%s (%zu): invalid buffer size (block size %d)\n", 1090 alg->name, size, EVP_CIPHER_block_size(cipher)); 1091 return; 1092 } 1093 1094 memset(control_tag, 0x3c, sizeof(control_tag)); 1095 memset(test_tag, 0x3c, sizeof(test_tag)); 1096 1097 key_len = EVP_CIPHER_key_length(cipher); 1098 iv_len = EVP_CIPHER_iv_length(cipher); 1099 1100 key = alloc_buffer(key_len); 1101 iv = generate_iv(iv_len, alg); 1102 cleartext = alloc_buffer(size); 1103 buffer = malloc(size); 1104 ciphertext = malloc(size); 1105 if (aad_len != 0) 1106 aad = alloc_buffer(aad_len); 1107 else 1108 aad = NULL; 1109 1110 /* OpenSSL encrypt */ 1111 openssl_gcm_encrypt(alg, cipher, key, iv, aad, aad_len, cleartext, 1112 ciphertext, size, control_tag); 1113 1114 /* OCF encrypt */ 1115 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, cleartext, 1116 buffer, size, test_tag, 1, &crid)) 1117 goto out; 1118 if (memcmp(ciphertext, buffer, size) != 0) { 1119 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 1120 printf("control:\n"); 1121 hexdump(ciphertext, size, NULL, 0); 1122 printf("test (cryptodev device %s):\n", crfind(crid)); 1123 hexdump(buffer, size, NULL, 0); 1124 goto out; 1125 } 1126 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1127 printf("%s (%zu) enc tag mismatch:\n", alg->name, size); 1128 printf("control:\n"); 1129 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1130 printf("test (cryptodev device %s):\n", crfind(crid)); 1131 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1132 goto out; 1133 } 1134 1135 /* OCF decrypt */ 1136 if (!ocf_gcm(alg, key, key_len, iv, iv_len, aad, aad_len, ciphertext, 1137 buffer, size, control_tag, 0, &crid)) 1138 goto out; 1139 if (memcmp(cleartext, buffer, size) != 0) { 1140 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 1141 printf("control:\n"); 1142 hexdump(cleartext, size, NULL, 0); 1143 printf("test (cryptodev device %s):\n", crfind(crid)); 1144 hexdump(buffer, size, NULL, 0); 1145 goto out; 1146 } 1147 1148 if (verbose) 1149 printf("%s (%zu) matched (cryptodev device %s)\n", 1150 alg->name, size, crfind(crid)); 1151 1152 out: 1153 free(aad); 1154 free(ciphertext); 1155 free(buffer); 1156 free(cleartext); 1157 free(iv); 1158 free(key); 1159 } 1160 1161 static void 1162 run_test(struct alg *alg, size_t size) 1163 { 1164 1165 switch (alg->type) { 1166 case T_HASH: 1167 run_hash_test(alg, size); 1168 break; 1169 case T_HMAC: 1170 run_hmac_test(alg, size); 1171 break; 1172 case T_BLKCIPHER: 1173 run_blkcipher_test(alg, size); 1174 break; 1175 case T_AUTHENC: 1176 run_authenc_test(alg, size); 1177 break; 1178 case T_GCM: 1179 run_gcm_test(alg, size); 1180 break; 1181 } 1182 } 1183 1184 static void 1185 run_test_sizes(struct alg *alg, size_t *sizes, u_int nsizes) 1186 { 1187 u_int i; 1188 1189 for (i = 0; i < nsizes; i++) 1190 run_test(alg, sizes[i]); 1191 } 1192 1193 static void 1194 run_hash_tests(size_t *sizes, u_int nsizes) 1195 { 1196 u_int i; 1197 1198 for (i = 0; i < nitems(algs); i++) 1199 if (algs[i].type == T_HASH) 1200 run_test_sizes(&algs[i], sizes, nsizes); 1201 } 1202 1203 static void 1204 run_hmac_tests(size_t *sizes, u_int nsizes) 1205 { 1206 u_int i; 1207 1208 for (i = 0; i < nitems(algs); i++) 1209 if (algs[i].type == T_HMAC) 1210 run_test_sizes(&algs[i], sizes, nsizes); 1211 } 1212 1213 static void 1214 run_blkcipher_tests(size_t *sizes, u_int nsizes) 1215 { 1216 u_int i; 1217 1218 for (i = 0; i < nitems(algs); i++) 1219 if (algs[i].type == T_BLKCIPHER) 1220 run_test_sizes(&algs[i], sizes, nsizes); 1221 } 1222 1223 static void 1224 run_authenc_tests(size_t *sizes, u_int nsizes) 1225 { 1226 struct alg *authenc, *cipher, *hmac; 1227 u_int i, j; 1228 1229 for (i = 0; i < nitems(algs); i++) { 1230 cipher = &algs[i]; 1231 if (cipher->type != T_BLKCIPHER) 1232 continue; 1233 for (j = 0; j < nitems(algs); j++) { 1234 hmac = &algs[j]; 1235 if (hmac->type != T_HMAC) 1236 continue; 1237 authenc = build_authenc(cipher, hmac); 1238 run_test_sizes(authenc, sizes, nsizes); 1239 free((char *)authenc->name); 1240 } 1241 } 1242 } 1243 1244 static void 1245 run_aead_tests(size_t *sizes, u_int nsizes) 1246 { 1247 u_int i; 1248 1249 for (i = 0; i < nitems(algs); i++) 1250 if (algs[i].type == T_GCM) 1251 run_test_sizes(&algs[i], sizes, nsizes); 1252 } 1253 1254 int 1255 main(int ac, char **av) 1256 { 1257 const char *algname; 1258 struct alg *alg; 1259 size_t sizes[128]; 1260 u_int i, nsizes; 1261 bool testall; 1262 int ch; 1263 1264 algname = NULL; 1265 crid = CRYPTO_FLAG_HARDWARE; 1266 testall = false; 1267 verbose = false; 1268 while ((ch = getopt(ac, av, "A:a:d:vz")) != -1) 1269 switch (ch) { 1270 case 'A': 1271 aad_len = atoi(optarg); 1272 break; 1273 case 'a': 1274 algname = optarg; 1275 break; 1276 case 'd': 1277 crid = crlookup(optarg); 1278 break; 1279 case 'v': 1280 verbose = true; 1281 break; 1282 case 'z': 1283 testall = true; 1284 break; 1285 default: 1286 usage(); 1287 } 1288 ac -= optind; 1289 av += optind; 1290 nsizes = 0; 1291 while (ac > 0) { 1292 char *cp; 1293 1294 if (nsizes >= nitems(sizes)) { 1295 warnx("Too many sizes, ignoring extras"); 1296 break; 1297 } 1298 sizes[nsizes] = strtol(av[0], &cp, 0); 1299 if (*cp != '\0') 1300 errx(1, "Bad size %s", av[0]); 1301 nsizes++; 1302 ac--; 1303 av++; 1304 } 1305 1306 if (algname == NULL) 1307 errx(1, "Algorithm required"); 1308 if (nsizes == 0) { 1309 sizes[0] = 16; 1310 nsizes++; 1311 if (testall) { 1312 while (sizes[nsizes - 1] * 2 < 240 * 1024) { 1313 assert(nsizes < nitems(sizes)); 1314 sizes[nsizes] = sizes[nsizes - 1] * 2; 1315 nsizes++; 1316 } 1317 if (sizes[nsizes - 1] < 240 * 1024) { 1318 assert(nsizes < nitems(sizes)); 1319 sizes[nsizes] = 240 * 1024; 1320 nsizes++; 1321 } 1322 } 1323 } 1324 1325 if (strcasecmp(algname, "hash") == 0) 1326 run_hash_tests(sizes, nsizes); 1327 else if (strcasecmp(algname, "hmac") == 0) 1328 run_hmac_tests(sizes, nsizes); 1329 else if (strcasecmp(algname, "blkcipher") == 0) 1330 run_blkcipher_tests(sizes, nsizes); 1331 else if (strcasecmp(algname, "authenc") == 0) 1332 run_authenc_tests(sizes, nsizes); 1333 else if (strcasecmp(algname, "aead") == 0) 1334 run_aead_tests(sizes, nsizes); 1335 else if (strcasecmp(algname, "all") == 0) { 1336 run_hash_tests(sizes, nsizes); 1337 run_hmac_tests(sizes, nsizes); 1338 run_blkcipher_tests(sizes, nsizes); 1339 run_authenc_tests(sizes, nsizes); 1340 run_aead_tests(sizes, nsizes); 1341 } else if (strchr(algname, '+') != NULL) { 1342 alg = build_authenc_name(algname); 1343 run_test_sizes(alg, sizes, nsizes); 1344 } else { 1345 alg = find_alg(algname); 1346 if (alg == NULL) 1347 errx(1, "Invalid algorithm %s", algname); 1348 run_test_sizes(alg, sizes, nsizes); 1349 } 1350 1351 return (0); 1352 } 1353