Annotation of embedaddon/strongswan/src/libstrongswan/crypto/crypto_tester.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2009-2010 Martin Willi
! 3: * Copyright (C) 2016-2019 Andreas Steffen
! 4: * HSR Hochschule fuer Technik Rapperswil
! 5: * Copyright (C) 2010 revosec AG
! 6: *
! 7: * This program is free software; you can redistribute it and/or modify it
! 8: * under the terms of the GNU General Public License as published by the
! 9: * Free Software Foundation; either version 2 of the License, or (at your
! 10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 11: *
! 12: * This program is distributed in the hope that it will be useful, but
! 13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 15: * for more details.
! 16: */
! 17:
! 18: #ifdef HAVE_DLADDR
! 19: # define _GNU_SOURCE
! 20: # include <dlfcn.h>
! 21: #endif
! 22: #include <time.h>
! 23:
! 24: #include "crypto_tester.h"
! 25:
! 26: #include <utils/debug.h>
! 27: #include <collections/linked_list.h>
! 28: #include <crypto/rngs/rng_tester.h>
! 29:
! 30: typedef struct private_crypto_tester_t private_crypto_tester_t;
! 31:
! 32: /**
! 33: * Private data of an crypto_tester_t object.
! 34: */
! 35: struct private_crypto_tester_t {
! 36:
! 37: /**
! 38: * Public crypto_tester_t interface.
! 39: */
! 40: crypto_tester_t public;
! 41:
! 42: /**
! 43: * List of crypter test vectors
! 44: */
! 45: linked_list_t *crypter;
! 46:
! 47: /**
! 48: * List of aead test vectors
! 49: */
! 50: linked_list_t *aead;
! 51:
! 52: /**
! 53: * List of signer test vectors
! 54: */
! 55: linked_list_t *signer;
! 56:
! 57: /**
! 58: * List of hasher test vectors
! 59: */
! 60: linked_list_t *hasher;
! 61:
! 62: /**
! 63: * List of PRF test vectors
! 64: */
! 65: linked_list_t *prf;
! 66:
! 67: /**
! 68: * List of XOF test vectors
! 69: */
! 70: linked_list_t *xof;
! 71:
! 72: /**
! 73: * List of DRBG test vectors
! 74: */
! 75: linked_list_t *drbg;
! 76:
! 77: /**
! 78: * List of RNG test vectors
! 79: */
! 80: linked_list_t *rng;
! 81:
! 82: /**
! 83: * List of Diffie-Hellman test vectors
! 84: */
! 85: linked_list_t *dh;
! 86:
! 87: /**
! 88: * Is a test vector required to pass a test?
! 89: */
! 90: bool required;
! 91:
! 92: /**
! 93: * should we run RNG_TRUE tests? Enough entropy?
! 94: */
! 95: bool rng_true;
! 96:
! 97: /**
! 98: * time we test each algorithm
! 99: */
! 100: int bench_time;
! 101:
! 102: /**
! 103: * size of buffer we use for benchmarking
! 104: */
! 105: int bench_size;
! 106: };
! 107:
! 108: /**
! 109: * Get the name of a test vector, if available
! 110: */
! 111: static const char* get_name(void *sym)
! 112: {
! 113: #ifdef HAVE_DLADDR
! 114: Dl_info dli;
! 115:
! 116: if (dladdr(sym, &dli))
! 117: {
! 118: return dli.dli_sname;
! 119: }
! 120: #endif
! 121: return "unknown";
! 122: }
! 123:
! 124: #if defined(CLOCK_THREAD_CPUTIME_ID) && defined(HAVE_CLOCK_GETTIME)
! 125:
! 126: /**
! 127: * Start a benchmark timer
! 128: */
! 129: static void start_timing(struct timespec *start)
! 130: {
! 131: clock_gettime(CLOCK_THREAD_CPUTIME_ID, start);
! 132: }
! 133:
! 134: /**
! 135: * End a benchmark timer, return ms
! 136: */
! 137: static u_int end_timing(struct timespec *start)
! 138: {
! 139: struct timespec end;
! 140:
! 141: clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
! 142: return (end.tv_nsec - start->tv_nsec) / 1000000 +
! 143: (end.tv_sec - start->tv_sec) * 1000;
! 144: }
! 145:
! 146: #else /* CLOCK_THREAD_CPUTIME_ID */
! 147:
! 148: /* Make benchmarking a no-op if CLOCK_THREAD_CPUTIME_ID is not available */
! 149: #define start_timing(start) ((start)->tv_sec = 0, (start)->tv_nsec = 0)
! 150: #define end_timing(...) (this->bench_time)
! 151:
! 152: #endif /* CLOCK_THREAD_CPUTIME_ID */
! 153:
! 154: /**
! 155: * Benchmark a crypter
! 156: */
! 157: static u_int bench_crypter(private_crypto_tester_t *this,
! 158: encryption_algorithm_t alg, crypter_constructor_t create, size_t key_size)
! 159: {
! 160: crypter_t *crypter;
! 161:
! 162: crypter = create(alg, key_size);
! 163: if (crypter)
! 164: {
! 165: char iv[crypter->get_iv_size(crypter)];
! 166: char key[crypter->get_key_size(crypter)];
! 167: chunk_t buf;
! 168: struct timespec start;
! 169: u_int runs;
! 170:
! 171: memset(iv, 0x56, sizeof(iv));
! 172: memset(key, 0x12, sizeof(key));
! 173: if (!crypter->set_key(crypter, chunk_from_thing(key)))
! 174: {
! 175: return 0;
! 176: }
! 177:
! 178: buf = chunk_alloc(this->bench_size);
! 179: memset(buf.ptr, 0x34, buf.len);
! 180:
! 181: runs = 0;
! 182: start_timing(&start);
! 183: while (end_timing(&start) < this->bench_time)
! 184: {
! 185: if (crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL))
! 186: {
! 187: runs++;
! 188: }
! 189: if (crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL))
! 190: {
! 191: runs++;
! 192: }
! 193: }
! 194: free(buf.ptr);
! 195: crypter->destroy(crypter);
! 196:
! 197: return runs;
! 198: }
! 199: return 0;
! 200: }
! 201:
! 202: METHOD(crypto_tester_t, test_crypter, bool,
! 203: private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
! 204: crypter_constructor_t create, u_int *speed, const char *plugin_name)
! 205: {
! 206: enumerator_t *enumerator;
! 207: crypter_test_vector_t *vector;
! 208: bool failed = FALSE;
! 209: u_int tested = 0;
! 210:
! 211: enumerator = this->crypter->create_enumerator(this->crypter);
! 212: while (enumerator->enumerate(enumerator, &vector))
! 213: {
! 214: crypter_t *crypter;
! 215: chunk_t key, iv, plain = chunk_empty, cipher = chunk_empty;
! 216:
! 217: if (vector->alg != alg)
! 218: {
! 219: continue;
! 220: }
! 221: if (key_size && key_size != vector->key_size)
! 222: { /* test only vectors with a specific key size, if key size given */
! 223: continue;
! 224: }
! 225:
! 226: crypter = create(alg, vector->key_size);
! 227: if (!crypter)
! 228: { /* key size not supported */
! 229: continue;
! 230: }
! 231: tested++;
! 232: failed = TRUE;
! 233:
! 234: key = chunk_create(vector->key, crypter->get_key_size(crypter));
! 235: if (!crypter->set_key(crypter, key))
! 236: {
! 237: goto failure;
! 238: }
! 239: iv = chunk_create(vector->iv, crypter->get_iv_size(crypter));
! 240:
! 241: /* allocated encryption */
! 242: plain = chunk_create(vector->plain, vector->len);
! 243: if (!crypter->encrypt(crypter, plain, iv, &cipher))
! 244: {
! 245: goto failure;
! 246: }
! 247: if (!memeq(vector->cipher, cipher.ptr, cipher.len))
! 248: {
! 249: goto failure;
! 250: }
! 251: /* inline decryption */
! 252: if (!crypter->decrypt(crypter, cipher, iv, NULL))
! 253: {
! 254: goto failure;
! 255: }
! 256: if (!memeq(vector->plain, cipher.ptr, cipher.len))
! 257: {
! 258: goto failure;
! 259: }
! 260: /* allocated decryption */
! 261: if (!crypter->decrypt(crypter,
! 262: chunk_create(vector->cipher, vector->len), iv, &plain))
! 263: {
! 264: goto failure;
! 265: }
! 266: if (!memeq(vector->plain, plain.ptr, plain.len))
! 267: {
! 268: goto failure;
! 269: }
! 270: /* inline encryption */
! 271: if (!crypter->encrypt(crypter, plain, iv, NULL))
! 272: {
! 273: goto failure;
! 274: }
! 275: if (!memeq(vector->cipher, plain.ptr, plain.len))
! 276: {
! 277: goto failure;
! 278: }
! 279:
! 280: failed = FALSE;
! 281: failure:
! 282: crypter->destroy(crypter);
! 283: chunk_free(&cipher);
! 284: if (plain.ptr != vector->plain)
! 285: {
! 286: chunk_free(&plain);
! 287: }
! 288: if (failed)
! 289: {
! 290: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 291: encryption_algorithm_names, alg, plugin_name, get_name(vector));
! 292: break;
! 293: }
! 294: }
! 295: enumerator->destroy(enumerator);
! 296: if (!tested)
! 297: {
! 298: if (failed)
! 299: {
! 300: DBG1(DBG_LIB,"disable %N[%s]: %zd byte key size not supported",
! 301: encryption_algorithm_names, alg, plugin_name, key_size);
! 302: return FALSE;
! 303: }
! 304: else
! 305: {
! 306: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 307: this->required ? "disabled" : "enabled ",
! 308: encryption_algorithm_names, alg, plugin_name);
! 309: return !this->required;
! 310: }
! 311: }
! 312: if (!failed)
! 313: {
! 314: if (speed)
! 315: {
! 316: *speed = bench_crypter(this, alg, create, key_size);
! 317: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points "
! 318: "(%zd bit key)", encryption_algorithm_names, alg,
! 319: plugin_name, tested, *speed, key_size * 8);
! 320: }
! 321: else
! 322: {
! 323: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 324: encryption_algorithm_names, alg, plugin_name, tested);
! 325: }
! 326: }
! 327: return !failed;
! 328: }
! 329:
! 330: /**
! 331: * Benchmark an aead transform
! 332: */
! 333: static u_int bench_aead(private_crypto_tester_t *this,
! 334: encryption_algorithm_t alg, aead_constructor_t create, size_t key_size)
! 335: {
! 336: aead_t *aead;
! 337:
! 338: aead = create(alg, key_size, 0);
! 339: if (aead)
! 340: {
! 341: char iv[aead->get_iv_size(aead)];
! 342: char key[aead->get_key_size(aead)];
! 343: char assoc[4];
! 344: chunk_t buf;
! 345: struct timespec start;
! 346: u_int runs;
! 347: size_t icv;
! 348:
! 349: memset(iv, 0x56, sizeof(iv));
! 350: memset(key, 0x12, sizeof(key));
! 351: memset(assoc, 0x78, sizeof(assoc));
! 352: if (!aead->set_key(aead, chunk_from_thing(key)))
! 353: {
! 354: return 0;
! 355: }
! 356: icv = aead->get_icv_size(aead);
! 357:
! 358: buf = chunk_alloc(this->bench_size + icv);
! 359: memset(buf.ptr, 0x34, buf.len);
! 360: buf.len -= icv;
! 361:
! 362: runs = 0;
! 363: start_timing(&start);
! 364: while (end_timing(&start) < this->bench_time)
! 365: {
! 366: if (aead->encrypt(aead, buf, chunk_from_thing(assoc),
! 367: chunk_from_thing(iv), NULL))
! 368: {
! 369: runs += 2;
! 370: }
! 371: if (aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv),
! 372: chunk_from_thing(assoc), chunk_from_thing(iv), NULL))
! 373: {
! 374: runs += 2;
! 375: }
! 376: }
! 377: free(buf.ptr);
! 378: aead->destroy(aead);
! 379:
! 380: return runs;
! 381: }
! 382: return 0;
! 383: }
! 384:
! 385: METHOD(crypto_tester_t, test_aead, bool,
! 386: private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
! 387: size_t salt_size, aead_constructor_t create,
! 388: u_int *speed, const char *plugin_name)
! 389: {
! 390: enumerator_t *enumerator;
! 391: aead_test_vector_t *vector;
! 392: bool failed = FALSE;
! 393: u_int tested = 0;
! 394:
! 395: enumerator = this->aead->create_enumerator(this->aead);
! 396: while (enumerator->enumerate(enumerator, &vector))
! 397: {
! 398: aead_t *aead;
! 399: chunk_t key, iv, assoc, plain = chunk_empty, cipher = chunk_empty;
! 400: size_t icv;
! 401:
! 402: if (vector->alg != alg)
! 403: {
! 404: continue;
! 405: }
! 406: if (key_size && key_size != vector->key_size)
! 407: { /* test only vectors with a specific key size, if key size given */
! 408: continue;
! 409: }
! 410: if (salt_size && salt_size != vector->salt_size)
! 411: {
! 412: continue;
! 413: }
! 414:
! 415: tested++;
! 416: failed = TRUE;
! 417: aead = create(alg, vector->key_size, vector->salt_size);
! 418: if (!aead)
! 419: {
! 420: DBG1(DBG_LIB, "%N[%s]: %u bit key size not supported",
! 421: encryption_algorithm_names, alg, plugin_name,
! 422: BITS_PER_BYTE * vector->key_size);
! 423: continue;
! 424: }
! 425:
! 426: key = chunk_create(vector->key, aead->get_key_size(aead));
! 427: if (!aead->set_key(aead, key))
! 428: {
! 429: goto failure;
! 430: }
! 431: iv = chunk_create(vector->iv, aead->get_iv_size(aead));
! 432: assoc = chunk_create(vector->adata, vector->alen);
! 433: icv = aead->get_icv_size(aead);
! 434:
! 435: /* allocated encryption */
! 436: plain = chunk_create(vector->plain, vector->len);
! 437: if (!aead->encrypt(aead, plain, assoc, iv, &cipher))
! 438: {
! 439: goto failure;
! 440: }
! 441: if (!memeq(vector->cipher, cipher.ptr, cipher.len))
! 442: {
! 443: goto failure;
! 444: }
! 445: /* inline decryption */
! 446: if (!aead->decrypt(aead, cipher, assoc, iv, NULL))
! 447: {
! 448: goto failure;
! 449: }
! 450: if (!memeq(vector->plain, cipher.ptr, cipher.len - icv))
! 451: {
! 452: goto failure;
! 453: }
! 454: /* allocated decryption */
! 455: if (!aead->decrypt(aead, chunk_create(vector->cipher, vector->len + icv),
! 456: assoc, iv, &plain))
! 457: {
! 458: goto failure;
! 459: }
! 460: if (!memeq(vector->plain, plain.ptr, plain.len))
! 461: {
! 462: goto failure;
! 463: }
! 464: plain.ptr = realloc(plain.ptr, plain.len + icv);
! 465: /* inline encryption */
! 466: if (!aead->encrypt(aead, plain, assoc, iv, NULL))
! 467: {
! 468: goto failure;
! 469: }
! 470: if (!memeq(vector->cipher, plain.ptr, plain.len + icv))
! 471: {
! 472: goto failure;
! 473: }
! 474:
! 475: failed = FALSE;
! 476: failure:
! 477: aead->destroy(aead);
! 478: chunk_free(&cipher);
! 479: if (plain.ptr != vector->plain)
! 480: {
! 481: chunk_free(&plain);
! 482: }
! 483: if (failed)
! 484: {
! 485: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 486: encryption_algorithm_names, alg, plugin_name, get_name(vector));
! 487: break;
! 488: }
! 489: }
! 490: enumerator->destroy(enumerator);
! 491: if (!tested)
! 492: {
! 493: if (failed)
! 494: {
! 495: DBG1(DBG_LIB,"disable %N[%s]: %zd byte key size not supported",
! 496: encryption_algorithm_names, alg, plugin_name, key_size);
! 497: return FALSE;
! 498: }
! 499: else
! 500: {
! 501: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 502: this->required ? "disabled" : "enabled ",
! 503: encryption_algorithm_names, alg, plugin_name);
! 504: return !this->required;
! 505: }
! 506: }
! 507: if (!failed)
! 508: {
! 509: if (speed)
! 510: {
! 511: *speed = bench_aead(this, alg, create, key_size);
! 512: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points "
! 513: "(%zd bit key)", encryption_algorithm_names, alg,
! 514: plugin_name, tested, *speed, key_size * 8);
! 515: }
! 516: else
! 517: {
! 518: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 519: encryption_algorithm_names, alg, plugin_name, tested);
! 520: }
! 521: }
! 522: return !failed;
! 523: }
! 524:
! 525: /**
! 526: * Benchmark a signer
! 527: */
! 528: static u_int bench_signer(private_crypto_tester_t *this,
! 529: integrity_algorithm_t alg, signer_constructor_t create)
! 530: {
! 531: signer_t *signer;
! 532:
! 533: signer = create(alg);
! 534: if (signer)
! 535: {
! 536: char key[signer->get_key_size(signer)];
! 537: char mac[signer->get_block_size(signer)];
! 538: chunk_t buf;
! 539: struct timespec start;
! 540: u_int runs;
! 541:
! 542: memset(key, 0x12, sizeof(key));
! 543: if (!signer->set_key(signer, chunk_from_thing(key)))
! 544: {
! 545: return 0;
! 546: }
! 547:
! 548: buf = chunk_alloc(this->bench_size);
! 549: memset(buf.ptr, 0x34, buf.len);
! 550:
! 551: runs = 0;
! 552: start_timing(&start);
! 553: while (end_timing(&start) < this->bench_time)
! 554: {
! 555: if (signer->get_signature(signer, buf, mac))
! 556: {
! 557: runs++;
! 558: }
! 559: if (signer->verify_signature(signer, buf, chunk_from_thing(mac)))
! 560: {
! 561: runs++;
! 562: }
! 563: }
! 564: free(buf.ptr);
! 565: signer->destroy(signer);
! 566:
! 567: return runs;
! 568: }
! 569: return 0;
! 570: }
! 571:
! 572: METHOD(crypto_tester_t, test_signer, bool,
! 573: private_crypto_tester_t *this, integrity_algorithm_t alg,
! 574: signer_constructor_t create, u_int *speed, const char *plugin_name)
! 575: {
! 576: enumerator_t *enumerator;
! 577: signer_test_vector_t *vector;
! 578: bool failed = FALSE;
! 579: u_int tested = 0;
! 580:
! 581: enumerator = this->signer->create_enumerator(this->signer);
! 582: while (enumerator->enumerate(enumerator, &vector))
! 583: {
! 584: signer_t *signer;
! 585: chunk_t key, data, mac = chunk_empty;
! 586:
! 587: if (vector->alg != alg)
! 588: {
! 589: continue;
! 590: }
! 591:
! 592: tested++;
! 593: failed = TRUE;
! 594: signer = create(alg);
! 595: if (!signer)
! 596: {
! 597: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 598: integrity_algorithm_names, alg, plugin_name);
! 599: break;
! 600: }
! 601:
! 602: data = chunk_create(vector->data, vector->len);
! 603: key = chunk_create(vector->key, signer->get_key_size(signer));
! 604: if (!signer->set_key(signer, key))
! 605: {
! 606: goto failure;
! 607: }
! 608: /* do partial append mode and check if key gets set correctly */
! 609: if (!signer->get_signature(signer, data, NULL))
! 610: {
! 611: goto failure;
! 612: }
! 613: if (!signer->set_key(signer, key))
! 614: {
! 615: goto failure;
! 616: }
! 617: /* allocated signature */
! 618: if (!signer->allocate_signature(signer, data, &mac))
! 619: {
! 620: goto failure;
! 621: }
! 622: if (mac.len != signer->get_block_size(signer))
! 623: {
! 624: goto failure;
! 625: }
! 626: if (!memeq(vector->mac, mac.ptr, mac.len))
! 627: {
! 628: goto failure;
! 629: }
! 630: /* signature to existing buffer */
! 631: memset(mac.ptr, 0, mac.len);
! 632: if (!signer->get_signature(signer, data, mac.ptr))
! 633: {
! 634: goto failure;
! 635: }
! 636: if (!memeq(vector->mac, mac.ptr, mac.len))
! 637: {
! 638: goto failure;
! 639: }
! 640: /* signature verification, good case */
! 641: if (!signer->verify_signature(signer, data, mac))
! 642: {
! 643: goto failure;
! 644: }
! 645: /* signature verification, bad case */
! 646: *(mac.ptr + mac.len - 1) += 1;
! 647: if (signer->verify_signature(signer, data, mac))
! 648: {
! 649: goto failure;
! 650: }
! 651: /* signature to existing buffer, using append mode */
! 652: if (data.len > 2)
! 653: {
! 654: if (!signer->allocate_signature(signer,
! 655: chunk_create(data.ptr, 1), NULL))
! 656: {
! 657: goto failure;
! 658: }
! 659: if (!signer->get_signature(signer,
! 660: chunk_create(data.ptr + 1, 1), NULL))
! 661: {
! 662: goto failure;
! 663: }
! 664: if (!signer->verify_signature(signer, chunk_skip(data, 2),
! 665: chunk_create(vector->mac, mac.len)))
! 666: {
! 667: goto failure;
! 668: }
! 669: }
! 670:
! 671: failed = FALSE;
! 672: failure:
! 673: signer->destroy(signer);
! 674: chunk_free(&mac);
! 675: if (failed)
! 676: {
! 677: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 678: integrity_algorithm_names, alg, plugin_name, get_name(vector));
! 679: break;
! 680: }
! 681: }
! 682: enumerator->destroy(enumerator);
! 683: if (!tested)
! 684: {
! 685: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 686: this->required ? "disabled" : "enabled ",
! 687: integrity_algorithm_names, alg, plugin_name);
! 688: return !this->required;
! 689: }
! 690: if (!failed)
! 691: {
! 692: if (speed)
! 693: {
! 694: *speed = bench_signer(this, alg, create);
! 695: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 696: integrity_algorithm_names, alg, plugin_name, tested, *speed);
! 697: }
! 698: else
! 699: {
! 700: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 701: integrity_algorithm_names, alg, plugin_name, tested);
! 702: }
! 703: }
! 704: return !failed;
! 705: }
! 706:
! 707: /**
! 708: * Benchmark a hasher
! 709: */
! 710: static u_int bench_hasher(private_crypto_tester_t *this,
! 711: hash_algorithm_t alg, hasher_constructor_t create)
! 712: {
! 713: hasher_t *hasher;
! 714:
! 715: hasher = create(alg);
! 716: if (hasher)
! 717: {
! 718: char hash[hasher->get_hash_size(hasher)];
! 719: chunk_t buf;
! 720: struct timespec start;
! 721: u_int runs;
! 722:
! 723: buf = chunk_alloc(this->bench_size);
! 724: memset(buf.ptr, 0x34, buf.len);
! 725:
! 726: runs = 0;
! 727: start_timing(&start);
! 728: while (end_timing(&start) < this->bench_time)
! 729: {
! 730: if (hasher->get_hash(hasher, buf, hash))
! 731: {
! 732: runs++;
! 733: }
! 734: }
! 735: free(buf.ptr);
! 736: hasher->destroy(hasher);
! 737:
! 738: return runs;
! 739: }
! 740: return 0;
! 741: }
! 742:
! 743: METHOD(crypto_tester_t, test_hasher, bool,
! 744: private_crypto_tester_t *this, hash_algorithm_t alg,
! 745: hasher_constructor_t create, u_int *speed, const char *plugin_name)
! 746: {
! 747: enumerator_t *enumerator;
! 748: hasher_test_vector_t *vector;
! 749: bool failed = FALSE;
! 750: u_int tested = 0;
! 751:
! 752: enumerator = this->hasher->create_enumerator(this->hasher);
! 753: while (enumerator->enumerate(enumerator, &vector))
! 754: {
! 755: hasher_t *hasher;
! 756: chunk_t data, hash;
! 757:
! 758: if (vector->alg != alg)
! 759: {
! 760: continue;
! 761: }
! 762:
! 763: tested++;
! 764: failed = TRUE;
! 765: hasher = create(alg);
! 766: if (!hasher)
! 767: {
! 768: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 769: hash_algorithm_names, alg, plugin_name);
! 770: break;
! 771: }
! 772:
! 773: /* allocated hash */
! 774: data = chunk_create(vector->data, vector->len);
! 775: if (!hasher->allocate_hash(hasher, data, &hash))
! 776: {
! 777: goto failure;
! 778: }
! 779: if (hash.len != hasher->get_hash_size(hasher))
! 780: {
! 781: goto failure;
! 782: }
! 783: if (!memeq(vector->hash, hash.ptr, hash.len))
! 784: {
! 785: goto failure;
! 786: }
! 787: /* hash to existing buffer, with a reset */
! 788: memset(hash.ptr, 0, hash.len);
! 789: if (!hasher->get_hash(hasher, data, NULL))
! 790: {
! 791: goto failure;
! 792: }
! 793: if (!hasher->reset(hasher))
! 794: {
! 795: goto failure;
! 796: }
! 797: if (!hasher->get_hash(hasher, data, hash.ptr))
! 798: {
! 799: goto failure;
! 800: }
! 801: if (!memeq(vector->hash, hash.ptr, hash.len))
! 802: {
! 803: goto failure;
! 804: }
! 805: /* hasher to existing buffer, using append mode */
! 806: if (data.len > 2)
! 807: {
! 808: memset(hash.ptr, 0, hash.len);
! 809: if (!hasher->allocate_hash(hasher, chunk_create(data.ptr, 1), NULL))
! 810: {
! 811: goto failure;
! 812: }
! 813: if (!hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL))
! 814: {
! 815: goto failure;
! 816: }
! 817: if (!hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr))
! 818: {
! 819: goto failure;
! 820: }
! 821: if (!memeq(vector->hash, hash.ptr, hash.len))
! 822: {
! 823: goto failure;
! 824: }
! 825: }
! 826:
! 827: failed = FALSE;
! 828: failure:
! 829: hasher->destroy(hasher);
! 830: chunk_free(&hash);
! 831: if (failed)
! 832: {
! 833: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 834: hash_algorithm_names, alg, plugin_name, get_name(vector));
! 835: break;
! 836: }
! 837: }
! 838: enumerator->destroy(enumerator);
! 839: if (!tested)
! 840: {
! 841: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 842: this->required ? "disabled" : "enabled ",
! 843: hash_algorithm_names, alg, plugin_name);
! 844: return !this->required;
! 845: }
! 846: if (!failed)
! 847: {
! 848: if (speed)
! 849: {
! 850: *speed = bench_hasher(this, alg, create);
! 851: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 852: hash_algorithm_names, alg, plugin_name, tested, *speed);
! 853: }
! 854: else
! 855: {
! 856: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 857: hash_algorithm_names, alg, plugin_name, tested);
! 858: }
! 859: }
! 860: return !failed;
! 861: }
! 862:
! 863: /**
! 864: * Benchmark a PRF
! 865: */
! 866: static u_int bench_prf(private_crypto_tester_t *this,
! 867: pseudo_random_function_t alg, prf_constructor_t create)
! 868: {
! 869: prf_t *prf;
! 870:
! 871: prf = create(alg);
! 872: if (prf)
! 873: {
! 874: char bytes[prf->get_block_size(prf)], key[prf->get_block_size(prf)];
! 875: chunk_t buf;
! 876: struct timespec start;
! 877: u_int runs;
! 878:
! 879: memset(key, 0x56, prf->get_block_size(prf));
! 880: if (!prf->set_key(prf, chunk_create(key, prf->get_block_size(prf))))
! 881: {
! 882: prf->destroy(prf);
! 883: return 0;
! 884: }
! 885:
! 886: buf = chunk_alloc(this->bench_size);
! 887: memset(buf.ptr, 0x34, buf.len);
! 888:
! 889: runs = 0;
! 890: start_timing(&start);
! 891: while (end_timing(&start) < this->bench_time)
! 892: {
! 893: if (prf->get_bytes(prf, buf, bytes))
! 894: {
! 895: runs++;
! 896: }
! 897: }
! 898: free(buf.ptr);
! 899: prf->destroy(prf);
! 900:
! 901: return runs;
! 902: }
! 903: return 0;
! 904: }
! 905:
! 906: METHOD(crypto_tester_t, test_prf, bool,
! 907: private_crypto_tester_t *this, pseudo_random_function_t alg,
! 908: prf_constructor_t create, u_int *speed, const char *plugin_name)
! 909: {
! 910: enumerator_t *enumerator;
! 911: prf_test_vector_t *vector;
! 912: bool failed = FALSE;
! 913: u_int tested = 0;
! 914:
! 915: enumerator = this->prf->create_enumerator(this->prf);
! 916: while (enumerator->enumerate(enumerator, &vector))
! 917: {
! 918: prf_t *prf;
! 919: chunk_t key, seed, out = chunk_empty;
! 920:
! 921: if (vector->alg != alg)
! 922: {
! 923: continue;
! 924: }
! 925:
! 926: tested++;
! 927: failed = TRUE;
! 928: prf = create(alg);
! 929: if (!prf)
! 930: {
! 931: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 932: pseudo_random_function_names, alg, plugin_name);
! 933: break;
! 934: }
! 935:
! 936: seed = chunk_create(vector->seed, vector->len);
! 937: key = chunk_create(vector->key, vector->key_size);
! 938: if (!prf->set_key(prf, key))
! 939: {
! 940: goto failure;
! 941: }
! 942: if (alg != PRF_FIPS_SHA1_160)
! 943: {
! 944: /* do partial append mode and check if key gets set correctly */
! 945: if (!prf->get_bytes(prf, seed, NULL))
! 946: {
! 947: goto failure;
! 948: }
! 949: if (!prf->set_key(prf, key))
! 950: {
! 951: goto failure;
! 952: }
! 953: }
! 954: /* allocated bytes */
! 955: if (!prf->allocate_bytes(prf, seed, &out))
! 956: {
! 957: goto failure;
! 958: }
! 959: if (out.len != prf->get_block_size(prf))
! 960: {
! 961: goto failure;
! 962: }
! 963: if (!memeq(vector->out, out.ptr, out.len))
! 964: {
! 965: goto failure;
! 966: }
! 967: /* bytes to existing buffer */
! 968: memset(out.ptr, 0, out.len);
! 969: if (vector->stateful)
! 970: {
! 971: if (!prf->set_key(prf, key))
! 972: {
! 973: goto failure;
! 974: }
! 975: }
! 976: if (!prf->get_bytes(prf, seed, out.ptr))
! 977: {
! 978: goto failure;
! 979: }
! 980: if (!memeq(vector->out, out.ptr, out.len))
! 981: {
! 982: goto failure;
! 983: }
! 984: /* bytes to existing buffer, using append mode */
! 985: if (alg != PRF_FIPS_SHA1_160 && seed.len > 2)
! 986: {
! 987: memset(out.ptr, 0, out.len);
! 988: if (vector->stateful)
! 989: {
! 990: if (!prf->set_key(prf, key))
! 991: {
! 992: goto failure;
! 993: }
! 994: }
! 995: if (!prf->allocate_bytes(prf, chunk_create(seed.ptr, 1), NULL))
! 996: {
! 997: goto failure;
! 998: }
! 999: if (!prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL))
! 1000: {
! 1001: goto failure;
! 1002: }
! 1003: if (!prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr))
! 1004: {
! 1005: goto failure;
! 1006: }
! 1007: if (!memeq(vector->out, out.ptr, out.len))
! 1008: {
! 1009: goto failure;
! 1010: }
! 1011: }
! 1012:
! 1013: failed = FALSE;
! 1014: failure:
! 1015: prf->destroy(prf);
! 1016: chunk_free(&out);
! 1017: if (failed)
! 1018: {
! 1019: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 1020: pseudo_random_function_names, alg, plugin_name, get_name(vector));
! 1021: break;
! 1022: }
! 1023: }
! 1024: enumerator->destroy(enumerator);
! 1025: if (!tested)
! 1026: {
! 1027: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 1028: this->required ? "disabled" : "enabled ",
! 1029: pseudo_random_function_names, alg, plugin_name);
! 1030: return !this->required;
! 1031: }
! 1032: if (!failed)
! 1033: {
! 1034: if (speed)
! 1035: {
! 1036: *speed = bench_prf(this, alg, create);
! 1037: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 1038: pseudo_random_function_names, alg, plugin_name, tested, *speed);
! 1039: }
! 1040: else
! 1041: {
! 1042: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 1043: pseudo_random_function_names, alg, plugin_name, tested);
! 1044: }
! 1045: }
! 1046: return !failed;
! 1047: }
! 1048:
! 1049: /**
! 1050: * Benchmark an XOF
! 1051: */
! 1052: static u_int bench_xof(private_crypto_tester_t *this,
! 1053: ext_out_function_t alg, xof_constructor_t create)
! 1054: {
! 1055: xof_t *xof;
! 1056:
! 1057: xof = create(alg);
! 1058: if (xof)
! 1059: {
! 1060: char seed[xof->get_seed_size(xof)];
! 1061: char bytes[xof->get_block_size(xof)];
! 1062: struct timespec start;
! 1063: u_int runs;
! 1064:
! 1065: memset(seed, 0x56, xof->get_seed_size(xof));
! 1066: if (!xof->set_seed(xof, chunk_create(seed, xof->get_seed_size(xof))))
! 1067: {
! 1068: xof->destroy(xof);
! 1069: return 0;
! 1070: }
! 1071:
! 1072: runs = 0;
! 1073: start_timing(&start);
! 1074: while (end_timing(&start) < this->bench_time)
! 1075: {
! 1076: if (xof->get_bytes(xof, xof->get_block_size(xof), bytes))
! 1077: {
! 1078: runs++;
! 1079: }
! 1080: }
! 1081: xof->destroy(xof);
! 1082:
! 1083: return runs;
! 1084: }
! 1085: return 0;
! 1086: }
! 1087:
! 1088: METHOD(crypto_tester_t, test_xof, bool,
! 1089: private_crypto_tester_t *this, ext_out_function_t alg,
! 1090: xof_constructor_t create, u_int *speed, const char *plugin_name)
! 1091: {
! 1092: enumerator_t *enumerator;
! 1093: xof_test_vector_t *vector;
! 1094: bool failed = FALSE;
! 1095: u_int tested = 0;
! 1096:
! 1097: enumerator = this->xof->create_enumerator(this->xof);
! 1098: while (enumerator->enumerate(enumerator, &vector))
! 1099: {
! 1100: xof_t *xof;
! 1101: chunk_t seed, out = chunk_empty;
! 1102:
! 1103: if (vector->alg != alg)
! 1104: {
! 1105: continue;
! 1106: }
! 1107:
! 1108: tested++;
! 1109: failed = TRUE;
! 1110: xof = create(alg);
! 1111: if (!xof)
! 1112: {
! 1113: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 1114: ext_out_function_names, alg, plugin_name);
! 1115: break;
! 1116: }
! 1117:
! 1118: seed = chunk_create(vector->seed, vector->len);
! 1119: if (!xof->set_seed(xof, seed))
! 1120: {
! 1121: goto failure;
! 1122: }
! 1123: /* allocated bytes */
! 1124: if (!xof->allocate_bytes(xof, vector->out_len, &out))
! 1125: {
! 1126: goto failure;
! 1127: }
! 1128: if (out.len != vector->out_len)
! 1129: {
! 1130: goto failure;
! 1131: }
! 1132: if (!memeq(vector->out, out.ptr, out.len))
! 1133: {
! 1134: goto failure;
! 1135: }
! 1136: /* bytes to existing buffer */
! 1137: memset(out.ptr, 0, out.len);
! 1138: if (!xof->set_seed(xof, seed))
! 1139: {
! 1140: goto failure;
! 1141: }
! 1142: if (!xof->get_bytes(xof, vector->out_len, out.ptr))
! 1143: {
! 1144: goto failure;
! 1145: }
! 1146: if (!memeq(vector->out, out.ptr, vector->out_len))
! 1147: {
! 1148: goto failure;
! 1149: }
! 1150: /* bytes to existing buffer, using append mode */
! 1151: /* TODO */
! 1152:
! 1153: failed = FALSE;
! 1154: failure:
! 1155: xof->destroy(xof);
! 1156: chunk_free(&out);
! 1157: if (failed)
! 1158: {
! 1159: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 1160: ext_out_function_names, alg, plugin_name, get_name(vector));
! 1161: break;
! 1162: }
! 1163: }
! 1164: enumerator->destroy(enumerator);
! 1165: if (!tested)
! 1166: {
! 1167: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 1168: this->required ? "disabled" : "enabled ",
! 1169: ext_out_function_names, alg, plugin_name);
! 1170: return !this->required;
! 1171: }
! 1172: if (!failed)
! 1173: {
! 1174: if (speed)
! 1175: {
! 1176: *speed = bench_xof(this, alg, create);
! 1177: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 1178: ext_out_function_names, alg, plugin_name, tested, *speed);
! 1179: }
! 1180: else
! 1181: {
! 1182: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 1183: ext_out_function_names, alg, plugin_name, tested);
! 1184: }
! 1185: }
! 1186: return !failed;
! 1187: }
! 1188:
! 1189: /**
! 1190: * Benchmark a DRBG
! 1191: */
! 1192: static u_int bench_drbg(private_crypto_tester_t *this,
! 1193: drbg_type_t type, drbg_constructor_t create)
! 1194: {
! 1195: drbg_t *drbg;
! 1196: rng_t *entropy;
! 1197: uint32_t strength = 128;
! 1198: chunk_t seed = chunk_alloca(48);
! 1199:
! 1200: memset(seed.ptr, 0x81, seed.len);
! 1201: entropy = rng_tester_create(seed);
! 1202:
! 1203: drbg = create(type, strength, entropy, chunk_empty);
! 1204: if (drbg)
! 1205: {
! 1206: struct timespec start;
! 1207: u_int runs = 0;
! 1208: size_t out_len = 128;
! 1209: char out_buf[out_len];
! 1210:
! 1211: start_timing(&start);
! 1212: while (end_timing(&start) < this->bench_time)
! 1213: {
! 1214: if (drbg->generate(drbg, out_len, out_buf))
! 1215: {
! 1216: runs++;
! 1217: }
! 1218: }
! 1219: drbg->destroy(drbg);
! 1220:
! 1221: return runs;
! 1222: }
! 1223: return 0;
! 1224: }
! 1225:
! 1226: METHOD(crypto_tester_t, test_drbg, bool,
! 1227: private_crypto_tester_t *this, drbg_type_t type,
! 1228: drbg_constructor_t create, u_int *speed, const char *plugin_name)
! 1229: {
! 1230: enumerator_t *enumerator;
! 1231: drbg_test_vector_t *vector;
! 1232: bool failed = FALSE;
! 1233: u_int tested = 0;
! 1234:
! 1235: enumerator = this->drbg->create_enumerator(this->drbg);
! 1236: while (enumerator->enumerate(enumerator, &vector))
! 1237: {
! 1238: drbg_t *drbg;
! 1239: rng_t *entropy;
! 1240: chunk_t out = chunk_empty;
! 1241:
! 1242: if (vector->type != type)
! 1243: {
! 1244: continue;
! 1245: }
! 1246: tested++;
! 1247: failed = TRUE;
! 1248:
! 1249: entropy = rng_tester_create(vector->entropy);
! 1250: out = chunk_alloc(vector->out.len);
! 1251:
! 1252: drbg = create(type, vector->strength, entropy,
! 1253: vector->personalization_str);
! 1254: if (!drbg)
! 1255: {
! 1256: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 1257: drbg_type_names, type, plugin_name);
! 1258: entropy->destroy(entropy);
! 1259: chunk_free(&out);
! 1260: break;
! 1261: }
! 1262: if (!drbg->reseed(drbg))
! 1263: {
! 1264: goto failure;
! 1265: }
! 1266: if (!drbg->generate(drbg, out.len, out.ptr))
! 1267: {
! 1268: goto failure;
! 1269: }
! 1270: if (!drbg->generate(drbg, out.len, out.ptr))
! 1271: {
! 1272: goto failure;
! 1273: }
! 1274: if (!chunk_equals(out, vector->out))
! 1275: {
! 1276: goto failure;
! 1277: }
! 1278: failed = FALSE;
! 1279:
! 1280: failure:
! 1281: drbg->destroy(drbg);
! 1282: chunk_free(&out);
! 1283: if (failed)
! 1284: {
! 1285: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 1286: drbg_type_names, type, plugin_name, get_name(vector));
! 1287: break;
! 1288: }
! 1289: }
! 1290: enumerator->destroy(enumerator);
! 1291: if (!tested)
! 1292: {
! 1293: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 1294: this->required ? "disabled" : "enabled ",
! 1295: drbg_type_names, type, plugin_name);
! 1296: return !this->required;
! 1297: }
! 1298: if (!failed)
! 1299: {
! 1300: if (speed)
! 1301: {
! 1302: *speed = bench_drbg(this, type, create);
! 1303: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 1304: drbg_type_names, type, plugin_name, tested, *speed);
! 1305: }
! 1306: else
! 1307: {
! 1308: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 1309: drbg_type_names, type, plugin_name, tested);
! 1310: }
! 1311: }
! 1312: return !failed;
! 1313: }
! 1314:
! 1315: /**
! 1316: * Benchmark a RNG
! 1317: */
! 1318: static u_int bench_rng(private_crypto_tester_t *this,
! 1319: rng_quality_t quality, rng_constructor_t create)
! 1320: {
! 1321: rng_t *rng;
! 1322:
! 1323: rng = create(quality);
! 1324: if (rng)
! 1325: {
! 1326: struct timespec start;
! 1327: chunk_t buf;
! 1328: u_int runs;
! 1329:
! 1330: runs = 0;
! 1331: buf = chunk_alloc(this->bench_size);
! 1332: start_timing(&start);
! 1333: while (end_timing(&start) < this->bench_time)
! 1334: {
! 1335: if (!rng->get_bytes(rng, buf.len, buf.ptr))
! 1336: {
! 1337: runs = 0;
! 1338: break;
! 1339: }
! 1340: runs++;
! 1341: }
! 1342: free(buf.ptr);
! 1343: rng->destroy(rng);
! 1344:
! 1345: return runs;
! 1346: }
! 1347: return 0;
! 1348: }
! 1349:
! 1350: METHOD(crypto_tester_t, test_rng, bool,
! 1351: private_crypto_tester_t *this, rng_quality_t quality,
! 1352: rng_constructor_t create, u_int *speed, const char *plugin_name)
! 1353: {
! 1354: enumerator_t *enumerator;
! 1355: rng_test_vector_t *vector;
! 1356: bool failed = FALSE;
! 1357: u_int tested = 0;
! 1358:
! 1359: if (!this->rng_true && quality == RNG_TRUE)
! 1360: {
! 1361: DBG1(DBG_LIB, "enabled %N[%s]: skipping test (disabled by config)",
! 1362: rng_quality_names, quality, plugin_name);
! 1363: return TRUE;
! 1364: }
! 1365:
! 1366: enumerator = this->rng->create_enumerator(this->rng);
! 1367: while (enumerator->enumerate(enumerator, &vector))
! 1368: {
! 1369: chunk_t data = chunk_empty;
! 1370: rng_t *rng;
! 1371:
! 1372: if (vector->quality != quality)
! 1373: {
! 1374: continue;
! 1375: }
! 1376:
! 1377: tested++;
! 1378: failed = TRUE;
! 1379: rng = create(quality);
! 1380: if (!rng)
! 1381: {
! 1382: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 1383: rng_quality_names, quality, plugin_name);
! 1384: break;
! 1385: }
! 1386:
! 1387: /* allocated bytes */
! 1388: if (!rng->allocate_bytes(rng, vector->len, &data) ||
! 1389: data.len != vector->len ||
! 1390: !vector->test(vector->user, data))
! 1391: {
! 1392: goto failure;
! 1393: }
! 1394: /* write bytes into existing buffer */
! 1395: memset(data.ptr, 0, data.len);
! 1396: if (!rng->get_bytes(rng, vector->len, data.ptr))
! 1397: {
! 1398: goto failure;
! 1399: }
! 1400: if (!vector->test(vector->user, data))
! 1401: {
! 1402: goto failure;
! 1403: }
! 1404:
! 1405: failed = FALSE;
! 1406: failure:
! 1407: rng->destroy(rng);
! 1408: chunk_free(&data);
! 1409: if (failed)
! 1410: {
! 1411: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 1412: rng_quality_names, quality, plugin_name, get_name(vector));
! 1413: break;
! 1414: }
! 1415: }
! 1416: enumerator->destroy(enumerator);
! 1417: if (!tested)
! 1418: {
! 1419: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
! 1420: this->required ? ", disabled" : "enabled ",
! 1421: rng_quality_names, quality, plugin_name);
! 1422: return !this->required;
! 1423: }
! 1424: if (!failed)
! 1425: {
! 1426: if (speed)
! 1427: {
! 1428: *speed = bench_rng(this, quality, create);
! 1429: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 1430: rng_quality_names, quality, plugin_name, tested, *speed);
! 1431: }
! 1432: else
! 1433: {
! 1434: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 1435: rng_quality_names, quality, plugin_name, tested);
! 1436: }
! 1437: }
! 1438: return !failed;
! 1439: }
! 1440:
! 1441: /**
! 1442: * Benchmark a DH backend
! 1443: */
! 1444: static u_int bench_dh(private_crypto_tester_t *this,
! 1445: diffie_hellman_group_t group, dh_constructor_t create)
! 1446: {
! 1447: chunk_t pub = chunk_empty, shared = chunk_empty;
! 1448: diffie_hellman_t *dh;
! 1449: struct timespec start;
! 1450: u_int runs;
! 1451:
! 1452: runs = 0;
! 1453: start_timing(&start);
! 1454: while (end_timing(&start) < this->bench_time)
! 1455: {
! 1456: dh = create(group);
! 1457: if (!dh)
! 1458: {
! 1459: return 0;
! 1460: }
! 1461: if (dh->get_my_public_value(dh, &pub) &&
! 1462: dh->set_other_public_value(dh, pub) &&
! 1463: dh->get_shared_secret(dh, &shared))
! 1464: {
! 1465: runs++;
! 1466: }
! 1467: chunk_free(&pub);
! 1468: chunk_free(&shared);
! 1469: dh->destroy(dh);
! 1470: }
! 1471: return runs;
! 1472: }
! 1473:
! 1474: METHOD(crypto_tester_t, test_dh, bool,
! 1475: private_crypto_tester_t *this, diffie_hellman_group_t group,
! 1476: dh_constructor_t create, u_int *speed, const char *plugin_name)
! 1477: {
! 1478: enumerator_t *enumerator;
! 1479: dh_test_vector_t *v;
! 1480: bool failed = FALSE;
! 1481: u_int tested = 0;
! 1482:
! 1483: enumerator = this->dh->create_enumerator(this->dh);
! 1484: while (enumerator->enumerate(enumerator, &v))
! 1485: {
! 1486: diffie_hellman_t *a, *b;
! 1487: chunk_t apub, bpub, asec, bsec;
! 1488:
! 1489: if (v->group != group)
! 1490: {
! 1491: continue;
! 1492: }
! 1493:
! 1494: a = create(group);
! 1495: b = create(group);
! 1496: if (!a || !b)
! 1497: {
! 1498: DESTROY_IF(a);
! 1499: DESTROY_IF(b);
! 1500: failed = TRUE;
! 1501: tested++;
! 1502: DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
! 1503: diffie_hellman_group_names, group, plugin_name);
! 1504: break;
! 1505: }
! 1506:
! 1507: if (!a->set_private_value || !b->set_private_value)
! 1508: { /* does not support testing */
! 1509: a->destroy(a);
! 1510: b->destroy(b);
! 1511: continue;
! 1512: }
! 1513: failed = TRUE;
! 1514: tested++;
! 1515:
! 1516: apub = bpub = asec = bsec = chunk_empty;
! 1517:
! 1518: if (!a->set_private_value(a, chunk_create(v->priv_a, v->priv_len)) ||
! 1519: !b->set_private_value(b, chunk_create(v->priv_b, v->priv_len)))
! 1520: {
! 1521: goto failure;
! 1522: }
! 1523: if (!a->get_my_public_value(a, &apub) ||
! 1524: !chunk_equals(apub, chunk_create(v->pub_a, v->pub_len)))
! 1525: {
! 1526: goto failure;
! 1527: }
! 1528: if (!b->get_my_public_value(b, &bpub) ||
! 1529: !chunk_equals(bpub, chunk_create(v->pub_b, v->pub_len)))
! 1530: {
! 1531: goto failure;
! 1532: }
! 1533: if (!a->set_other_public_value(a, bpub) ||
! 1534: !b->set_other_public_value(b, apub))
! 1535: {
! 1536: goto failure;
! 1537: }
! 1538: if (!a->get_shared_secret(a, &asec) ||
! 1539: !chunk_equals(asec, chunk_create(v->shared, v->shared_len)))
! 1540: {
! 1541: goto failure;
! 1542: }
! 1543: if (!b->get_shared_secret(b, &bsec) ||
! 1544: !chunk_equals(bsec, chunk_create(v->shared, v->shared_len)))
! 1545: {
! 1546: goto failure;
! 1547: }
! 1548:
! 1549: failed = FALSE;
! 1550: failure:
! 1551: a->destroy(a);
! 1552: b->destroy(b);
! 1553: chunk_free(&apub);
! 1554: chunk_free(&bpub);
! 1555: chunk_free(&asec);
! 1556: chunk_free(&bsec);
! 1557: if (failed)
! 1558: {
! 1559: DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
! 1560: diffie_hellman_group_names, group, plugin_name, get_name(v));
! 1561: break;
! 1562: }
! 1563: }
! 1564: enumerator->destroy(enumerator);
! 1565: if (!tested)
! 1566: {
! 1567: DBG1(DBG_LIB, "%s %N[%s]: no test vectors found / untestable",
! 1568: this->required ? "disabled" : "enabled ",
! 1569: diffie_hellman_group_names, group, plugin_name);
! 1570: return !this->required;
! 1571: }
! 1572: if (!failed)
! 1573: {
! 1574: if (speed)
! 1575: {
! 1576: *speed = bench_dh(this, group, create);
! 1577: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
! 1578: diffie_hellman_group_names, group, plugin_name, tested, *speed);
! 1579: }
! 1580: else
! 1581: {
! 1582: DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
! 1583: diffie_hellman_group_names, group, plugin_name, tested);
! 1584: }
! 1585: }
! 1586: return !failed;
! 1587: }
! 1588:
! 1589: METHOD(crypto_tester_t, add_crypter_vector, void,
! 1590: private_crypto_tester_t *this, crypter_test_vector_t *vector)
! 1591: {
! 1592: this->crypter->insert_last(this->crypter, vector);
! 1593: }
! 1594:
! 1595: METHOD(crypto_tester_t, add_aead_vector, void,
! 1596: private_crypto_tester_t *this, aead_test_vector_t *vector)
! 1597: {
! 1598: this->aead->insert_last(this->aead, vector);
! 1599: }
! 1600:
! 1601: METHOD(crypto_tester_t, add_signer_vector, void,
! 1602: private_crypto_tester_t *this, signer_test_vector_t *vector)
! 1603: {
! 1604: this->signer->insert_last(this->signer, vector);
! 1605: }
! 1606:
! 1607: METHOD(crypto_tester_t, add_hasher_vector, void,
! 1608: private_crypto_tester_t *this, hasher_test_vector_t *vector)
! 1609: {
! 1610: this->hasher->insert_last(this->hasher, vector);
! 1611: }
! 1612:
! 1613: METHOD(crypto_tester_t, add_prf_vector, void,
! 1614: private_crypto_tester_t *this, prf_test_vector_t *vector)
! 1615: {
! 1616: this->prf->insert_last(this->prf, vector);
! 1617: }
! 1618:
! 1619: METHOD(crypto_tester_t, add_xof_vector, void,
! 1620: private_crypto_tester_t *this, xof_test_vector_t *vector)
! 1621: {
! 1622: this->xof->insert_last(this->xof, vector);
! 1623: }
! 1624:
! 1625: METHOD(crypto_tester_t, add_drbg_vector, void,
! 1626: private_crypto_tester_t *this, drbg_test_vector_t *vector)
! 1627: {
! 1628: this->drbg->insert_last(this->drbg, vector);
! 1629: }
! 1630:
! 1631: METHOD(crypto_tester_t, add_rng_vector, void,
! 1632: private_crypto_tester_t *this, rng_test_vector_t *vector)
! 1633: {
! 1634: this->rng->insert_last(this->rng, vector);
! 1635: }
! 1636:
! 1637: METHOD(crypto_tester_t, add_dh_vector, void,
! 1638: private_crypto_tester_t *this, dh_test_vector_t *vector)
! 1639: {
! 1640: this->dh->insert_last(this->dh, vector);
! 1641: }
! 1642:
! 1643: METHOD(crypto_tester_t, destroy, void,
! 1644: private_crypto_tester_t *this)
! 1645: {
! 1646: this->crypter->destroy(this->crypter);
! 1647: this->aead->destroy(this->aead);
! 1648: this->signer->destroy(this->signer);
! 1649: this->hasher->destroy(this->hasher);
! 1650: this->prf->destroy(this->prf);
! 1651: this->xof->destroy(this->xof);
! 1652: this->drbg->destroy(this->drbg);
! 1653: this->rng->destroy(this->rng);
! 1654: this->dh->destroy(this->dh);
! 1655: free(this);
! 1656: }
! 1657:
! 1658: /**
! 1659: * See header
! 1660: */
! 1661: crypto_tester_t *crypto_tester_create()
! 1662: {
! 1663: private_crypto_tester_t *this;
! 1664:
! 1665: INIT(this,
! 1666: .public = {
! 1667: .test_crypter = _test_crypter,
! 1668: .test_aead = _test_aead,
! 1669: .test_signer = _test_signer,
! 1670: .test_hasher = _test_hasher,
! 1671: .test_prf = _test_prf,
! 1672: .test_xof = _test_xof,
! 1673: .test_drbg = _test_drbg,
! 1674: .test_rng = _test_rng,
! 1675: .test_dh = _test_dh,
! 1676: .add_crypter_vector = _add_crypter_vector,
! 1677: .add_aead_vector = _add_aead_vector,
! 1678: .add_signer_vector = _add_signer_vector,
! 1679: .add_hasher_vector = _add_hasher_vector,
! 1680: .add_prf_vector = _add_prf_vector,
! 1681: .add_xof_vector = _add_xof_vector,
! 1682: .add_drbg_vector = _add_drbg_vector,
! 1683: .add_rng_vector = _add_rng_vector,
! 1684: .add_dh_vector = _add_dh_vector,
! 1685: .destroy = _destroy,
! 1686: },
! 1687: .crypter = linked_list_create(),
! 1688: .aead = linked_list_create(),
! 1689: .signer = linked_list_create(),
! 1690: .hasher = linked_list_create(),
! 1691: .prf = linked_list_create(),
! 1692: .xof = linked_list_create(),
! 1693: .drbg = linked_list_create(),
! 1694: .rng = linked_list_create(),
! 1695: .dh = linked_list_create(),
! 1696:
! 1697: .required = lib->settings->get_bool(lib->settings,
! 1698: "%s.crypto_test.required", FALSE, lib->ns),
! 1699: .rng_true = lib->settings->get_bool(lib->settings,
! 1700: "%s.crypto_test.rng_true", FALSE, lib->ns),
! 1701: .bench_time = lib->settings->get_int(lib->settings,
! 1702: "%s.crypto_test.bench_time", 50, lib->ns),
! 1703: .bench_size = lib->settings->get_int(lib->settings,
! 1704: "%s.crypto_test.bench_size", 1024, lib->ns),
! 1705: );
! 1706:
! 1707: /* enforce a block size of 16, should be fine for all algorithms */
! 1708: this->bench_size = this->bench_size / 16 * 16;
! 1709:
! 1710: return &this->public;
! 1711: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>