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