Version bump to 5.8.4
[strongswan.git] / src / libstrongswan / crypto / crypto_tester.c
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 }