2 * Copyright (C) 2009-2010 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2010 revosec AG
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 #include "crypto_tester.h"
25 #include <utils/debug.h>
26 #include <collections/linked_list.h>
28 typedef struct private_crypto_tester_t private_crypto_tester_t
;
31 * Private data of an crypto_tester_t object.
33 struct private_crypto_tester_t
{
36 * Public crypto_tester_t interface.
38 crypto_tester_t
public;
41 * List of crypter test vectors
43 linked_list_t
*crypter
;
46 * List of aead test vectors
51 * List of signer test vectors
53 linked_list_t
*signer
;
56 * List of hasher test vectors
58 linked_list_t
*hasher
;
61 * List of PRF test vectors
66 * List of RNG test vectors
71 * List of Diffie-Hellman test vectors
76 * Is a test vector required to pass a test?
81 * should we run RNG_TRUE tests? Enough entropy?
86 * time we test each algorithm
91 * size of buffer we use for benchmarking
97 * Get the name of a test vector, if available
99 static const char* get_name(void *sym
)
104 if (dladdr(sym
, &dli
))
106 return dli
.dli_sname
;
112 #if defined(CLOCK_THREAD_CPUTIME_ID) && defined(HAVE_CLOCK_GETTIME)
115 * Start a benchmark timer
117 static void start_timing(struct timespec
*start
)
119 clock_gettime(CLOCK_THREAD_CPUTIME_ID
, start
);
123 * End a benchmark timer, return ms
125 static u_int
end_timing(struct timespec
*start
)
129 clock_gettime(CLOCK_THREAD_CPUTIME_ID
, &end
);
130 return (end
.tv_nsec
- start
->tv_nsec
) / 1000000 +
131 (end
.tv_sec
- start
->tv_sec
) * 1000;
134 #else /* CLOCK_THREAD_CPUTIME_ID */
136 /* Make benchmarking a no-op if CLOCK_THREAD_CPUTIME_ID is not available */
137 #define start_timing(start) ((start)->tv_sec = 0, (start)->tv_nsec = 0)
138 #define end_timing(...) (this->bench_time)
140 #endif /* CLOCK_THREAD_CPUTIME_ID */
143 * Benchmark a crypter
145 static u_int
bench_crypter(private_crypto_tester_t
*this,
146 encryption_algorithm_t alg
, crypter_constructor_t create
, size_t key_size
)
150 crypter
= create(alg
, key_size
);
153 char iv
[crypter
->get_iv_size(crypter
)];
154 char key
[crypter
->get_key_size(crypter
)];
156 struct timespec start
;
159 memset(iv
, 0x56, sizeof(iv
));
160 memset(key
, 0x12, sizeof(key
));
161 if (!crypter
->set_key(crypter
, chunk_from_thing(key
)))
166 buf
= chunk_alloc(this->bench_size
);
167 memset(buf
.ptr
, 0x34, buf
.len
);
170 start_timing(&start
);
171 while (end_timing(&start
) < this->bench_time
)
173 if (crypter
->encrypt(crypter
, buf
, chunk_from_thing(iv
), NULL
))
177 if (crypter
->decrypt(crypter
, buf
, chunk_from_thing(iv
), NULL
))
183 crypter
->destroy(crypter
);
190 METHOD(crypto_tester_t
, test_crypter
, bool,
191 private_crypto_tester_t
*this, encryption_algorithm_t alg
, size_t key_size
,
192 crypter_constructor_t create
, u_int
*speed
, const char *plugin_name
)
194 enumerator_t
*enumerator
;
195 crypter_test_vector_t
*vector
;
199 enumerator
= this->crypter
->create_enumerator(this->crypter
);
200 while (enumerator
->enumerate(enumerator
, &vector
))
203 chunk_t key
, iv
, plain
= chunk_empty
, cipher
= chunk_empty
;
205 if (vector
->alg
!= alg
)
209 if (key_size
&& key_size
!= vector
->key_size
)
210 { /* test only vectors with a specific key size, if key size given */
214 crypter
= create(alg
, vector
->key_size
);
216 { /* key size not supported */
222 key
= chunk_create(vector
->key
, crypter
->get_key_size(crypter
));
223 if (!crypter
->set_key(crypter
, key
))
227 iv
= chunk_create(vector
->iv
, crypter
->get_iv_size(crypter
));
229 /* allocated encryption */
230 plain
= chunk_create(vector
->plain
, vector
->len
);
231 if (!crypter
->encrypt(crypter
, plain
, iv
, &cipher
))
235 if (!memeq(vector
->cipher
, cipher
.ptr
, cipher
.len
))
239 /* inline decryption */
240 if (!crypter
->decrypt(crypter
, cipher
, iv
, NULL
))
244 if (!memeq(vector
->plain
, cipher
.ptr
, cipher
.len
))
248 /* allocated decryption */
249 if (!crypter
->decrypt(crypter
,
250 chunk_create(vector
->cipher
, vector
->len
), iv
, &plain
))
254 if (!memeq(vector
->plain
, plain
.ptr
, plain
.len
))
258 /* inline encryption */
259 if (!crypter
->encrypt(crypter
, plain
, iv
, NULL
))
263 if (!memeq(vector
->cipher
, plain
.ptr
, plain
.len
))
270 crypter
->destroy(crypter
);
272 if (plain
.ptr
!= vector
->plain
)
278 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
279 encryption_algorithm_names
, alg
, plugin_name
, get_name(vector
));
283 enumerator
->destroy(enumerator
);
288 DBG1(DBG_LIB
,"disable %N[%s]: %zd byte key size not supported",
289 encryption_algorithm_names
, alg
, plugin_name
, key_size
);
294 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
295 this->required ?
"disabled" : "enabled ",
296 encryption_algorithm_names
, alg
, plugin_name
);
297 return !this->required
;
304 *speed
= bench_crypter(this, alg
, create
, key_size
);
305 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points "
306 "(%zd bit key)", encryption_algorithm_names
, alg
,
307 plugin_name
, tested
, *speed
, key_size
* 8);
311 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
312 encryption_algorithm_names
, alg
, plugin_name
, tested
);
319 * Benchmark an aead transform
321 static u_int
bench_aead(private_crypto_tester_t
*this,
322 encryption_algorithm_t alg
, aead_constructor_t create
, size_t key_size
)
326 aead
= create(alg
, key_size
, 0);
329 char iv
[aead
->get_iv_size(aead
)];
330 char key
[aead
->get_key_size(aead
)];
333 struct timespec start
;
337 memset(iv
, 0x56, sizeof(iv
));
338 memset(key
, 0x12, sizeof(key
));
339 memset(assoc
, 0x78, sizeof(assoc
));
340 if (!aead
->set_key(aead
, chunk_from_thing(key
)))
344 icv
= aead
->get_icv_size(aead
);
346 buf
= chunk_alloc(this->bench_size
+ icv
);
347 memset(buf
.ptr
, 0x34, buf
.len
);
351 start_timing(&start
);
352 while (end_timing(&start
) < this->bench_time
)
354 if (aead
->encrypt(aead
, buf
, chunk_from_thing(assoc
),
355 chunk_from_thing(iv
), NULL
))
359 if (aead
->decrypt(aead
, chunk_create(buf
.ptr
, buf
.len
+ icv
),
360 chunk_from_thing(assoc
), chunk_from_thing(iv
), NULL
))
373 METHOD(crypto_tester_t
, test_aead
, bool,
374 private_crypto_tester_t
*this, encryption_algorithm_t alg
, size_t key_size
,
375 size_t salt_size
, aead_constructor_t create
,
376 u_int
*speed
, const char *plugin_name
)
378 enumerator_t
*enumerator
;
379 aead_test_vector_t
*vector
;
383 enumerator
= this->aead
->create_enumerator(this->aead
);
384 while (enumerator
->enumerate(enumerator
, &vector
))
387 chunk_t key
, iv
, assoc
, plain
= chunk_empty
, cipher
= chunk_empty
;
390 if (vector
->alg
!= alg
)
394 if (key_size
&& key_size
!= vector
->key_size
)
395 { /* test only vectors with a specific key size, if key size given */
398 if (salt_size
&& salt_size
!= vector
->salt_size
)
405 aead
= create(alg
, vector
->key_size
, vector
->salt_size
);
408 DBG1(DBG_LIB
, "%N[%s]: %u bit key size not supported",
409 encryption_algorithm_names
, alg
, plugin_name
,
410 BITS_PER_BYTE
* vector
->key_size
);
414 key
= chunk_create(vector
->key
, aead
->get_key_size(aead
));
415 if (!aead
->set_key(aead
, key
))
419 iv
= chunk_create(vector
->iv
, aead
->get_iv_size(aead
));
420 assoc
= chunk_create(vector
->adata
, vector
->alen
);
421 icv
= aead
->get_icv_size(aead
);
423 /* allocated encryption */
424 plain
= chunk_create(vector
->plain
, vector
->len
);
425 if (!aead
->encrypt(aead
, plain
, assoc
, iv
, &cipher
))
429 if (!memeq(vector
->cipher
, cipher
.ptr
, cipher
.len
))
433 /* inline decryption */
434 if (!aead
->decrypt(aead
, cipher
, assoc
, iv
, NULL
))
438 if (!memeq(vector
->plain
, cipher
.ptr
, cipher
.len
- icv
))
442 /* allocated decryption */
443 if (!aead
->decrypt(aead
, chunk_create(vector
->cipher
, vector
->len
+ icv
),
448 if (!memeq(vector
->plain
, plain
.ptr
, plain
.len
))
452 plain
.ptr
= realloc(plain
.ptr
, plain
.len
+ icv
);
453 /* inline encryption */
454 if (!aead
->encrypt(aead
, plain
, assoc
, iv
, NULL
))
458 if (!memeq(vector
->cipher
, plain
.ptr
, plain
.len
+ icv
))
467 if (plain
.ptr
!= vector
->plain
)
473 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
474 encryption_algorithm_names
, alg
, plugin_name
, get_name(vector
));
478 enumerator
->destroy(enumerator
);
483 DBG1(DBG_LIB
,"disable %N[%s]: %zd byte key size not supported",
484 encryption_algorithm_names
, alg
, plugin_name
, key_size
);
489 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
490 this->required ?
"disabled" : "enabled ",
491 encryption_algorithm_names
, alg
, plugin_name
);
492 return !this->required
;
499 *speed
= bench_aead(this, alg
, create
, key_size
);
500 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points "
501 "(%zd bit key)", encryption_algorithm_names
, alg
,
502 plugin_name
, tested
, *speed
, key_size
* 8);
506 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
507 encryption_algorithm_names
, alg
, plugin_name
, tested
);
516 static u_int
bench_signer(private_crypto_tester_t
*this,
517 integrity_algorithm_t alg
, signer_constructor_t create
)
521 signer
= create(alg
);
524 char key
[signer
->get_key_size(signer
)];
525 char mac
[signer
->get_block_size(signer
)];
527 struct timespec start
;
530 memset(key
, 0x12, sizeof(key
));
531 if (!signer
->set_key(signer
, chunk_from_thing(key
)))
536 buf
= chunk_alloc(this->bench_size
);
537 memset(buf
.ptr
, 0x34, buf
.len
);
540 start_timing(&start
);
541 while (end_timing(&start
) < this->bench_time
)
543 if (signer
->get_signature(signer
, buf
, mac
))
547 if (signer
->verify_signature(signer
, buf
, chunk_from_thing(mac
)))
553 signer
->destroy(signer
);
560 METHOD(crypto_tester_t
, test_signer
, bool,
561 private_crypto_tester_t
*this, integrity_algorithm_t alg
,
562 signer_constructor_t create
, u_int
*speed
, const char *plugin_name
)
564 enumerator_t
*enumerator
;
565 signer_test_vector_t
*vector
;
569 enumerator
= this->signer
->create_enumerator(this->signer
);
570 while (enumerator
->enumerate(enumerator
, &vector
))
573 chunk_t key
, data
, mac
= chunk_empty
;
575 if (vector
->alg
!= alg
)
582 signer
= create(alg
);
585 DBG1(DBG_LIB
, "disabled %N[%s]: creating instance failed",
586 integrity_algorithm_names
, alg
, plugin_name
);
590 data
= chunk_create(vector
->data
, vector
->len
);
591 key
= chunk_create(vector
->key
, signer
->get_key_size(signer
));
592 if (!signer
->set_key(signer
, key
))
596 /* do partial append mode and check if key gets set correctly */
597 if (!signer
->get_signature(signer
, data
, NULL
))
601 if (!signer
->set_key(signer
, key
))
605 /* allocated signature */
606 if (!signer
->allocate_signature(signer
, data
, &mac
))
610 if (mac
.len
!= signer
->get_block_size(signer
))
614 if (!memeq(vector
->mac
, mac
.ptr
, mac
.len
))
618 /* signature to existing buffer */
619 memset(mac
.ptr
, 0, mac
.len
);
620 if (!signer
->get_signature(signer
, data
, mac
.ptr
))
624 if (!memeq(vector
->mac
, mac
.ptr
, mac
.len
))
628 /* signature verification, good case */
629 if (!signer
->verify_signature(signer
, data
, mac
))
633 /* signature verification, bad case */
634 *(mac
.ptr
+ mac
.len
- 1) += 1;
635 if (signer
->verify_signature(signer
, data
, mac
))
639 /* signature to existing buffer, using append mode */
642 if (!signer
->allocate_signature(signer
,
643 chunk_create(data
.ptr
, 1), NULL
))
647 if (!signer
->get_signature(signer
,
648 chunk_create(data
.ptr
+ 1, 1), NULL
))
652 if (!signer
->verify_signature(signer
, chunk_skip(data
, 2),
653 chunk_create(vector
->mac
, mac
.len
)))
661 signer
->destroy(signer
);
665 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
666 integrity_algorithm_names
, alg
, plugin_name
, get_name(vector
));
670 enumerator
->destroy(enumerator
);
673 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
674 this->required ?
"disabled" : "enabled ",
675 integrity_algorithm_names
, alg
, plugin_name
);
676 return !this->required
;
682 *speed
= bench_signer(this, alg
, create
);
683 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points",
684 integrity_algorithm_names
, alg
, plugin_name
, tested
, *speed
);
688 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
689 integrity_algorithm_names
, alg
, plugin_name
, tested
);
698 static u_int
bench_hasher(private_crypto_tester_t
*this,
699 hash_algorithm_t alg
, hasher_constructor_t create
)
703 hasher
= create(alg
);
706 char hash
[hasher
->get_hash_size(hasher
)];
708 struct timespec start
;
711 buf
= chunk_alloc(this->bench_size
);
712 memset(buf
.ptr
, 0x34, buf
.len
);
715 start_timing(&start
);
716 while (end_timing(&start
) < this->bench_time
)
718 if (hasher
->get_hash(hasher
, buf
, hash
))
724 hasher
->destroy(hasher
);
731 METHOD(crypto_tester_t
, test_hasher
, bool,
732 private_crypto_tester_t
*this, hash_algorithm_t alg
,
733 hasher_constructor_t create
, u_int
*speed
, const char *plugin_name
)
735 enumerator_t
*enumerator
;
736 hasher_test_vector_t
*vector
;
740 enumerator
= this->hasher
->create_enumerator(this->hasher
);
741 while (enumerator
->enumerate(enumerator
, &vector
))
746 if (vector
->alg
!= alg
)
753 hasher
= create(alg
);
756 DBG1(DBG_LIB
, "disabled %N[%s]: creating instance failed",
757 hash_algorithm_names
, alg
, plugin_name
);
762 data
= chunk_create(vector
->data
, vector
->len
);
763 if (!hasher
->allocate_hash(hasher
, data
, &hash
))
767 if (hash
.len
!= hasher
->get_hash_size(hasher
))
771 if (!memeq(vector
->hash
, hash
.ptr
, hash
.len
))
775 /* hash to existing buffer, with a reset */
776 memset(hash
.ptr
, 0, hash
.len
);
777 if (!hasher
->get_hash(hasher
, data
, NULL
))
781 if (!hasher
->reset(hasher
))
785 if (!hasher
->get_hash(hasher
, data
, hash
.ptr
))
789 if (!memeq(vector
->hash
, hash
.ptr
, hash
.len
))
793 /* hasher to existing buffer, using append mode */
796 memset(hash
.ptr
, 0, hash
.len
);
797 if (!hasher
->allocate_hash(hasher
, chunk_create(data
.ptr
, 1), NULL
))
801 if (!hasher
->get_hash(hasher
, chunk_create(data
.ptr
+ 1, 1), NULL
))
805 if (!hasher
->get_hash(hasher
, chunk_skip(data
, 2), hash
.ptr
))
809 if (!memeq(vector
->hash
, hash
.ptr
, hash
.len
))
817 hasher
->destroy(hasher
);
821 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
822 hash_algorithm_names
, alg
, plugin_name
, get_name(vector
));
826 enumerator
->destroy(enumerator
);
829 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
830 this->required ?
"disabled" : "enabled ",
831 hash_algorithm_names
, alg
, plugin_name
);
832 return !this->required
;
838 *speed
= bench_hasher(this, alg
, create
);
839 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points",
840 hash_algorithm_names
, alg
, plugin_name
, tested
, *speed
);
844 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
845 hash_algorithm_names
, alg
, plugin_name
, tested
);
854 static u_int
bench_prf(private_crypto_tester_t
*this,
855 pseudo_random_function_t alg
, prf_constructor_t create
)
862 char bytes
[prf
->get_block_size(prf
)], key
[prf
->get_block_size(prf
)];
864 struct timespec start
;
867 memset(key
, 0x56, prf
->get_block_size(prf
));
868 if (!prf
->set_key(prf
, chunk_create(key
, prf
->get_block_size(prf
))))
874 buf
= chunk_alloc(this->bench_size
);
875 memset(buf
.ptr
, 0x34, buf
.len
);
878 start_timing(&start
);
879 while (end_timing(&start
) < this->bench_time
)
881 if (prf
->get_bytes(prf
, buf
, bytes
))
894 METHOD(crypto_tester_t
, test_prf
, bool,
895 private_crypto_tester_t
*this, pseudo_random_function_t alg
,
896 prf_constructor_t create
, u_int
*speed
, const char *plugin_name
)
898 enumerator_t
*enumerator
;
899 prf_test_vector_t
*vector
;
903 enumerator
= this->prf
->create_enumerator(this->prf
);
904 while (enumerator
->enumerate(enumerator
, &vector
))
907 chunk_t key
, seed
, out
= chunk_empty
;
909 if (vector
->alg
!= alg
)
919 DBG1(DBG_LIB
, "disabled %N[%s]: creating instance failed",
920 pseudo_random_function_names
, alg
, plugin_name
);
924 seed
= chunk_create(vector
->seed
, vector
->len
);
925 key
= chunk_create(vector
->key
, vector
->key_size
);
926 if (!prf
->set_key(prf
, key
))
930 if (alg
!= PRF_FIPS_SHA1_160
)
932 /* do partial append mode and check if key gets set correctly */
933 if (!prf
->get_bytes(prf
, seed
, NULL
))
937 if (!prf
->set_key(prf
, key
))
942 /* allocated bytes */
943 if (!prf
->allocate_bytes(prf
, seed
, &out
))
947 if (out
.len
!= prf
->get_block_size(prf
))
951 if (!memeq(vector
->out
, out
.ptr
, out
.len
))
955 /* bytes to existing buffer */
956 memset(out
.ptr
, 0, out
.len
);
957 if (vector
->stateful
)
959 if (!prf
->set_key(prf
, key
))
964 if (!prf
->get_bytes(prf
, seed
, out
.ptr
))
968 if (!memeq(vector
->out
, out
.ptr
, out
.len
))
972 /* bytes to existing buffer, using append mode */
973 if (alg
!= PRF_FIPS_SHA1_160
&& seed
.len
> 2)
975 memset(out
.ptr
, 0, out
.len
);
976 if (vector
->stateful
)
978 if (!prf
->set_key(prf
, key
))
983 if (!prf
->allocate_bytes(prf
, chunk_create(seed
.ptr
, 1), NULL
))
987 if (!prf
->get_bytes(prf
, chunk_create(seed
.ptr
+ 1, 1), NULL
))
991 if (!prf
->get_bytes(prf
, chunk_skip(seed
, 2), out
.ptr
))
995 if (!memeq(vector
->out
, out
.ptr
, out
.len
))
1007 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
1008 pseudo_random_function_names
, alg
, plugin_name
, get_name(vector
));
1012 enumerator
->destroy(enumerator
);
1015 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
1016 this->required ?
"disabled" : "enabled ",
1017 pseudo_random_function_names
, alg
, plugin_name
);
1018 return !this->required
;
1024 *speed
= bench_prf(this, alg
, create
);
1025 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points",
1026 pseudo_random_function_names
, alg
, plugin_name
, tested
, *speed
);
1030 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
1031 pseudo_random_function_names
, alg
, plugin_name
, tested
);
1040 static u_int
bench_rng(private_crypto_tester_t
*this,
1041 rng_quality_t quality
, rng_constructor_t create
)
1045 rng
= create(quality
);
1048 struct timespec start
;
1053 buf
= chunk_alloc(this->bench_size
);
1054 start_timing(&start
);
1055 while (end_timing(&start
) < this->bench_time
)
1057 if (!rng
->get_bytes(rng
, buf
.len
, buf
.ptr
))
1072 METHOD(crypto_tester_t
, test_rng
, bool,
1073 private_crypto_tester_t
*this, rng_quality_t quality
,
1074 rng_constructor_t create
, u_int
*speed
, const char *plugin_name
)
1076 enumerator_t
*enumerator
;
1077 rng_test_vector_t
*vector
;
1078 bool failed
= FALSE
;
1081 if (!this->rng_true
&& quality
== RNG_TRUE
)
1083 DBG1(DBG_LIB
, "enabled %N[%s]: skipping test (disabled by config)",
1084 rng_quality_names
, quality
, plugin_name
);
1088 enumerator
= this->rng
->create_enumerator(this->rng
);
1089 while (enumerator
->enumerate(enumerator
, &vector
))
1091 chunk_t data
= chunk_empty
;
1094 if (vector
->quality
!= quality
)
1101 rng
= create(quality
);
1104 DBG1(DBG_LIB
, "disabled %N[%s]: creating instance failed",
1105 rng_quality_names
, quality
, plugin_name
);
1109 /* allocated bytes */
1110 if (!rng
->allocate_bytes(rng
, vector
->len
, &data
) ||
1111 data
.len
!= vector
->len
||
1112 !vector
->test(vector
->user
, data
))
1116 /* write bytes into existing buffer */
1117 memset(data
.ptr
, 0, data
.len
);
1118 if (!rng
->get_bytes(rng
, vector
->len
, data
.ptr
))
1122 if (!vector
->test(vector
->user
, data
))
1133 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
1134 rng_quality_names
, quality
, plugin_name
, get_name(vector
));
1138 enumerator
->destroy(enumerator
);
1141 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found",
1142 this->required ?
", disabled" : "enabled ",
1143 rng_quality_names
, quality
, plugin_name
);
1144 return !this->required
;
1150 *speed
= bench_rng(this, quality
, create
);
1151 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points",
1152 rng_quality_names
, quality
, plugin_name
, tested
, *speed
);
1156 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
1157 rng_quality_names
, quality
, plugin_name
, tested
);
1164 * Benchmark a DH backend
1166 static u_int
bench_dh(private_crypto_tester_t
*this,
1167 diffie_hellman_group_t group
, dh_constructor_t create
)
1169 chunk_t pub
= chunk_empty
, shared
= chunk_empty
;
1170 diffie_hellman_t
*dh
;
1171 struct timespec start
;
1175 start_timing(&start
);
1176 while (end_timing(&start
) < this->bench_time
)
1183 if (dh
->get_my_public_value(dh
, &pub
) &&
1184 dh
->set_other_public_value(dh
, pub
) &&
1185 dh
->get_shared_secret(dh
, &shared
))
1190 chunk_free(&shared
);
1196 METHOD(crypto_tester_t
, test_dh
, bool,
1197 private_crypto_tester_t
*this, diffie_hellman_group_t group
,
1198 dh_constructor_t create
, u_int
*speed
, const char *plugin_name
)
1200 enumerator_t
*enumerator
;
1201 dh_test_vector_t
*v
;
1202 bool failed
= FALSE
;
1205 enumerator
= this->dh
->create_enumerator(this->dh
);
1206 while (enumerator
->enumerate(enumerator
, &v
))
1208 diffie_hellman_t
*a
, *b
;
1209 chunk_t apub
, bpub
, asec
, bsec
;
1211 if (v
->group
!= group
)
1224 DBG1(DBG_LIB
, "disabled %N[%s]: creating instance failed",
1225 diffie_hellman_group_names
, group
, plugin_name
);
1229 if (!a
->set_private_value
|| !b
->set_private_value
)
1230 { /* does not support testing */
1238 apub
= bpub
= asec
= bsec
= chunk_empty
;
1240 if (!a
->set_private_value(a
, chunk_create(v
->priv_a
, v
->priv_len
)) ||
1241 !b
->set_private_value(b
, chunk_create(v
->priv_b
, v
->priv_len
)))
1245 if (!a
->get_my_public_value(a
, &apub
) ||
1246 !chunk_equals(apub
, chunk_create(v
->pub_a
, v
->pub_len
)))
1250 if (!b
->get_my_public_value(b
, &bpub
) ||
1251 !chunk_equals(bpub
, chunk_create(v
->pub_b
, v
->pub_len
)))
1255 if (!a
->set_other_public_value(a
, bpub
) ||
1256 !b
->set_other_public_value(b
, apub
))
1260 if (!a
->get_shared_secret(a
, &asec
) ||
1261 !chunk_equals(asec
, chunk_create(v
->shared
, v
->shared_len
)))
1265 if (!b
->get_shared_secret(b
, &bsec
) ||
1266 !chunk_equals(bsec
, chunk_create(v
->shared
, v
->shared_len
)))
1281 DBG1(DBG_LIB
, "disabled %N[%s]: %s test vector failed",
1282 diffie_hellman_group_names
, group
, plugin_name
, get_name(v
));
1286 enumerator
->destroy(enumerator
);
1289 DBG1(DBG_LIB
, "%s %N[%s]: no test vectors found / untestable",
1290 this->required ?
"disabled" : "enabled ",
1291 diffie_hellman_group_names
, group
, plugin_name
);
1292 return !this->required
;
1298 *speed
= bench_dh(this, group
, create
);
1299 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors, %d points",
1300 diffie_hellman_group_names
, group
, plugin_name
, tested
, *speed
);
1304 DBG1(DBG_LIB
, "enabled %N[%s]: passed %u test vectors",
1305 diffie_hellman_group_names
, group
, plugin_name
, tested
);
1311 METHOD(crypto_tester_t
, add_crypter_vector
, void,
1312 private_crypto_tester_t
*this, crypter_test_vector_t
*vector
)
1314 this->crypter
->insert_last(this->crypter
, vector
);
1317 METHOD(crypto_tester_t
, add_aead_vector
, void,
1318 private_crypto_tester_t
*this, aead_test_vector_t
*vector
)
1320 this->aead
->insert_last(this->aead
, vector
);
1323 METHOD(crypto_tester_t
, add_signer_vector
, void,
1324 private_crypto_tester_t
*this, signer_test_vector_t
*vector
)
1326 this->signer
->insert_last(this->signer
, vector
);
1329 METHOD(crypto_tester_t
, add_hasher_vector
, void,
1330 private_crypto_tester_t
*this, hasher_test_vector_t
*vector
)
1332 this->hasher
->insert_last(this->hasher
, vector
);
1335 METHOD(crypto_tester_t
, add_prf_vector
, void,
1336 private_crypto_tester_t
*this, prf_test_vector_t
*vector
)
1338 this->prf
->insert_last(this->prf
, vector
);
1341 METHOD(crypto_tester_t
, add_rng_vector
, void,
1342 private_crypto_tester_t
*this, rng_test_vector_t
*vector
)
1344 this->rng
->insert_last(this->rng
, vector
);
1347 METHOD(crypto_tester_t
, add_dh_vector
, void,
1348 private_crypto_tester_t
*this, dh_test_vector_t
*vector
)
1350 this->dh
->insert_last(this->dh
, vector
);
1353 METHOD(crypto_tester_t
, destroy
, void,
1354 private_crypto_tester_t
*this)
1356 this->crypter
->destroy(this->crypter
);
1357 this->aead
->destroy(this->aead
);
1358 this->signer
->destroy(this->signer
);
1359 this->hasher
->destroy(this->hasher
);
1360 this->prf
->destroy(this->prf
);
1361 this->rng
->destroy(this->rng
);
1362 this->dh
->destroy(this->dh
);
1369 crypto_tester_t
*crypto_tester_create()
1371 private_crypto_tester_t
*this;
1375 .test_crypter
= _test_crypter
,
1376 .test_aead
= _test_aead
,
1377 .test_signer
= _test_signer
,
1378 .test_hasher
= _test_hasher
,
1379 .test_prf
= _test_prf
,
1380 .test_rng
= _test_rng
,
1381 .test_dh
= _test_dh
,
1382 .add_crypter_vector
= _add_crypter_vector
,
1383 .add_aead_vector
= _add_aead_vector
,
1384 .add_signer_vector
= _add_signer_vector
,
1385 .add_hasher_vector
= _add_hasher_vector
,
1386 .add_prf_vector
= _add_prf_vector
,
1387 .add_rng_vector
= _add_rng_vector
,
1388 .add_dh_vector
= _add_dh_vector
,
1389 .destroy
= _destroy
,
1391 .crypter
= linked_list_create(),
1392 .aead
= linked_list_create(),
1393 .signer
= linked_list_create(),
1394 .hasher
= linked_list_create(),
1395 .prf
= linked_list_create(),
1396 .rng
= linked_list_create(),
1397 .dh
= linked_list_create(),
1399 .required
= lib
->settings
->get_bool(lib
->settings
,
1400 "%s.crypto_test.required", FALSE
, lib
->ns
),
1401 .rng_true
= lib
->settings
->get_bool(lib
->settings
,
1402 "%s.crypto_test.rng_true", FALSE
, lib
->ns
),
1403 .bench_time
= lib
->settings
->get_int(lib
->settings
,
1404 "%s.crypto_test.bench_time", 50, lib
->ns
),
1405 .bench_size
= lib
->settings
->get_int(lib
->settings
,
1406 "%s.crypto_test.bench_size", 1024, lib
->ns
),
1409 /* enforce a block size of 16, should be fine for all algorithms */
1410 this->bench_size
= this->bench_size
/ 16 * 16;
1412 return &this->public;