aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-08-18 20:15:18 +0200
committerMartin Willi <martin@revosec.ch>2010-08-19 19:02:33 +0200
commite09a87d652a3727c2288f9752c9ef12c473387ba (patch)
tree720215ab03cfb9b4476325333f9d64f9b94dc182 /src/libstrongswan
parentb519071299562400b8f3f3a7c43e5d2d2009c08b (diff)
downloadstrongswan-e09a87d652a3727c2288f9752c9ef12c473387ba.tar.bz2
strongswan-e09a87d652a3727c2288f9752c9ef12c473387ba.tar.xz
Added AEAD support to crypto tester
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c171
-rw-r--r--src/libstrongswan/crypto/crypto_tester.h44
2 files changed, 214 insertions, 1 deletions
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index a5434cff0..79703830c 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -41,6 +41,11 @@ struct private_crypto_tester_t {
linked_list_t *crypter;
/**
+ * List of aead test vectors
+ */
+ linked_list_t *aead;
+
+ /**
* List of signer test vectors
*/
linked_list_t *signer;
@@ -256,6 +261,162 @@ METHOD(crypto_tester_t, test_crypter, bool,
}
/**
+ * Benchmark an aead transform
+ */
+static u_int bench_aead(private_crypto_tester_t *this,
+ encryption_algorithm_t alg, aead_constructor_t create)
+{
+ aead_t *aead;
+
+ aead = create(alg, 0);
+ if (aead)
+ {
+ char iv[aead->get_iv_size(aead)];
+ char key[aead->get_key_size(aead)];
+ char assoc[4];
+ chunk_t buf;
+ struct timespec start;
+ u_int runs;
+ size_t icv;
+
+ memset(iv, 0x56, sizeof(iv));
+ memset(key, 0x12, sizeof(key));
+ memset(assoc, 0x78, sizeof(assoc));
+ aead->set_key(aead, chunk_from_thing(key));
+ icv = aead->get_icv_size(aead);
+
+ buf = chunk_alloc(this->bench_size + icv);
+ memset(buf.ptr, 0x34, buf.len);
+ buf.len -= icv;
+
+ runs = 0;
+ start_timing(&start);
+ while (end_timing(&start) < this->bench_time)
+ {
+ aead->encrypt(aead, buf, chunk_from_thing(assoc),
+ chunk_from_thing(iv), NULL);
+ aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv),
+ chunk_from_thing(assoc), chunk_from_thing(iv), NULL);
+ runs++;
+ }
+ free(buf.ptr);
+ aead->destroy(aead);
+
+ return runs;
+ }
+ return 0;
+}
+
+METHOD(crypto_tester_t, test_aead, bool,
+ private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
+ aead_constructor_t create, u_int *speed)
+{
+ enumerator_t *enumerator;
+ aead_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->aead->create_enumerator(this->aead);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ aead_t *aead;
+ chunk_t key, plain, cipher, iv, assoc;
+ size_t icv;
+
+ if (vector->alg != alg)
+ {
+ continue;
+ }
+ if (key_size && key_size != vector->key_size)
+ { /* test only vectors with a specific key size, if key size given */
+ continue;
+ }
+ aead = create(alg, vector->key_size);
+ if (!aead)
+ { /* key size not supported... */
+ continue;
+ }
+
+ failed = FALSE;
+ tested++;
+
+ key = chunk_create(vector->key, aead->get_key_size(aead));
+ aead->set_key(aead, key);
+ iv = chunk_create(vector->iv, aead->get_iv_size(aead));
+ assoc = chunk_create(vector->adata, vector->alen);
+ icv = aead->get_icv_size(aead);
+
+ /* allocated encryption */
+ plain = chunk_create(vector->plain, vector->len);
+ aead->encrypt(aead, plain, assoc, iv, &cipher);
+ if (!memeq(vector->cipher, cipher.ptr, cipher.len))
+ {
+ failed = TRUE;
+ }
+ /* inline decryption */
+ if (!aead->decrypt(aead, cipher, assoc, iv, NULL))
+ {
+ failed = TRUE;
+ }
+ if (!memeq(vector->plain, cipher.ptr, cipher.len - icv))
+ {
+ failed = TRUE;
+ }
+ free(cipher.ptr);
+ /* allocated decryption */
+ cipher = chunk_create(vector->cipher, vector->len + icv);
+ if (!aead->decrypt(aead, cipher, assoc, iv, &plain))
+ {
+ plain = chunk_empty;
+ failed = TRUE;
+ }
+ else if (!memeq(vector->plain, plain.ptr, plain.len))
+ {
+ failed = TRUE;
+ }
+ plain.ptr = realloc(plain.ptr, plain.len + icv);
+ /* inline encryption */
+ aead->encrypt(aead, plain, assoc, iv, NULL);
+ if (!memeq(vector->cipher, plain.ptr, plain.len + icv))
+ {
+ failed = TRUE;
+ }
+ free(plain.ptr);
+
+ aead->destroy(aead);
+ if (failed)
+ {
+ DBG1(DBG_LIB, "disabled %N: %s test vector failed",
+ encryption_algorithm_names, alg, get_name(vector));
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1(DBG_LIB, "%s %N: no test vectors found",
+ this->required ? "disabled" : "enabled ",
+ encryption_algorithm_names, alg);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ if (speed)
+ {
+ *speed = bench_aead(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;
+}
+
+/**
* Benchmark a signer
*/
static u_int bench_signer(private_crypto_tester_t *this,
@@ -805,6 +966,12 @@ METHOD(crypto_tester_t, add_crypter_vector, void,
this->crypter->insert_last(this->crypter, vector);
}
+METHOD(crypto_tester_t, add_aead_vector, void,
+ private_crypto_tester_t *this, aead_test_vector_t *vector)
+{
+ this->aead->insert_last(this->aead, vector);
+}
+
METHOD(crypto_tester_t, add_signer_vector, void,
private_crypto_tester_t *this, signer_test_vector_t *vector)
{
@@ -833,6 +1000,7 @@ METHOD(crypto_tester_t, destroy, void,
private_crypto_tester_t *this)
{
this->crypter->destroy(this->crypter);
+ this->aead->destroy(this->aead);
this->signer->destroy(this->signer);
this->hasher->destroy(this->hasher);
this->prf->destroy(this->prf);
@@ -850,11 +1018,13 @@ crypto_tester_t *crypto_tester_create()
INIT(this,
.public = {
.test_crypter = _test_crypter,
+ .test_aead = _test_aead,
.test_signer = _test_signer,
.test_hasher = _test_hasher,
.test_prf = _test_prf,
.test_rng = _test_rng,
.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,
@@ -862,6 +1032,7 @@ crypto_tester_t *crypto_tester_create()
.destroy = _destroy,
},
.crypter = linked_list_create(),
+ .aead = linked_list_create(),
.signer = linked_list_create(),
.hasher = linked_list_create(),
.prf = linked_list_create(),
diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h
index a670931a4..cef0b3c18 100644
--- a/src/libstrongswan/crypto/crypto_tester.h
+++ b/src/libstrongswan/crypto/crypto_tester.h
@@ -26,6 +26,7 @@ typedef struct crypto_tester_t crypto_tester_t;
#include <crypto/crypto_factory.h>
typedef struct crypter_test_vector_t crypter_test_vector_t;
+typedef struct aead_test_vector_t aead_test_vector_t;
typedef struct signer_test_vector_t signer_test_vector_t;
typedef struct hasher_test_vector_t hasher_test_vector_t;
typedef struct prf_test_vector_t prf_test_vector_t;
@@ -48,6 +49,27 @@ struct crypter_test_vector_t {
u_char *cipher;
};
+struct aead_test_vector_t {
+ /** encryption algorithm this vector tests */
+ encryption_algorithm_t alg;
+ /** key length to use, in bytes */
+ size_t key_size;
+ /** encryption key of test vector */
+ u_char *key;
+ /** initialization vector, using crypters blocksize bytes */
+ u_char *iv;
+ /** length of associated data */
+ size_t alen;
+ /** associated data */
+ u_char *adata;
+ /** length of plain text */
+ size_t len;
+ /** plain text */
+ u_char *plain;
+ /** cipher text */
+ u_char *cipher;
+};
+
struct signer_test_vector_t {
/** signer algorithm this test vector tests */
pseudo_random_function_t alg;
@@ -114,7 +136,7 @@ struct crypto_tester_t {
* Test a crypter algorithm, optionally using a specified key size.
*
* @param alg algorithm to test
- * @param key_size key size to test, 0 for all
+ * @param key_size key size to test, 0 for default
* @param create constructor function for the crypter
* @param speed speed test result, NULL to omit
* @return TRUE if test passed
@@ -122,6 +144,19 @@ struct crypto_tester_t {
bool (*test_crypter)(crypto_tester_t *this, encryption_algorithm_t alg,
size_t key_size, crypter_constructor_t create,
u_int *speed);
+
+ /**
+ * Test an aead algorithm, optionally using a specified key size.
+ *
+ * @param alg algorithm to test
+ * @param key_size key size to test, 0 for default
+ * @param create constructor function for the aead transform
+ * @param speed speed test result, NULL to omit
+ * @return TRUE if test passed
+ */
+ bool (*test_aead)(crypto_tester_t *this, encryption_algorithm_t alg,
+ size_t key_size, aead_constructor_t create,
+ u_int *speed);
/**
* Test a signer algorithm.
*
@@ -170,6 +205,13 @@ struct crypto_tester_t {
void (*add_crypter_vector)(crypto_tester_t *this,
crypter_test_vector_t *vector);
/**
+ * Add a test vector to test an aead transform.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_aead_vector)(crypto_tester_t *this,
+ aead_test_vector_t *vector);
+ /**
* Add a test vector to test a signer.
*
* @param vector pointer to test vector