summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto/crypto_factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/crypto/crypto_factory.c')
-rw-r--r--src/libstrongswan/crypto/crypto_factory.c178
1 files changed, 136 insertions, 42 deletions
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
index dcc881f1d..fea8d0793 100644
--- a/src/libstrongswan/crypto/crypto_factory.c
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -11,14 +11,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crypto_factory.c 4592 2008-11-05 16:21:57Z martin $
*/
#include "crypto_factory.h"
-#include <utils/linked_list.h>
+#include <debug.h>
#include <utils/mutex.h>
+#include <utils/linked_list.h>
+#include <crypto/crypto_tester.h>
typedef struct entry_t entry_t;
struct entry_t {
@@ -78,6 +78,21 @@ struct private_crypto_factory_t {
linked_list_t *dhs;
/**
+ * test manager to test crypto algorithms
+ */
+ crypto_tester_t *tester;
+
+ /**
+ * whether to test algorithms during registration
+ */
+ bool test_on_add;
+
+ /**
+ * whether to test algorithms on each crypto primitive construction
+ */
+ bool test_on_create;
+
+ /**
* rwlock to lock access to modules
*/
rwlock_t *lock;
@@ -92,13 +107,19 @@ static crypter_t* create_crypter(private_crypto_factory_t *this,
enumerator_t *enumerator;
entry_t *entry;
crypter_t *crypter = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->crypters->create_enumerator(this->crypters);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_crypter(this->tester, algo, key_size,
+ entry->create_crypter))
+ {
+ continue;
+ }
crypter = entry->create_crypter(algo, key_size);
if (crypter)
{
@@ -120,13 +141,19 @@ static signer_t* create_signer(private_crypto_factory_t *this,
enumerator_t *enumerator;
entry_t *entry;
signer_t *signer = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->signers->create_enumerator(this->signers);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_signer(this->tester, algo,
+ entry->create_signer))
+ {
+ continue;
+ }
signer = entry->create_signer(algo);
if (signer)
{
@@ -136,7 +163,7 @@ static signer_t* create_signer(private_crypto_factory_t *this,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
-
+
return signer;
}
@@ -156,6 +183,12 @@ static hasher_t* create_hasher(private_crypto_factory_t *this,
{
if (algo == HASH_PREFERRED || entry->algo == algo)
{
+ if (this->test_on_create && algo != HASH_PREFERRED &&
+ !this->tester->test_hasher(this->tester, algo,
+ entry->create_hasher))
+ {
+ continue;
+ }
hasher = entry->create_hasher(entry->algo);
if (hasher)
{
@@ -184,6 +217,11 @@ static prf_t* create_prf(private_crypto_factory_t *this,
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_prf(this->tester, algo, entry->create_prf))
+ {
+ continue;
+ }
prf = entry->create_prf(algo);
if (prf)
{
@@ -205,13 +243,18 @@ static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
entry_t *entry;
u_int diff = ~0;
rng_constructor_t constr = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->rngs->create_enumerator(this->rngs);
while (enumerator->enumerate(enumerator, &entry))
{ /* find the best matching quality, but at least as good as requested */
if (entry->algo >= quality && diff > entry->algo - quality)
{
+ if (this->test_on_create &&
+ !this->tester->test_rng(this->tester, quality, entry->create_rng))
+ {
+ continue;
+ }
diff = entry->algo - quality;
constr = entry->create_rng;
if (diff == 0)
@@ -264,13 +307,17 @@ static void add_crypter(private_crypto_factory_t *this,
encryption_algorithm_t algo,
crypter_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_crypter = create;
- this->lock->write_lock(this->lock);
- this->crypters->insert_last(this->crypters, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_crypter(this->tester, algo, 0, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_crypter = create;
+ this->lock->write_lock(this->lock);
+ this->crypters->insert_last(this->crypters, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -302,13 +349,17 @@ static void remove_crypter(private_crypto_factory_t *this,
static void add_signer(private_crypto_factory_t *this,
integrity_algorithm_t algo, signer_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_signer = create;
- this->lock->write_lock(this->lock);
- this->signers->insert_last(this->signers, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_signer(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_signer = create;
+ this->lock->write_lock(this->lock);
+ this->signers->insert_last(this->signers, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -340,13 +391,17 @@ static void remove_signer(private_crypto_factory_t *this,
static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
hasher_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_hasher = create;
- this->lock->write_lock(this->lock);
- this->hashers->insert_last(this->hashers, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_hasher(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_hasher = create;
+ this->lock->write_lock(this->lock);
+ this->hashers->insert_last(this->hashers, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -378,13 +433,17 @@ static void remove_hasher(private_crypto_factory_t *this,
static void add_prf(private_crypto_factory_t *this,
pseudo_random_function_t algo, prf_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_prf = create;
- this->lock->write_lock(this->lock);
- this->prfs->insert_last(this->prfs, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_prf(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_prf = create;
+ this->lock->write_lock(this->lock);
+ this->prfs->insert_last(this->prfs, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -415,13 +474,17 @@ static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
static void add_rng(private_crypto_factory_t *this, rng_quality_t quality,
rng_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = quality;
- entry->create_rng = create;
- this->lock->write_lock(this->lock);
- this->rngs->insert_last(this->rngs, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_rng(this->tester, quality, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = quality;
+ entry->create_rng = create;
+ this->lock->write_lock(this->lock);
+ this->rngs->insert_last(this->rngs, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -605,6 +668,30 @@ static enumerator_t* create_dh_enumerator(private_crypto_factory_t *this)
}
/**
+ * Implementation of crypto_factory_t.add_test_vector
+ */
+static void add_test_vector(private_crypto_factory_t *this,
+ transform_type_t type, void *vector)
+{
+ switch (type)
+ {
+ case ENCRYPTION_ALGORITHM:
+ return this->tester->add_crypter_vector(this->tester, vector);
+ case INTEGRITY_ALGORITHM:
+ return this->tester->add_signer_vector(this->tester, vector);
+ case HASH_ALGORITHM:
+ return this->tester->add_hasher_vector(this->tester, vector);
+ case PSEUDO_RANDOM_FUNCTION:
+ return this->tester->add_prf_vector(this->tester, vector);
+ case RANDOM_NUMBER_GENERATOR:
+ return this->tester->add_rng_vector(this->tester, vector);
+ default:
+ DBG1("%N test vectors not supported, ignored",
+ transform_type_names, type);
+ }
+}
+
+/**
* Implementation of crypto_factory_t.destroy
*/
static void destroy(private_crypto_factory_t *this)
@@ -615,6 +702,7 @@ static void destroy(private_crypto_factory_t *this)
this->prfs->destroy_function(this->prfs, free);
this->rngs->destroy_function(this->rngs, free);
this->dhs->destroy_function(this->dhs, free);
+ this->tester->destroy(this->tester);
this->lock->destroy(this->lock);
free(this);
}
@@ -649,6 +737,7 @@ crypto_factory_t *crypto_factory_create()
this->public.create_hasher_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_hasher_enumerator;
this->public.create_prf_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_prf_enumerator;
this->public.create_dh_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_dh_enumerator;
+ this->public.add_test_vector = (void(*)(crypto_factory_t*, transform_type_t type, ...))add_test_vector;
this->public.destroy = (void(*)(crypto_factory_t*))destroy;
this->crypters = linked_list_create();
@@ -658,6 +747,11 @@ crypto_factory_t *crypto_factory_create()
this->rngs = linked_list_create();
this->dhs = linked_list_create();
this->lock = rwlock_create(RWLOCK_DEFAULT);
+ this->tester = crypto_tester_create();
+ this->test_on_add = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_add", FALSE);
+ this->test_on_create = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_create", FALSE);
return &this->public;
}