summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto/crypto_tester.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/crypto/crypto_tester.c')
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c193
1 files changed, 179 insertions, 14 deletions
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index 15ed17381..5607d35b9 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -68,6 +68,11 @@ struct private_crypto_tester_t {
linked_list_t *rng;
/**
+ * List of Diffie-Hellman test vectors
+ */
+ linked_list_t *dh;
+
+ /**
* Is a test vector required to pass a test?
*/
bool required;
@@ -138,11 +143,11 @@ static u_int end_timing(struct timespec *start)
* Benchmark a crypter
*/
static u_int bench_crypter(private_crypto_tester_t *this,
- encryption_algorithm_t alg, crypter_constructor_t create)
+ encryption_algorithm_t alg, crypter_constructor_t create, size_t key_size)
{
crypter_t *crypter;
- crypter = create(alg, 0);
+ crypter = create(alg, key_size);
if (crypter)
{
char iv[crypter->get_iv_size(crypter)];
@@ -280,8 +285,8 @@ failure:
{
if (failed)
{
- DBG1(DBG_LIB,"disable %N[%s]: no key size supported",
- encryption_algorithm_names, alg, plugin_name);
+ DBG1(DBG_LIB,"disable %N[%s]: %zd byte key size not supported",
+ encryption_algorithm_names, alg, plugin_name, key_size);
return FALSE;
}
else
@@ -296,9 +301,10 @@ failure:
{
if (speed)
{
- *speed = bench_crypter(this, alg, create);
- DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
- encryption_algorithm_names, alg, plugin_name, tested, *speed);
+ *speed = bench_crypter(this, alg, create, key_size);
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points "
+ "(%zd bit key)", encryption_algorithm_names, alg,
+ plugin_name, tested, *speed, key_size * 8);
}
else
{
@@ -313,11 +319,11 @@ failure:
* Benchmark an aead transform
*/
static u_int bench_aead(private_crypto_tester_t *this,
- encryption_algorithm_t alg, aead_constructor_t create)
+ encryption_algorithm_t alg, aead_constructor_t create, size_t key_size)
{
aead_t *aead;
- aead = create(alg, 0, 0);
+ aead = create(alg, key_size, 0);
if (aead)
{
char iv[aead->get_iv_size(aead)];
@@ -474,8 +480,8 @@ failure:
{
if (failed)
{
- DBG1(DBG_LIB,"disable %N[%s]: no key size supported",
- encryption_algorithm_names, alg, plugin_name);
+ DBG1(DBG_LIB,"disable %N[%s]: %zd byte key size not supported",
+ encryption_algorithm_names, alg, plugin_name, key_size);
return FALSE;
}
else
@@ -490,9 +496,10 @@ failure:
{
if (speed)
{
- *speed = bench_aead(this, alg, create);
- DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
- encryption_algorithm_names, alg, plugin_name, tested, *speed);
+ *speed = bench_aead(this, alg, create, key_size);
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points "
+ "(%zd bit key)", encryption_algorithm_names, alg,
+ plugin_name, tested, *speed, key_size * 8);
}
else
{
@@ -1153,6 +1160,154 @@ failure:
return !failed;
}
+/**
+ * Benchmark a DH backend
+ */
+static u_int bench_dh(private_crypto_tester_t *this,
+ diffie_hellman_group_t group, dh_constructor_t create)
+{
+ chunk_t pub = chunk_empty, shared = chunk_empty;
+ diffie_hellman_t *dh;
+ struct timespec start;
+ u_int runs;
+
+ runs = 0;
+ start_timing(&start);
+ while (end_timing(&start) < this->bench_time)
+ {
+ dh = create(group);
+ if (!dh)
+ {
+ return 0;
+ }
+ if (dh->get_my_public_value(dh, &pub) &&
+ dh->set_other_public_value(dh, pub) &&
+ dh->get_shared_secret(dh, &shared))
+ {
+ runs++;
+ }
+ chunk_free(&pub);
+ chunk_free(&shared);
+ dh->destroy(dh);
+ }
+ return runs;
+}
+
+METHOD(crypto_tester_t, test_dh, bool,
+ private_crypto_tester_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create, u_int *speed, const char *plugin_name)
+{
+ enumerator_t *enumerator;
+ dh_test_vector_t *v;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->dh->create_enumerator(this->dh);
+ while (enumerator->enumerate(enumerator, &v))
+ {
+ diffie_hellman_t *a, *b;
+ chunk_t apub, bpub, asec, bsec;
+
+ if (v->group != group)
+ {
+ continue;
+ }
+
+ a = create(group);
+ b = create(group);
+ if (!a || !b)
+ {
+ DESTROY_IF(a);
+ DESTROY_IF(b);
+ failed = TRUE;
+ tested++;
+ DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
+ diffie_hellman_group_names, group, plugin_name);
+ break;
+ }
+
+ if (!a->set_private_value || !b->set_private_value)
+ { /* does not support testing */
+ a->destroy(a);
+ b->destroy(b);
+ continue;
+ }
+ failed = TRUE;
+ tested++;
+
+ apub = bpub = asec = bsec = chunk_empty;
+
+ if (!a->set_private_value(a, chunk_create(v->priv_a, v->priv_len)) ||
+ !b->set_private_value(b, chunk_create(v->priv_b, v->priv_len)))
+ {
+ goto failure;
+ }
+ if (!a->get_my_public_value(a, &apub) ||
+ !chunk_equals(apub, chunk_create(v->pub_a, v->pub_len)))
+ {
+ goto failure;
+ }
+ if (!b->get_my_public_value(b, &bpub) ||
+ !chunk_equals(bpub, chunk_create(v->pub_b, v->pub_len)))
+ {
+ goto failure;
+ }
+ if (!a->set_other_public_value(a, bpub) ||
+ !b->set_other_public_value(b, apub))
+ {
+ goto failure;
+ }
+ if (!a->get_shared_secret(a, &asec) ||
+ !chunk_equals(asec, chunk_create(v->shared, v->shared_len)))
+ {
+ goto failure;
+ }
+ if (!b->get_shared_secret(b, &bsec) ||
+ !chunk_equals(bsec, chunk_create(v->shared, v->shared_len)))
+ {
+ goto failure;
+ }
+
+ failed = FALSE;
+failure:
+ a->destroy(a);
+ b->destroy(b);
+ chunk_free(&apub);
+ chunk_free(&bpub);
+ chunk_free(&asec);
+ chunk_free(&bsec);
+ if (failed)
+ {
+ DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
+ diffie_hellman_group_names, group, plugin_name, get_name(v));
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1(DBG_LIB, "%s %N[%s]: no test vectors found / untestable",
+ this->required ? "disabled" : "enabled ",
+ diffie_hellman_group_names, group, plugin_name);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ if (speed)
+ {
+ *speed = bench_dh(this, group, create);
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
+ diffie_hellman_group_names, group, plugin_name, tested, *speed);
+ }
+ else
+ {
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
+ diffie_hellman_group_names, group, plugin_name, tested);
+ }
+ }
+ return !failed;
+}
+
METHOD(crypto_tester_t, add_crypter_vector, void,
private_crypto_tester_t *this, crypter_test_vector_t *vector)
{
@@ -1189,6 +1344,12 @@ METHOD(crypto_tester_t, add_rng_vector, void,
this->rng->insert_last(this->rng, vector);
}
+METHOD(crypto_tester_t, add_dh_vector, void,
+ private_crypto_tester_t *this, dh_test_vector_t *vector)
+{
+ this->dh->insert_last(this->dh, vector);
+}
+
METHOD(crypto_tester_t, destroy, void,
private_crypto_tester_t *this)
{
@@ -1198,6 +1359,7 @@ METHOD(crypto_tester_t, destroy, void,
this->hasher->destroy(this->hasher);
this->prf->destroy(this->prf);
this->rng->destroy(this->rng);
+ this->dh->destroy(this->dh);
free(this);
}
@@ -1216,12 +1378,14 @@ crypto_tester_t *crypto_tester_create()
.test_hasher = _test_hasher,
.test_prf = _test_prf,
.test_rng = _test_rng,
+ .test_dh = _test_dh,
.add_crypter_vector = _add_crypter_vector,
.add_aead_vector = _add_aead_vector,
.add_signer_vector = _add_signer_vector,
.add_hasher_vector = _add_hasher_vector,
.add_prf_vector = _add_prf_vector,
.add_rng_vector = _add_rng_vector,
+ .add_dh_vector = _add_dh_vector,
.destroy = _destroy,
},
.crypter = linked_list_create(),
@@ -1230,6 +1394,7 @@ crypto_tester_t *crypto_tester_create()
.hasher = linked_list_create(),
.prf = linked_list_create(),
.rng = linked_list_create(),
+ .dh = linked_list_create(),
.required = lib->settings->get_bool(lib->settings,
"%s.crypto_test.required", FALSE, lib->ns),