crypto-tester: Support testing DH groups using DH test vectors

This commit is contained in:
Martin Willi
2015-04-15 14:37:38 +02:00
parent 3941545fb9
commit a94955e88a
3 changed files with 224 additions and 2 deletions
+163
View File
@@ -67,6 +67,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?
*/
@@ -1155,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)
{
@@ -1191,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)
{
@@ -1200,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);
}
@@ -1218,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(),
@@ -1232,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),