2 * Copyright (C) 2013-2014 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Copyright (C) 2016 Andreas Steffen
5 * HSR Hochschule fuer Technik Rapperswil
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>.
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
18 #include "crypto_factory.h"
20 #include <utils/debug.h>
21 #include <threading/rwlock.h>
22 #include <collections/linked_list.h>
23 #include <crypto/crypto_tester.h>
24 #include <utils/test.h>
26 const char *default_plugin_name
= "default";
28 typedef struct entry_t entry_t
;
37 * plugin that registered this algorithm
39 const char *plugin_name
;
50 crypter_constructor_t create_crypter
;
51 aead_constructor_t create_aead
;
52 signer_constructor_t create_signer
;
53 hasher_constructor_t create_hasher
;
54 prf_constructor_t create_prf
;
55 xof_constructor_t create_xof
;
56 rng_constructor_t create_rng
;
57 nonce_gen_constructor_t create_nonce_gen
;
58 dh_constructor_t create_dh
;
63 typedef struct private_crypto_factory_t private_crypto_factory_t
;
66 * private data of crypto_factory
68 struct private_crypto_factory_t
{
73 crypto_factory_t
public;
76 * registered crypters, as entry_t
78 linked_list_t
*crypters
;
81 * registered aead transforms, as entry_t
86 * registered signers, as entry_t
88 linked_list_t
*signers
;
91 * registered hashers, as entry_t
93 linked_list_t
*hashers
;
96 * registered prfs, as entry_t
101 * registered xofs, as entry_t
106 * registered rngs, as entry_t
111 * registered nonce generators, as entry_t
113 linked_list_t
*nonce_gens
;
116 * registered diffie hellman, as entry_t
121 * test manager to test crypto algorithms
123 crypto_tester_t
*tester
;
126 * whether to test algorithms during registration
131 * whether to test algorithms on each crypto primitive construction
136 * run algorithm benchmark during registration
141 * Number of failed test vectors during "add".
146 * rwlock to lock access to modules
151 METHOD(crypto_factory_t
, create_crypter
, crypter_t
*,
152 private_crypto_factory_t
*this, encryption_algorithm_t algo
,
155 enumerator_t
*enumerator
;
157 crypter_t
*crypter
= NULL
;
159 this->lock
->read_lock(this->lock
);
160 enumerator
= this->crypters
->create_enumerator(this->crypters
);
161 while (enumerator
->enumerate(enumerator
, &entry
))
163 if (entry
->algo
== algo
)
165 if (this->test_on_create
&&
166 !this->tester
->test_crypter(this->tester
, algo
, key_size
,
167 entry
->create_crypter
, NULL
,
168 default_plugin_name
))
172 crypter
= entry
->create_crypter(algo
, key_size
);
179 enumerator
->destroy(enumerator
);
180 this->lock
->unlock(this->lock
);
184 METHOD(crypto_factory_t
, create_aead
, aead_t
*,
185 private_crypto_factory_t
*this, encryption_algorithm_t algo
,
186 size_t key_size
, size_t salt_size
)
188 enumerator_t
*enumerator
;
192 this->lock
->read_lock(this->lock
);
193 enumerator
= this->aeads
->create_enumerator(this->aeads
);
194 while (enumerator
->enumerate(enumerator
, &entry
))
196 if (entry
->algo
== algo
)
198 if (this->test_on_create
&&
199 !this->tester
->test_aead(this->tester
, algo
, key_size
,
200 salt_size
, entry
->create_aead
, NULL
,
201 default_plugin_name
))
205 aead
= entry
->create_aead(algo
, key_size
, salt_size
);
212 enumerator
->destroy(enumerator
);
213 this->lock
->unlock(this->lock
);
217 METHOD(crypto_factory_t
, create_signer
, signer_t
*,
218 private_crypto_factory_t
*this, integrity_algorithm_t algo
)
220 enumerator_t
*enumerator
;
222 signer_t
*signer
= NULL
;
224 this->lock
->read_lock(this->lock
);
225 enumerator
= this->signers
->create_enumerator(this->signers
);
226 while (enumerator
->enumerate(enumerator
, &entry
))
228 if (entry
->algo
== algo
)
230 if (this->test_on_create
&&
231 !this->tester
->test_signer(this->tester
, algo
,
232 entry
->create_signer
, NULL
,
233 default_plugin_name
))
237 signer
= entry
->create_signer(algo
);
244 enumerator
->destroy(enumerator
);
245 this->lock
->unlock(this->lock
);
249 METHOD(crypto_factory_t
, create_hasher
, hasher_t
*,
250 private_crypto_factory_t
*this, hash_algorithm_t algo
)
252 enumerator_t
*enumerator
;
254 hasher_t
*hasher
= NULL
;
256 this->lock
->read_lock(this->lock
);
257 enumerator
= this->hashers
->create_enumerator(this->hashers
);
258 while (enumerator
->enumerate(enumerator
, &entry
))
260 if (entry
->algo
== algo
)
262 if (this->test_on_create
&&
263 !this->tester
->test_hasher(this->tester
, algo
,
264 entry
->create_hasher
, NULL
,
265 default_plugin_name
))
269 hasher
= entry
->create_hasher(entry
->algo
);
276 enumerator
->destroy(enumerator
);
277 this->lock
->unlock(this->lock
);
281 METHOD(crypto_factory_t
, create_prf
, prf_t
*,
282 private_crypto_factory_t
*this, pseudo_random_function_t algo
)
284 enumerator_t
*enumerator
;
288 this->lock
->read_lock(this->lock
);
289 enumerator
= this->prfs
->create_enumerator(this->prfs
);
290 while (enumerator
->enumerate(enumerator
, &entry
))
292 if (entry
->algo
== algo
)
294 if (this->test_on_create
&&
295 !this->tester
->test_prf(this->tester
, algo
,
296 entry
->create_prf
, NULL
,
297 default_plugin_name
))
301 prf
= entry
->create_prf(algo
);
308 enumerator
->destroy(enumerator
);
309 this->lock
->unlock(this->lock
);
313 METHOD(crypto_factory_t
, create_xof
, xof_t
*,
314 private_crypto_factory_t
*this, ext_out_function_t algo
)
316 enumerator_t
*enumerator
;
320 this->lock
->read_lock(this->lock
);
321 enumerator
= this->xofs
->create_enumerator(this->xofs
);
322 while (enumerator
->enumerate(enumerator
, &entry
))
324 if (entry
->algo
== algo
)
326 if (this->test_on_create
&&
327 !this->tester
->test_xof(this->tester
, algo
,
328 entry
->create_xof
, NULL
,
329 default_plugin_name
))
333 xof
= entry
->create_xof(algo
);
340 enumerator
->destroy(enumerator
);
341 this->lock
->unlock(this->lock
);
345 METHOD(crypto_factory_t
, create_rng
, rng_t
*,
346 private_crypto_factory_t
*this, rng_quality_t quality
)
348 enumerator_t
*enumerator
;
352 this->lock
->read_lock(this->lock
);
353 enumerator
= this->rngs
->create_enumerator(this->rngs
);
354 while (enumerator
->enumerate(enumerator
, &entry
))
355 { /* find the best matching quality, but at least as good as requested */
356 if (entry
->algo
>= quality
)
358 if (this->test_on_create
&&
359 !this->tester
->test_rng(this->tester
, quality
,
360 entry
->create_rng
, NULL
,
361 default_plugin_name
))
365 rng
= entry
->create_rng(quality
);
372 enumerator
->destroy(enumerator
);
373 this->lock
->unlock(this->lock
);
377 METHOD(crypto_factory_t
, create_nonce_gen
, nonce_gen_t
*,
378 private_crypto_factory_t
*this)
380 enumerator_t
*enumerator
;
382 nonce_gen_t
*nonce_gen
= NULL
;
384 this->lock
->read_lock(this->lock
);
385 enumerator
= this->nonce_gens
->create_enumerator(this->nonce_gens
);
386 while (enumerator
->enumerate(enumerator
, &entry
))
388 nonce_gen
= entry
->create_nonce_gen();
394 enumerator
->destroy(enumerator
);
395 this->lock
->unlock(this->lock
);
400 METHOD(crypto_factory_t
, create_dh
, diffie_hellman_t
*,
401 private_crypto_factory_t
*this, diffie_hellman_group_t group
, ...)
403 enumerator_t
*enumerator
;
406 chunk_t g
= chunk_empty
, p
= chunk_empty
;
407 diffie_hellman_t
*diffie_hellman
= NULL
;
409 if (group
== MODP_CUSTOM
)
411 va_start(args
, group
);
412 g
= va_arg(args
, chunk_t
);
413 p
= va_arg(args
, chunk_t
);
417 this->lock
->read_lock(this->lock
);
418 enumerator
= this->dhs
->create_enumerator(this->dhs
);
419 while (enumerator
->enumerate(enumerator
, &entry
))
421 if (entry
->algo
== group
)
423 if (this->test_on_create
&& group
!= MODP_CUSTOM
&&
424 !this->tester
->test_dh(this->tester
, group
,
425 entry
->create_dh
, NULL
, default_plugin_name
))
429 diffie_hellman
= entry
->create_dh(group
, g
, p
);
436 enumerator
->destroy(enumerator
);
437 this->lock
->unlock(this->lock
);
438 return diffie_hellman
;
442 * Insert an algorithm entry to a list
444 * Entries maintain the order in which algorithms were added, unless they were
445 * benchmarked and speed is provided, which then is used to order entries of
446 * the same algorithm.
447 * An exception are RNG entries, which are sorted by algorithm identifier.
449 static void add_entry(private_crypto_factory_t
*this, linked_list_t
*list
,
450 int algo
, const char *plugin_name
,
451 u_int speed
, void *create
)
453 enumerator_t
*enumerator
;
454 entry_t
*entry
, *current
;
455 bool sort
= (list
== this->rngs
), found
= FALSE
;
459 .plugin_name
= plugin_name
,
462 entry
->create
= create
;
464 this->lock
->write_lock(this->lock
);
465 enumerator
= list
->create_enumerator(list
);
466 while (enumerator
->enumerate(enumerator
, ¤t
))
468 if (sort
&& current
->algo
> algo
)
472 else if (current
->algo
== algo
)
474 if (speed
> current
->speed
)
485 list
->insert_before(list
, enumerator
, entry
);
486 enumerator
->destroy(enumerator
);
487 this->lock
->unlock(this->lock
);
490 METHOD(crypto_factory_t
, add_crypter
, bool,
491 private_crypto_factory_t
*this, encryption_algorithm_t algo
, size_t key_size
,
492 const char *plugin_name
, crypter_constructor_t create
)
496 if (!this->test_on_add
||
497 this->tester
->test_crypter(this->tester
, algo
, key_size
, create
,
498 this->bench ?
&speed
: NULL
, plugin_name
))
500 add_entry(this, this->crypters
, algo
, plugin_name
, speed
, create
);
503 this->test_failures
++;
507 METHOD(crypto_factory_t
, remove_crypter
, void,
508 private_crypto_factory_t
*this, crypter_constructor_t create
)
511 enumerator_t
*enumerator
;
513 this->lock
->write_lock(this->lock
);
514 enumerator
= this->crypters
->create_enumerator(this->crypters
);
515 while (enumerator
->enumerate(enumerator
, &entry
))
517 if (entry
->create_crypter
== create
)
519 this->crypters
->remove_at(this->crypters
, enumerator
);
523 enumerator
->destroy(enumerator
);
524 this->lock
->unlock(this->lock
);
527 METHOD(crypto_factory_t
, add_aead
, bool,
528 private_crypto_factory_t
*this, encryption_algorithm_t algo
, size_t key_size
,
529 const char *plugin_name
, aead_constructor_t create
)
533 if (!this->test_on_add
||
534 this->tester
->test_aead(this->tester
, algo
, key_size
, 0, create
,
535 this->bench ?
&speed
: NULL
, plugin_name
))
537 add_entry(this, this->aeads
, algo
, plugin_name
, speed
, create
);
540 this->test_failures
++;
544 METHOD(crypto_factory_t
, remove_aead
, void,
545 private_crypto_factory_t
*this, aead_constructor_t create
)
548 enumerator_t
*enumerator
;
550 this->lock
->write_lock(this->lock
);
551 enumerator
= this->aeads
->create_enumerator(this->aeads
);
552 while (enumerator
->enumerate(enumerator
, &entry
))
554 if (entry
->create_aead
== create
)
556 this->aeads
->remove_at(this->aeads
, enumerator
);
560 enumerator
->destroy(enumerator
);
561 this->lock
->unlock(this->lock
);
564 METHOD(crypto_factory_t
, add_signer
, bool,
565 private_crypto_factory_t
*this, integrity_algorithm_t algo
,
566 const char *plugin_name
, signer_constructor_t create
)
570 if (!this->test_on_add
||
571 this->tester
->test_signer(this->tester
, algo
, create
,
572 this->bench ?
&speed
: NULL
, plugin_name
))
574 add_entry(this, this->signers
, algo
, plugin_name
, speed
, create
);
577 this->test_failures
++;
581 METHOD(crypto_factory_t
, remove_signer
, void,
582 private_crypto_factory_t
*this, signer_constructor_t create
)
585 enumerator_t
*enumerator
;
587 this->lock
->write_lock(this->lock
);
588 enumerator
= this->signers
->create_enumerator(this->signers
);
589 while (enumerator
->enumerate(enumerator
, &entry
))
591 if (entry
->create_signer
== create
)
593 this->signers
->remove_at(this->signers
, enumerator
);
597 enumerator
->destroy(enumerator
);
598 this->lock
->unlock(this->lock
);
601 METHOD(crypto_factory_t
, add_hasher
, bool,
602 private_crypto_factory_t
*this, hash_algorithm_t algo
,
603 const char *plugin_name
, hasher_constructor_t create
)
607 if (!this->test_on_add
||
608 this->tester
->test_hasher(this->tester
, algo
, create
,
609 this->bench ?
&speed
: NULL
, plugin_name
))
611 add_entry(this, this->hashers
, algo
, plugin_name
, speed
, create
);
614 this->test_failures
++;
618 METHOD(crypto_factory_t
, remove_hasher
, void,
619 private_crypto_factory_t
*this, hasher_constructor_t create
)
622 enumerator_t
*enumerator
;
624 this->lock
->write_lock(this->lock
);
625 enumerator
= this->hashers
->create_enumerator(this->hashers
);
626 while (enumerator
->enumerate(enumerator
, &entry
))
628 if (entry
->create_hasher
== create
)
630 this->hashers
->remove_at(this->hashers
, enumerator
);
634 enumerator
->destroy(enumerator
);
635 this->lock
->unlock(this->lock
);
638 METHOD(crypto_factory_t
, add_prf
, bool,
639 private_crypto_factory_t
*this, pseudo_random_function_t algo
,
640 const char *plugin_name
, prf_constructor_t create
)
644 if (!this->test_on_add
||
645 this->tester
->test_prf(this->tester
, algo
, create
,
646 this->bench ?
&speed
: NULL
, plugin_name
))
648 add_entry(this, this->prfs
, algo
, plugin_name
, speed
, create
);
651 this->test_failures
++;
655 METHOD(crypto_factory_t
, remove_prf
, void,
656 private_crypto_factory_t
*this, prf_constructor_t create
)
659 enumerator_t
*enumerator
;
661 this->lock
->write_lock(this->lock
);
662 enumerator
= this->prfs
->create_enumerator(this->prfs
);
663 while (enumerator
->enumerate(enumerator
, &entry
))
665 if (entry
->create_prf
== create
)
667 this->prfs
->remove_at(this->prfs
, enumerator
);
671 enumerator
->destroy(enumerator
);
672 this->lock
->unlock(this->lock
);
675 METHOD(crypto_factory_t
, add_xof
, bool,
676 private_crypto_factory_t
*this, ext_out_function_t algo
,
677 const char *plugin_name
, xof_constructor_t create
)
681 if (!this->test_on_add
||
682 this->tester
->test_xof(this->tester
, algo
, create
,
683 this->bench ?
&speed
: NULL
, plugin_name
))
685 add_entry(this, this->xofs
, algo
, plugin_name
, speed
, create
);
688 this->test_failures
++;
692 METHOD(crypto_factory_t
, remove_xof
, void,
693 private_crypto_factory_t
*this, xof_constructor_t create
)
696 enumerator_t
*enumerator
;
698 this->lock
->write_lock(this->lock
);
699 enumerator
= this->xofs
->create_enumerator(this->xofs
);
700 while (enumerator
->enumerate(enumerator
, &entry
))
702 if (entry
->create_xof
== create
)
704 this->xofs
->remove_at(this->xofs
, enumerator
);
708 enumerator
->destroy(enumerator
);
709 this->lock
->unlock(this->lock
);
712 METHOD(crypto_factory_t
, add_rng
, bool,
713 private_crypto_factory_t
*this, rng_quality_t quality
,
714 const char *plugin_name
, rng_constructor_t create
)
718 if (!this->test_on_add
||
719 this->tester
->test_rng(this->tester
, quality
, create
,
720 this->bench ?
&speed
: NULL
, plugin_name
))
722 add_entry(this, this->rngs
, quality
, plugin_name
, speed
, create
);
725 this->test_failures
++;
729 METHOD(crypto_factory_t
, remove_rng
, void,
730 private_crypto_factory_t
*this, rng_constructor_t create
)
733 enumerator_t
*enumerator
;
735 this->lock
->write_lock(this->lock
);
736 enumerator
= this->rngs
->create_enumerator(this->rngs
);
737 while (enumerator
->enumerate(enumerator
, &entry
))
739 if (entry
->create_rng
== create
)
741 this->rngs
->remove_at(this->rngs
, enumerator
);
745 enumerator
->destroy(enumerator
);
746 this->lock
->unlock(this->lock
);
749 METHOD(crypto_factory_t
, add_nonce_gen
, bool,
750 private_crypto_factory_t
*this, const char *plugin_name
,
751 nonce_gen_constructor_t create
)
753 add_entry(this, this->nonce_gens
, 0, plugin_name
, 0, create
);
757 METHOD(crypto_factory_t
, remove_nonce_gen
, void,
758 private_crypto_factory_t
*this, nonce_gen_constructor_t create
)
761 enumerator_t
*enumerator
;
763 this->lock
->write_lock(this->lock
);
764 enumerator
= this->nonce_gens
->create_enumerator(this->nonce_gens
);
765 while (enumerator
->enumerate(enumerator
, &entry
))
767 if (entry
->create_nonce_gen
== create
)
769 this->nonce_gens
->remove_at(this->nonce_gens
, enumerator
);
773 enumerator
->destroy(enumerator
);
774 this->lock
->unlock(this->lock
);
777 METHOD(crypto_factory_t
, add_dh
, bool,
778 private_crypto_factory_t
*this, diffie_hellman_group_t group
,
779 const char *plugin_name
, dh_constructor_t create
)
783 if (!this->test_on_add
||
784 this->tester
->test_dh(this->tester
, group
, create
,
785 this->bench ?
&speed
: NULL
, plugin_name
))
787 add_entry(this, this->dhs
, group
, plugin_name
, 0, create
);
790 this->test_failures
++;
794 METHOD(crypto_factory_t
, remove_dh
, void,
795 private_crypto_factory_t
*this, dh_constructor_t create
)
798 enumerator_t
*enumerator
;
800 this->lock
->write_lock(this->lock
);
801 enumerator
= this->dhs
->create_enumerator(this->dhs
);
802 while (enumerator
->enumerate(enumerator
, &entry
))
804 if (entry
->create_dh
== create
)
806 this->dhs
->remove_at(this->dhs
, enumerator
);
810 enumerator
->destroy(enumerator
);
811 this->lock
->unlock(this->lock
);
815 * match algorithms of an entry?
817 static bool entry_match(entry_t
*a
, entry_t
*b
)
819 return a
->algo
== b
->algo
;
823 * check for uniqueness of an entry
825 static bool unique_check(linked_list_t
*list
, entry_t
**in
, entry_t
**out
)
827 if (list
->find_first(list
, (void*)entry_match
, NULL
, *in
) == SUCCESS
)
832 list
->insert_last(list
, *in
);
837 * create an enumerator over entry->algo in list with locking and unique check
839 static enumerator_t
*create_enumerator(private_crypto_factory_t
*this,
840 linked_list_t
*list
, void *filter
)
842 this->lock
->read_lock(this->lock
);
843 return enumerator_create_filter(
844 enumerator_create_filter(
845 list
->create_enumerator(list
), (void*)unique_check
,
846 linked_list_create(), (void*)list
->destroy
),
847 filter
, this->lock
, (void*)this->lock
->unlock
);
851 * Filter function to enumerate algorithm, not entry
853 static bool crypter_filter(void *n
, entry_t
**entry
, encryption_algorithm_t
*algo
,
854 void *i2
, const char **plugin_name
)
856 *algo
= (*entry
)->algo
;
857 *plugin_name
= (*entry
)->plugin_name
;
861 METHOD(crypto_factory_t
, create_crypter_enumerator
, enumerator_t
*,
862 private_crypto_factory_t
*this)
864 return create_enumerator(this, this->crypters
, crypter_filter
);
867 METHOD(crypto_factory_t
, create_aead_enumerator
, enumerator_t
*,
868 private_crypto_factory_t
*this)
870 return create_enumerator(this, this->aeads
, crypter_filter
);
874 * Filter function to enumerate algorithm, not entry
876 static bool signer_filter(void *n
, entry_t
**entry
, integrity_algorithm_t
*algo
,
877 void *i2
, const char **plugin_name
)
879 *algo
= (*entry
)->algo
;
880 *plugin_name
= (*entry
)->plugin_name
;
884 METHOD(crypto_factory_t
, create_signer_enumerator
, enumerator_t
*,
885 private_crypto_factory_t
*this)
887 return create_enumerator(this, this->signers
, signer_filter
);
891 * Filter function to enumerate algorithm, not entry
893 static bool hasher_filter(void *n
, entry_t
**entry
, hash_algorithm_t
*algo
,
894 void *i2
, const char **plugin_name
)
896 *algo
= (*entry
)->algo
;
897 *plugin_name
= (*entry
)->plugin_name
;
901 METHOD(crypto_factory_t
, create_hasher_enumerator
, enumerator_t
*,
902 private_crypto_factory_t
*this)
904 return create_enumerator(this, this->hashers
, hasher_filter
);
908 * Filter function to enumerate algorithm, not entry
910 static bool prf_filter(void *n
, entry_t
**entry
, pseudo_random_function_t
*algo
,
911 void *i2
, const char **plugin_name
)
913 *algo
= (*entry
)->algo
;
914 *plugin_name
= (*entry
)->plugin_name
;
918 METHOD(crypto_factory_t
, create_prf_enumerator
, enumerator_t
*,
919 private_crypto_factory_t
*this)
921 return create_enumerator(this, this->prfs
, prf_filter
);
925 * Filter function to enumerate algorithm, not entry
927 static bool xof_filter(void *n
, entry_t
**entry
, ext_out_function_t
*algo
,
928 void *i2
, const char **plugin_name
)
930 *algo
= (*entry
)->algo
;
931 *plugin_name
= (*entry
)->plugin_name
;
935 METHOD(crypto_factory_t
, create_xof_enumerator
, enumerator_t
*,
936 private_crypto_factory_t
*this)
938 return create_enumerator(this, this->xofs
, xof_filter
);
942 * Filter function to enumerate group, not entry
944 static bool dh_filter(void *n
, entry_t
**entry
, diffie_hellman_group_t
*group
,
945 void *i2
, const char **plugin_name
)
947 *group
= (*entry
)->algo
;
948 *plugin_name
= (*entry
)->plugin_name
;
952 METHOD(crypto_factory_t
, create_dh_enumerator
, enumerator_t
*,
953 private_crypto_factory_t
*this)
955 return create_enumerator(this, this->dhs
, dh_filter
);
959 * Filter function to enumerate strength, not entry
961 static bool rng_filter(void *n
, entry_t
**entry
, rng_quality_t
*quality
,
962 void *i2
, const char **plugin_name
)
964 *quality
= (*entry
)->algo
;
965 *plugin_name
= (*entry
)->plugin_name
;
969 METHOD(crypto_factory_t
, create_rng_enumerator
, enumerator_t
*,
970 private_crypto_factory_t
*this)
972 return create_enumerator(this, this->rngs
, rng_filter
);
976 * Filter function to enumerate plugin name, not entry
978 static bool nonce_gen_filter(void *n
, entry_t
**entry
, const char **plugin_name
)
980 *plugin_name
= (*entry
)->plugin_name
;
984 METHOD(crypto_factory_t
, create_nonce_gen_enumerator
, enumerator_t
*,
985 private_crypto_factory_t
*this)
987 return create_enumerator(this, this->nonce_gens
, nonce_gen_filter
);
990 METHOD(crypto_factory_t
, add_test_vector
, void,
991 private_crypto_factory_t
*this, transform_type_t type
, void *vector
)
995 case ENCRYPTION_ALGORITHM
:
996 return this->tester
->add_crypter_vector(this->tester
, vector
);
998 return this->tester
->add_aead_vector(this->tester
, vector
);
999 case INTEGRITY_ALGORITHM
:
1000 return this->tester
->add_signer_vector(this->tester
, vector
);
1001 case HASH_ALGORITHM
:
1002 return this->tester
->add_hasher_vector(this->tester
, vector
);
1003 case PSEUDO_RANDOM_FUNCTION
:
1004 return this->tester
->add_prf_vector(this->tester
, vector
);
1005 case EXTENDED_OUTPUT_FUNCTION
:
1006 return this->tester
->add_xof_vector(this->tester
, vector
);
1007 case RANDOM_NUMBER_GENERATOR
:
1008 return this->tester
->add_rng_vector(this->tester
, vector
);
1009 case DIFFIE_HELLMAN_GROUP
:
1010 return this->tester
->add_dh_vector(this->tester
, vector
);
1012 DBG1(DBG_LIB
, "%N test vectors not supported, ignored",
1013 transform_type_names
, type
);
1018 * Private enumerator for create_verify_enumerator()
1021 enumerator_t
public;
1022 enumerator_t
*inner
;
1023 transform_type_t type
;
1024 crypto_tester_t
*tester
;
1026 } verify_enumerator_t
;
1028 METHOD(enumerator_t
, verify_enumerate
, bool,
1029 verify_enumerator_t
*this, u_int
*alg
, const char **plugin
, bool *valid
)
1033 if (!this->inner
->enumerate(this->inner
, &entry
))
1039 case ENCRYPTION_ALGORITHM
:
1040 *valid
= this->tester
->test_crypter(this->tester
, entry
->algo
, 0,
1041 entry
->create_crypter
, NULL
, entry
->plugin_name
);
1043 case AEAD_ALGORITHM
:
1044 *valid
= this->tester
->test_aead(this->tester
, entry
->algo
, 0, 0,
1045 entry
->create_aead
, NULL
, entry
->plugin_name
);
1047 case INTEGRITY_ALGORITHM
:
1048 *valid
= this->tester
->test_signer(this->tester
, entry
->algo
,
1049 entry
->create_signer
, NULL
, entry
->plugin_name
);
1051 case HASH_ALGORITHM
:
1052 *valid
= this->tester
->test_hasher(this->tester
, entry
->algo
,
1053 entry
->create_hasher
, NULL
, entry
->plugin_name
);
1055 case PSEUDO_RANDOM_FUNCTION
:
1056 *valid
= this->tester
->test_prf(this->tester
, entry
->algo
,
1057 entry
->create_prf
, NULL
, entry
->plugin_name
);
1059 case EXTENDED_OUTPUT_FUNCTION
:
1060 *valid
= this->tester
->test_xof(this->tester
, entry
->algo
,
1061 entry
->create_xof
, NULL
, entry
->plugin_name
);
1063 case RANDOM_NUMBER_GENERATOR
:
1064 *valid
= this->tester
->test_rng(this->tester
, entry
->algo
,
1065 entry
->create_rng
, NULL
, entry
->plugin_name
);
1067 case DIFFIE_HELLMAN_GROUP
:
1068 *valid
= this->tester
->test_dh(this->tester
, entry
->algo
,
1069 entry
->create_dh
, NULL
, entry
->plugin_name
);
1074 *plugin
= entry
->plugin_name
;
1079 METHOD(enumerator_t
, verify_destroy
, void,
1080 verify_enumerator_t
*this)
1082 this->inner
->destroy(this->inner
);
1083 this->lock
->unlock(this->lock
);
1087 METHOD(crypto_factory_t
, create_verify_enumerator
, enumerator_t
*,
1088 private_crypto_factory_t
*this, transform_type_t type
)
1090 verify_enumerator_t
*enumerator
;
1091 enumerator_t
*inner
;
1093 this->lock
->read_lock(this->lock
);
1096 case ENCRYPTION_ALGORITHM
:
1097 inner
= this->crypters
->create_enumerator(this->crypters
);
1099 case AEAD_ALGORITHM
:
1100 inner
= this->aeads
->create_enumerator(this->aeads
);
1102 case INTEGRITY_ALGORITHM
:
1103 inner
= this->signers
->create_enumerator(this->signers
);
1105 case HASH_ALGORITHM
:
1106 inner
= this->hashers
->create_enumerator(this->hashers
);
1108 case PSEUDO_RANDOM_FUNCTION
:
1109 inner
= this->prfs
->create_enumerator(this->prfs
);
1111 case EXTENDED_OUTPUT_FUNCTION
:
1112 inner
= this->xofs
->create_enumerator(this->xofs
);
1114 case RANDOM_NUMBER_GENERATOR
:
1115 inner
= this->rngs
->create_enumerator(this->rngs
);
1117 case DIFFIE_HELLMAN_GROUP
:
1118 inner
= this->dhs
->create_enumerator(this->dhs
);
1121 this->lock
->unlock(this->lock
);
1122 return enumerator_create_empty();
1126 .enumerate
= (void*)_verify_enumerate
,
1127 .destroy
= _verify_destroy
,
1131 .tester
= this->tester
,
1134 return &enumerator
->public;
1137 METHOD(crypto_factory_t
, destroy
, void,
1138 private_crypto_factory_t
*this)
1140 this->crypters
->destroy(this->crypters
);
1141 this->aeads
->destroy(this->aeads
);
1142 this->signers
->destroy(this->signers
);
1143 this->hashers
->destroy(this->hashers
);
1144 this->prfs
->destroy(this->prfs
);
1145 this->xofs
->destroy(this->xofs
);
1146 this->rngs
->destroy(this->rngs
);
1147 this->nonce_gens
->destroy(this->nonce_gens
);
1148 this->dhs
->destroy(this->dhs
);
1149 this->tester
->destroy(this->tester
);
1150 this->lock
->destroy(this->lock
);
1157 crypto_factory_t
*crypto_factory_create()
1159 private_crypto_factory_t
*this;
1163 .create_crypter
= _create_crypter
,
1164 .create_aead
= _create_aead
,
1165 .create_signer
= _create_signer
,
1166 .create_hasher
= _create_hasher
,
1167 .create_prf
= _create_prf
,
1168 .create_xof
= _create_xof
,
1169 .create_rng
= _create_rng
,
1170 .create_nonce_gen
= _create_nonce_gen
,
1171 .create_dh
= _create_dh
,
1172 .add_crypter
= _add_crypter
,
1173 .remove_crypter
= _remove_crypter
,
1174 .add_aead
= _add_aead
,
1175 .remove_aead
= _remove_aead
,
1176 .add_signer
= _add_signer
,
1177 .remove_signer
= _remove_signer
,
1178 .add_hasher
= _add_hasher
,
1179 .remove_hasher
= _remove_hasher
,
1180 .add_prf
= _add_prf
,
1181 .remove_prf
= _remove_prf
,
1182 .add_xof
= _add_xof
,
1183 .remove_xof
= _remove_xof
,
1184 .add_rng
= _add_rng
,
1185 .remove_rng
= _remove_rng
,
1186 .add_nonce_gen
= _add_nonce_gen
,
1187 .remove_nonce_gen
= _remove_nonce_gen
,
1189 .remove_dh
= _remove_dh
,
1190 .create_crypter_enumerator
= _create_crypter_enumerator
,
1191 .create_aead_enumerator
= _create_aead_enumerator
,
1192 .create_signer_enumerator
= _create_signer_enumerator
,
1193 .create_hasher_enumerator
= _create_hasher_enumerator
,
1194 .create_prf_enumerator
= _create_prf_enumerator
,
1195 .create_xof_enumerator
= _create_xof_enumerator
,
1196 .create_dh_enumerator
= _create_dh_enumerator
,
1197 .create_rng_enumerator
= _create_rng_enumerator
,
1198 .create_nonce_gen_enumerator
= _create_nonce_gen_enumerator
,
1199 .add_test_vector
= _add_test_vector
,
1200 .create_verify_enumerator
= _create_verify_enumerator
,
1201 .destroy
= _destroy
,
1203 .crypters
= linked_list_create(),
1204 .aeads
= linked_list_create(),
1205 .signers
= linked_list_create(),
1206 .hashers
= linked_list_create(),
1207 .prfs
= linked_list_create(),
1208 .xofs
= linked_list_create(),
1209 .rngs
= linked_list_create(),
1210 .nonce_gens
= linked_list_create(),
1211 .dhs
= linked_list_create(),
1212 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
1213 .tester
= crypto_tester_create(),
1214 .test_on_add
= lib
->settings
->get_bool(lib
->settings
,
1215 "%s.crypto_test.on_add", FALSE
, lib
->ns
),
1216 .test_on_create
= lib
->settings
->get_bool(lib
->settings
,
1217 "%s.crypto_test.on_create", FALSE
, lib
->ns
),
1218 .bench
= lib
->settings
->get_bool(lib
->settings
,
1219 "%s.crypto_test.bench", FALSE
, lib
->ns
),
1222 return &this->public;