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