File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / crypto_factory.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 2 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2013-2014 Tobias Brunner
    3:  * Copyright (C) 2008 Martin Willi
    4:  * Copyright (C) 2016-2019 Andreas Steffen
    5:  * HSR Hochschule fuer Technik Rapperswil
    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: #include "crypto_factory.h"
   19: 
   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>
   25: 
   26: const char *default_plugin_name = "default";
   27: 
   28: typedef struct entry_t entry_t;
   29: 
   30: struct entry_t {
   31: 	/**
   32: 	 * algorithm
   33: 	 */
   34: 	u_int algo;
   35: 
   36: 	/**
   37: 	 * plugin that registered this algorithm
   38: 	 */
   39: 	const char *plugin_name;
   40: 
   41: 	/**
   42: 	 * benchmarked speed
   43: 	 */
   44: 	u_int speed;
   45: 
   46: 	/**
   47: 	 * constructor
   48: 	 */
   49: 	union {
   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: 		drbg_constructor_t create_drbg;
   57: 		rng_constructor_t create_rng;
   58: 		nonce_gen_constructor_t create_nonce_gen;
   59: 		dh_constructor_t create_dh;
   60: 		void *create;
   61: 	};
   62: };
   63: 
   64: typedef struct private_crypto_factory_t private_crypto_factory_t;
   65: 
   66: /**
   67:  * private data of crypto_factory
   68:  */
   69: struct private_crypto_factory_t {
   70: 
   71: 	/**
   72: 	 * public functions
   73: 	 */
   74: 	crypto_factory_t public;
   75: 
   76: 	/**
   77: 	 * registered crypters, as entry_t
   78: 	 */
   79: 	linked_list_t *crypters;
   80: 
   81: 	/**
   82: 	 * registered aead transforms, as entry_t
   83: 	 */
   84: 	linked_list_t *aeads;
   85: 
   86: 	/**
   87: 	 * registered signers, as entry_t
   88: 	 */
   89: 	linked_list_t *signers;
   90: 
   91: 	/**
   92: 	 * registered hashers, as entry_t
   93: 	 */
   94: 	linked_list_t *hashers;
   95: 
   96: 	/**
   97: 	 * registered prfs, as entry_t
   98: 	 */
   99: 	linked_list_t *prfs;
  100: 
  101: 	/**
  102: 	 * registered xofs, as entry_t
  103: 	 */
  104: 	linked_list_t *xofs;
  105: 
  106: 	/**
  107: 	 * registered drbgs, as entry_t
  108: 	 */
  109: 	linked_list_t *drbgs;
  110: 
  111: 	/**
  112: 	 * registered rngs, as entry_t
  113: 	 */
  114: 	linked_list_t *rngs;
  115: 
  116: 	/**
  117: 	 * registered nonce generators, as entry_t
  118: 	 */
  119: 	linked_list_t *nonce_gens;
  120: 
  121: 	/**
  122: 	 * registered diffie hellman, as entry_t
  123: 	 */
  124: 	linked_list_t *dhs;
  125: 
  126: 	/**
  127: 	 * test manager to test crypto algorithms
  128: 	 */
  129: 	crypto_tester_t *tester;
  130: 
  131: 	/**
  132: 	 * whether to test algorithms during registration
  133: 	 */
  134: 	bool test_on_add;
  135: 
  136: 	/**
  137: 	 * whether to test algorithms on each crypto primitive construction
  138: 	 */
  139: 	bool test_on_create;
  140: 
  141: 	/**
  142: 	 * run algorithm benchmark during registration
  143: 	 */
  144: 	bool bench;
  145: 
  146: 	/**
  147: 	 * Number of failed test vectors during "add".
  148: 	 */
  149: 	u_int test_failures;
  150: 
  151: 	/**
  152: 	 * rwlock to lock access to modules
  153: 	 */
  154: 	rwlock_t *lock;
  155: };
  156: 
  157: METHOD(crypto_factory_t, create_crypter, crypter_t*,
  158: 	private_crypto_factory_t *this, encryption_algorithm_t algo,
  159: 	size_t key_size)
  160: {
  161: 	enumerator_t *enumerator;
  162: 	entry_t *entry;
  163: 	crypter_t *crypter = NULL;
  164: 
  165: 	this->lock->read_lock(this->lock);
  166: 	enumerator = this->crypters->create_enumerator(this->crypters);
  167: 	while (enumerator->enumerate(enumerator, &entry))
  168: 	{
  169: 		if (entry->algo == algo)
  170: 		{
  171: 			if (this->test_on_create &&
  172: 				!this->tester->test_crypter(this->tester, algo, key_size,
  173: 											entry->create_crypter, NULL,
  174: 											default_plugin_name))
  175: 			{
  176: 				continue;
  177: 			}
  178: 			crypter = entry->create_crypter(algo, key_size);
  179: 			if (crypter)
  180: 			{
  181: 				break;
  182: 			}
  183: 		}
  184: 	}
  185: 	enumerator->destroy(enumerator);
  186: 	this->lock->unlock(this->lock);
  187: 	return crypter;
  188: }
  189: 
  190: METHOD(crypto_factory_t, create_aead, aead_t*,
  191: 	private_crypto_factory_t *this, encryption_algorithm_t algo,
  192: 	size_t key_size, size_t salt_size)
  193: {
  194: 	enumerator_t *enumerator;
  195: 	entry_t *entry;
  196: 	aead_t *aead = NULL;
  197: 
  198: 	this->lock->read_lock(this->lock);
  199: 	enumerator = this->aeads->create_enumerator(this->aeads);
  200: 	while (enumerator->enumerate(enumerator, &entry))
  201: 	{
  202: 		if (entry->algo == algo)
  203: 		{
  204: 			if (this->test_on_create &&
  205: 				!this->tester->test_aead(this->tester, algo, key_size,
  206: 										 salt_size, entry->create_aead, NULL,
  207: 										 default_plugin_name))
  208: 			{
  209: 				continue;
  210: 			}
  211: 			aead = entry->create_aead(algo, key_size, salt_size);
  212: 			if (aead)
  213: 			{
  214: 				break;
  215: 			}
  216: 		}
  217: 	}
  218: 	enumerator->destroy(enumerator);
  219: 	this->lock->unlock(this->lock);
  220: 	return aead;
  221: }
  222: 
  223: METHOD(crypto_factory_t, create_signer, signer_t*,
  224: 	private_crypto_factory_t *this, integrity_algorithm_t algo)
  225: {
  226: 	enumerator_t *enumerator;
  227: 	entry_t *entry;
  228: 	signer_t *signer = NULL;
  229: 
  230: 	this->lock->read_lock(this->lock);
  231: 	enumerator = this->signers->create_enumerator(this->signers);
  232: 	while (enumerator->enumerate(enumerator, &entry))
  233: 	{
  234: 		if (entry->algo == algo)
  235: 		{
  236: 			if (this->test_on_create &&
  237: 				!this->tester->test_signer(this->tester, algo,
  238: 										   entry->create_signer, NULL,
  239: 										   default_plugin_name))
  240: 			{
  241: 				continue;
  242: 			}
  243: 			signer = entry->create_signer(algo);
  244: 			if (signer)
  245: 			{
  246: 				break;
  247: 			}
  248: 		}
  249: 	}
  250: 	enumerator->destroy(enumerator);
  251: 	this->lock->unlock(this->lock);
  252: 	return signer;
  253: }
  254: 
  255: METHOD(crypto_factory_t, create_hasher, hasher_t*,
  256: 	private_crypto_factory_t *this, hash_algorithm_t algo)
  257: {
  258: 	enumerator_t *enumerator;
  259: 	entry_t *entry;
  260: 	hasher_t *hasher = NULL;
  261: 
  262: 	this->lock->read_lock(this->lock);
  263: 	enumerator = this->hashers->create_enumerator(this->hashers);
  264: 	while (enumerator->enumerate(enumerator, &entry))
  265: 	{
  266: 		if (entry->algo == algo)
  267: 		{
  268: 			if (this->test_on_create &&
  269: 				!this->tester->test_hasher(this->tester, algo,
  270: 										   entry->create_hasher, NULL,
  271: 										   default_plugin_name))
  272: 			{
  273: 				continue;
  274: 			}
  275: 			hasher = entry->create_hasher(entry->algo);
  276: 			if (hasher)
  277: 			{
  278: 				break;
  279: 			}
  280: 		}
  281: 	}
  282: 	enumerator->destroy(enumerator);
  283: 	this->lock->unlock(this->lock);
  284: 	return hasher;
  285: }
  286: 
  287: METHOD(crypto_factory_t, create_prf, prf_t*,
  288: 	private_crypto_factory_t *this, pseudo_random_function_t algo)
  289: {
  290: 	enumerator_t *enumerator;
  291: 	entry_t *entry;
  292: 	prf_t *prf = NULL;
  293: 
  294: 	this->lock->read_lock(this->lock);
  295: 	enumerator = this->prfs->create_enumerator(this->prfs);
  296: 	while (enumerator->enumerate(enumerator, &entry))
  297: 	{
  298: 		if (entry->algo == algo)
  299: 		{
  300: 			if (this->test_on_create &&
  301: 				!this->tester->test_prf(this->tester, algo,
  302: 										entry->create_prf, NULL,
  303: 										default_plugin_name))
  304: 			{
  305: 				continue;
  306: 			}
  307: 			prf = entry->create_prf(algo);
  308: 			if (prf)
  309: 			{
  310: 				break;
  311: 			}
  312: 		}
  313: 	}
  314: 	enumerator->destroy(enumerator);
  315: 	this->lock->unlock(this->lock);
  316: 	return prf;
  317: }
  318: 
  319: METHOD(crypto_factory_t, create_xof, xof_t*,
  320: 	private_crypto_factory_t *this, ext_out_function_t algo)
  321: {
  322: 	enumerator_t *enumerator;
  323: 	entry_t *entry;
  324: 	xof_t *xof = NULL;
  325: 
  326: 	this->lock->read_lock(this->lock);
  327: 	enumerator = this->xofs->create_enumerator(this->xofs);
  328: 	while (enumerator->enumerate(enumerator, &entry))
  329: 	{
  330: 		if (entry->algo == algo)
  331: 		{
  332: 			if (this->test_on_create &&
  333: 				!this->tester->test_xof(this->tester, algo,
  334: 										entry->create_xof, NULL,
  335: 										default_plugin_name))
  336: 			{
  337: 				continue;
  338: 			}
  339: 			xof = entry->create_xof(algo);
  340: 			if (xof)
  341: 			{
  342: 				break;
  343: 			}
  344: 		}
  345: 	}
  346: 	enumerator->destroy(enumerator);
  347: 	this->lock->unlock(this->lock);
  348: 	return xof;
  349: }
  350: 
  351: METHOD(crypto_factory_t, create_drbg, drbg_t*,
  352: 	private_crypto_factory_t *this, drbg_type_t type, uint32_t strength,
  353: 	rng_t *entropy, chunk_t personalization_str)
  354: {
  355: 	enumerator_t *enumerator;
  356: 	entry_t *entry;
  357: 	drbg_t *drbg = NULL;
  358: 
  359: 	this->lock->read_lock(this->lock);
  360: 	enumerator = this->drbgs->create_enumerator(this->drbgs);
  361: 	while (enumerator->enumerate(enumerator, &entry))
  362: 	{
  363: 		if (entry->algo == type)
  364: 		{
  365: 			if (this->test_on_create &&
  366: 				!this->tester->test_drbg(this->tester, type,
  367: 										 entry->create_drbg, NULL,
  368: 										 default_plugin_name))
  369: 			{
  370: 				continue;
  371: 			}
  372: 			drbg = entry->create_drbg(type, strength, entropy,
  373: 									  personalization_str);
  374: 			if (drbg)
  375: 			{
  376: 				break;
  377: 			}
  378: 		}
  379: 	}
  380: 	enumerator->destroy(enumerator);
  381: 	this->lock->unlock(this->lock);
  382: 	return drbg;
  383: }
  384: 
  385: METHOD(crypto_factory_t, create_rng, rng_t*,
  386: 	private_crypto_factory_t *this, rng_quality_t quality)
  387: {
  388: 	enumerator_t *enumerator;
  389: 	entry_t *entry;
  390: 	rng_t *rng = NULL;
  391: 
  392: 	this->lock->read_lock(this->lock);
  393: 	enumerator = this->rngs->create_enumerator(this->rngs);
  394: 	while (enumerator->enumerate(enumerator, &entry))
  395: 	{	/* find the best matching quality, but at least as good as requested */
  396: 		if (entry->algo >= quality)
  397: 		{
  398: 			if (this->test_on_create &&
  399: 				!this->tester->test_rng(this->tester, quality,
  400: 										entry->create_rng, NULL,
  401: 										default_plugin_name))
  402: 			{
  403: 				continue;
  404: 			}
  405: 			rng = entry->create_rng(quality);
  406: 			if (rng)
  407: 			{
  408: 				break;
  409: 			}
  410: 		}
  411: 	}
  412: 	enumerator->destroy(enumerator);
  413: 	this->lock->unlock(this->lock);
  414: 	return rng;
  415: }
  416: 
  417: METHOD(crypto_factory_t, create_nonce_gen, nonce_gen_t*,
  418: 	private_crypto_factory_t *this)
  419: {
  420: 	enumerator_t *enumerator;
  421: 	entry_t *entry;
  422: 	nonce_gen_t *nonce_gen = NULL;
  423: 
  424: 	this->lock->read_lock(this->lock);
  425: 	enumerator = this->nonce_gens->create_enumerator(this->nonce_gens);
  426: 	while (enumerator->enumerate(enumerator, &entry))
  427: 	{
  428: 		nonce_gen = entry->create_nonce_gen();
  429: 		if (nonce_gen)
  430: 		{
  431: 			break;
  432: 		}
  433: 	}
  434: 	enumerator->destroy(enumerator);
  435: 	this->lock->unlock(this->lock);
  436: 
  437: 	return nonce_gen;
  438: }
  439: 
  440: METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
  441: 	private_crypto_factory_t *this, diffie_hellman_group_t group, ...)
  442: {
  443: 	enumerator_t *enumerator;
  444: 	entry_t *entry;
  445: 	va_list args;
  446: 	chunk_t g = chunk_empty, p = chunk_empty;
  447: 	diffie_hellman_t *diffie_hellman = NULL;
  448: 
  449: 	if (group == MODP_CUSTOM)
  450: 	{
  451: 		va_start(args, group);
  452: 		g = va_arg(args, chunk_t);
  453: 		p = va_arg(args, chunk_t);
  454: 		va_end(args);
  455: 	}
  456: 
  457: 	this->lock->read_lock(this->lock);
  458: 	enumerator = this->dhs->create_enumerator(this->dhs);
  459: 	while (enumerator->enumerate(enumerator, &entry))
  460: 	{
  461: 		if (entry->algo == group)
  462: 		{
  463: 			if (this->test_on_create && group != MODP_CUSTOM &&
  464: 				!this->tester->test_dh(this->tester, group,
  465: 								entry->create_dh, NULL, default_plugin_name))
  466: 			{
  467: 				continue;
  468: 			}
  469: 			diffie_hellman = entry->create_dh(group, g, p);
  470: 			if (diffie_hellman)
  471: 			{
  472: 				break;
  473: 			}
  474: 		}
  475: 	}
  476: 	enumerator->destroy(enumerator);
  477: 	this->lock->unlock(this->lock);
  478: 	return diffie_hellman;
  479: }
  480: 
  481: /**
  482:  * Insert an algorithm entry to a list
  483:  *
  484:  * Entries maintain the order in which algorithms were added, unless they were
  485:  * benchmarked and speed is provided, which then is used to order entries of
  486:  * the same algorithm.
  487:  * An exception are RNG entries, which are sorted by algorithm identifier.
  488:  */
  489: static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
  490: 					  int algo, const char *plugin_name,
  491: 					  u_int speed, void *create)
  492: {
  493: 	enumerator_t *enumerator;
  494: 	entry_t *entry, *current;
  495: 	bool sort = (list == this->rngs), found = FALSE;
  496: 
  497: 	INIT(entry,
  498: 		.algo = algo,
  499: 		.plugin_name = plugin_name,
  500: 		.speed = speed,
  501: 	);
  502: 	entry->create = create;
  503: 
  504: 	this->lock->write_lock(this->lock);
  505: 	enumerator = list->create_enumerator(list);
  506: 	while (enumerator->enumerate(enumerator, &current))
  507: 	{
  508: 		if (sort && current->algo > algo)
  509: 		{
  510: 			break;
  511: 		}
  512: 		else if (current->algo == algo)
  513: 		{
  514: 			if (speed > current->speed)
  515: 			{
  516: 				break;
  517: 			}
  518: 			found = TRUE;
  519: 		}
  520: 		else if (found)
  521: 		{
  522: 			break;
  523: 		}
  524: 	}
  525: 	list->insert_before(list, enumerator, entry);
  526: 	enumerator->destroy(enumerator);
  527: 	this->lock->unlock(this->lock);
  528: }
  529: 
  530: METHOD(crypto_factory_t, add_crypter, bool,
  531: 	private_crypto_factory_t *this, encryption_algorithm_t algo, size_t key_size,
  532: 	const char *plugin_name, crypter_constructor_t create)
  533: {
  534: 	u_int speed = 0;
  535: 
  536: 	if (!this->test_on_add ||
  537: 		this->tester->test_crypter(this->tester, algo, key_size, create,
  538: 								   this->bench ? &speed : NULL, plugin_name))
  539: 	{
  540: 		add_entry(this, this->crypters, algo, plugin_name, speed, create);
  541: 		return TRUE;
  542: 	}
  543: 	this->test_failures++;
  544: 	return FALSE;
  545: }
  546: 
  547: METHOD(crypto_factory_t, remove_crypter, void,
  548: 	private_crypto_factory_t *this, crypter_constructor_t create)
  549: {
  550: 	entry_t *entry;
  551: 	enumerator_t *enumerator;
  552: 
  553: 	this->lock->write_lock(this->lock);
  554: 	enumerator = this->crypters->create_enumerator(this->crypters);
  555: 	while (enumerator->enumerate(enumerator, &entry))
  556: 	{
  557: 		if (entry->create_crypter == create)
  558: 		{
  559: 			this->crypters->remove_at(this->crypters, enumerator);
  560: 			free(entry);
  561: 		}
  562: 	}
  563: 	enumerator->destroy(enumerator);
  564: 	this->lock->unlock(this->lock);
  565: }
  566: 
  567: METHOD(crypto_factory_t, add_aead, bool,
  568: 	private_crypto_factory_t *this, encryption_algorithm_t algo, size_t key_size,
  569: 	const char *plugin_name, aead_constructor_t create)
  570: {
  571: 	u_int speed = 0;
  572: 
  573: 	if (!this->test_on_add ||
  574: 		this->tester->test_aead(this->tester, algo, key_size, 0, create,
  575: 								this->bench ? &speed : NULL, plugin_name))
  576: 	{
  577: 		add_entry(this, this->aeads, algo, plugin_name, speed, create);
  578: 		return TRUE;
  579: 	}
  580: 	this->test_failures++;
  581: 	return FALSE;
  582: }
  583: 
  584: METHOD(crypto_factory_t, remove_aead, void,
  585: 	private_crypto_factory_t *this, aead_constructor_t create)
  586: {
  587: 	entry_t *entry;
  588: 	enumerator_t *enumerator;
  589: 
  590: 	this->lock->write_lock(this->lock);
  591: 	enumerator = this->aeads->create_enumerator(this->aeads);
  592: 	while (enumerator->enumerate(enumerator, &entry))
  593: 	{
  594: 		if (entry->create_aead == create)
  595: 		{
  596: 			this->aeads->remove_at(this->aeads, enumerator);
  597: 			free(entry);
  598: 		}
  599: 	}
  600: 	enumerator->destroy(enumerator);
  601: 	this->lock->unlock(this->lock);
  602: }
  603: 
  604: METHOD(crypto_factory_t, add_signer, bool,
  605: 	private_crypto_factory_t *this, integrity_algorithm_t algo,
  606: 	const char *plugin_name, signer_constructor_t create)
  607: {
  608: 	u_int speed = 0;
  609: 
  610: 	if (!this->test_on_add ||
  611: 		this->tester->test_signer(this->tester, algo, create,
  612: 								  this->bench ? &speed : NULL, plugin_name))
  613: 	{
  614: 		add_entry(this, this->signers, algo, plugin_name, speed, create);
  615: 		return TRUE;
  616: 	}
  617: 	this->test_failures++;
  618: 	return FALSE;
  619: }
  620: 
  621: METHOD(crypto_factory_t, remove_signer, void,
  622: 	private_crypto_factory_t *this, signer_constructor_t create)
  623: {
  624: 	entry_t *entry;
  625: 	enumerator_t *enumerator;
  626: 
  627: 	this->lock->write_lock(this->lock);
  628: 	enumerator = this->signers->create_enumerator(this->signers);
  629: 	while (enumerator->enumerate(enumerator, &entry))
  630: 	{
  631: 		if (entry->create_signer == create)
  632: 		{
  633: 			this->signers->remove_at(this->signers, enumerator);
  634: 			free(entry);
  635: 		}
  636: 	}
  637: 	enumerator->destroy(enumerator);
  638: 	this->lock->unlock(this->lock);
  639: }
  640: 
  641: METHOD(crypto_factory_t, add_hasher, bool,
  642: 	private_crypto_factory_t *this, hash_algorithm_t algo,
  643: 	const char *plugin_name, hasher_constructor_t create)
  644: {
  645: 	u_int speed = 0;
  646: 
  647: 	if (!this->test_on_add ||
  648: 		this->tester->test_hasher(this->tester, algo, create,
  649: 								  this->bench ? &speed : NULL, plugin_name))
  650: 	{
  651: 		add_entry(this, this->hashers, algo, plugin_name, speed, create);
  652: 		return TRUE;
  653: 	}
  654: 	this->test_failures++;
  655: 	return FALSE;
  656: }
  657: 
  658: METHOD(crypto_factory_t, remove_hasher, void,
  659: 	private_crypto_factory_t *this, hasher_constructor_t create)
  660: {
  661: 	entry_t *entry;
  662: 	enumerator_t *enumerator;
  663: 
  664: 	this->lock->write_lock(this->lock);
  665: 	enumerator = this->hashers->create_enumerator(this->hashers);
  666: 	while (enumerator->enumerate(enumerator, &entry))
  667: 	{
  668: 		if (entry->create_hasher == create)
  669: 		{
  670: 			this->hashers->remove_at(this->hashers, enumerator);
  671: 			free(entry);
  672: 		}
  673: 	}
  674: 	enumerator->destroy(enumerator);
  675: 	this->lock->unlock(this->lock);
  676: }
  677: 
  678: METHOD(crypto_factory_t, add_prf, bool,
  679: 	private_crypto_factory_t *this, pseudo_random_function_t algo,
  680: 	const char *plugin_name, prf_constructor_t create)
  681: {
  682: 	u_int speed = 0;
  683: 
  684: 	if (!this->test_on_add ||
  685: 		this->tester->test_prf(this->tester, algo, create,
  686: 							   this->bench ? &speed : NULL, plugin_name))
  687: 	{
  688: 		add_entry(this, this->prfs, algo, plugin_name, speed, create);
  689: 		return TRUE;
  690: 	}
  691: 	this->test_failures++;
  692: 	return FALSE;
  693: }
  694: 
  695: METHOD(crypto_factory_t, remove_prf, void,
  696: 	private_crypto_factory_t *this, prf_constructor_t create)
  697: {
  698: 	entry_t *entry;
  699: 	enumerator_t *enumerator;
  700: 
  701: 	this->lock->write_lock(this->lock);
  702: 	enumerator = this->prfs->create_enumerator(this->prfs);
  703: 	while (enumerator->enumerate(enumerator, &entry))
  704: 	{
  705: 		if (entry->create_prf == create)
  706: 		{
  707: 			this->prfs->remove_at(this->prfs, enumerator);
  708: 			free(entry);
  709: 		}
  710: 	}
  711: 	enumerator->destroy(enumerator);
  712: 	this->lock->unlock(this->lock);
  713: }
  714: 
  715: METHOD(crypto_factory_t, add_xof, bool,
  716: 	private_crypto_factory_t *this, ext_out_function_t algo,
  717: 	const char *plugin_name, xof_constructor_t create)
  718: {
  719: 	u_int speed = 0;
  720: 
  721: 	if (!this->test_on_add ||
  722: 		this->tester->test_xof(this->tester, algo, create,
  723: 							   this->bench ? &speed : NULL, plugin_name))
  724: 	{
  725: 		add_entry(this, this->xofs, algo, plugin_name, speed, create);
  726: 		return TRUE;
  727: 	}
  728: 	this->test_failures++;
  729: 	return FALSE;
  730: }
  731: 
  732: METHOD(crypto_factory_t, remove_xof, void,
  733: 	private_crypto_factory_t *this, xof_constructor_t create)
  734: {
  735: 	entry_t *entry;
  736: 	enumerator_t *enumerator;
  737: 
  738: 	this->lock->write_lock(this->lock);
  739: 	enumerator = this->xofs->create_enumerator(this->xofs);
  740: 	while (enumerator->enumerate(enumerator, &entry))
  741: 	{
  742: 		if (entry->create_xof == create)
  743: 		{
  744: 			this->xofs->remove_at(this->xofs, enumerator);
  745: 			free(entry);
  746: 		}
  747: 	}
  748: 	enumerator->destroy(enumerator);
  749: 	this->lock->unlock(this->lock);
  750: }
  751: 
  752: METHOD(crypto_factory_t, add_drbg, bool,
  753: 	private_crypto_factory_t *this, drbg_type_t type,
  754: 	const char *plugin_name, drbg_constructor_t create)
  755: {
  756: 	u_int speed = 0;
  757: 
  758: 	if (!this->test_on_add ||
  759: 		this->tester->test_drbg(this->tester, type, create,
  760: 							   this->bench ? &speed : NULL, plugin_name))
  761: 	{
  762: 		add_entry(this, this->drbgs, type, plugin_name, speed, create);
  763: 		return TRUE;
  764: 	}
  765: 	this->test_failures++;
  766: 	return FALSE;
  767: }
  768: 
  769: METHOD(crypto_factory_t, remove_drbg, void,
  770: 	private_crypto_factory_t *this, drbg_constructor_t create)
  771: {
  772: 	entry_t *entry;
  773: 	enumerator_t *enumerator;
  774: 
  775: 	this->lock->write_lock(this->lock);
  776: 	enumerator = this->drbgs->create_enumerator(this->drbgs);
  777: 	while (enumerator->enumerate(enumerator, &entry))
  778: 	{
  779: 		if (entry->create_drbg == create)
  780: 		{
  781: 			this->drbgs->remove_at(this->drbgs, enumerator);
  782: 			free(entry);
  783: 		}
  784: 	}
  785: 	enumerator->destroy(enumerator);
  786: 	this->lock->unlock(this->lock);
  787: }
  788: 
  789: METHOD(crypto_factory_t, add_rng, bool,
  790: 	private_crypto_factory_t *this, rng_quality_t quality,
  791: 	const char *plugin_name, rng_constructor_t create)
  792: {
  793: 	u_int speed = 0;
  794: 
  795: 	if (!this->test_on_add ||
  796: 		this->tester->test_rng(this->tester, quality, create,
  797: 							   this->bench ? &speed : NULL, plugin_name))
  798: 	{
  799: 		add_entry(this, this->rngs, quality, plugin_name, speed, create);
  800: 		return TRUE;
  801: 	}
  802: 	this->test_failures++;
  803: 	return FALSE;
  804: }
  805: 
  806: METHOD(crypto_factory_t, remove_rng, void,
  807: 	private_crypto_factory_t *this, rng_constructor_t create)
  808: {
  809: 	entry_t *entry;
  810: 	enumerator_t *enumerator;
  811: 
  812: 	this->lock->write_lock(this->lock);
  813: 	enumerator = this->rngs->create_enumerator(this->rngs);
  814: 	while (enumerator->enumerate(enumerator, &entry))
  815: 	{
  816: 		if (entry->create_rng == create)
  817: 		{
  818: 			this->rngs->remove_at(this->rngs, enumerator);
  819: 			free(entry);
  820: 		}
  821: 	}
  822: 	enumerator->destroy(enumerator);
  823: 	this->lock->unlock(this->lock);
  824: }
  825: 
  826: METHOD(crypto_factory_t, add_nonce_gen, bool,
  827: 	private_crypto_factory_t *this, const char *plugin_name,
  828: 	nonce_gen_constructor_t create)
  829: {
  830: 	add_entry(this, this->nonce_gens, 0, plugin_name, 0, create);
  831: 	return TRUE;
  832: }
  833: 
  834: METHOD(crypto_factory_t, remove_nonce_gen, void,
  835: 	private_crypto_factory_t *this, nonce_gen_constructor_t create)
  836: {
  837: 	entry_t *entry;
  838: 	enumerator_t *enumerator;
  839: 
  840: 	this->lock->write_lock(this->lock);
  841: 	enumerator = this->nonce_gens->create_enumerator(this->nonce_gens);
  842: 	while (enumerator->enumerate(enumerator, &entry))
  843: 	{
  844: 		if (entry->create_nonce_gen == create)
  845: 		{
  846: 			this->nonce_gens->remove_at(this->nonce_gens, enumerator);
  847: 			free(entry);
  848: 		}
  849: 	}
  850: 	enumerator->destroy(enumerator);
  851: 	this->lock->unlock(this->lock);
  852: }
  853: 
  854: METHOD(crypto_factory_t, add_dh, bool,
  855: 	private_crypto_factory_t *this, diffie_hellman_group_t group,
  856: 	const char *plugin_name, dh_constructor_t create)
  857: {
  858: 	u_int speed = 0;
  859: 
  860: 	if (!this->test_on_add ||
  861: 		this->tester->test_dh(this->tester, group, create,
  862: 							  this->bench ? &speed : NULL, plugin_name))
  863: 	{
  864: 		add_entry(this, this->dhs, group, plugin_name, 0, create);
  865: 		return TRUE;
  866: 	}
  867: 	this->test_failures++;
  868: 	return FALSE;
  869: }
  870: 
  871: METHOD(crypto_factory_t, remove_dh, void,
  872: 	private_crypto_factory_t *this, dh_constructor_t create)
  873: {
  874: 	entry_t *entry;
  875: 	enumerator_t *enumerator;
  876: 
  877: 	this->lock->write_lock(this->lock);
  878: 	enumerator = this->dhs->create_enumerator(this->dhs);
  879: 	while (enumerator->enumerate(enumerator, &entry))
  880: 	{
  881: 		if (entry->create_dh == create)
  882: 		{
  883: 			this->dhs->remove_at(this->dhs, enumerator);
  884: 			free(entry);
  885: 		}
  886: 	}
  887: 	enumerator->destroy(enumerator);
  888: 	this->lock->unlock(this->lock);
  889: }
  890: 
  891: CALLBACK(entry_match, bool,
  892: 	entry_t *a, va_list args)
  893: {
  894: 	entry_t *b;
  895: 
  896: 	VA_ARGS_VGET(args, b);
  897: 	return a->algo == b->algo;
  898: }
  899: 
  900: CALLBACK(unique_check, bool,
  901: 	linked_list_t *list, enumerator_t *orig, va_list args)
  902: {
  903: 	entry_t *entry, **out;
  904: 
  905: 	VA_ARGS_VGET(args, out);
  906: 
  907: 	while (orig->enumerate(orig, &entry))
  908: 	{
  909: 		if (list->find_first(list, entry_match, NULL, entry))
  910: 		{
  911: 			continue;
  912: 		}
  913: 		*out = entry;
  914: 		list->insert_last(list, entry);
  915: 		return TRUE;
  916: 	}
  917: 	return FALSE;
  918: }
  919: 
  920: /**
  921:  * create an enumerator over entry->algo in list with locking and unique check
  922:  */
  923: static enumerator_t *create_enumerator(private_crypto_factory_t *this,
  924: 									linked_list_t *list,
  925: 									bool (*filter)(void*,enumerator_t*,va_list))
  926: {
  927: 	this->lock->read_lock(this->lock);
  928: 	return enumerator_create_filter(
  929: 				enumerator_create_filter(
  930: 					list->create_enumerator(list), unique_check,
  931: 					linked_list_create(), (void*)list->destroy),
  932: 				filter,	this->lock, (void*)this->lock->unlock);
  933: }
  934: 
  935: CALLBACK(crypter_filter, bool,
  936: 	void *n, enumerator_t *orig, va_list args)
  937: {
  938: 	entry_t *entry;
  939: 	encryption_algorithm_t *algo;
  940: 	const char **plugin_name;
  941: 
  942: 	VA_ARGS_VGET(args, algo, plugin_name);
  943: 
  944: 	if (orig->enumerate(orig, &entry))
  945: 	{
  946: 		*algo = entry->algo;
  947: 		*plugin_name = entry->plugin_name;
  948: 		return TRUE;
  949: 	}
  950: 	return FALSE;
  951: }
  952: 
  953: METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
  954: 	private_crypto_factory_t *this)
  955: {
  956: 	return create_enumerator(this, this->crypters, crypter_filter);
  957: }
  958: 
  959: METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
  960: 	private_crypto_factory_t *this)
  961: {
  962: 	return create_enumerator(this, this->aeads, crypter_filter);
  963: }
  964: 
  965: CALLBACK(signer_filter, bool,
  966: 	void *n, enumerator_t *orig, va_list args)
  967: {
  968: 	entry_t *entry;
  969: 	integrity_algorithm_t *algo;
  970: 	const char **plugin_name;
  971: 
  972: 	VA_ARGS_VGET(args, algo, plugin_name);
  973: 
  974: 	if (orig->enumerate(orig, &entry))
  975: 	{
  976: 		*algo = entry->algo;
  977: 		*plugin_name = entry->plugin_name;
  978: 		return TRUE;
  979: 	}
  980: 	return FALSE;
  981: }
  982: 
  983: METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
  984: 	private_crypto_factory_t *this)
  985: {
  986: 	return create_enumerator(this, this->signers, signer_filter);
  987: }
  988: 
  989: CALLBACK(hasher_filter, bool,
  990: 	void *n, enumerator_t *orig, va_list args)
  991: {
  992: 	entry_t *entry;
  993: 	hash_algorithm_t *algo;
  994: 	const char **plugin_name;
  995: 
  996: 	VA_ARGS_VGET(args, algo, plugin_name);
  997: 
  998: 	if (orig->enumerate(orig, &entry))
  999: 	{
 1000: 		*algo = entry->algo;
 1001: 		*plugin_name = entry->plugin_name;
 1002: 		return TRUE;
 1003: 	}
 1004: 	return FALSE;
 1005: }
 1006: 
 1007: METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
 1008: 	private_crypto_factory_t *this)
 1009: {
 1010: 	return create_enumerator(this, this->hashers, hasher_filter);
 1011: }
 1012: 
 1013: CALLBACK(prf_filter, bool,
 1014: 	void *n, enumerator_t *orig, va_list args)
 1015: {
 1016: 	entry_t *entry;
 1017: 	pseudo_random_function_t *algo;
 1018: 	const char **plugin_name;
 1019: 
 1020: 	VA_ARGS_VGET(args, algo, plugin_name);
 1021: 
 1022: 	if (orig->enumerate(orig, &entry))
 1023: 	{
 1024: 		*algo = entry->algo;
 1025: 		*plugin_name = entry->plugin_name;
 1026: 		return TRUE;
 1027: 	}
 1028: 	return FALSE;
 1029: }
 1030: 
 1031: METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
 1032: 	private_crypto_factory_t *this)
 1033: {
 1034: 	return create_enumerator(this, this->prfs, prf_filter);
 1035: }
 1036: 
 1037: CALLBACK(xof_filter, bool,
 1038: 	void *n, enumerator_t *orig, va_list args)
 1039: {
 1040: 	entry_t *entry;
 1041: 	ext_out_function_t *algo;
 1042: 	const char **plugin_name;
 1043: 
 1044: 	VA_ARGS_VGET(args, algo, plugin_name);
 1045: 
 1046: 	if (orig->enumerate(orig, &entry))
 1047: 	{
 1048: 		*algo = entry->algo;
 1049: 		*plugin_name = entry->plugin_name;
 1050: 		return TRUE;
 1051: 	}
 1052: 	return FALSE;
 1053: }
 1054: 
 1055: METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
 1056: 	private_crypto_factory_t *this)
 1057: {
 1058: 	return create_enumerator(this, this->xofs, xof_filter);
 1059: }
 1060: 
 1061: CALLBACK(drbg_filter, bool,
 1062: 	void *n, enumerator_t *orig, va_list args)
 1063: {
 1064: 	entry_t *entry;
 1065: 	drbg_type_t *type;
 1066: 	const char **plugin_name;
 1067: 
 1068: 	VA_ARGS_VGET(args, type, plugin_name);
 1069: 
 1070: 	if (orig->enumerate(orig, &entry))
 1071: 	{
 1072: 		*type = entry->algo;
 1073: 		*plugin_name = entry->plugin_name;
 1074: 		return TRUE;
 1075: 	}
 1076: 	return FALSE;
 1077: }
 1078: 
 1079: METHOD(crypto_factory_t, create_drbg_enumerator, enumerator_t*,
 1080: 	private_crypto_factory_t *this)
 1081: {
 1082: 	return create_enumerator(this, this->drbgs, drbg_filter);
 1083: }
 1084: 
 1085: CALLBACK(dh_filter, bool,
 1086: 	void *n, enumerator_t *orig, va_list args)
 1087: {
 1088: 	entry_t *entry;
 1089: 	diffie_hellman_group_t *algo;
 1090: 	const char **plugin_name;
 1091: 
 1092: 	VA_ARGS_VGET(args, algo, plugin_name);
 1093: 
 1094: 	if (orig->enumerate(orig, &entry))
 1095: 	{
 1096: 		*algo = entry->algo;
 1097: 		*plugin_name = entry->plugin_name;
 1098: 		return TRUE;
 1099: 	}
 1100: 	return FALSE;
 1101: }
 1102: 
 1103: METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
 1104: 	private_crypto_factory_t *this)
 1105: {
 1106: 	return create_enumerator(this, this->dhs, dh_filter);
 1107: }
 1108: 
 1109: CALLBACK(rng_filter, bool,
 1110: 	void *n, enumerator_t *orig, va_list args)
 1111: {
 1112: 	entry_t *entry;
 1113: 	rng_quality_t *algo;
 1114: 	const char **plugin_name;
 1115: 
 1116: 	VA_ARGS_VGET(args, algo, plugin_name);
 1117: 
 1118: 	if (orig->enumerate(orig, &entry))
 1119: 	{
 1120: 		*algo = entry->algo;
 1121: 		*plugin_name = entry->plugin_name;
 1122: 		return TRUE;
 1123: 	}
 1124: 	return FALSE;
 1125: }
 1126: 
 1127: METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*,
 1128: 	private_crypto_factory_t *this)
 1129: {
 1130: 	return create_enumerator(this, this->rngs, rng_filter);
 1131: }
 1132: 
 1133: CALLBACK(nonce_gen_filter, bool,
 1134: 	void *n, enumerator_t *orig, va_list args)
 1135: {
 1136: 	entry_t *entry;
 1137: 	const char **plugin_name;
 1138: 
 1139: 	VA_ARGS_VGET(args, plugin_name);
 1140: 
 1141: 	if (orig->enumerate(orig, &entry))
 1142: 	{
 1143: 		*plugin_name = entry->plugin_name;
 1144: 		return TRUE;
 1145: 	}
 1146: 	return FALSE;
 1147: }
 1148: 
 1149: METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*,
 1150: 	private_crypto_factory_t *this)
 1151: {
 1152: 	return create_enumerator(this, this->nonce_gens, nonce_gen_filter);
 1153: }
 1154: 
 1155: METHOD(crypto_factory_t, add_test_vector, void,
 1156: 	private_crypto_factory_t *this, transform_type_t type, void *vector)
 1157: {
 1158: 	switch (type)
 1159: 	{
 1160: 		case ENCRYPTION_ALGORITHM:
 1161: 			return this->tester->add_crypter_vector(this->tester, vector);
 1162: 		case AEAD_ALGORITHM:
 1163: 			return this->tester->add_aead_vector(this->tester, vector);
 1164: 		case INTEGRITY_ALGORITHM:
 1165: 			return this->tester->add_signer_vector(this->tester, vector);
 1166: 		case HASH_ALGORITHM:
 1167: 			return this->tester->add_hasher_vector(this->tester, vector);
 1168: 		case PSEUDO_RANDOM_FUNCTION:
 1169: 			return this->tester->add_prf_vector(this->tester, vector);
 1170: 		case EXTENDED_OUTPUT_FUNCTION:
 1171: 			return this->tester->add_xof_vector(this->tester, vector);
 1172: 		case DETERMINISTIC_RANDOM_BIT_GENERATOR:
 1173: 			return this->tester->add_drbg_vector(this->tester, vector);
 1174: 		case RANDOM_NUMBER_GENERATOR:
 1175: 			return this->tester->add_rng_vector(this->tester, vector);
 1176: 		case DIFFIE_HELLMAN_GROUP:
 1177: 			return this->tester->add_dh_vector(this->tester, vector);
 1178: 		default:
 1179: 			DBG1(DBG_LIB, "%N test vectors not supported, ignored",
 1180: 				 transform_type_names, type);
 1181: 	}
 1182: }
 1183: 
 1184: /**
 1185:  * Private enumerator for create_verify_enumerator()
 1186:  */
 1187: typedef struct {
 1188: 	enumerator_t public;
 1189: 	enumerator_t *inner;
 1190: 	transform_type_t type;
 1191: 	crypto_tester_t *tester;
 1192: 	rwlock_t *lock;
 1193: } verify_enumerator_t;
 1194: 
 1195: METHOD(enumerator_t, verify_enumerate, bool,
 1196: 	verify_enumerator_t *this, va_list args)
 1197: {
 1198: 	const char **plugin;
 1199: 	entry_t *entry;
 1200: 	u_int *alg;
 1201: 	bool *valid;
 1202: 
 1203: 	VA_ARGS_VGET(args, alg, plugin, valid);
 1204: 
 1205: 	if (!this->inner->enumerate(this->inner, &entry))
 1206: 	{
 1207: 		return FALSE;
 1208: 	}
 1209: 	switch (this->type)
 1210: 	{
 1211: 		case ENCRYPTION_ALGORITHM:
 1212: 			*valid = this->tester->test_crypter(this->tester, entry->algo, 0,
 1213: 							entry->create_crypter, NULL, entry->plugin_name);
 1214: 			break;
 1215: 		case AEAD_ALGORITHM:
 1216: 			*valid = this->tester->test_aead(this->tester, entry->algo, 0, 0,
 1217: 							entry->create_aead, NULL, entry->plugin_name);
 1218: 			break;
 1219: 		case INTEGRITY_ALGORITHM:
 1220: 			*valid = this->tester->test_signer(this->tester, entry->algo,
 1221: 							entry->create_signer, NULL, entry->plugin_name);
 1222: 			break;
 1223: 		case HASH_ALGORITHM:
 1224: 			*valid = this->tester->test_hasher(this->tester, entry->algo,
 1225: 							entry->create_hasher, NULL, entry->plugin_name);
 1226: 			break;
 1227: 		case PSEUDO_RANDOM_FUNCTION:
 1228: 			*valid = this->tester->test_prf(this->tester, entry->algo,
 1229: 							entry->create_prf, NULL, entry->plugin_name);
 1230: 			break;
 1231: 		case EXTENDED_OUTPUT_FUNCTION:
 1232: 			*valid = this->tester->test_xof(this->tester, entry->algo,
 1233: 							entry->create_xof, NULL, entry->plugin_name);
 1234: 			break;
 1235: 		case DETERMINISTIC_RANDOM_BIT_GENERATOR:
 1236: 			*valid = this->tester->test_drbg(this->tester, entry->algo,
 1237: 							entry->create_drbg, NULL, entry->plugin_name);
 1238: 			break;
 1239: 		case RANDOM_NUMBER_GENERATOR:
 1240: 			*valid = this->tester->test_rng(this->tester, entry->algo,
 1241: 							entry->create_rng, NULL, entry->plugin_name);
 1242: 			break;
 1243: 		case DIFFIE_HELLMAN_GROUP:
 1244: 			*valid = this->tester->test_dh(this->tester, entry->algo,
 1245: 							entry->create_dh, NULL, entry->plugin_name);
 1246: 			break;
 1247: 		default:
 1248: 			return FALSE;
 1249: 	}
 1250: 	*plugin = entry->plugin_name;
 1251: 	*alg = entry->algo;
 1252: 	return TRUE;
 1253: }
 1254: 
 1255: METHOD(enumerator_t, verify_destroy, void,
 1256: 	verify_enumerator_t *this)
 1257: {
 1258: 	this->inner->destroy(this->inner);
 1259: 	this->lock->unlock(this->lock);
 1260: 	free(this);
 1261: }
 1262: 
 1263: METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*,
 1264: 	private_crypto_factory_t *this, transform_type_t type)
 1265: {
 1266: 	verify_enumerator_t *enumerator;
 1267: 	enumerator_t *inner;
 1268: 
 1269: 	this->lock->read_lock(this->lock);
 1270: 	switch (type)
 1271: 	{
 1272: 		case ENCRYPTION_ALGORITHM:
 1273: 			inner = this->crypters->create_enumerator(this->crypters);
 1274: 			break;
 1275: 		case AEAD_ALGORITHM:
 1276: 			inner = this->aeads->create_enumerator(this->aeads);
 1277: 			break;
 1278: 		case INTEGRITY_ALGORITHM:
 1279: 			inner = this->signers->create_enumerator(this->signers);
 1280: 			break;
 1281: 		case HASH_ALGORITHM:
 1282: 			inner = this->hashers->create_enumerator(this->hashers);
 1283: 			break;
 1284: 		case PSEUDO_RANDOM_FUNCTION:
 1285: 			inner = this->prfs->create_enumerator(this->prfs);
 1286: 			break;
 1287: 		case EXTENDED_OUTPUT_FUNCTION:
 1288: 			inner = this->xofs->create_enumerator(this->xofs);
 1289: 			break;
 1290: 		case DETERMINISTIC_RANDOM_BIT_GENERATOR:
 1291: 			inner = this->drbgs->create_enumerator(this->drbgs);
 1292: 			break;
 1293: 		case RANDOM_NUMBER_GENERATOR:
 1294: 			inner = this->rngs->create_enumerator(this->rngs);
 1295: 			break;
 1296: 		case DIFFIE_HELLMAN_GROUP:
 1297: 			inner = this->dhs->create_enumerator(this->dhs);
 1298: 			break;
 1299: 		default:
 1300: 			this->lock->unlock(this->lock);
 1301: 			return enumerator_create_empty();
 1302: 	}
 1303: 	INIT(enumerator,
 1304: 		.public = {
 1305: 			.enumerate = enumerator_enumerate_default,
 1306: 			.venumerate = _verify_enumerate,
 1307: 			.destroy = _verify_destroy,
 1308: 		},
 1309: 		.inner = inner,
 1310: 		.type = type,
 1311: 		.tester = this->tester,
 1312: 		.lock = this->lock,
 1313: 	);
 1314: 	return &enumerator->public;
 1315: }
 1316: 
 1317: METHOD(crypto_factory_t, destroy, void,
 1318: 	private_crypto_factory_t *this)
 1319: {
 1320: 	this->crypters->destroy(this->crypters);
 1321: 	this->aeads->destroy(this->aeads);
 1322: 	this->signers->destroy(this->signers);
 1323: 	this->hashers->destroy(this->hashers);
 1324: 	this->prfs->destroy(this->prfs);
 1325: 	this->xofs->destroy(this->xofs);
 1326: 	this->drbgs->destroy(this->drbgs);
 1327: 	this->rngs->destroy(this->rngs);
 1328: 	this->nonce_gens->destroy(this->nonce_gens);
 1329: 	this->dhs->destroy(this->dhs);
 1330: 	this->tester->destroy(this->tester);
 1331: 	this->lock->destroy(this->lock);
 1332: 	free(this);
 1333: }
 1334: 
 1335: /*
 1336:  * see header file
 1337:  */
 1338: crypto_factory_t *crypto_factory_create()
 1339: {
 1340: 	private_crypto_factory_t *this;
 1341: 
 1342: 	INIT(this,
 1343: 		.public = {
 1344: 			.create_crypter = _create_crypter,
 1345: 			.create_aead = _create_aead,
 1346: 			.create_signer = _create_signer,
 1347: 			.create_hasher = _create_hasher,
 1348: 			.create_prf = _create_prf,
 1349: 			.create_xof = _create_xof,
 1350: 			.create_drbg = _create_drbg,
 1351: 			.create_rng = _create_rng,
 1352: 			.create_nonce_gen = _create_nonce_gen,
 1353: 			.create_dh = _create_dh,
 1354: 			.add_crypter = _add_crypter,
 1355: 			.remove_crypter = _remove_crypter,
 1356: 			.add_aead = _add_aead,
 1357: 			.remove_aead = _remove_aead,
 1358: 			.add_signer = _add_signer,
 1359: 			.remove_signer = _remove_signer,
 1360: 			.add_hasher = _add_hasher,
 1361: 			.remove_hasher = _remove_hasher,
 1362: 			.add_prf = _add_prf,
 1363: 			.remove_prf = _remove_prf,
 1364: 			.add_xof = _add_xof,
 1365: 			.remove_xof = _remove_xof,
 1366: 			.add_drbg = _add_drbg,
 1367: 			.remove_drbg = _remove_drbg,
 1368: 			.add_rng = _add_rng,
 1369: 			.remove_rng = _remove_rng,
 1370: 			.add_nonce_gen = _add_nonce_gen,
 1371: 			.remove_nonce_gen = _remove_nonce_gen,
 1372: 			.add_dh = _add_dh,
 1373: 			.remove_dh = _remove_dh,
 1374: 			.create_crypter_enumerator = _create_crypter_enumerator,
 1375: 			.create_aead_enumerator = _create_aead_enumerator,
 1376: 			.create_signer_enumerator = _create_signer_enumerator,
 1377: 			.create_hasher_enumerator = _create_hasher_enumerator,
 1378: 			.create_prf_enumerator = _create_prf_enumerator,
 1379: 			.create_xof_enumerator = _create_xof_enumerator,
 1380: 			.create_drbg_enumerator = _create_drbg_enumerator,
 1381: 			.create_dh_enumerator = _create_dh_enumerator,
 1382: 			.create_rng_enumerator = _create_rng_enumerator,
 1383: 			.create_nonce_gen_enumerator = _create_nonce_gen_enumerator,
 1384: 			.add_test_vector = _add_test_vector,
 1385: 			.create_verify_enumerator = _create_verify_enumerator,
 1386: 			.destroy = _destroy,
 1387: 		},
 1388: 		.crypters = linked_list_create(),
 1389: 		.aeads = linked_list_create(),
 1390: 		.signers = linked_list_create(),
 1391: 		.hashers = linked_list_create(),
 1392: 		.prfs = linked_list_create(),
 1393: 		.xofs = linked_list_create(),
 1394: 		.drbgs = linked_list_create(),
 1395: 		.rngs = linked_list_create(),
 1396: 		.nonce_gens = linked_list_create(),
 1397: 		.dhs = linked_list_create(),
 1398: 		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
 1399: 		.tester = crypto_tester_create(),
 1400: 		.test_on_add = lib->settings->get_bool(lib->settings,
 1401: 								"%s.crypto_test.on_add", FALSE, lib->ns),
 1402: 		.test_on_create = lib->settings->get_bool(lib->settings,
 1403: 								"%s.crypto_test.on_create", FALSE, lib->ns),
 1404: 		.bench = lib->settings->get_bool(lib->settings,
 1405: 								"%s.crypto_test.bench", FALSE, lib->ns),
 1406: 	);
 1407: 
 1408: 	return &this->public;
 1409: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>