2d13896d697555ef8bf842d8bdbf63251d6f8460
[strongswan.git] / src / libstrongswan / crypto / crypto_factory.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "crypto_factory.h"
17
18 #include <debug.h>
19 #include <threading/rwlock.h>
20 #include <utils/linked_list.h>
21 #include <crypto/crypto_tester.h>
22
23 const char *default_plugin_name = "default";
24
25 typedef struct entry_t entry_t;
26
27 struct entry_t {
28 /**
29 * algorithm
30 */
31 u_int algo;
32
33 /**
34 * plugin that registered this algorithm
35 */
36 const char *plugin_name;
37
38 /**
39 * benchmarked speed
40 */
41 u_int speed;
42
43 /**
44 * constructor
45 */
46 union {
47 crypter_constructor_t create_crypter;
48 aead_constructor_t create_aead;
49 signer_constructor_t create_signer;
50 hasher_constructor_t create_hasher;
51 prf_constructor_t create_prf;
52 rng_constructor_t create_rng;
53 dh_constructor_t create_dh;
54 void *create;
55 };
56 };
57
58 typedef struct private_crypto_factory_t private_crypto_factory_t;
59
60 /**
61 * private data of crypto_factory
62 */
63 struct private_crypto_factory_t {
64
65 /**
66 * public functions
67 */
68 crypto_factory_t public;
69
70 /**
71 * registered crypters, as entry_t
72 */
73 linked_list_t *crypters;
74
75 /**
76 * registered aead transforms, as entry_t
77 */
78 linked_list_t *aeads;
79
80 /**
81 * registered signers, as entry_t
82 */
83 linked_list_t *signers;
84
85 /**
86 * registered hashers, as entry_t
87 */
88 linked_list_t *hashers;
89
90 /**
91 * registered prfs, as entry_t
92 */
93 linked_list_t *prfs;
94
95 /**
96 * registered rngs, as entry_t
97 */
98 linked_list_t *rngs;
99
100 /**
101 * registered diffie hellman, as entry_t
102 */
103 linked_list_t *dhs;
104
105 /**
106 * test manager to test crypto algorithms
107 */
108 crypto_tester_t *tester;
109
110 /**
111 * whether to test algorithms during registration
112 */
113 bool test_on_add;
114
115 /**
116 * whether to test algorithms on each crypto primitive construction
117 */
118 bool test_on_create;
119
120 /**
121 * run algorithm benchmark during registration
122 */
123 bool bench;
124
125 /**
126 * rwlock to lock access to modules
127 */
128 rwlock_t *lock;
129 };
130
131 METHOD(crypto_factory_t, create_crypter, crypter_t*,
132 private_crypto_factory_t *this, encryption_algorithm_t algo,
133 size_t key_size)
134 {
135 enumerator_t *enumerator;
136 entry_t *entry;
137 crypter_t *crypter = NULL;
138
139 this->lock->read_lock(this->lock);
140 enumerator = this->crypters->create_enumerator(this->crypters);
141 while (enumerator->enumerate(enumerator, &entry))
142 {
143 if (entry->algo == algo)
144 {
145 if (this->test_on_create &&
146 !this->tester->test_crypter(this->tester, algo, key_size,
147 entry->create_crypter, NULL,
148 default_plugin_name))
149 {
150 continue;
151 }
152 crypter = entry->create_crypter(algo, key_size);
153 if (crypter)
154 {
155 break;
156 }
157 }
158 }
159 enumerator->destroy(enumerator);
160 this->lock->unlock(this->lock);
161 return crypter;
162 }
163
164 METHOD(crypto_factory_t, create_aead, aead_t*,
165 private_crypto_factory_t *this, encryption_algorithm_t algo,
166 size_t key_size)
167 {
168 enumerator_t *enumerator;
169 entry_t *entry;
170 aead_t *aead = NULL;
171
172 this->lock->read_lock(this->lock);
173 enumerator = this->aeads->create_enumerator(this->aeads);
174 while (enumerator->enumerate(enumerator, &entry))
175 {
176 if (entry->algo == algo)
177 {
178 if (this->test_on_create &&
179 !this->tester->test_aead(this->tester, algo, key_size,
180 entry->create_aead, NULL,
181 default_plugin_name))
182 {
183 continue;
184 }
185 aead = entry->create_aead(algo, key_size);
186 if (aead)
187 {
188 break;
189 }
190 }
191 }
192 enumerator->destroy(enumerator);
193 this->lock->unlock(this->lock);
194 return aead;
195 }
196
197 METHOD(crypto_factory_t, create_signer, signer_t*,
198 private_crypto_factory_t *this, integrity_algorithm_t algo)
199 {
200 enumerator_t *enumerator;
201 entry_t *entry;
202 signer_t *signer = NULL;
203
204 this->lock->read_lock(this->lock);
205 enumerator = this->signers->create_enumerator(this->signers);
206 while (enumerator->enumerate(enumerator, &entry))
207 {
208 if (entry->algo == algo)
209 {
210 if (this->test_on_create &&
211 !this->tester->test_signer(this->tester, algo,
212 entry->create_signer, NULL,
213 default_plugin_name))
214 {
215 continue;
216 }
217 signer = entry->create_signer(algo);
218 if (signer)
219 {
220 break;
221 }
222 }
223 }
224 enumerator->destroy(enumerator);
225 this->lock->unlock(this->lock);
226
227 return signer;
228 }
229
230 METHOD(crypto_factory_t, create_hasher, hasher_t*,
231 private_crypto_factory_t *this, hash_algorithm_t algo)
232 {
233 enumerator_t *enumerator;
234 entry_t *entry;
235 hasher_t *hasher = NULL;
236
237 this->lock->read_lock(this->lock);
238 enumerator = this->hashers->create_enumerator(this->hashers);
239 while (enumerator->enumerate(enumerator, &entry))
240 {
241 if (algo == HASH_PREFERRED || entry->algo == algo)
242 {
243 if (this->test_on_create && algo != HASH_PREFERRED &&
244 !this->tester->test_hasher(this->tester, algo,
245 entry->create_hasher, NULL,
246 default_plugin_name))
247 {
248 continue;
249 }
250 hasher = entry->create_hasher(entry->algo);
251 if (hasher)
252 {
253 break;
254 }
255 }
256 }
257 enumerator->destroy(enumerator);
258 this->lock->unlock(this->lock);
259 return hasher;
260 }
261
262 METHOD(crypto_factory_t, create_prf, prf_t*,
263 private_crypto_factory_t *this, pseudo_random_function_t algo)
264 {
265 enumerator_t *enumerator;
266 entry_t *entry;
267 prf_t *prf = NULL;
268
269 this->lock->read_lock(this->lock);
270 enumerator = this->prfs->create_enumerator(this->prfs);
271 while (enumerator->enumerate(enumerator, &entry))
272 {
273 if (entry->algo == algo)
274 {
275 if (this->test_on_create &&
276 !this->tester->test_prf(this->tester, algo,
277 entry->create_prf, NULL,
278 default_plugin_name))
279 {
280 continue;
281 }
282 prf = entry->create_prf(algo);
283 if (prf)
284 {
285 break;
286 }
287 }
288 }
289 enumerator->destroy(enumerator);
290 this->lock->unlock(this->lock);
291 return prf;
292 }
293
294 METHOD(crypto_factory_t, create_rng, rng_t*,
295 private_crypto_factory_t *this, rng_quality_t quality)
296 {
297 enumerator_t *enumerator;
298 entry_t *entry;
299 u_int diff = ~0;
300 rng_constructor_t constr = NULL;
301
302 this->lock->read_lock(this->lock);
303 enumerator = this->rngs->create_enumerator(this->rngs);
304 while (enumerator->enumerate(enumerator, &entry))
305 { /* find the best matching quality, but at least as good as requested */
306 if (entry->algo >= quality && diff > entry->algo - quality)
307 {
308 if (this->test_on_create &&
309 !this->tester->test_rng(this->tester, quality,
310 entry->create_rng, NULL,
311 default_plugin_name))
312 {
313 continue;
314 }
315 diff = entry->algo - quality;
316 constr = entry->create_rng;
317 if (diff == 0)
318 { /* perfect match, won't get better */
319 break;
320 }
321 }
322 }
323 enumerator->destroy(enumerator);
324 this->lock->unlock(this->lock);
325 if (constr)
326 {
327 return constr(quality);
328 }
329 return NULL;
330 }
331
332 METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
333 private_crypto_factory_t *this, diffie_hellman_group_t group, ...)
334 {
335 enumerator_t *enumerator;
336 entry_t *entry;
337 diffie_hellman_t *diffie_hellman = NULL;
338
339 this->lock->read_lock(this->lock);
340 enumerator = this->dhs->create_enumerator(this->dhs);
341 while (enumerator->enumerate(enumerator, &entry))
342 {
343 if (entry->algo == group)
344 {
345 if (group == MODP_CUSTOM)
346 {
347 va_list args;
348 chunk_t g, p;
349
350 va_start(args, group);
351 g = va_arg(args, chunk_t);
352 p = va_arg(args, chunk_t);
353 va_end(args);
354 diffie_hellman = entry->create_dh(MODP_CUSTOM, g, p);
355 }
356 else
357 {
358 diffie_hellman = entry->create_dh(group);
359 }
360 if (diffie_hellman)
361 {
362 break;
363 }
364 }
365 }
366 enumerator->destroy(enumerator);
367 this->lock->unlock(this->lock);
368 return diffie_hellman;
369 }
370
371 /**
372 * Insert an algorithm entry to a list
373 */
374 static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
375 int algo, const char *plugin_name,
376 u_int speed, void *create)
377 {
378 entry_t *entry, *current;
379 linked_list_t *tmp;
380 bool inserted = FALSE;
381
382 INIT(entry,
383 .algo = algo,
384 .plugin_name = plugin_name,
385 .speed = speed,
386 );
387 entry->create = create;
388
389 this->lock->write_lock(this->lock);
390 if (speed)
391 { /* insert sorted by speed using a temporary list */
392 tmp = linked_list_create();
393 while (list->remove_first(list, (void**)&current) == SUCCESS)
394 {
395 tmp->insert_last(tmp, current);
396 }
397 while (tmp->remove_first(tmp, (void**)&current) == SUCCESS)
398 {
399 if (!inserted &&
400 current->algo == algo &&
401 current->speed < speed)
402 {
403 list->insert_last(list, entry);
404 inserted = TRUE;
405 }
406 list->insert_last(list, current);
407 }
408 tmp->destroy(tmp);
409 }
410 if (!inserted)
411 {
412 list->insert_last(list, entry);
413 }
414 this->lock->unlock(this->lock);
415 }
416
417 METHOD(crypto_factory_t, add_crypter, void,
418 private_crypto_factory_t *this, encryption_algorithm_t algo,
419 const char *plugin_name, crypter_constructor_t create)
420 {
421 u_int speed = 0;
422
423 if (!this->test_on_add ||
424 this->tester->test_crypter(this->tester, algo, 0, create,
425 this->bench ? &speed : NULL, plugin_name))
426 {
427 add_entry(this, this->crypters, algo, plugin_name, speed, create);
428 }
429 }
430
431 METHOD(crypto_factory_t, remove_crypter, void,
432 private_crypto_factory_t *this, crypter_constructor_t create)
433 {
434 entry_t *entry;
435 enumerator_t *enumerator;
436
437 this->lock->write_lock(this->lock);
438 enumerator = this->crypters->create_enumerator(this->crypters);
439 while (enumerator->enumerate(enumerator, &entry))
440 {
441 if (entry->create_crypter == create)
442 {
443 this->crypters->remove_at(this->crypters, enumerator);
444 free(entry);
445 }
446 }
447 enumerator->destroy(enumerator);
448 this->lock->unlock(this->lock);
449 }
450
451 METHOD(crypto_factory_t, add_aead, void,
452 private_crypto_factory_t *this, encryption_algorithm_t algo,
453 const char *plugin_name, aead_constructor_t create)
454 {
455 u_int speed = 0;
456
457 if (!this->test_on_add ||
458 this->tester->test_aead(this->tester, algo, 0, create,
459 this->bench ? &speed : NULL, plugin_name))
460 {
461 add_entry(this, this->aeads, algo, plugin_name, speed, create);
462 }
463 }
464
465 METHOD(crypto_factory_t, remove_aead, void,
466 private_crypto_factory_t *this, aead_constructor_t create)
467 {
468 entry_t *entry;
469 enumerator_t *enumerator;
470
471 this->lock->write_lock(this->lock);
472 enumerator = this->aeads->create_enumerator(this->aeads);
473 while (enumerator->enumerate(enumerator, &entry))
474 {
475 if (entry->create_aead == create)
476 {
477 this->aeads->remove_at(this->aeads, enumerator);
478 free(entry);
479 }
480 }
481 enumerator->destroy(enumerator);
482 this->lock->unlock(this->lock);
483 }
484
485 METHOD(crypto_factory_t, add_signer, void,
486 private_crypto_factory_t *this, integrity_algorithm_t algo,
487 const char *plugin_name, signer_constructor_t create)
488 {
489 u_int speed = 0;
490
491 if (!this->test_on_add ||
492 this->tester->test_signer(this->tester, algo, create,
493 this->bench ? &speed : NULL, plugin_name))
494 {
495 add_entry(this, this->signers, algo, plugin_name, speed, create);
496 }
497 }
498
499 METHOD(crypto_factory_t, remove_signer, void,
500 private_crypto_factory_t *this, signer_constructor_t create)
501 {
502 entry_t *entry;
503 enumerator_t *enumerator;
504
505 this->lock->write_lock(this->lock);
506 enumerator = this->signers->create_enumerator(this->signers);
507 while (enumerator->enumerate(enumerator, &entry))
508 {
509 if (entry->create_signer == create)
510 {
511 this->signers->remove_at(this->signers, enumerator);
512 free(entry);
513 }
514 }
515 enumerator->destroy(enumerator);
516 this->lock->unlock(this->lock);
517 }
518
519 METHOD(crypto_factory_t, add_hasher, void,
520 private_crypto_factory_t *this, hash_algorithm_t algo,
521 const char *plugin_name, hasher_constructor_t create)
522 {
523 u_int speed = 0;
524
525 if (!this->test_on_add ||
526 this->tester->test_hasher(this->tester, algo, create,
527 this->bench ? &speed : NULL, plugin_name))
528 {
529 add_entry(this, this->hashers, algo, plugin_name, speed, create);
530 }
531 }
532
533 METHOD(crypto_factory_t, remove_hasher, void,
534 private_crypto_factory_t *this, hasher_constructor_t create)
535 {
536 entry_t *entry;
537 enumerator_t *enumerator;
538
539 this->lock->write_lock(this->lock);
540 enumerator = this->hashers->create_enumerator(this->hashers);
541 while (enumerator->enumerate(enumerator, &entry))
542 {
543 if (entry->create_hasher == create)
544 {
545 this->hashers->remove_at(this->hashers, enumerator);
546 free(entry);
547 }
548 }
549 enumerator->destroy(enumerator);
550 this->lock->unlock(this->lock);
551 }
552
553 METHOD(crypto_factory_t, add_prf, void,
554 private_crypto_factory_t *this, pseudo_random_function_t algo,
555 const char *plugin_name, prf_constructor_t create)
556 {
557 u_int speed = 0;
558
559 if (!this->test_on_add ||
560 this->tester->test_prf(this->tester, algo, create,
561 this->bench ? &speed : NULL, plugin_name))
562 {
563 add_entry(this, this->prfs, algo, plugin_name, speed, create);
564 }
565 }
566
567 METHOD(crypto_factory_t, remove_prf, void,
568 private_crypto_factory_t *this, prf_constructor_t create)
569 {
570 entry_t *entry;
571 enumerator_t *enumerator;
572
573 this->lock->write_lock(this->lock);
574 enumerator = this->prfs->create_enumerator(this->prfs);
575 while (enumerator->enumerate(enumerator, &entry))
576 {
577 if (entry->create_prf == create)
578 {
579 this->prfs->remove_at(this->prfs, enumerator);
580 free(entry);
581 }
582 }
583 enumerator->destroy(enumerator);
584 this->lock->unlock(this->lock);
585 }
586
587 METHOD(crypto_factory_t, add_rng, void,
588 private_crypto_factory_t *this, rng_quality_t quality,
589 const char *plugin_name, rng_constructor_t create)
590 {
591 u_int speed = 0;
592
593 if (!this->test_on_add ||
594 this->tester->test_rng(this->tester, quality, create,
595 this->bench ? &speed : NULL, plugin_name))
596 {
597 add_entry(this, this->rngs, quality, plugin_name, speed, create);
598 }
599 }
600
601 METHOD(crypto_factory_t, remove_rng, void,
602 private_crypto_factory_t *this, rng_constructor_t create)
603 {
604 entry_t *entry;
605 enumerator_t *enumerator;
606
607 this->lock->write_lock(this->lock);
608 enumerator = this->rngs->create_enumerator(this->rngs);
609 while (enumerator->enumerate(enumerator, &entry))
610 {
611 if (entry->create_rng == create)
612 {
613 this->rngs->remove_at(this->rngs, enumerator);
614 free(entry);
615 }
616 }
617 enumerator->destroy(enumerator);
618 this->lock->unlock(this->lock);
619 }
620
621 METHOD(crypto_factory_t, add_dh, void,
622 private_crypto_factory_t *this, diffie_hellman_group_t group,
623 const char *plugin_name, dh_constructor_t create)
624 {
625 add_entry(this, this->dhs, group, plugin_name, 0, create);
626 }
627
628 METHOD(crypto_factory_t, remove_dh, void,
629 private_crypto_factory_t *this, dh_constructor_t create)
630 {
631 entry_t *entry;
632 enumerator_t *enumerator;
633
634 this->lock->write_lock(this->lock);
635 enumerator = this->dhs->create_enumerator(this->dhs);
636 while (enumerator->enumerate(enumerator, &entry))
637 {
638 if (entry->create_dh == create)
639 {
640 this->dhs->remove_at(this->dhs, enumerator);
641 free(entry);
642 }
643 }
644 enumerator->destroy(enumerator);
645 this->lock->unlock(this->lock);
646 }
647
648 /**
649 * match algorithms of an entry?
650 */
651 static bool entry_match(entry_t *a, entry_t *b)
652 {
653 return a->algo == b->algo;
654 }
655
656 /**
657 * check for uniqueness of an entry
658 */
659 static bool unique_check(linked_list_t *list, entry_t **in, entry_t **out)
660 {
661 if (list->find_first(list, (void*)entry_match, NULL, *in) == SUCCESS)
662 {
663 return FALSE;
664 }
665 *out = *in;
666 list->insert_last(list, *in);
667 return TRUE;
668 }
669
670 /**
671 * create an enumerator over entry->algo in list with locking and unique check
672 */
673 static enumerator_t *create_enumerator(private_crypto_factory_t *this,
674 linked_list_t *list, void *filter)
675 {
676 this->lock->read_lock(this->lock);
677 return enumerator_create_filter(
678 enumerator_create_filter(
679 list->create_enumerator(list), (void*)unique_check,
680 linked_list_create(), (void*)list->destroy),
681 filter, this->lock, (void*)this->lock->unlock);
682 }
683
684 /**
685 * Filter function to enumerate algorithm, not entry
686 */
687 static bool crypter_filter(void *n, entry_t **entry, encryption_algorithm_t *algo,
688 void *i2, const char **plugin_name)
689 {
690 *algo = (*entry)->algo;
691 *plugin_name = (*entry)->plugin_name;
692 return TRUE;
693 }
694
695 METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
696 private_crypto_factory_t *this)
697 {
698 return create_enumerator(this, this->crypters, crypter_filter);
699 }
700
701 METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
702 private_crypto_factory_t *this)
703 {
704 return create_enumerator(this, this->aeads, crypter_filter);
705 }
706
707 /**
708 * Filter function to enumerate algorithm, not entry
709 */
710 static bool signer_filter(void *n, entry_t **entry, integrity_algorithm_t *algo,
711 void *i2, const char **plugin_name)
712 {
713 *algo = (*entry)->algo;
714 *plugin_name = (*entry)->plugin_name;
715 return TRUE;
716 }
717
718 METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
719 private_crypto_factory_t *this)
720 {
721 return create_enumerator(this, this->signers, signer_filter);
722 }
723
724 /**
725 * Filter function to enumerate algorithm, not entry
726 */
727 static bool hasher_filter(void *n, entry_t **entry, hash_algorithm_t *algo,
728 void *i2, const char **plugin_name)
729 {
730 *algo = (*entry)->algo;
731 *plugin_name = (*entry)->plugin_name;
732 return TRUE;
733 }
734
735 METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
736 private_crypto_factory_t *this)
737 {
738 return create_enumerator(this, this->hashers, hasher_filter);
739 }
740
741 /**
742 * Filter function to enumerate algorithm, not entry
743 */
744 static bool prf_filter(void *n, entry_t **entry, pseudo_random_function_t *algo,
745 void *i2, const char **plugin_name)
746 {
747 *algo = (*entry)->algo;
748 *plugin_name = (*entry)->plugin_name;
749 return TRUE;
750 }
751
752 METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
753 private_crypto_factory_t *this)
754 {
755 return create_enumerator(this, this->prfs, prf_filter);
756 }
757
758 /**
759 * Filter function to enumerate algorithm, not entry
760 */
761 static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group,
762 void *i2, const char **plugin_name)
763 {
764 *group = (*entry)->algo;
765 *plugin_name = (*entry)->plugin_name;
766 return TRUE;
767 }
768
769 METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
770 private_crypto_factory_t *this)
771 {
772 return create_enumerator(this, this->dhs, dh_filter);
773 }
774
775 /**
776 * Filter function to enumerate algorithm, not entry
777 */
778 static bool rng_filter(void *n, entry_t **entry, rng_quality_t *quality,
779 void *i2, const char **plugin_name)
780 {
781 *quality = (*entry)->algo;
782 *plugin_name = (*entry)->plugin_name;
783 return TRUE;
784 }
785
786 METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*,
787 private_crypto_factory_t *this)
788 {
789 return create_enumerator(this, this->rngs, rng_filter);
790 }
791 METHOD(crypto_factory_t, add_test_vector, void,
792 private_crypto_factory_t *this, transform_type_t type, void *vector)
793 {
794 switch (type)
795 {
796 case ENCRYPTION_ALGORITHM:
797 return this->tester->add_crypter_vector(this->tester, vector);
798 case AEAD_ALGORITHM:
799 return this->tester->add_aead_vector(this->tester, vector);
800 case INTEGRITY_ALGORITHM:
801 return this->tester->add_signer_vector(this->tester, vector);
802 case HASH_ALGORITHM:
803 return this->tester->add_hasher_vector(this->tester, vector);
804 case PSEUDO_RANDOM_FUNCTION:
805 return this->tester->add_prf_vector(this->tester, vector);
806 case RANDOM_NUMBER_GENERATOR:
807 return this->tester->add_rng_vector(this->tester, vector);
808 default:
809 DBG1(DBG_LIB, "%N test vectors not supported, ignored",
810 transform_type_names, type);
811 }
812 }
813
814 METHOD(crypto_factory_t, destroy, void,
815 private_crypto_factory_t *this)
816 {
817 this->crypters->destroy(this->crypters);
818 this->aeads->destroy(this->aeads);
819 this->signers->destroy(this->signers);
820 this->hashers->destroy(this->hashers);
821 this->prfs->destroy(this->prfs);
822 this->rngs->destroy(this->rngs);
823 this->dhs->destroy(this->dhs);
824 this->tester->destroy(this->tester);
825 this->lock->destroy(this->lock);
826 free(this);
827 }
828
829 /*
830 * see header file
831 */
832 crypto_factory_t *crypto_factory_create()
833 {
834 private_crypto_factory_t *this;
835
836 INIT(this,
837 .public = {
838 .create_crypter = _create_crypter,
839 .create_aead = _create_aead,
840 .create_signer = _create_signer,
841 .create_hasher = _create_hasher,
842 .create_prf = _create_prf,
843 .create_rng = _create_rng,
844 .create_dh = _create_dh,
845 .add_crypter = _add_crypter,
846 .remove_crypter = _remove_crypter,
847 .add_aead = _add_aead,
848 .remove_aead = _remove_aead,
849 .add_signer = _add_signer,
850 .remove_signer = _remove_signer,
851 .add_hasher = _add_hasher,
852 .remove_hasher = _remove_hasher,
853 .add_prf = _add_prf,
854 .remove_prf = _remove_prf,
855 .add_rng = _add_rng,
856 .remove_rng = _remove_rng,
857 .add_dh = _add_dh,
858 .remove_dh = _remove_dh,
859 .create_crypter_enumerator = _create_crypter_enumerator,
860 .create_aead_enumerator = _create_aead_enumerator,
861 .create_signer_enumerator = _create_signer_enumerator,
862 .create_hasher_enumerator = _create_hasher_enumerator,
863 .create_prf_enumerator = _create_prf_enumerator,
864 .create_dh_enumerator = _create_dh_enumerator,
865 .create_rng_enumerator = _create_rng_enumerator,
866 .add_test_vector = _add_test_vector,
867 .destroy = _destroy,
868 },
869 .crypters = linked_list_create(),
870 .aeads = linked_list_create(),
871 .signers = linked_list_create(),
872 .hashers = linked_list_create(),
873 .prfs = linked_list_create(),
874 .rngs = linked_list_create(),
875 .dhs = linked_list_create(),
876 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
877 .tester = crypto_tester_create(),
878 .test_on_add = lib->settings->get_bool(lib->settings,
879 "libstrongswan.crypto_test.on_add", FALSE),
880 .test_on_create = lib->settings->get_bool(lib->settings,
881 "libstrongswan.crypto_test.on_create", FALSE),
882 .bench = lib->settings->get_bool(lib->settings,
883 "libstrongswan.crypto_test.bench", FALSE),
884 );
885
886 return &this->public;
887 }
888