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