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 (96 bit nonce) 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 158struct ocf_session { 159 int fd; 160 int ses; 161 int crid; 162}; 163 164static 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 }, 257 .evp_cipher = EVP_chacha20_poly1305 }, 258}; 259 260static bool testall, verbose; 261static int requested_crid; 262static size_t aad_sizes[48], sizes[EALG_MAX_BLOCK_LEN * 2]; 263static u_int naad_sizes, nsizes; 264static u_int iv_size; 265 266static void 267usage(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 275static const struct alg * 276find_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 286static struct alg * 287build_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 305static void 306free_eta(struct alg *eta) 307{ 308 free(__DECONST(char *, eta->name)); 309 free(eta); 310} 311 312static struct alg * 313build_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 332static int 333devcrypto(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 350static void 351reset_user_soft(void) 352{ 353 int off = 0; 354 sysctlbyname(CRYPT_SOFT_ALLOW, NULL, NULL, &off, sizeof(off)); 355} 356 357static void 358enable_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 371static int 372crlookup(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 388static const char * 389crfind(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 405static char 406rdigit(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 415static char * 416alloc_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 427static char * 428generate_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 459static void 460ocf_init_sop(struct session2_op *sop) 461{ 462 memset(sop, 0, sizeof(*sop)); 463 sop->crid = requested_crid; 464} 465 466static bool 467ocf_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 485static void 486ocf_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 495static void 496ocf_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 502static void 503ocf_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 509static bool 510ocf_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 540static bool 541openssl_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 (true); 568 569err_out: 570 warnx("OpenSSL %s HASH failed%s: %s", alg->name, errs, 571 ERR_error_string(ERR_get_error(), NULL)); 572 return (false); 573} 574 575static void 576run_hash_test(const struct alg *alg, size_t size) 577{ 578 const EVP_MD *md; 579 char *buffer; 580 u_int digest_len; 581 int crid; 582 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 583 584 memset(control_digest, 0x3c, sizeof(control_digest)); 585 memset(test_digest, 0x3c, sizeof(test_digest)); 586 587 md = alg->evp_md(); 588 assert((size_t)EVP_MD_size(md) <= sizeof(control_digest)); 589 590 buffer = alloc_buffer(size); 591 592 /* OpenSSL HASH. */ 593 digest_len = sizeof(control_digest); 594 if (!openssl_hash(alg, md, buffer, size, control_digest, &digest_len)) 595 goto out; 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 617out: 618 free(buffer); 619} 620 621static bool 622ocf_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 654static void 655run_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 warnx("OpenSSL %s (%zu) HMAC failed: %s", alg->name, 678 size, ERR_error_string(ERR_get_error(), NULL)); 679 goto out; 680 } 681 682 /* cryptodev HMAC. */ 683 if (!ocf_hmac(alg, buffer, size, key, key_len, test_digest, &crid)) 684 goto out; 685 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 686 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 687 printf("%s (%zu) mismatch in trailer:\n", 688 alg->name, size); 689 else 690 printf("%s (%zu) mismatch:\n", alg->name, size); 691 printf("control:\n"); 692 hexdump(control_digest, sizeof(control_digest), NULL, 0); 693 printf("test (cryptodev device %s):\n", crfind(crid)); 694 hexdump(test_digest, sizeof(test_digest), NULL, 0); 695 goto out; 696 } 697 698 if (verbose) 699 printf("%s (%zu) matched (cryptodev device %s)\n", 700 alg->name, size, crfind(crid)); 701 702out: 703 free(buffer); 704 free(key); 705} 706 707static bool 708openssl_cipher(const struct alg *alg, const EVP_CIPHER *cipher, const char *key, 709 const char *iv, const char *input, char *output, size_t size, int enc) 710{ 711 EVP_CIPHER_CTX *ctx; 712 int outl, total; 713 714 ctx = EVP_CIPHER_CTX_new(); 715 if (ctx == NULL) { 716 warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name, 717 size, ERR_error_string(ERR_get_error(), NULL)); 718 return (false); 719 } 720 if (EVP_CipherInit_ex(ctx, cipher, NULL, (const u_char *)key, 721 (const u_char *)iv, enc) != 1) { 722 warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name, 723 size, ERR_error_string(ERR_get_error(), NULL)); 724 goto error; 725 } 726 EVP_CIPHER_CTX_set_padding(ctx, 0); 727 if (EVP_CipherUpdate(ctx, (u_char *)output, &outl, 728 (const u_char *)input, size) != 1) { 729 warnx("OpenSSL %s (%zu) cipher update failed: %s", alg->name, 730 size, ERR_error_string(ERR_get_error(), NULL)); 731 goto error; 732 } 733 total = outl; 734 if (EVP_CipherFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) { 735 warnx("OpenSSL %s (%zu) cipher final failed: %s", alg->name, 736 size, ERR_error_string(ERR_get_error(), NULL)); 737 goto error; 738 } 739 total += outl; 740 if ((size_t)total != size) { 741 warnx("OpenSSL %s (%zu) cipher size mismatch: %d", alg->name, 742 size, total); 743 goto error; 744 } 745 EVP_CIPHER_CTX_free(ctx); 746 return (true); 747 748error: 749 EVP_CIPHER_CTX_free(ctx); 750 return (false); 751} 752 753static bool 754ocf_init_cipher_session(const struct alg *alg, const char *key, size_t key_len, 755 struct ocf_session *ses) 756{ 757 struct session2_op sop; 758 759 ocf_init_sop(&sop); 760 sop.keylen = key_len; 761 sop.key = key; 762 sop.cipher = alg->cipher; 763 return (ocf_init_session(&sop, "cipher", alg->name, ses)); 764} 765 766static bool 767ocf_cipher(const struct ocf_session *ses, const struct alg *alg, const char *iv, 768 const char *input, char *output, size_t size, int op) 769{ 770 struct crypt_op cop; 771 772 ocf_init_cop(ses, &cop); 773 cop.op = op; 774 cop.len = size; 775 cop.src = input; 776 cop.dst = output; 777 cop.iv = iv; 778 779 if (ioctl(ses->fd, CIOCCRYPT, &cop) < 0) { 780 warn("cryptodev %s (%zu) cipher failed for device %s", 781 alg->name, size, crfind(ses->crid)); 782 return (false); 783 } 784 785 return (true); 786} 787 788static void 789run_cipher_test(const struct alg *alg, size_t size) 790{ 791 struct ocf_session ses; 792 const EVP_CIPHER *cipher; 793 char *buffer, *cleartext, *ciphertext; 794 char *iv, *key; 795 u_int iv_len, key_len; 796 797 cipher = alg->evp_cipher(); 798 if (size % EVP_CIPHER_block_size(cipher) != 0) { 799 if (verbose) 800 printf( 801 "%s (%zu): invalid buffer size (block size %d)\n", 802 alg->name, size, EVP_CIPHER_block_size(cipher)); 803 return; 804 } 805 806 /* 807 * XTS requires at least one full block so that any partial 808 * block at the end has cipher text to steal. Hardcoding the 809 * AES block size isn't ideal, but OpenSSL doesn't have a 810 * notion of a "native" block size. 811 */ 812 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE && 813 size < AES_BLOCK_LEN) { 814 if (verbose) 815 printf("%s (%zu): invalid buffer size\n", alg->name, 816 size); 817 return; 818 } 819 820 key_len = EVP_CIPHER_key_length(cipher); 821 iv_len = EVP_CIPHER_iv_length(cipher); 822 823 key = alloc_buffer(key_len); 824 iv = generate_iv(iv_len, alg); 825 cleartext = alloc_buffer(size); 826 buffer = malloc(size); 827 ciphertext = malloc(size); 828 829 /* OpenSSL cipher. */ 830 if (!openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 831 1)) 832 goto out_noocf; 833 if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) { 834 warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name, 835 size); 836 goto out_noocf; 837 } 838 if (!openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0)) 839 goto out_noocf; 840 if (memcmp(cleartext, buffer, size) != 0) { 841 printf("OpenSSL %s (%zu): cipher mismatch:", alg->name, size); 842 printf("original:\n"); 843 hexdump(cleartext, size, NULL, 0); 844 printf("decrypted:\n"); 845 hexdump(buffer, size, NULL, 0); 846 goto out_noocf; 847 } 848 849 if (!ocf_init_cipher_session(alg, key, key_len, &ses)) 850 goto out_noocf; 851 852 /* OCF encrypt. */ 853 if (!ocf_cipher(&ses, alg, iv, cleartext, buffer, size, COP_ENCRYPT)) 854 goto out; 855 if (memcmp(ciphertext, buffer, size) != 0) { 856 printf("%s (%zu) encryption mismatch:\n", alg->name, size); 857 printf("control:\n"); 858 hexdump(ciphertext, size, NULL, 0); 859 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 860 hexdump(buffer, size, NULL, 0); 861 goto out; 862 } 863 864 /* OCF decrypt. */ 865 if (!ocf_cipher(&ses, alg, iv, ciphertext, buffer, size, COP_DECRYPT)) 866 goto out; 867 if (memcmp(cleartext, buffer, size) != 0) { 868 printf("%s (%zu) decryption mismatch:\n", alg->name, size); 869 printf("control:\n"); 870 hexdump(cleartext, size, NULL, 0); 871 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 872 hexdump(buffer, size, NULL, 0); 873 goto out; 874 } 875 876 if (verbose) 877 printf("%s (%zu) matched (cryptodev device %s)\n", 878 alg->name, size, crfind(ses.crid)); 879 880out: 881 ocf_destroy_session(&ses); 882out_noocf: 883 free(ciphertext); 884 free(buffer); 885 free(cleartext); 886 free(iv); 887 free(key); 888} 889 890static bool 891ocf_init_eta_session(const struct alg *alg, const char *cipher_key, 892 size_t cipher_key_len, const char *auth_key, size_t auth_key_len, 893 struct ocf_session *ses) 894{ 895 struct session2_op sop; 896 897 ocf_init_sop(&sop); 898 sop.keylen = cipher_key_len; 899 sop.key = cipher_key; 900 sop.cipher = alg->cipher; 901 sop.mackeylen = auth_key_len; 902 sop.mackey = auth_key; 903 sop.mac = alg->mac; 904 return (ocf_init_session(&sop, "ETA", alg->name, ses)); 905} 906 907static int 908ocf_eta(const struct ocf_session *ses, const char *iv, size_t iv_len, 909 const char *aad, size_t aad_len, const char *input, char *output, 910 size_t size, char *digest, int op) 911{ 912 int ret; 913 914 if (aad_len != 0) { 915 struct crypt_aead caead; 916 917 ocf_init_caead(ses, &caead); 918 caead.op = op; 919 caead.len = size; 920 caead.aadlen = aad_len; 921 caead.ivlen = iv_len; 922 caead.src = input; 923 caead.dst = output; 924 caead.aad = aad; 925 caead.tag = digest; 926 caead.iv = iv; 927 928 ret = ioctl(ses->fd, CIOCCRYPTAEAD, &caead); 929 } else { 930 struct crypt_op cop; 931 932 ocf_init_cop(ses, &cop); 933 cop.op = op; 934 cop.len = size; 935 cop.src = input; 936 cop.dst = output; 937 cop.mac = digest; 938 cop.iv = iv; 939 940 ret = ioctl(ses->fd, CIOCCRYPT, &cop); 941 } 942 943 if (ret < 0) 944 return (errno); 945 return (0); 946} 947 948static void 949run_eta_test(const struct alg *alg, size_t aad_len, size_t size) 950{ 951 struct ocf_session ses; 952 const EVP_CIPHER *cipher; 953 const EVP_MD *md; 954 char *buffer, *cleartext, *ciphertext; 955 char *iv, *auth_key, *cipher_key; 956 u_int iv_len, auth_key_len, cipher_key_len, digest_len; 957 int error; 958 char control_digest[EVP_MAX_MD_SIZE], test_digest[EVP_MAX_MD_SIZE]; 959 960 cipher = alg->evp_cipher(); 961 if (size % EVP_CIPHER_block_size(cipher) != 0) { 962 if (verbose) 963 printf( 964 "%s (%zu, %zu): invalid buffer size (block size %d)\n", 965 alg->name, aad_len, size, 966 EVP_CIPHER_block_size(cipher)); 967 return; 968 } 969 970 /* See comment in run_cipher_test. */ 971 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE && 972 size < AES_BLOCK_LEN) { 973 if (verbose) 974 printf("%s (%zu): invalid buffer size\n", alg->name, 975 size); 976 return; 977 } 978 979 memset(control_digest, 0x3c, sizeof(control_digest)); 980 memset(test_digest, 0x3c, sizeof(test_digest)); 981 982 md = alg->evp_md(); 983 984 cipher_key_len = EVP_CIPHER_key_length(cipher); 985 iv_len = EVP_CIPHER_iv_length(cipher); 986 auth_key_len = EVP_MD_size(md); 987 988 cipher_key = alloc_buffer(cipher_key_len); 989 iv = generate_iv(iv_len, alg); 990 auth_key = alloc_buffer(auth_key_len); 991 cleartext = alloc_buffer(aad_len + size); 992 buffer = malloc(aad_len + size); 993 ciphertext = malloc(aad_len + size); 994 995 /* OpenSSL encrypt + HMAC. */ 996 if (aad_len != 0) 997 memcpy(ciphertext, cleartext, aad_len); 998 if (!openssl_cipher(alg, cipher, cipher_key, iv, cleartext + aad_len, 999 ciphertext + aad_len, size, 1)) 1000 goto out_noocf; 1001 if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len, 1002 size) == 0) { 1003 warnx("OpenSSL %s (%zu, %zu): cipher text unchanged", 1004 alg->name, aad_len, size); 1005 goto out_noocf; 1006 } 1007 digest_len = sizeof(control_digest); 1008 if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext, 1009 aad_len + size, (u_char *)control_digest, &digest_len) == NULL) { 1010 warnx("OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name, 1011 aad_len, size, ERR_error_string(ERR_get_error(), NULL)); 1012 goto out_noocf; 1013 } 1014 1015 if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key, 1016 auth_key_len, &ses)) 1017 goto out_noocf; 1018 1019 /* OCF encrypt + HMAC. */ 1020 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? cleartext : NULL, 1021 aad_len, cleartext + aad_len, buffer + aad_len, size, test_digest, 1022 COP_ENCRYPT); 1023 if (error != 0) { 1024 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s", 1025 alg->name, aad_len, size, crfind(ses.crid)); 1026 goto out; 1027 } 1028 if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) { 1029 printf("%s (%zu, %zu) encryption mismatch:\n", alg->name, 1030 aad_len, size); 1031 printf("control:\n"); 1032 hexdump(ciphertext + aad_len, size, NULL, 0); 1033 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1034 hexdump(buffer + aad_len, size, NULL, 0); 1035 goto out; 1036 } 1037 if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { 1038 if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) 1039 printf("%s (%zu, %zu) enc hash mismatch in trailer:\n", 1040 alg->name, aad_len, size); 1041 else 1042 printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name, 1043 aad_len, size); 1044 printf("control:\n"); 1045 hexdump(control_digest, sizeof(control_digest), NULL, 0); 1046 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1047 hexdump(test_digest, sizeof(test_digest), NULL, 0); 1048 goto out; 1049 } 1050 1051 /* OCF HMAC + decrypt. */ 1052 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL, 1053 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest, 1054 COP_DECRYPT); 1055 if (error != 0) { 1056 warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s", 1057 alg->name, aad_len, size, crfind(ses.crid)); 1058 goto out; 1059 } 1060 if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) { 1061 printf("%s (%zu, %zu) decryption mismatch:\n", alg->name, 1062 aad_len, size); 1063 printf("control:\n"); 1064 hexdump(cleartext, size, NULL, 0); 1065 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1066 hexdump(buffer, size, NULL, 0); 1067 goto out; 1068 } 1069 1070 /* Verify OCF HMAC + decrypt fails with busted MAC. */ 1071 test_digest[0] ^= 0x1; 1072 error = ocf_eta(&ses, iv, iv_len, aad_len != 0 ? ciphertext : NULL, 1073 aad_len, ciphertext + aad_len, buffer + aad_len, size, test_digest, 1074 COP_DECRYPT); 1075 if (error != EBADMSG) { 1076 if (error != 0) 1077 warnc(error, 1078 "cryptodev %s (%zu, %zu) corrupt tag failed for device %s", 1079 alg->name, aad_len, size, crfind(ses.crid)); 1080 else 1081 warnx( 1082 "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s", 1083 alg->name, aad_len, size, crfind(ses.crid)); 1084 goto out; 1085 } 1086 1087 if (verbose) 1088 printf("%s (%zu, %zu) matched (cryptodev device %s)\n", 1089 alg->name, aad_len, size, crfind(ses.crid)); 1090 1091out: 1092 ocf_destroy_session(&ses); 1093out_noocf: 1094 free(ciphertext); 1095 free(buffer); 1096 free(cleartext); 1097 free(auth_key); 1098 free(iv); 1099 free(cipher_key); 1100} 1101 1102static bool 1103openssl_gmac(const struct alg *alg, const EVP_CIPHER *cipher, const char *key, 1104 const char *iv, const char *input, size_t size, char *tag) 1105{ 1106 EVP_CIPHER_CTX *ctx; 1107 int outl; 1108 1109 ctx = EVP_CIPHER_CTX_new(); 1110 if (ctx == NULL) { 1111 warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1112 size, ERR_error_string(ERR_get_error(), NULL)); 1113 return (false); 1114 } 1115 if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1116 (const u_char *)iv) != 1) { 1117 warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1118 size, ERR_error_string(ERR_get_error(), NULL)); 1119 goto error; 1120 } 1121 EVP_CIPHER_CTX_set_padding(ctx, 0); 1122 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)input, 1123 size) != 1) { 1124 warnx("OpenSSL %s (%zu) update failed: %s", 1125 alg->name, size, ERR_error_string(ERR_get_error(), NULL)); 1126 goto error; 1127 } 1128 if (EVP_EncryptFinal_ex(ctx, NULL, &outl) != 1) { 1129 warnx("OpenSSL %s (%zu) final failed: %s", alg->name, 1130 size, ERR_error_string(ERR_get_error(), NULL)); 1131 goto error; 1132 } 1133 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len, 1134 tag) != 1) { 1135 warnx("OpenSSL %s (%zu) get tag failed: %s", alg->name, 1136 size, ERR_error_string(ERR_get_error(), NULL)); 1137 goto error; 1138 } 1139 EVP_CIPHER_CTX_free(ctx); 1140 return (true); 1141 1142error: 1143 EVP_CIPHER_CTX_free(ctx); 1144 return (false); 1145} 1146 1147static bool 1148ocf_mac(const struct alg *alg, const char *input, size_t size, const char *key, 1149 size_t key_len, const char *iv, char *tag, int *cridp) 1150{ 1151 struct ocf_session ses; 1152 struct session2_op sop; 1153 struct crypt_op cop; 1154 1155 ocf_init_sop(&sop); 1156 sop.mackeylen = key_len; 1157 sop.mackey = key; 1158 sop.mac = alg->mac; 1159 if (!ocf_init_session(&sop, "MAC", alg->name, &ses)) 1160 return (false); 1161 1162 ocf_init_cop(&ses, &cop); 1163 cop.op = 0; 1164 cop.len = size; 1165 cop.src = input; 1166 cop.mac = tag; 1167 cop.iv = iv; 1168 1169 if (ioctl(ses.fd, CIOCCRYPT, &cop) < 0) { 1170 warn("cryptodev %s (%zu) failed for device %s", alg->name, 1171 size, crfind(ses.crid)); 1172 ocf_destroy_session(&ses); 1173 return (false); 1174 } 1175 1176 *cridp = ses.crid; 1177 ocf_destroy_session(&ses); 1178 return (true); 1179} 1180 1181static void 1182run_gmac_test(const struct alg *alg, size_t size) 1183{ 1184 const EVP_CIPHER *cipher; 1185 char *iv, *key, *buffer; 1186 u_int iv_len, key_len; 1187 int crid; 1188 char control_tag[AES_GMAC_HASH_LEN], test_tag[AES_GMAC_HASH_LEN]; 1189 1190 cipher = alg->evp_cipher(); 1191 1192 memset(control_tag, 0x3c, sizeof(control_tag)); 1193 memset(test_tag, 0x3c, sizeof(test_tag)); 1194 1195 key_len = EVP_CIPHER_key_length(cipher); 1196 iv_len = EVP_CIPHER_iv_length(cipher); 1197 1198 key = alloc_buffer(key_len); 1199 iv = generate_iv(iv_len, alg); 1200 buffer = alloc_buffer(size); 1201 1202 /* OpenSSL GMAC. */ 1203 if (!openssl_gmac(alg, cipher, key, iv, buffer, size, control_tag)) 1204 goto out; 1205 1206 /* OCF GMAC. */ 1207 if (!ocf_mac(alg, buffer, size, key, key_len, iv, test_tag, &crid)) 1208 goto out; 1209 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1210 printf("%s (%zu) mismatch:\n", alg->name, size); 1211 printf("control:\n"); 1212 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1213 printf("test (cryptodev device %s):\n", crfind(crid)); 1214 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1215 goto out; 1216 } 1217 1218 if (verbose) 1219 printf("%s (%zu) matched (cryptodev device %s)\n", 1220 alg->name, size, crfind(crid)); 1221 1222out: 1223 free(buffer); 1224 free(iv); 1225 free(key); 1226} 1227 1228static bool 1229openssl_digest(const struct alg *alg, const char *key, u_int key_len, 1230 const char *input, size_t size, char *tag, u_int tag_len) 1231{ 1232 EVP_MD_CTX *mdctx; 1233 EVP_PKEY *pkey; 1234 size_t len; 1235 1236 pkey = EVP_PKEY_new_raw_private_key(alg->pkey, NULL, key, key_len); 1237 if (pkey == NULL) { 1238 warnx("OpenSSL %s (%zu) pkey new failed: %s", alg->name, 1239 size, ERR_error_string(ERR_get_error(), NULL)); 1240 return (false); 1241 } 1242 mdctx = EVP_MD_CTX_new(); 1243 if (mdctx == NULL) { 1244 warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1245 size, ERR_error_string(ERR_get_error(), NULL)); 1246 EVP_PKEY_free(pkey); 1247 return (false); 1248 } 1249 if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1) { 1250 warnx("OpenSSL %s (%zu) digest sign init failed: %s", 1251 alg->name, size, ERR_error_string(ERR_get_error(), NULL)); 1252 goto error; 1253 } 1254 if (EVP_DigestSignUpdate(mdctx, input, size) != 1) { 1255 warnx("OpenSSL %s (%zu) digest update failed: %s", alg->name, 1256 size, ERR_error_string(ERR_get_error(), NULL)); 1257 goto error; 1258 } 1259 len = tag_len; 1260 if (EVP_DigestSignFinal(mdctx, tag, &len) != 1) { 1261 warnx("OpenSSL %s (%zu) digest final failed: %s", alg->name, 1262 size, ERR_error_string(ERR_get_error(), NULL)); 1263 goto error; 1264 } 1265 EVP_MD_CTX_free(mdctx); 1266 EVP_PKEY_free(pkey); 1267 return (true); 1268 1269error: 1270 EVP_MD_CTX_free(mdctx); 1271 EVP_PKEY_free(pkey); 1272 return (false); 1273} 1274 1275static void 1276run_digest_test(const struct alg *alg, size_t size) 1277{ 1278 char *key, *buffer; 1279 u_int key_len; 1280 int crid; 1281 char control_tag[EVP_MAX_MD_SIZE], test_tag[EVP_MAX_MD_SIZE]; 1282 1283 memset(control_tag, 0x3c, sizeof(control_tag)); 1284 memset(test_tag, 0x3c, sizeof(test_tag)); 1285 1286 key_len = alg->key_len; 1287 1288 key = alloc_buffer(key_len); 1289 buffer = alloc_buffer(size); 1290 1291 /* OpenSSL Poly1305. */ 1292 if (!openssl_digest(alg, key, key_len, buffer, size, control_tag, 1293 sizeof(control_tag))) 1294 goto out; 1295 1296 /* OCF Poly1305. */ 1297 if (!ocf_mac(alg, buffer, size, key, key_len, NULL, test_tag, &crid)) 1298 goto out; 1299 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1300 printf("%s (%zu) mismatch:\n", alg->name, size); 1301 printf("control:\n"); 1302 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1303 printf("test (cryptodev device %s):\n", crfind(crid)); 1304 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1305 goto out; 1306 } 1307 1308 if (verbose) 1309 printf("%s (%zu) matched (cryptodev device %s)\n", 1310 alg->name, size, crfind(crid)); 1311 1312out: 1313 free(buffer); 1314 free(key); 1315} 1316 1317static bool 1318openssl_aead_encrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1319 const char *key, const char *iv, size_t iv_len, const char *aad, 1320 size_t aad_len, const char *input, char *output, size_t size, char *tag) 1321{ 1322 EVP_CIPHER_CTX *ctx; 1323 int outl, total; 1324 1325 ctx = EVP_CIPHER_CTX_new(); 1326 if (ctx == NULL) { 1327 warnx("OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1328 size, ERR_error_string(ERR_get_error(), NULL)); 1329 return (false); 1330 } 1331 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) { 1332 warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1333 size, ERR_error_string(ERR_get_error(), NULL)); 1334 goto error; 1335 } 1336 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1337 1) { 1338 warnx("OpenSSL %s (%zu) setting iv length failed: %s", alg->name, 1339 size, ERR_error_string(ERR_get_error(), NULL)); 1340 goto error; 1341 } 1342 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key, 1343 (const u_char *)iv) != 1) { 1344 warnx("OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1345 size, ERR_error_string(ERR_get_error(), NULL)); 1346 goto error; 1347 } 1348 EVP_CIPHER_CTX_set_padding(ctx, 0); 1349 if (aad != NULL) { 1350 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1351 aad_len) != 1) { 1352 warnx("OpenSSL %s (%zu) aad update failed: %s", 1353 alg->name, size, 1354 ERR_error_string(ERR_get_error(), NULL)); 1355 goto error; 1356 } 1357 } 1358 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 1359 (const u_char *)input, size) != 1) { 1360 warnx("OpenSSL %s (%zu) encrypt update failed: %s", alg->name, 1361 size, ERR_error_string(ERR_get_error(), NULL)); 1362 goto error; 1363 } 1364 total = outl; 1365 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) { 1366 warnx("OpenSSL %s (%zu) encrypt final failed: %s", alg->name, 1367 size, ERR_error_string(ERR_get_error(), NULL)); 1368 goto error; 1369 } 1370 total += outl; 1371 if ((size_t)total != size) { 1372 warnx("OpenSSL %s (%zu) encrypt size mismatch: %d", alg->name, 1373 size, total); 1374 goto error; 1375 } 1376 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, alg->tag_len, 1377 tag) != 1) { 1378 warnx("OpenSSL %s (%zu) get tag failed: %s", alg->name, 1379 size, ERR_error_string(ERR_get_error(), NULL)); 1380 goto error; 1381 } 1382 EVP_CIPHER_CTX_free(ctx); 1383 return (true); 1384 1385error: 1386 EVP_CIPHER_CTX_free(ctx); 1387 return (false); 1388} 1389 1390#ifdef notused 1391static bool 1392openssl_aead_decrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1393 const char *key, const char *iv, const char *aad, size_t aad_len, 1394 const char *input, char *output, size_t size, char *tag) 1395{ 1396 EVP_CIPHER_CTX *ctx; 1397 int outl, total; 1398 bool valid; 1399 1400 ctx = EVP_CIPHER_CTX_new(); 1401 if (ctx == NULL) 1402 errx(1, "OpenSSL %s (%zu) ctx new failed: %s", alg->name, 1403 size, ERR_error_string(ERR_get_error(), NULL)); 1404 if (EVP_DecryptInit_ex(ctx, cipher, NULL, (const u_char *)key, 1405 (const u_char *)iv) != 1) 1406 errx(1, "OpenSSL %s (%zu) ctx init failed: %s", alg->name, 1407 size, ERR_error_string(ERR_get_error(), NULL)); 1408 EVP_CIPHER_CTX_set_padding(ctx, 0); 1409 if (aad != NULL) { 1410 if (EVP_DecryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1411 aad_len) != 1) 1412 errx(1, "OpenSSL %s (%zu) aad update failed: %s", 1413 alg->name, size, 1414 ERR_error_string(ERR_get_error(), NULL)); 1415 } 1416 if (EVP_DecryptUpdate(ctx, (u_char *)output, &outl, 1417 (const u_char *)input, size) != 1) 1418 errx(1, "OpenSSL %s (%zu) decrypt update failed: %s", alg->name, 1419 size, ERR_error_string(ERR_get_error(), NULL)); 1420 total = outl; 1421 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, alg->tag_len, 1422 tag) != 1) 1423 errx(1, "OpenSSL %s (%zu) get tag failed: %s", alg->name, 1424 size, ERR_error_string(ERR_get_error(), NULL)); 1425 valid = (EVP_DecryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1); 1426 total += outl; 1427 if (total != size) 1428 errx(1, "OpenSSL %s (%zu) decrypt size mismatch: %d", alg->name, 1429 size, total); 1430 EVP_CIPHER_CTX_free(ctx); 1431 return (valid); 1432} 1433#endif 1434 1435static bool 1436openssl_ccm_encrypt(const struct alg *alg, const EVP_CIPHER *cipher, 1437 const char *key, const char *iv, size_t iv_len, const char *aad, 1438 size_t aad_len, const char *input, char *output, size_t size, char *tag) 1439{ 1440 EVP_CIPHER_CTX *ctx; 1441 int outl, total; 1442 1443 ctx = EVP_CIPHER_CTX_new(); 1444 if (ctx == NULL) { 1445 warnx("OpenSSL %s/%zu (%zu, %zu) ctx new failed: %s", 1446 alg->name, iv_len, aad_len, size, 1447 ERR_error_string(ERR_get_error(), NULL)); 1448 return (false); 1449 } 1450 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) { 1451 warnx("OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s", 1452 alg->name, iv_len, aad_len, size, 1453 ERR_error_string(ERR_get_error(), NULL)); 1454 goto error; 1455 } 1456 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL) != 1457 1) { 1458 warnx("OpenSSL %s/%zu (%zu, %zu) setting iv length failed: %s", 1459 alg->name, iv_len, aad_len, size, 1460 ERR_error_string(ERR_get_error(), NULL)); 1461 goto error; 1462 } 1463 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AES_CBC_MAC_HASH_LEN, 1464 NULL) != 1) { 1465 warnx("OpenSSL %s/%zu (%zu, %zu) setting tag length failed: %s", 1466 alg->name, iv_len, aad_len, size, 1467 ERR_error_string(ERR_get_error(), NULL)); 1468 goto error; 1469 } 1470 if (EVP_EncryptInit_ex(ctx, NULL, NULL, (const u_char *)key, 1471 (const u_char *)iv) != 1) { 1472 warnx("OpenSSL %s/%zu (%zu, %zu) ctx init failed: %s", 1473 alg->name, iv_len, aad_len, size, 1474 ERR_error_string(ERR_get_error(), NULL)); 1475 goto error; 1476 } 1477 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, size) != 1) { 1478 warnx("OpenSSL %s/%zu (%zu, %zu) unable to set data length: %s", 1479 alg->name, iv_len, aad_len, size, 1480 ERR_error_string(ERR_get_error(), NULL)); 1481 goto error; 1482 } 1483 1484 if (aad != NULL) { 1485 if (EVP_EncryptUpdate(ctx, NULL, &outl, (const u_char *)aad, 1486 aad_len) != 1) { 1487 warnx("OpenSSL %s/%zu (%zu, %zu) aad update failed: %s", 1488 alg->name, iv_len, aad_len, size, 1489 ERR_error_string(ERR_get_error(), NULL)); 1490 goto error; 1491 } 1492 } 1493 if (EVP_EncryptUpdate(ctx, (u_char *)output, &outl, 1494 (const u_char *)input, size) != 1) { 1495 warnx("OpenSSL %s/%zu (%zu, %zu) encrypt update failed: %s", 1496 alg->name, iv_len, aad_len, size, 1497 ERR_error_string(ERR_get_error(), NULL)); 1498 goto error; 1499 } 1500 total = outl; 1501 if (EVP_EncryptFinal_ex(ctx, (u_char *)output + outl, &outl) != 1) { 1502 warnx("OpenSSL %s/%zu (%zu, %zu) encrypt final failed: %s", 1503 alg->name, iv_len, aad_len, size, 1504 ERR_error_string(ERR_get_error(), NULL)); 1505 goto error; 1506 } 1507 total += outl; 1508 if ((size_t)total != size) { 1509 warnx("OpenSSL %s/%zu (%zu, %zu) encrypt size mismatch: %d", 1510 alg->name, iv_len, aad_len, size, total); 1511 goto error; 1512 } 1513 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_CBC_MAC_HASH_LEN, 1514 tag) != 1) { 1515 warnx("OpenSSL %s/%zu (%zu, %zu) get tag failed: %s", 1516 alg->name, iv_len, aad_len, size, 1517 ERR_error_string(ERR_get_error(), NULL)); 1518 goto error; 1519 } 1520 EVP_CIPHER_CTX_free(ctx); 1521 return (true); 1522 1523error: 1524 EVP_CIPHER_CTX_free(ctx); 1525 return (false); 1526} 1527 1528static bool 1529ocf_init_aead_session(const struct alg *alg, const char *key, size_t key_len, 1530 size_t iv_len, struct ocf_session *ses) 1531{ 1532 struct session2_op sop; 1533 1534 ocf_init_sop(&sop); 1535 sop.keylen = key_len; 1536 sop.key = key; 1537 sop.cipher = alg->cipher; 1538 sop.ivlen = iv_len; 1539 return (ocf_init_session(&sop, "AEAD", alg->name, ses)); 1540} 1541 1542static int 1543ocf_aead(const struct ocf_session *ses, const char *iv, size_t iv_len, 1544 const char *aad, size_t aad_len, const char *input, char *output, 1545 size_t size, char *tag, int op) 1546{ 1547 struct crypt_aead caead; 1548 1549 ocf_init_caead(ses, &caead); 1550 caead.op = op; 1551 caead.len = size; 1552 caead.aadlen = aad_len; 1553 caead.ivlen = iv_len; 1554 caead.src = input; 1555 caead.dst = output; 1556 caead.aad = aad; 1557 caead.tag = tag; 1558 caead.iv = iv; 1559 1560 if (ioctl(ses->fd, CIOCCRYPTAEAD, &caead) < 0) 1561 return (errno); 1562 return (0); 1563} 1564 1565#define AEAD_MAX_TAG_LEN \ 1566 MAX(MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN), POLY1305_HASH_LEN) 1567 1568static size_t 1569max_ccm_buffer_length(size_t iv_len) 1570{ 1571 const u_int L = 15 - iv_len; 1572 1573 switch (L) { 1574 case 2: 1575 return (0xffff); 1576 case 3: 1577 return (0xffffff); 1578#ifdef __LP64__ 1579 case 4: 1580 return (0xffffffff); 1581 case 5: 1582 return (0xffffffffff); 1583 case 6: 1584 return (0xffffffffffff); 1585 case 7: 1586 return (0xffffffffffffff); 1587 default: 1588 return (0xffffffffffffffff); 1589#else 1590 default: 1591 return (0xffffffff); 1592#endif 1593 } 1594} 1595 1596static void 1597run_aead_test(const struct alg *alg, size_t aad_len, size_t size, 1598 size_t iv_len) 1599{ 1600 struct ocf_session ses; 1601 const EVP_CIPHER *cipher; 1602 char *aad, *buffer, *cleartext, *ciphertext; 1603 char *iv, *key; 1604 u_int key_len; 1605 int error; 1606 char control_tag[AEAD_MAX_TAG_LEN], test_tag[AEAD_MAX_TAG_LEN]; 1607 bool ok; 1608 1609 cipher = alg->evp_cipher(); 1610 if (size % EVP_CIPHER_block_size(cipher) != 0) { 1611 if (verbose) 1612 printf( 1613 "%s/%zu (%zu, %zu): invalid buffer size (block size %d)\n", 1614 alg->name, iv_len, aad_len, size, 1615 EVP_CIPHER_block_size(cipher)); 1616 return; 1617 } 1618 1619 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE && 1620 size > max_ccm_buffer_length(iv_len)) { 1621 if (verbose) 1622 printf("%s/%zu (%zu, %zu): invalid buffer size\n", 1623 alg->name, iv_len, aad_len, size); 1624 return; 1625 } 1626 1627 memset(control_tag, 0x3c, sizeof(control_tag)); 1628 memset(test_tag, 0x3c, sizeof(test_tag)); 1629 1630 key_len = EVP_CIPHER_key_length(cipher); 1631 1632 key = alloc_buffer(key_len); 1633 iv = generate_iv(iv_len, alg); 1634 cleartext = alloc_buffer(size); 1635 buffer = malloc(size); 1636 ciphertext = malloc(size); 1637 if (aad_len != 0) 1638 aad = alloc_buffer(aad_len); 1639 else 1640 aad = NULL; 1641 1642 /* OpenSSL encrypt */ 1643 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE) 1644 ok = openssl_ccm_encrypt(alg, cipher, key, iv, iv_len, aad, 1645 aad_len, cleartext, ciphertext, size, control_tag); 1646 else 1647 ok = openssl_aead_encrypt(alg, cipher, key, iv, iv_len, aad, 1648 aad_len, cleartext, ciphertext, size, control_tag); 1649 if (!ok) 1650 goto out_noocf; 1651 1652 if (!ocf_init_aead_session(alg, key, key_len, iv_len, &ses)) 1653 goto out_noocf; 1654 1655 /* OCF encrypt */ 1656 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, cleartext, buffer, 1657 size, test_tag, COP_ENCRYPT); 1658 if (error != 0) { 1659 warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s", 1660 alg->name, iv_len, aad_len, size, crfind(ses.crid)); 1661 goto out; 1662 } 1663 if (memcmp(ciphertext, buffer, size) != 0) { 1664 printf("%s/%zu (%zu, %zu) encryption mismatch:\n", alg->name, 1665 iv_len, aad_len, size); 1666 printf("control:\n"); 1667 hexdump(ciphertext, size, NULL, 0); 1668 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1669 hexdump(buffer, size, NULL, 0); 1670 goto out; 1671 } 1672 if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { 1673 printf("%s/%zu (%zu, %zu) enc tag mismatch:\n", alg->name, 1674 iv_len, aad_len, size); 1675 printf("control:\n"); 1676 hexdump(control_tag, sizeof(control_tag), NULL, 0); 1677 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1678 hexdump(test_tag, sizeof(test_tag), NULL, 0); 1679 goto out; 1680 } 1681 1682 /* OCF decrypt */ 1683 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext, 1684 buffer, size, control_tag, COP_DECRYPT); 1685 if (error != 0) { 1686 warnc(error, "cryptodev %s/%zu (%zu, %zu) failed for device %s", 1687 alg->name, iv_len, aad_len, size, crfind(ses.crid)); 1688 goto out; 1689 } 1690 if (memcmp(cleartext, buffer, size) != 0) { 1691 printf("%s/%zu (%zu, %zu) decryption mismatch:\n", alg->name, 1692 iv_len, aad_len, size); 1693 printf("control:\n"); 1694 hexdump(cleartext, size, NULL, 0); 1695 printf("test (cryptodev device %s):\n", crfind(ses.crid)); 1696 hexdump(buffer, size, NULL, 0); 1697 goto out; 1698 } 1699 1700 /* Verify OCF decrypt fails with busted tag. */ 1701 test_tag[0] ^= 0x1; 1702 error = ocf_aead(&ses, iv, iv_len, aad, aad_len, ciphertext, 1703 buffer, size, test_tag, COP_DECRYPT); 1704 if (error != EBADMSG) { 1705 if (error != 0) 1706 warnc(error, 1707 "cryptodev %s/%zu (%zu, %zu) corrupt tag failed for device %s", 1708 alg->name, iv_len, aad_len, size, crfind(ses.crid)); 1709 else 1710 warnx( 1711 "cryptodev %s/%zu (%zu, %zu) corrupt tag didn't fail for device %s", 1712 alg->name, iv_len, aad_len, size, crfind(ses.crid)); 1713 goto out; 1714 } 1715 1716 if (verbose) 1717 printf("%s/%zu (%zu, %zu) matched (cryptodev device %s)\n", 1718 alg->name, iv_len, aad_len, size, crfind(ses.crid)); 1719 1720out: 1721 ocf_destroy_session(&ses); 1722out_noocf: 1723 free(aad); 1724 free(ciphertext); 1725 free(buffer); 1726 free(cleartext); 1727 free(iv); 1728 free(key); 1729} 1730 1731static void 1732run_test(const struct alg *alg, size_t aad_len, size_t size, size_t iv_len) 1733{ 1734 1735 switch (alg->type) { 1736 case T_HASH: 1737 run_hash_test(alg, size); 1738 break; 1739 case T_HMAC: 1740 run_hmac_test(alg, size); 1741 break; 1742 case T_GMAC: 1743 run_gmac_test(alg, size); 1744 break; 1745 case T_DIGEST: 1746 run_digest_test(alg, size); 1747 break; 1748 case T_CIPHER: 1749 run_cipher_test(alg, size); 1750 break; 1751 case T_ETA: 1752 run_eta_test(alg, aad_len, size); 1753 break; 1754 case T_AEAD: 1755 run_aead_test(alg, aad_len, size, iv_len); 1756 break; 1757 } 1758} 1759 1760static void 1761run_test_sizes(const struct alg *alg) 1762{ 1763 u_int i, j, k; 1764 1765 switch (alg->type) { 1766 default: 1767 for (i = 0; i < nsizes; i++) 1768 run_test(alg, 0, sizes[i], 0); 1769 break; 1770 case T_ETA: 1771 for (i = 0; i < naad_sizes; i++) 1772 for (j = 0; j < nsizes; j++) 1773 run_test(alg, aad_sizes[i], sizes[j], 0); 1774 break; 1775 case T_AEAD: 1776 for (i = 0; i < naad_sizes; i++) { 1777 for (j = 0; j < nsizes; j++) { 1778 if (iv_size != 0) 1779 run_test(alg, aad_sizes[i], sizes[j], 1780 iv_size); 1781 else if (testall) { 1782 for (k = 0; alg->iv_sizes[k] != 0; k++) 1783 run_test(alg, aad_sizes[i], 1784 sizes[j], alg->iv_sizes[k]); 1785 } else 1786 run_test(alg, aad_sizes[i], sizes[j], 1787 alg->iv_sizes[0]); 1788 } 1789 } 1790 break; 1791 } 1792} 1793 1794static void 1795run_hash_tests(void) 1796{ 1797 u_int i; 1798 1799 for (i = 0; i < nitems(algs); i++) 1800 if (algs[i].type == T_HASH) 1801 run_test_sizes(&algs[i]); 1802} 1803 1804static void 1805run_mac_tests(void) 1806{ 1807 u_int i; 1808 1809 for (i = 0; i < nitems(algs); i++) 1810 if (algs[i].type == T_HMAC || algs[i].type == T_GMAC || 1811 algs[i].type == T_DIGEST) 1812 run_test_sizes(&algs[i]); 1813} 1814 1815static void 1816run_cipher_tests(void) 1817{ 1818 u_int i; 1819 1820 for (i = 0; i < nitems(algs); i++) 1821 if (algs[i].type == T_CIPHER) 1822 run_test_sizes(&algs[i]); 1823} 1824 1825static void 1826run_eta_tests(void) 1827{ 1828 const struct alg *cipher, *mac; 1829 struct alg *eta; 1830 u_int i, j; 1831 1832 for (i = 0; i < nitems(algs); i++) { 1833 cipher = &algs[i]; 1834 if (cipher->type != T_CIPHER) 1835 continue; 1836 for (j = 0; j < nitems(algs); j++) { 1837 mac = &algs[j]; 1838 if (mac->type != T_HMAC) 1839 continue; 1840 eta = build_eta(cipher, mac); 1841 run_test_sizes(eta); 1842 free_eta(eta); 1843 } 1844 } 1845} 1846 1847static void 1848run_aead_tests(void) 1849{ 1850 u_int i; 1851 1852 for (i = 0; i < nitems(algs); i++) 1853 if (algs[i].type == T_AEAD) 1854 run_test_sizes(&algs[i]); 1855} 1856 1857static void 1858run_prefix_tests(const char *prefix) 1859{ 1860 size_t prefix_len; 1861 u_int i; 1862 1863 prefix_len = strlen(prefix); 1864 for (i = 0; i < nitems(algs); i++) 1865 if (strlen(algs[i].name) >= prefix_len && 1866 memcmp(algs[i].name, prefix, prefix_len) == 0) 1867 run_test_sizes(&algs[i]); 1868} 1869 1870int 1871main(int ac, char **av) 1872{ 1873 const char *algname; 1874 const struct alg *alg; 1875 struct alg *eta; 1876 char *cp; 1877 size_t base_size; 1878 u_int i; 1879 int ch; 1880 1881 algname = NULL; 1882 requested_crid = CRYPTO_FLAG_HARDWARE; 1883 testall = false; 1884 verbose = false; 1885 iv_size = 0; 1886 while ((ch = getopt(ac, av, "A:a:d:I:vz")) != -1) 1887 switch (ch) { 1888 case 'A': 1889 if (naad_sizes >= nitems(aad_sizes)) { 1890 warnx("Too many AAD sizes, ignoring extras"); 1891 break; 1892 } 1893 aad_sizes[naad_sizes] = strtol(optarg, &cp, 0); 1894 if (*cp != '\0') 1895 errx(1, "Bad AAD size %s", optarg); 1896 naad_sizes++; 1897 break; 1898 case 'a': 1899 algname = optarg; 1900 break; 1901 case 'd': 1902 requested_crid = crlookup(optarg); 1903 break; 1904 case 'I': 1905 iv_size = strtol(optarg, &cp, 0); 1906 if (*cp != '\0') 1907 errx(1, "Bad IV size %s", optarg); 1908 break; 1909 case 'v': 1910 verbose = true; 1911 break; 1912 case 'z': 1913 testall = true; 1914 break; 1915 default: 1916 usage(); 1917 } 1918 ac -= optind; 1919 av += optind; 1920 nsizes = 0; 1921 while (ac > 0) { 1922 if (nsizes >= nitems(sizes)) { 1923 warnx("Too many sizes, ignoring extras"); 1924 break; 1925 } 1926 sizes[nsizes] = strtol(av[0], &cp, 0); 1927 if (*cp != '\0') 1928 errx(1, "Bad size %s", av[0]); 1929 nsizes++; 1930 ac--; 1931 av++; 1932 } 1933 1934 if (algname == NULL) 1935 errx(1, "Algorithm required"); 1936 1937 if (naad_sizes == 0) { 1938 if (testall) { 1939 for (i = 0; i <= 32; i++) { 1940 aad_sizes[naad_sizes] = i; 1941 naad_sizes++; 1942 } 1943 1944 base_size = 32; 1945 while (base_size * 2 < 512) { 1946 base_size *= 2; 1947 assert(naad_sizes < nitems(aad_sizes)); 1948 aad_sizes[naad_sizes] = base_size; 1949 naad_sizes++; 1950 } 1951 } else { 1952 aad_sizes[0] = 0; 1953 naad_sizes = 1; 1954 } 1955 } 1956 1957 if (nsizes == 0) { 1958 if (testall) { 1959 for (i = 1; i <= EALG_MAX_BLOCK_LEN; i++) { 1960 sizes[nsizes] = i; 1961 nsizes++; 1962 } 1963 1964 for (i = EALG_MAX_BLOCK_LEN + 8; 1965 i <= EALG_MAX_BLOCK_LEN * 2; i += 8) { 1966 sizes[nsizes] = i; 1967 nsizes++; 1968 } 1969 1970 base_size = EALG_MAX_BLOCK_LEN * 2; 1971 while (base_size * 2 < 240 * 1024) { 1972 base_size *= 2; 1973 assert(nsizes < nitems(sizes)); 1974 sizes[nsizes] = base_size; 1975 nsizes++; 1976 } 1977 1978 if (sizes[nsizes - 1] < 240 * 1024) { 1979 assert(nsizes < nitems(sizes)); 1980 sizes[nsizes] = 240 * 1024; 1981 nsizes++; 1982 } 1983 } else { 1984 sizes[0] = 16; 1985 nsizes = 1; 1986 } 1987 } 1988 1989 if (strcasecmp(algname, "hash") == 0) 1990 run_hash_tests(); 1991 else if (strcasecmp(algname, "mac") == 0) 1992 run_mac_tests(); 1993 else if (strcasecmp(algname, "cipher") == 0) 1994 run_cipher_tests(); 1995 else if (strcasecmp(algname, "eta") == 0) 1996 run_eta_tests(); 1997 else if (strcasecmp(algname, "aead") == 0) 1998 run_aead_tests(); 1999 else if (strcasecmp(algname, "gmac") == 0 || 2000 strcasecmp(algname, "aes-cbc") == 0 || 2001 strcasecmp(algname, "aes-ctr") == 0 || 2002 strcasecmp(algname, "aes-xts") == 0 || 2003 strcasecmp(algname, "camellia-cbc") == 0 || 2004 strcasecmp(algname, "aes-gcm") == 0 || 2005 strcasecmp(algname, "aes-ccm") == 0) 2006 run_prefix_tests(algname); 2007 else if (strcasecmp(algname, "all") == 0) { 2008 run_hash_tests(); 2009 run_mac_tests(); 2010 run_cipher_tests(); 2011 run_eta_tests(); 2012 run_aead_tests(); 2013 } else if (strchr(algname, '+') != NULL) { 2014 eta = build_eta_name(algname); 2015 run_test_sizes(eta); 2016 free_eta(eta); 2017 } else { 2018 alg = find_alg(algname); 2019 if (alg == NULL) 2020 errx(1, "Invalid algorithm %s", algname); 2021 run_test_sizes(alg); 2022 } 2023 2024 return (0); 2025} 2026