mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-16 00:00:37 -04:00
Implemented algorithm benchmarking during registration
This commit is contained in:
parent
e2c3b4820b
commit
1b0eff58e0
@ -22,8 +22,10 @@
|
|||||||
|
|
||||||
typedef struct entry_t entry_t;
|
typedef struct entry_t entry_t;
|
||||||
struct entry_t {
|
struct entry_t {
|
||||||
/** algorithm */
|
/* algorithm */
|
||||||
u_int algo;
|
u_int algo;
|
||||||
|
/* benchmarked speed */
|
||||||
|
u_int speed;
|
||||||
/* constructor */
|
/* constructor */
|
||||||
union {
|
union {
|
||||||
crypter_constructor_t create_crypter;
|
crypter_constructor_t create_crypter;
|
||||||
@ -32,6 +34,7 @@ struct entry_t {
|
|||||||
prf_constructor_t create_prf;
|
prf_constructor_t create_prf;
|
||||||
rng_constructor_t create_rng;
|
rng_constructor_t create_rng;
|
||||||
dh_constructor_t create_dh;
|
dh_constructor_t create_dh;
|
||||||
|
void *create;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,6 +95,11 @@ struct private_crypto_factory_t {
|
|||||||
*/
|
*/
|
||||||
bool test_on_create;
|
bool test_on_create;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run algorithm benchmark during registration
|
||||||
|
*/
|
||||||
|
bool bench;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rwlock to lock access to modules
|
* rwlock to lock access to modules
|
||||||
*/
|
*/
|
||||||
@ -114,7 +122,7 @@ METHOD(crypto_factory_t, create_crypter, crypter_t*,
|
|||||||
{
|
{
|
||||||
if (this->test_on_create &&
|
if (this->test_on_create &&
|
||||||
!this->tester->test_crypter(this->tester, algo, key_size,
|
!this->tester->test_crypter(this->tester, algo, key_size,
|
||||||
entry->create_crypter))
|
entry->create_crypter, NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -145,7 +153,7 @@ METHOD(crypto_factory_t, create_signer, signer_t*,
|
|||||||
{
|
{
|
||||||
if (this->test_on_create &&
|
if (this->test_on_create &&
|
||||||
!this->tester->test_signer(this->tester, algo,
|
!this->tester->test_signer(this->tester, algo,
|
||||||
entry->create_signer))
|
entry->create_signer, NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -177,7 +185,7 @@ METHOD(crypto_factory_t, create_hasher, hasher_t*,
|
|||||||
{
|
{
|
||||||
if (this->test_on_create && algo != HASH_PREFERRED &&
|
if (this->test_on_create && algo != HASH_PREFERRED &&
|
||||||
!this->tester->test_hasher(this->tester, algo,
|
!this->tester->test_hasher(this->tester, algo,
|
||||||
entry->create_hasher))
|
entry->create_hasher, NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -207,7 +215,8 @@ METHOD(crypto_factory_t, create_prf, prf_t*,
|
|||||||
if (entry->algo == algo)
|
if (entry->algo == algo)
|
||||||
{
|
{
|
||||||
if (this->test_on_create &&
|
if (this->test_on_create &&
|
||||||
!this->tester->test_prf(this->tester, algo, entry->create_prf))
|
!this->tester->test_prf(this->tester, algo,
|
||||||
|
entry->create_prf, NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -238,7 +247,8 @@ METHOD(crypto_factory_t, create_rng, rng_t*,
|
|||||||
if (entry->algo >= quality && diff > entry->algo - quality)
|
if (entry->algo >= quality && diff > entry->algo - quality)
|
||||||
{
|
{
|
||||||
if (this->test_on_create &&
|
if (this->test_on_create &&
|
||||||
!this->tester->test_rng(this->tester, quality, entry->create_rng))
|
!this->tester->test_rng(this->tester, quality,
|
||||||
|
entry->create_rng, NULL))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -284,20 +294,61 @@ METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
|
|||||||
return diffie_hellman;
|
return diffie_hellman;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert an algorithm entry to a list
|
||||||
|
*/
|
||||||
|
static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
|
||||||
|
int algo, u_int speed, void *create)
|
||||||
|
{
|
||||||
|
entry_t *entry, *current;
|
||||||
|
linked_list_t *tmp;
|
||||||
|
bool inserted = FALSE;
|
||||||
|
|
||||||
|
INIT(entry,
|
||||||
|
.algo = algo,
|
||||||
|
.speed = speed,
|
||||||
|
);
|
||||||
|
entry->create = create;
|
||||||
|
|
||||||
|
this->lock->write_lock(this->lock);
|
||||||
|
if (speed)
|
||||||
|
{ /* insert sorted by speed using a temporary list */
|
||||||
|
tmp = linked_list_create();
|
||||||
|
while (list->remove_first(list, (void**)¤t) == SUCCESS)
|
||||||
|
{
|
||||||
|
tmp->insert_last(tmp, current);
|
||||||
|
}
|
||||||
|
while (tmp->remove_first(tmp, (void**)¤t) == SUCCESS)
|
||||||
|
{
|
||||||
|
if (!inserted &&
|
||||||
|
current->algo == algo &&
|
||||||
|
current->speed < speed)
|
||||||
|
{
|
||||||
|
list->insert_last(list, entry);
|
||||||
|
inserted = TRUE;
|
||||||
|
}
|
||||||
|
list->insert_last(list, current);
|
||||||
|
}
|
||||||
|
tmp->destroy(tmp);
|
||||||
|
}
|
||||||
|
if (!inserted)
|
||||||
|
{
|
||||||
|
list->insert_last(list, entry);
|
||||||
|
}
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_factory_t, add_crypter, void,
|
METHOD(crypto_factory_t, add_crypter, void,
|
||||||
private_crypto_factory_t *this, encryption_algorithm_t algo,
|
private_crypto_factory_t *this, encryption_algorithm_t algo,
|
||||||
crypter_constructor_t create)
|
crypter_constructor_t create)
|
||||||
{
|
{
|
||||||
if (!this->test_on_add ||
|
u_int speed = 0;
|
||||||
this->tester->test_crypter(this->tester, algo, 0, create))
|
|
||||||
{
|
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
|
||||||
|
|
||||||
entry->algo = algo;
|
if (!this->test_on_add ||
|
||||||
entry->create_crypter = create;
|
this->tester->test_crypter(this->tester, algo, 0, create,
|
||||||
this->lock->write_lock(this->lock);
|
this->bench ? &speed : NULL))
|
||||||
this->crypters->insert_last(this->crypters, entry);
|
{
|
||||||
this->lock->unlock(this->lock);
|
add_entry(this, this->crypters, algo, speed, create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,16 +376,13 @@ METHOD(crypto_factory_t, add_signer, void,
|
|||||||
private_crypto_factory_t *this, integrity_algorithm_t algo,
|
private_crypto_factory_t *this, integrity_algorithm_t algo,
|
||||||
signer_constructor_t create)
|
signer_constructor_t create)
|
||||||
{
|
{
|
||||||
if (!this->test_on_add ||
|
u_int speed = 0;
|
||||||
this->tester->test_signer(this->tester, algo, create))
|
|
||||||
{
|
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
|
||||||
|
|
||||||
entry->algo = algo;
|
if (!this->test_on_add ||
|
||||||
entry->create_signer = create;
|
this->tester->test_signer(this->tester, algo, create,
|
||||||
this->lock->write_lock(this->lock);
|
this->bench ? &speed : NULL))
|
||||||
this->signers->insert_last(this->signers, entry);
|
{
|
||||||
this->lock->unlock(this->lock);
|
add_entry(this, this->signers, algo, speed, create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,16 +410,13 @@ METHOD(crypto_factory_t, add_hasher, void,
|
|||||||
private_crypto_factory_t *this, hash_algorithm_t algo,
|
private_crypto_factory_t *this, hash_algorithm_t algo,
|
||||||
hasher_constructor_t create)
|
hasher_constructor_t create)
|
||||||
{
|
{
|
||||||
if (!this->test_on_add ||
|
u_int speed = 0;
|
||||||
this->tester->test_hasher(this->tester, algo, create))
|
|
||||||
{
|
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
|
||||||
|
|
||||||
entry->algo = algo;
|
if (!this->test_on_add ||
|
||||||
entry->create_hasher = create;
|
this->tester->test_hasher(this->tester, algo, create,
|
||||||
this->lock->write_lock(this->lock);
|
this->bench ? &speed : NULL))
|
||||||
this->hashers->insert_last(this->hashers, entry);
|
{
|
||||||
this->lock->unlock(this->lock);
|
add_entry(this, this->hashers, algo, speed, create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,16 +444,13 @@ METHOD(crypto_factory_t, add_prf, void,
|
|||||||
private_crypto_factory_t *this, pseudo_random_function_t algo,
|
private_crypto_factory_t *this, pseudo_random_function_t algo,
|
||||||
prf_constructor_t create)
|
prf_constructor_t create)
|
||||||
{
|
{
|
||||||
if (!this->test_on_add ||
|
u_int speed = 0;
|
||||||
this->tester->test_prf(this->tester, algo, create))
|
|
||||||
{
|
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
|
||||||
|
|
||||||
entry->algo = algo;
|
if (!this->test_on_add ||
|
||||||
entry->create_prf = create;
|
this->tester->test_prf(this->tester, algo, create,
|
||||||
this->lock->write_lock(this->lock);
|
this->bench ? &speed : NULL))
|
||||||
this->prfs->insert_last(this->prfs, entry);
|
{
|
||||||
this->lock->unlock(this->lock);
|
add_entry(this, this->prfs, algo, speed, create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,16 +478,13 @@ METHOD(crypto_factory_t, add_rng, void,
|
|||||||
private_crypto_factory_t *this, rng_quality_t quality,
|
private_crypto_factory_t *this, rng_quality_t quality,
|
||||||
rng_constructor_t create)
|
rng_constructor_t create)
|
||||||
{
|
{
|
||||||
if (!this->test_on_add ||
|
u_int speed = 0;
|
||||||
this->tester->test_rng(this->tester, quality, create))
|
|
||||||
{
|
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
|
||||||
|
|
||||||
entry->algo = quality;
|
if (!this->test_on_add ||
|
||||||
entry->create_rng = create;
|
this->tester->test_rng(this->tester, quality, create,
|
||||||
this->lock->write_lock(this->lock);
|
this->bench ? &speed : NULL))
|
||||||
this->rngs->insert_last(this->rngs, entry);
|
{
|
||||||
this->lock->unlock(this->lock);
|
add_entry(this, this->rngs, quality, speed, create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,13 +512,7 @@ METHOD(crypto_factory_t, add_dh, void,
|
|||||||
private_crypto_factory_t *this, diffie_hellman_group_t group,
|
private_crypto_factory_t *this, diffie_hellman_group_t group,
|
||||||
dh_constructor_t create)
|
dh_constructor_t create)
|
||||||
{
|
{
|
||||||
entry_t *entry = malloc_thing(entry_t);
|
add_entry(this, this->dhs, group, 0, create);
|
||||||
|
|
||||||
entry->algo = group;
|
|
||||||
entry->create_dh = create;
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
this->dhs->insert_last(this->dhs, entry);
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(crypto_factory_t, remove_dh, void,
|
METHOD(crypto_factory_t, remove_dh, void,
|
||||||
@ -695,6 +728,8 @@ crypto_factory_t *crypto_factory_create()
|
|||||||
"libstrongswan.crypto_test.on_add", FALSE),
|
"libstrongswan.crypto_test.on_add", FALSE),
|
||||||
.test_on_create = lib->settings->get_bool(lib->settings,
|
.test_on_create = lib->settings->get_bool(lib->settings,
|
||||||
"libstrongswan.crypto_test.on_create", FALSE),
|
"libstrongswan.crypto_test.on_create", FALSE),
|
||||||
|
.bench = lib->settings->get_bool(lib->settings,
|
||||||
|
"libstrongswan.crypto_test.bench", FALSE),
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009 Martin Willi
|
* Copyright (C) 2009-2010 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
* Copyright (C) 2010 revosec AG
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@ -15,6 +16,7 @@
|
|||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "crypto_tester.h"
|
#include "crypto_tester.h"
|
||||||
|
|
||||||
@ -67,6 +69,16 @@ struct private_crypto_tester_t {
|
|||||||
* should we run RNG_TRUE tests? Enough entropy?
|
* should we run RNG_TRUE tests? Enough entropy?
|
||||||
*/
|
*/
|
||||||
bool rng_true;
|
bool rng_true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* time we test each algorithm
|
||||||
|
*/
|
||||||
|
int bench_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* size of buffer we use for benchmarking
|
||||||
|
*/
|
||||||
|
int bench_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,9 +97,69 @@ static const char* get_name(void *sym)
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a benchmark timer
|
||||||
|
*/
|
||||||
|
static void start_timing(struct timespec *start)
|
||||||
|
{
|
||||||
|
clock_gettime(CLOCK_THREAD_CPUTIME_ID, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a benchmark timer, return ms
|
||||||
|
*/
|
||||||
|
static u_int end_timing(struct timespec *start)
|
||||||
|
{
|
||||||
|
struct timespec end;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
|
||||||
|
return (end.tv_nsec - start->tv_nsec) / 1000000 +
|
||||||
|
(end.tv_sec - start->tv_sec) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark a crypter
|
||||||
|
*/
|
||||||
|
static u_int bench_crypter(private_crypto_tester_t *this,
|
||||||
|
encryption_algorithm_t alg, crypter_constructor_t create)
|
||||||
|
{
|
||||||
|
crypter_t *crypter;
|
||||||
|
|
||||||
|
crypter = create(alg, 0);
|
||||||
|
if (crypter)
|
||||||
|
{
|
||||||
|
char iv[crypter->get_iv_size(crypter)];
|
||||||
|
char key[crypter->get_key_size(crypter)];
|
||||||
|
chunk_t buf;
|
||||||
|
struct timespec start;
|
||||||
|
u_int runs;
|
||||||
|
|
||||||
|
memset(iv, 0x56, sizeof(iv));
|
||||||
|
memset(key, 0x12, sizeof(key));
|
||||||
|
crypter->set_key(crypter, chunk_from_thing(key));
|
||||||
|
|
||||||
|
buf = chunk_alloc(this->bench_size);
|
||||||
|
memset(buf.ptr, 0x34, buf.len);
|
||||||
|
|
||||||
|
runs = 0;
|
||||||
|
start_timing(&start);
|
||||||
|
while (end_timing(&start) < this->bench_time)
|
||||||
|
{
|
||||||
|
crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL);
|
||||||
|
crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL);
|
||||||
|
runs++;
|
||||||
|
}
|
||||||
|
free(buf.ptr);
|
||||||
|
crypter->destroy(crypter);
|
||||||
|
|
||||||
|
return runs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_tester_t, test_crypter, bool,
|
METHOD(crypto_tester_t, test_crypter, bool,
|
||||||
private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
|
private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
|
||||||
crypter_constructor_t create)
|
crypter_constructor_t create, u_int *speed)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
crypter_test_vector_t *vector;
|
crypter_test_vector_t *vector;
|
||||||
@ -168,15 +240,63 @@ METHOD(crypto_tester_t, test_crypter, bool,
|
|||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
if (speed)
|
||||||
encryption_algorithm_names, alg, tested);
|
{
|
||||||
|
*speed = bench_crypter(this, alg, create);
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points",
|
||||||
|
encryption_algorithm_names, alg, tested, *speed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
||||||
|
encryption_algorithm_names, alg, tested);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark a signer
|
||||||
|
*/
|
||||||
|
static u_int bench_signer(private_crypto_tester_t *this,
|
||||||
|
encryption_algorithm_t alg, signer_constructor_t create)
|
||||||
|
{
|
||||||
|
signer_t *signer;
|
||||||
|
|
||||||
|
signer = create(alg);
|
||||||
|
if (signer)
|
||||||
|
{
|
||||||
|
char key[signer->get_key_size(signer)];
|
||||||
|
char mac[signer->get_block_size(signer)];
|
||||||
|
chunk_t buf;
|
||||||
|
struct timespec start;
|
||||||
|
u_int runs;
|
||||||
|
|
||||||
|
memset(key, 0x12, sizeof(key));
|
||||||
|
signer->set_key(signer, chunk_from_thing(key));
|
||||||
|
|
||||||
|
buf = chunk_alloc(this->bench_size);
|
||||||
|
memset(buf.ptr, 0x34, buf.len);
|
||||||
|
|
||||||
|
runs = 0;
|
||||||
|
start_timing(&start);
|
||||||
|
while (end_timing(&start) < this->bench_time)
|
||||||
|
{
|
||||||
|
signer->get_signature(signer, buf, mac);
|
||||||
|
signer->verify_signature(signer, buf, chunk_from_thing(mac));
|
||||||
|
runs++;
|
||||||
|
}
|
||||||
|
free(buf.ptr);
|
||||||
|
signer->destroy(signer);
|
||||||
|
|
||||||
|
return runs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_tester_t, test_signer, bool,
|
METHOD(crypto_tester_t, test_signer, bool,
|
||||||
private_crypto_tester_t *this, integrity_algorithm_t alg,
|
private_crypto_tester_t *this, integrity_algorithm_t alg,
|
||||||
signer_constructor_t create)
|
signer_constructor_t create, u_int *speed)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
signer_test_vector_t *vector;
|
signer_test_vector_t *vector;
|
||||||
@ -270,15 +390,58 @@ METHOD(crypto_tester_t, test_signer, bool,
|
|||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
if (speed)
|
||||||
integrity_algorithm_names, alg, tested);
|
{
|
||||||
|
*speed = bench_signer(this, alg, create);
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points",
|
||||||
|
integrity_algorithm_names, alg, tested, *speed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
||||||
|
integrity_algorithm_names, alg, tested);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark a hasher
|
||||||
|
*/
|
||||||
|
static u_int bench_hasher(private_crypto_tester_t *this,
|
||||||
|
hash_algorithm_t alg, hasher_constructor_t create)
|
||||||
|
{
|
||||||
|
hasher_t *hasher;
|
||||||
|
|
||||||
|
hasher = create(alg);
|
||||||
|
if (hasher)
|
||||||
|
{
|
||||||
|
char hash[hasher->get_hash_size(hasher)];
|
||||||
|
chunk_t buf;
|
||||||
|
struct timespec start;
|
||||||
|
u_int runs;
|
||||||
|
|
||||||
|
buf = chunk_alloc(this->bench_size);
|
||||||
|
memset(buf.ptr, 0x34, buf.len);
|
||||||
|
|
||||||
|
runs = 0;
|
||||||
|
start_timing(&start);
|
||||||
|
while (end_timing(&start) < this->bench_time)
|
||||||
|
{
|
||||||
|
hasher->get_hash(hasher, buf, hash);
|
||||||
|
runs++;
|
||||||
|
}
|
||||||
|
free(buf.ptr);
|
||||||
|
hasher->destroy(hasher);
|
||||||
|
|
||||||
|
return runs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_tester_t, test_hasher, bool,
|
METHOD(crypto_tester_t, test_hasher, bool,
|
||||||
private_crypto_tester_t *this, hash_algorithm_t alg,
|
private_crypto_tester_t *this, hash_algorithm_t alg,
|
||||||
hasher_constructor_t create)
|
hasher_constructor_t create, u_int *speed)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
hasher_test_vector_t *vector;
|
hasher_test_vector_t *vector;
|
||||||
@ -358,15 +521,58 @@ METHOD(crypto_tester_t, test_hasher, bool,
|
|||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
if (speed)
|
||||||
hash_algorithm_names, alg, tested);
|
{
|
||||||
|
*speed = bench_hasher(this, alg, create);
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points",
|
||||||
|
hash_algorithm_names, alg, tested, *speed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
||||||
|
hash_algorithm_names, alg, tested);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark a PRF
|
||||||
|
*/
|
||||||
|
static u_int bench_prf(private_crypto_tester_t *this,
|
||||||
|
pseudo_random_function_t alg, prf_constructor_t create)
|
||||||
|
{
|
||||||
|
prf_t *prf;
|
||||||
|
|
||||||
|
prf = create(alg);
|
||||||
|
if (prf)
|
||||||
|
{
|
||||||
|
char bytes[prf->get_block_size(prf)];
|
||||||
|
chunk_t buf;
|
||||||
|
struct timespec start;
|
||||||
|
u_int runs;
|
||||||
|
|
||||||
|
buf = chunk_alloc(this->bench_size);
|
||||||
|
memset(buf.ptr, 0x34, buf.len);
|
||||||
|
|
||||||
|
runs = 0;
|
||||||
|
start_timing(&start);
|
||||||
|
while (end_timing(&start) < this->bench_time)
|
||||||
|
{
|
||||||
|
prf->get_bytes(prf, buf, bytes);
|
||||||
|
runs++;
|
||||||
|
}
|
||||||
|
free(buf.ptr);
|
||||||
|
prf->destroy(prf);
|
||||||
|
|
||||||
|
return runs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_tester_t, test_prf, bool,
|
METHOD(crypto_tester_t, test_prf, bool,
|
||||||
private_crypto_tester_t *this, pseudo_random_function_t alg,
|
private_crypto_tester_t *this, pseudo_random_function_t alg,
|
||||||
prf_constructor_t create)
|
prf_constructor_t create, u_int *speed)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
prf_test_vector_t *vector;
|
prf_test_vector_t *vector;
|
||||||
@ -457,15 +663,55 @@ METHOD(crypto_tester_t, test_prf, bool,
|
|||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
if (speed)
|
||||||
pseudo_random_function_names, alg, tested);
|
{
|
||||||
|
*speed = bench_prf(this, alg, create);
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points",
|
||||||
|
pseudo_random_function_names, alg, tested, *speed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
||||||
|
pseudo_random_function_names, alg, tested);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark a RNG
|
||||||
|
*/
|
||||||
|
static u_int bench_rng(private_crypto_tester_t *this,
|
||||||
|
rng_quality_t quality, rng_constructor_t create)
|
||||||
|
{
|
||||||
|
rng_t *rng;
|
||||||
|
|
||||||
|
rng = create(quality);
|
||||||
|
if (rng)
|
||||||
|
{
|
||||||
|
struct timespec start;
|
||||||
|
chunk_t buf;
|
||||||
|
u_int runs;
|
||||||
|
|
||||||
|
runs = 0;
|
||||||
|
buf = chunk_alloc(this->bench_size);
|
||||||
|
start_timing(&start);
|
||||||
|
while (end_timing(&start) < this->bench_time)
|
||||||
|
{
|
||||||
|
rng->get_bytes(rng, buf.len, buf.ptr);
|
||||||
|
runs++;
|
||||||
|
}
|
||||||
|
free(buf.ptr);
|
||||||
|
rng->destroy(rng);
|
||||||
|
|
||||||
|
return runs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(crypto_tester_t, test_rng, bool,
|
METHOD(crypto_tester_t, test_rng, bool,
|
||||||
private_crypto_tester_t *this, rng_quality_t quality,
|
private_crypto_tester_t *this, rng_quality_t quality,
|
||||||
rng_constructor_t create)
|
rng_constructor_t create, u_int *speed)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
rng_test_vector_t *vector;
|
rng_test_vector_t *vector;
|
||||||
@ -539,8 +785,17 @@ METHOD(crypto_tester_t, test_rng, bool,
|
|||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
if (speed)
|
||||||
rng_quality_names, quality, tested);
|
{
|
||||||
|
*speed = bench_rng(this, quality, create);
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors, %d points",
|
||||||
|
rng_quality_names, quality, tested, *speed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
|
||||||
|
rng_quality_names, quality, tested);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !failed;
|
return !failed;
|
||||||
}
|
}
|
||||||
@ -617,8 +872,15 @@ crypto_tester_t *crypto_tester_create()
|
|||||||
"libstrongswan.crypto_test.required", FALSE),
|
"libstrongswan.crypto_test.required", FALSE),
|
||||||
.rng_true = lib->settings->get_bool(lib->settings,
|
.rng_true = lib->settings->get_bool(lib->settings,
|
||||||
"libstrongswan.crypto_test.rng_true", FALSE),
|
"libstrongswan.crypto_test.rng_true", FALSE),
|
||||||
|
.bench_time = lib->settings->get_int(lib->settings,
|
||||||
|
"libstrongswan.crypto_test.bench_time", 50),
|
||||||
|
.bench_size = lib->settings->get_int(lib->settings,
|
||||||
|
"libstrongswan.crypto_test.bench_size", 1024),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* enforce a block size of 16, should be fine for all algorithms */
|
||||||
|
this->bench_size = this->bench_size / 16 * 16;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,46 +116,52 @@ struct crypto_tester_t {
|
|||||||
* @param alg algorithm to test
|
* @param alg algorithm to test
|
||||||
* @param key_size key size to test, 0 for all
|
* @param key_size key size to test, 0 for all
|
||||||
* @param create constructor function for the crypter
|
* @param create constructor function for the crypter
|
||||||
|
* @param speed speed test result, NULL to omit
|
||||||
* @return TRUE if test passed
|
* @return TRUE if test passed
|
||||||
*/
|
*/
|
||||||
bool (*test_crypter)(crypto_tester_t *this, encryption_algorithm_t alg,
|
bool (*test_crypter)(crypto_tester_t *this, encryption_algorithm_t alg,
|
||||||
size_t key_size, crypter_constructor_t create);
|
size_t key_size, crypter_constructor_t create,
|
||||||
|
u_int *speed);
|
||||||
/**
|
/**
|
||||||
* Test a signer algorithm.
|
* Test a signer algorithm.
|
||||||
*
|
*
|
||||||
* @param alg algorithm to test
|
* @param alg algorithm to test
|
||||||
* @param create constructor function for the signer
|
* @param create constructor function for the signer
|
||||||
|
* @param speed speed test result, NULL to omit
|
||||||
* @return TRUE if test passed
|
* @return TRUE if test passed
|
||||||
*/
|
*/
|
||||||
bool (*test_signer)(crypto_tester_t *this, integrity_algorithm_t alg,
|
bool (*test_signer)(crypto_tester_t *this, integrity_algorithm_t alg,
|
||||||
signer_constructor_t create);
|
signer_constructor_t create, u_int *speed);
|
||||||
/**
|
/**
|
||||||
* Test a hasher algorithm.
|
* Test a hasher algorithm.
|
||||||
*
|
*
|
||||||
* @param alg algorithm to test
|
* @param alg algorithm to test
|
||||||
* @param create constructor function for the hasher
|
* @param create constructor function for the hasher
|
||||||
|
* @param speed speed test result, NULL to omit
|
||||||
* @return TRUE if test passed
|
* @return TRUE if test passed
|
||||||
*/
|
*/
|
||||||
bool (*test_hasher)(crypto_tester_t *this, hash_algorithm_t alg,
|
bool (*test_hasher)(crypto_tester_t *this, hash_algorithm_t alg,
|
||||||
hasher_constructor_t create);
|
hasher_constructor_t create, u_int *speed);
|
||||||
/**
|
/**
|
||||||
* Test a PRF algorithm.
|
* Test a PRF algorithm.
|
||||||
*
|
*
|
||||||
* @param alg algorithm to test
|
* @param alg algorithm to test
|
||||||
* @param create constructor function for the PRF
|
* @param create constructor function for the PRF
|
||||||
|
* @param speed speed test result, NULL to omit
|
||||||
* @return TRUE if test passed
|
* @return TRUE if test passed
|
||||||
*/
|
*/
|
||||||
bool (*test_prf)(crypto_tester_t *this, pseudo_random_function_t alg,
|
bool (*test_prf)(crypto_tester_t *this, pseudo_random_function_t alg,
|
||||||
prf_constructor_t create);
|
prf_constructor_t create, u_int *speed);
|
||||||
/**
|
/**
|
||||||
* Test a RNG implementation.
|
* Test a RNG implementation.
|
||||||
*
|
*
|
||||||
* @param alg algorithm to test
|
* @param alg algorithm to test
|
||||||
* @param create constructor function for the RNG
|
* @param create constructor function for the RNG
|
||||||
|
* @param speed speed test result, NULL to omit
|
||||||
* @return TRUE if test passed
|
* @return TRUE if test passed
|
||||||
*/
|
*/
|
||||||
bool (*test_rng)(crypto_tester_t *this, rng_quality_t quality,
|
bool (*test_rng)(crypto_tester_t *this, rng_quality_t quality,
|
||||||
rng_constructor_t create);
|
rng_constructor_t create, u_int *speed);
|
||||||
/**
|
/**
|
||||||
* Add a test vector to test a crypter.
|
* Add a test vector to test a crypter.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user