summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2010-11-28 11:42:20 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2010-11-28 11:42:20 +0000
commitf73fba54dc8b30c6482e1e8abf15bbf455592fcd (patch)
treea449515607c5e51a5c703d7a9b1149c9e4a11560 /src/libstrongswan/crypto
parentb8064f4099997a9e2179f3ad4ace605f5ccac3a1 (diff)
downloadvyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.tar.gz
vyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.zip
[svn-upgrade] new version strongswan (4.5.0)
Diffstat (limited to 'src/libstrongswan/crypto')
-rw-r--r--src/libstrongswan/crypto/aead.c162
-rw-r--r--src/libstrongswan/crypto/aead.h119
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c23
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.h39
-rw-r--r--src/libstrongswan/crypto/crypto_factory.c507
-rw-r--r--src/libstrongswan/crypto/crypto_factory.h54
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c614
-rw-r--r--src/libstrongswan/crypto/crypto_tester.h60
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c24
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h10
-rw-r--r--src/libstrongswan/crypto/prfs/prf.c7
-rw-r--r--src/libstrongswan/crypto/prfs/prf.h8
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.c254
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.txt22
-rw-r--r--src/libstrongswan/crypto/signers/signer.c9
-rw-r--r--src/libstrongswan/crypto/signers/signer.h10
-rw-r--r--src/libstrongswan/crypto/transform.c7
-rw-r--r--src/libstrongswan/crypto/transform.h1
18 files changed, 1483 insertions, 447 deletions
diff --git a/src/libstrongswan/crypto/aead.c b/src/libstrongswan/crypto/aead.c
new file mode 100644
index 000000000..51cb05909
--- /dev/null
+++ b/src/libstrongswan/crypto/aead.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * 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.
+ */
+
+#include "aead.h"
+
+#include <debug.h>
+
+typedef struct private_aead_t private_aead_t;
+
+/**
+ * Private data of an aead_t object.
+ */
+struct private_aead_t {
+
+ /**
+ * Public aead_t interface.
+ */
+ aead_t public;
+
+ /**
+ * traditional crypter
+ */
+ crypter_t *crypter;
+
+ /**
+ * draditional signer
+ */
+ signer_t *signer;
+};
+
+METHOD(aead_t, encrypt, void,
+ private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
+ chunk_t *encrypted)
+{
+ chunk_t encr, sig;
+
+ this->signer->get_signature(this->signer, assoc, NULL);
+ this->signer->get_signature(this->signer, iv, NULL);
+
+ if (encrypted)
+ {
+ this->crypter->encrypt(this->crypter, plain, iv, &encr);
+ this->signer->allocate_signature(this->signer, encr, &sig);
+ *encrypted = chunk_cat("cmm", iv, encr, sig);
+ }
+ else
+ {
+ this->crypter->encrypt(this->crypter, plain, iv, NULL);
+ this->signer->get_signature(this->signer, plain, plain.ptr + plain.len);
+ }
+}
+
+METHOD(aead_t, decrypt, bool,
+ private_aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
+ chunk_t *plain)
+{
+ chunk_t sig;
+ size_t bs;
+
+ bs = this->crypter->get_block_size(this->crypter);
+ sig.len = this->signer->get_block_size(this->signer);
+ if (sig.len > encrypted.len || (encrypted.len - sig.len) % bs)
+ {
+ DBG1(DBG_LIB, "invalid encrypted data length %d with block size %d",
+ encrypted.len - sig.len, bs);
+ return FALSE;
+ }
+ chunk_split(encrypted, "mm", encrypted.len - sig.len,
+ &encrypted, sig.len, &sig);
+
+ this->signer->get_signature(this->signer, assoc, NULL);
+ this->signer->get_signature(this->signer, iv, NULL);
+ if (!this->signer->verify_signature(this->signer, encrypted, sig))
+ {
+ DBG1(DBG_LIB, "MAC verification failed");
+ return FALSE;
+ }
+ this->crypter->decrypt(this->crypter, encrypted, iv, plain);
+ return TRUE;
+}
+
+METHOD(aead_t, get_block_size, size_t,
+ private_aead_t *this)
+{
+ return this->crypter->get_block_size(this->crypter);
+}
+
+METHOD(aead_t, get_icv_size, size_t,
+ private_aead_t *this)
+{
+ return this->signer->get_block_size(this->signer);
+}
+
+METHOD(aead_t, get_iv_size, size_t,
+ private_aead_t *this)
+{
+ return this->crypter->get_iv_size(this->crypter);
+}
+
+METHOD(aead_t, get_key_size, size_t,
+ private_aead_t *this)
+{
+ return this->crypter->get_key_size(this->crypter) +
+ this->signer->get_key_size(this->signer);
+}
+
+METHOD(aead_t, set_key, void,
+ private_aead_t *this, chunk_t key)
+{
+ chunk_t sig, enc;
+
+ chunk_split(key, "mm", this->signer->get_key_size(this->signer), &sig,
+ this->crypter->get_key_size(this->crypter), &enc);
+
+ this->signer->set_key(this->signer, sig);
+ this->crypter->set_key(this->crypter, enc);
+}
+
+METHOD(aead_t, destroy, void,
+ private_aead_t *this)
+{
+ this->crypter->destroy(this->crypter);
+ this->signer->destroy(this->signer);
+ free(this);
+}
+
+/**
+ * See header
+ */
+aead_t *aead_create(crypter_t *crypter, signer_t *signer)
+{
+ private_aead_t *this;
+
+ INIT(this,
+ .public = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_block_size = _get_block_size,
+ .get_icv_size = _get_icv_size,
+ .get_iv_size = _get_iv_size,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ .crypter = crypter,
+ .signer = signer,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/crypto/aead.h b/src/libstrongswan/crypto/aead.h
new file mode 100644
index 000000000..d560381d9
--- /dev/null
+++ b/src/libstrongswan/crypto/aead.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * 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.
+ */
+
+/**
+ * @defgroup aead aead
+ * @{ @ingroup crypto
+ */
+
+#ifndef AEAD_H_
+#define AEAD_H_
+
+typedef struct aead_t aead_t;
+
+#include <library.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+
+/**
+ * Authenticated encryption / authentication decryption interface.
+ */
+struct aead_t {
+
+ /**
+ * Encrypt and sign data, sign associated data.
+ *
+ * The plain data must be a multiple of get_block_size(), the IV must
+ * have a length of get_iv_size().
+ * If encrypted is NULL, the encryption is done inline. The buffer must
+ * have space for additional get_icv_size() data, the ICV value is
+ * appended silently to the plain chunk.
+ *
+ * @param plain data to encrypt and sign
+ * @param assoc associated data to sign
+ * @param iv initialization vector
+ * @param encrypted allocated encryption result
+ */
+ void (*encrypt)(aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
+ chunk_t *encrypted);
+
+ /**
+ * Decrypt and verify data, verify associated data.
+ *
+ * The IV must have a length of get_iv_size().
+ * If plain is NULL, the decryption is done inline. The decrypted data
+ * is returned in the encrypted chunk, the last get_icv_size() bytes
+ * contain the verified ICV.
+ *
+ * @param encrypted data to encrypt and verify
+ * @param assoc associated data to verify
+ * @param iv initialization vector
+ * @param plain allocated result, if successful
+ * @return TRUE if MAC verification successful
+ */
+ bool (*decrypt)(aead_t *this, chunk_t encrypted, chunk_t assoc, chunk_t iv,
+ chunk_t *plain);
+
+ /**
+ * Get the block size for encryption.
+ *
+ * @return block size in bytes
+ */
+ size_t (*get_block_size)(aead_t *this);
+
+ /**
+ * Get the integrity check value size of the algorithm.
+ *
+ * @return ICV size in bytes
+ */
+ size_t (*get_icv_size)(aead_t *this);
+
+ /**
+ * Get the size of the initialization vector.
+ *
+ * @return IV size in bytes
+ */
+ size_t (*get_iv_size)(aead_t *this);
+
+ /**
+ * Get the size of the key material (for encryption and authentication).
+ *
+ * @return key size in bytes
+ */
+ size_t (*get_key_size)(aead_t *this);
+
+ /**
+ * Set the key for encryption and authentication.
+ *
+ * @param key encryption and authentication key
+ */
+ void (*set_key)(aead_t *this, chunk_t key);
+
+ /**
+ * Destroy a aead_t.
+ */
+ void (*destroy)(aead_t *this);
+};
+
+/**
+ * Create a aead instance using traditional transforms.
+ *
+ * @param crypter encryption transform for this aead
+ * @param signer integrity tranform for this aead
+ * @return aead transform
+ */
+aead_t *aead_create(crypter_t *crypter, signer_t *signer);
+
+#endif /** AEAD_H_ @}*/
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index ebd35a8a0..0730c707c 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -159,4 +159,25 @@ int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size)
return oid;
}
-
+/*
+ * Described in header.
+ */
+bool encryption_algorithm_is_aead(encryption_algorithm_t alg)
+{
+ switch (alg)
+ {
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ case ENCR_NULL_AUTH_AES_GMAC:
+ case ENCR_CAMELLIA_CCM_ICV8:
+ case ENCR_CAMELLIA_CCM_ICV12:
+ case ENCR_CAMELLIA_CCM_ICV16:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h
index f052a181d..3bf039681 100644
--- a/src/libstrongswan/crypto/crypters/crypter.h
+++ b/src/libstrongswan/crypto/crypters/crypter.h
@@ -42,6 +42,7 @@ enum encryption_algorithm_t {
ENCR_DES_IV32 = 9,
ENCR_NULL = 11,
ENCR_AES_CBC = 12,
+ /** CTR as specified for IPsec (RFC5930/RFC3686), nonce appended to key */
ENCR_AES_CTR = 13,
ENCR_AES_CCM_ICV8 = 14,
ENCR_AES_CCM_ICV12 = 15,
@@ -51,6 +52,7 @@ enum encryption_algorithm_t {
ENCR_AES_GCM_ICV16 = 20,
ENCR_NULL_AUTH_AES_GMAC = 21,
ENCR_CAMELLIA_CBC = 23,
+ /* CTR as specified for IPsec (RFC5529), nonce appended to key */
ENCR_CAMELLIA_CTR = 24,
ENCR_CAMELLIA_CCM_ICV8 = 25,
ENCR_CAMELLIA_CCM_ICV12 = 26,
@@ -81,8 +83,8 @@ struct crypter_t {
/**
* Encrypt a chunk of data and allocate space for the encrypted value.
*
- * The length of the iv must equal to get_block_size(), while the length
- * of data must be a multiple it.
+ * The length of the iv must equal to get_iv_size(), while the length
+ * of data must be a multiple of get_block_size().
* If encrypted is NULL, the encryption is done in-place (overwriting data).
*
* @param data data to encrypt
@@ -95,8 +97,8 @@ struct crypter_t {
/**
* Decrypt a chunk of data and allocate space for the decrypted value.
*
- * The length of the iv must equal to get_block_size(), while the length
- * of data must be a multiple it.
+ * The length of the iv must equal to get_iv_size(), while the length
+ * of data must be a multiple of get_block_size().
* If decrpyted is NULL, the encryption is done in-place (overwriting data).
*
* @param data data to decrypt
@@ -109,14 +111,29 @@ struct crypter_t {
/**
* Get the block size of the crypto algorithm.
*
- * @return block size in bytes
+ * get_block_size() returns the smallest block the crypter can handle,
+ * not the block size of the underlying crypto algorithm. For counter mode,
+ * it is usually 1.
+ *
+ * @return block size in bytes
*/
size_t (*get_block_size) (crypter_t *this);
/**
+ * Get the IV size of the crypto algorithm.
+ *
+ * @return initialization vector size in bytes
+ */
+ size_t (*get_iv_size)(crypter_t *this);
+
+ /**
* Get the key size of the crypto algorithm.
*
- * @return key size in bytes
+ * get_key_size() might return a key length different from the key
+ * size passed to the factory constructor. For Counter Mode, the nonce
+ * is handled as a part of the key material and is passed to set_key().
+ *
+ * @return key size in bytes
*/
size_t (*get_key_size) (crypter_t *this);
@@ -125,7 +142,7 @@ struct crypter_t {
*
* The length of the key must match get_key_size().
*
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (crypter_t *this, chunk_t key);
@@ -153,4 +170,12 @@ encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size);
*/
int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size);
+/**
+ * Check if an encryption algorithm identifier is an AEAD algorithm.
+ *
+ * @param alg algorithm identifier
+ * @return TRUE if it is an AEAD algorithm
+ */
+bool encryption_algorithm_is_aead(encryption_algorithm_t alg);
+
#endif /** CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
index fee71953d..f2f01987d 100644
--- a/src/libstrongswan/crypto/crypto_factory.c
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -22,16 +22,20 @@
typedef struct entry_t entry_t;
struct entry_t {
- /** algorithm */
+ /* algorithm */
u_int algo;
+ /* benchmarked speed */
+ u_int speed;
/* constructor */
union {
crypter_constructor_t create_crypter;
+ aead_constructor_t create_aead;
signer_constructor_t create_signer;
hasher_constructor_t create_hasher;
prf_constructor_t create_prf;
rng_constructor_t create_rng;
dh_constructor_t create_dh;
+ void *create;
};
};
@@ -53,6 +57,11 @@ struct private_crypto_factory_t {
linked_list_t *crypters;
/**
+ * registered aead transforms, as entry_t
+ */
+ linked_list_t *aeads;
+
+ /**
* registered signers, as entry_t
*/
linked_list_t *signers;
@@ -93,16 +102,19 @@ struct private_crypto_factory_t {
bool test_on_create;
/**
+ * run algorithm benchmark during registration
+ */
+ bool bench;
+
+ /**
* rwlock to lock access to modules
*/
rwlock_t *lock;
};
-/**
- * Implementation of crypto_factory_t.create_crypter.
- */
-static crypter_t* create_crypter(private_crypto_factory_t *this,
- encryption_algorithm_t algo, size_t key_size)
+METHOD(crypto_factory_t, create_crypter, crypter_t*,
+ private_crypto_factory_t *this, encryption_algorithm_t algo,
+ size_t key_size)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -116,7 +128,7 @@ static crypter_t* create_crypter(private_crypto_factory_t *this,
{
if (this->test_on_create &&
!this->tester->test_crypter(this->tester, algo, key_size,
- entry->create_crypter))
+ entry->create_crypter, NULL))
{
continue;
}
@@ -132,11 +144,40 @@ static crypter_t* create_crypter(private_crypto_factory_t *this,
return crypter;
}
-/**
- * Implementation of crypto_factory_t.create_signer.
- */
-static signer_t* create_signer(private_crypto_factory_t *this,
- integrity_algorithm_t algo)
+METHOD(crypto_factory_t, create_aead, aead_t*,
+ private_crypto_factory_t *this, encryption_algorithm_t algo,
+ size_t key_size)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ aead_t *aead = NULL;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->aeads->create_enumerator(this->aeads);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ if (this->test_on_create &&
+ !this->tester->test_aead(this->tester, algo, key_size,
+ entry->create_aead, NULL))
+ {
+ continue;
+ }
+ aead = entry->create_aead(algo, key_size);
+ if (aead)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ return aead;
+}
+
+METHOD(crypto_factory_t, create_signer, signer_t*,
+ private_crypto_factory_t *this, integrity_algorithm_t algo)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -150,7 +191,7 @@ static signer_t* create_signer(private_crypto_factory_t *this,
{
if (this->test_on_create &&
!this->tester->test_signer(this->tester, algo,
- entry->create_signer))
+ entry->create_signer, NULL))
{
continue;
}
@@ -167,11 +208,8 @@ static signer_t* create_signer(private_crypto_factory_t *this,
return signer;
}
-/**
- * Implementation of crypto_factory_t.create_hasher.
- */
-static hasher_t* create_hasher(private_crypto_factory_t *this,
- hash_algorithm_t algo)
+METHOD(crypto_factory_t, create_hasher, hasher_t*,
+ private_crypto_factory_t *this, hash_algorithm_t algo)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -185,7 +223,7 @@ static hasher_t* create_hasher(private_crypto_factory_t *this,
{
if (this->test_on_create && algo != HASH_PREFERRED &&
!this->tester->test_hasher(this->tester, algo,
- entry->create_hasher))
+ entry->create_hasher, NULL))
{
continue;
}
@@ -201,11 +239,8 @@ static hasher_t* create_hasher(private_crypto_factory_t *this,
return hasher;
}
-/**
- * Implementation of crypto_factory_t.create_prf.
- */
-static prf_t* create_prf(private_crypto_factory_t *this,
- pseudo_random_function_t algo)
+METHOD(crypto_factory_t, create_prf, prf_t*,
+ private_crypto_factory_t *this, pseudo_random_function_t algo)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -218,7 +253,8 @@ 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))
+ !this->tester->test_prf(this->tester, algo,
+ entry->create_prf, NULL))
{
continue;
}
@@ -234,10 +270,8 @@ static prf_t* create_prf(private_crypto_factory_t *this,
return prf;
}
-/**
- * Implementation of crypto_factory_t.create_rng.
- */
-static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
+METHOD(crypto_factory_t, create_rng, rng_t*,
+ private_crypto_factory_t *this, rng_quality_t quality)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -251,7 +285,8 @@ static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
if (entry->algo >= quality && diff > entry->algo - quality)
{
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;
}
@@ -272,11 +307,8 @@ static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
return NULL;
}
-/**
- * Implementation of crypto_factory_t.create_dh.
- */
-static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
- diffie_hellman_group_t group)
+METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
+ private_crypto_factory_t *this, diffie_hellman_group_t group, ...)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -288,7 +320,21 @@ static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
{
if (entry->algo == group)
{
- diffie_hellman = entry->create_dh(group);
+ if (group == MODP_CUSTOM)
+ {
+ va_list args;
+ chunk_t g, p;
+
+ va_start(args, group);
+ g = va_arg(args, chunk_t);
+ p = va_arg(args, chunk_t);
+ va_end(args);
+ diffie_hellman = entry->create_dh(MODP_CUSTOM, g, p);
+ }
+ else
+ {
+ diffie_hellman = entry->create_dh(group);
+ }
if (diffie_hellman)
{
break;
@@ -301,30 +347,65 @@ static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
}
/**
- * Implementation of crypto_factory_t.add_crypter.
+ * Insert an algorithm entry to a list
*/
-static void add_crypter(private_crypto_factory_t *this,
- encryption_algorithm_t algo,
- crypter_constructor_t create)
+static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
+ int algo, u_int speed, void *create)
{
- if (!this->test_on_add ||
- this->tester->test_crypter(this->tester, algo, 0, 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**)&current) == SUCCESS)
+ {
+ tmp->insert_last(tmp, current);
+ }
+ while (tmp->remove_first(tmp, (void**)&current) == 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)
{
- entry_t *entry = malloc_thing(entry_t);
+ list->insert_last(list, entry);
+ }
+ this->lock->unlock(this->lock);
+}
+
+METHOD(crypto_factory_t, add_crypter, void,
+ private_crypto_factory_t *this, encryption_algorithm_t algo,
+ crypter_constructor_t create)
+{
+ u_int speed = 0;
- 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,
+ this->bench ? &speed : NULL))
+ {
+ add_entry(this, this->crypters, algo, speed, create);
}
}
-/**
- * Implementation of crypto_factory_t.remove_crypter.
- */
-static void remove_crypter(private_crypto_factory_t *this,
- crypter_constructor_t create)
+METHOD(crypto_factory_t, remove_crypter, void,
+ private_crypto_factory_t *this, crypter_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -343,30 +424,56 @@ static void remove_crypter(private_crypto_factory_t *this,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.add_signer.
- */
-static void add_signer(private_crypto_factory_t *this,
- integrity_algorithm_t algo, signer_constructor_t create)
+METHOD(crypto_factory_t, add_aead, void,
+ private_crypto_factory_t *this, encryption_algorithm_t algo,
+ aead_constructor_t create)
{
+ u_int speed = 0;
+
if (!this->test_on_add ||
- this->tester->test_signer(this->tester, algo, create))
+ this->tester->test_aead(this->tester, algo, 0, create,
+ this->bench ? &speed : NULL))
{
- entry_t *entry = malloc_thing(entry_t);
+ add_entry(this, this->aeads, algo, speed, create);
+ }
+}
- 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);
+METHOD(crypto_factory_t, remove_aead, void,
+ private_crypto_factory_t *this, aead_constructor_t create)
+{
+ entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->aeads->create_enumerator(this->aeads);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create_aead == create)
+ {
+ this->aeads->remove_at(this->aeads, enumerator);
+ free(entry);
+ }
}
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.remove_signer.
- */
-static void remove_signer(private_crypto_factory_t *this,
- signer_constructor_t create)
+METHOD(crypto_factory_t, add_signer, void,
+ private_crypto_factory_t *this, integrity_algorithm_t algo,
+ signer_constructor_t create)
+{
+ u_int speed = 0;
+
+ if (!this->test_on_add ||
+ this->tester->test_signer(this->tester, algo, create,
+ this->bench ? &speed : NULL))
+ {
+ add_entry(this, this->signers, algo, speed, create);
+ }
+}
+
+METHOD(crypto_factory_t, remove_signer, void,
+ private_crypto_factory_t *this, signer_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -385,30 +492,22 @@ static void remove_signer(private_crypto_factory_t *this,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.add_hasher.
- */
-static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
- hasher_constructor_t create)
+METHOD(crypto_factory_t, add_hasher, void,
+ private_crypto_factory_t *this, hash_algorithm_t algo,
+ hasher_constructor_t create)
{
+ u_int speed = 0;
+
if (!this->test_on_add ||
- this->tester->test_hasher(this->tester, algo, create))
+ this->tester->test_hasher(this->tester, algo, create,
+ this->bench ? &speed : NULL))
{
- 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);
+ add_entry(this, this->hashers, algo, speed, create);
}
}
-/**
- * Implementation of crypto_factory_t.remove_hasher.
- */
-static void remove_hasher(private_crypto_factory_t *this,
- hasher_constructor_t create)
+METHOD(crypto_factory_t, remove_hasher, void,
+ private_crypto_factory_t *this, hasher_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -427,29 +526,22 @@ static void remove_hasher(private_crypto_factory_t *this,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.add_prf.
- */
-static void add_prf(private_crypto_factory_t *this,
- pseudo_random_function_t algo, prf_constructor_t create)
+METHOD(crypto_factory_t, add_prf, void,
+ private_crypto_factory_t *this, pseudo_random_function_t algo,
+ prf_constructor_t create)
{
+ u_int speed = 0;
+
if (!this->test_on_add ||
- this->tester->test_prf(this->tester, algo, create))
+ this->tester->test_prf(this->tester, algo, create,
+ this->bench ? &speed : NULL))
{
- 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);
+ add_entry(this, this->prfs, algo, speed, create);
}
}
-/**
- * Implementation of crypto_factory_t.remove_prf.
- */
-static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
+METHOD(crypto_factory_t, remove_prf, void,
+ private_crypto_factory_t *this, prf_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -468,29 +560,22 @@ static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.add_rng.
- */
-static void add_rng(private_crypto_factory_t *this, rng_quality_t quality,
- rng_constructor_t create)
+METHOD(crypto_factory_t, add_rng, void,
+ private_crypto_factory_t *this, rng_quality_t quality,
+ rng_constructor_t create)
{
+ u_int speed = 0;
+
if (!this->test_on_add ||
- this->tester->test_rng(this->tester, quality, create))
+ this->tester->test_rng(this->tester, quality, create,
+ this->bench ? &speed : NULL))
{
- 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);
+ add_entry(this, this->rngs, quality, speed, create);
}
}
-/**
- * Implementation of crypto_factory_t.remove_rng.
- */
-static void remove_rng(private_crypto_factory_t *this, rng_constructor_t create)
+METHOD(crypto_factory_t, remove_rng, void,
+ private_crypto_factory_t *this, rng_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -509,25 +594,15 @@ static void remove_rng(private_crypto_factory_t *this, rng_constructor_t create)
this->lock->unlock(this->lock);
}
-/**
- * Implementation of crypto_factory_t.add_dh.
- */
-static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group,
- dh_constructor_t create)
+METHOD(crypto_factory_t, add_dh, void,
+ private_crypto_factory_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- 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);
+ add_entry(this, this->dhs, group, 0, create);
}
-/**
- * Implementation of crypto_factory_t.remove_dh.
- */
-static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create)
+METHOD(crypto_factory_t, remove_dh, void,
+ private_crypto_factory_t *this, dh_constructor_t create)
{
entry_t *entry;
enumerator_t *enumerator;
@@ -591,14 +666,18 @@ static bool crypter_filter(void *n, entry_t **entry, encryption_algorithm_t *alg
return TRUE;
}
-/**
- * Implementation of crypto_factory_t.create_crypter_enumerator
- */
-static enumerator_t* create_crypter_enumerator(private_crypto_factory_t *this)
+METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
{
return create_enumerator(this, this->crypters, crypter_filter);
}
+METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
+{
+ return create_enumerator(this, this->aeads, crypter_filter);
+}
+
/**
* Filter function to enumerate algorithm, not entry
*/
@@ -608,10 +687,8 @@ static bool signer_filter(void *n, entry_t **entry, integrity_algorithm_t *algo)
return TRUE;
}
-/**
- * Implementation of crypto_factory_t.create_signer_enumerator
- */
-static enumerator_t* create_signer_enumerator(private_crypto_factory_t *this)
+METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
{
return create_enumerator(this, this->signers, signer_filter);
}
@@ -625,10 +702,8 @@ static bool hasher_filter(void *n, entry_t **entry, hash_algorithm_t *algo)
return TRUE;
}
-/**
- * Implementation of crypto_factory_t.create_hasher_enumerator
- */
-static enumerator_t* create_hasher_enumerator(private_crypto_factory_t *this)
+METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
{
return create_enumerator(this, this->hashers, hasher_filter);
}
@@ -642,10 +717,8 @@ static bool prf_filter(void *n, entry_t **entry, pseudo_random_function_t *algo)
return TRUE;
}
-/**
- * Implementation of crypto_factory_t.create_prf_enumerator
- */
-static enumerator_t* create_prf_enumerator(private_crypto_factory_t *this)
+METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
{
return create_enumerator(this, this->prfs, prf_filter);
}
@@ -659,24 +732,21 @@ static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group)
return TRUE;
}
-/**
- * Implementation of crypto_factory_t.create_dh_enumerator
- */
-static enumerator_t* create_dh_enumerator(private_crypto_factory_t *this)
+METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
{
return create_enumerator(this, this->dhs, dh_filter);
}
-/**
- * Implementation of crypto_factory_t.add_test_vector
- */
-static void add_test_vector(private_crypto_factory_t *this,
- transform_type_t type, void *vector)
+METHOD(crypto_factory_t, add_test_vector, void,
+ 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 AEAD_ALGORITHM:
+ return this->tester->add_aead_vector(this->tester, vector);
case INTEGRITY_ALGORITHM:
return this->tester->add_signer_vector(this->tester, vector);
case HASH_ALGORITHM:
@@ -691,17 +761,16 @@ static void add_test_vector(private_crypto_factory_t *this,
}
}
-/**
- * Implementation of crypto_factory_t.destroy
- */
-static void destroy(private_crypto_factory_t *this)
-{
- this->crypters->destroy_function(this->crypters, free);
- this->signers->destroy_function(this->signers, free);
- this->hashers->destroy_function(this->hashers, free);
- this->prfs->destroy_function(this->prfs, free);
- this->rngs->destroy_function(this->rngs, free);
- this->dhs->destroy_function(this->dhs, free);
+METHOD(crypto_factory_t, destroy, void,
+ private_crypto_factory_t *this)
+{
+ this->crypters->destroy(this->crypters);
+ this->aeads->destroy(this->aeads);
+ this->signers->destroy(this->signers);
+ this->hashers->destroy(this->hashers);
+ this->prfs->destroy(this->prfs);
+ this->rngs->destroy(this->rngs);
+ this->dhs->destroy(this->dhs);
this->tester->destroy(this->tester);
this->lock->destroy(this->lock);
free(this);
@@ -712,46 +781,56 @@ static void destroy(private_crypto_factory_t *this)
*/
crypto_factory_t *crypto_factory_create()
{
- private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t);
-
- this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter;
- this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer;
- this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher;
- this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf;
- this->public.create_rng = (rng_t*(*)(crypto_factory_t*, rng_quality_t quality))create_rng;
- this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh;
- this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter;
- this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter;
- this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer;
- this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer;
- this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher;
- this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher;
- this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf;
- this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf;
- this->public.add_rng = (void(*)(crypto_factory_t*, rng_quality_t quality, rng_constructor_t create))add_rng;
- this->public.remove_rng = (void(*)(crypto_factory_t*, rng_constructor_t create))remove_rng;
- this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh;
- this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh;
- this->public.create_crypter_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_crypter_enumerator;
- this->public.create_signer_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_signer_enumerator;
- 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();
- this->signers = linked_list_create();
- this->hashers = linked_list_create();
- this->prfs = linked_list_create();
- this->rngs = linked_list_create();
- this->dhs = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_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);
+ private_crypto_factory_t *this;
+
+ INIT(this,
+ .public = {
+ .create_crypter = _create_crypter,
+ .create_aead = _create_aead,
+ .create_signer = _create_signer,
+ .create_hasher = _create_hasher,
+ .create_prf = _create_prf,
+ .create_rng = _create_rng,
+ .create_dh = _create_dh,
+ .add_crypter = _add_crypter,
+ .remove_crypter = _remove_crypter,
+ .add_aead = _add_aead,
+ .remove_aead = _remove_aead,
+ .add_signer = _add_signer,
+ .remove_signer = _remove_signer,
+ .add_hasher = _add_hasher,
+ .remove_hasher = _remove_hasher,
+ .add_prf = _add_prf,
+ .remove_prf = _remove_prf,
+ .add_rng = _add_rng,
+ .remove_rng = _remove_rng,
+ .add_dh = _add_dh,
+ .remove_dh = _remove_dh,
+ .create_crypter_enumerator = _create_crypter_enumerator,
+ .create_aead_enumerator = _create_aead_enumerator,
+ .create_signer_enumerator = _create_signer_enumerator,
+ .create_hasher_enumerator = _create_hasher_enumerator,
+ .create_prf_enumerator = _create_prf_enumerator,
+ .create_dh_enumerator = _create_dh_enumerator,
+ .add_test_vector = _add_test_vector,
+ .destroy = _destroy,
+ },
+ .crypters = linked_list_create(),
+ .aeads = linked_list_create(),
+ .signers = linked_list_create(),
+ .hashers = linked_list_create(),
+ .prfs = linked_list_create(),
+ .rngs = linked_list_create(),
+ .dhs = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .tester = crypto_tester_create(),
+ .test_on_add = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_add", FALSE),
+ .test_on_create = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_create", FALSE),
+ .bench = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.bench", FALSE),
+ );
return &this->public;
}
diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h
index 9c6effd26..ff06eda7b 100644
--- a/src/libstrongswan/crypto/crypto_factory.h
+++ b/src/libstrongswan/crypto/crypto_factory.h
@@ -25,6 +25,7 @@ typedef struct crypto_factory_t crypto_factory_t;
#include <library.h>
#include <crypto/crypters/crypter.h>
+#include <crypto/aead.h>
#include <crypto/signers/signer.h>
#include <crypto/hashers/hasher.h>
#include <crypto/prfs/prf.h>
@@ -38,6 +39,11 @@ typedef struct crypto_factory_t crypto_factory_t;
typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
size_t key_size);
/**
+ * Constructor function for aead transforms
+ */
+typedef aead_t* (*aead_constructor_t)(encryption_algorithm_t algo,
+ size_t key_size);
+/**
* Constructor function for signers
*/
typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
@@ -59,8 +65,11 @@ typedef rng_t* (*rng_constructor_t)(rng_quality_t quality);
/**
* Constructor function for diffie hellman
+ *
+ * The DH constructor accepts additional arguments for:
+ * - MODP_CUSTOM: chunk_t generator, chunk_t prime
*/
-typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group);
+typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group, ...);
/**
* Handles crypto modules and creates instances.
@@ -78,6 +87,16 @@ struct crypto_factory_t {
encryption_algorithm_t algo, size_t key_size);
/**
+ * Create a aead instance.
+ *
+ * @param algo encryption algorithm
+ * @param key_size length of the key in bytes
+ * @return aead_t instance, NULL if not supported
+ */
+ aead_t* (*create_aead)(crypto_factory_t *this,
+ encryption_algorithm_t algo, size_t key_size);
+
+ /**
* Create a symmetric signer instance.
*
* @param algo MAC algorithm to use
@@ -113,11 +132,13 @@ struct crypto_factory_t {
/**
* Create a diffie hellman instance.
*
+ * Additional arguments are passed to the DH constructor.
+ *
* @param group diffie hellman group
* @return diffie_hellman_t instance, NULL if not supported
*/
diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
- diffie_hellman_group_t group);
+ diffie_hellman_group_t group, ...);
/**
* Register a crypter constructor.
@@ -137,6 +158,23 @@ struct crypto_factory_t {
void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
/**
+ * Unregister a aead constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_aead)(crypto_factory_t *this, aead_constructor_t create);
+
+ /**
+ * Register a aead constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_aead)(crypto_factory_t *this, encryption_algorithm_t algo,
+ aead_constructor_t create);
+
+ /**
* Register a signer constructor.
*
* @param algo algorithm to constructor
@@ -230,6 +268,13 @@ struct crypto_factory_t {
enumerator_t* (*create_crypter_enumerator)(crypto_factory_t *this);
/**
+ * Create an enumerator over all registered aead algorithms.
+ *
+ * @return enumerator over encryption_algorithm_t
+ */
+ enumerator_t* (*create_aead_enumerator)(crypto_factory_t *this);
+
+ /**
* Create an enumerator over all registered signer algorithms.
*
* @return enumerator over integrity_algorithm_t
@@ -261,9 +306,10 @@ struct crypto_factory_t {
* Add a test vector to the crypto factory.
*
* @param type type of the test vector
- * @param ... pointer to a test vector, defined in crypto_tester.h
+ * @param vector pointer to a test vector, defined in crypto_tester.h
*/
- void (*add_test_vector)(crypto_factory_t *this, transform_type_t type, ...);
+ void (*add_test_vector)(crypto_factory_t *this, transform_type_t type,
+ void *vector);
/**
* Destroy a crypto_factory instance.
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index 76cc1cf2c..d17485ff2 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2009 Martin Willi
+ * Copyright (C) 2009-2010 Martin Willi
* Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 revosec AG
*
* 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
@@ -13,6 +14,10 @@
* for more details.
*/
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <time.h>
+
#include "crypto_tester.h"
#include <debug.h>
@@ -36,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;
@@ -64,13 +74,98 @@ struct private_crypto_tester_t {
* should we run RNG_TRUE tests? Enough entropy?
*/
bool rng_true;
+
+ /**
+ * time we test each algorithm
+ */
+ int bench_time;
+
+ /**
+ * size of buffer we use for benchmarking
+ */
+ int bench_size;
};
/**
- * Implementation of crypto_tester_t.test_crypter
+ * Get the name of a test vector, if available
+ */
+static const char* get_name(void *sym)
+{
+#ifdef HAVE_DLADDR
+ Dl_info dli;
+
+ if (dladdr(sym, &dli))
+ {
+ return dli.dli_sname;
+ }
+#endif
+ 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 bool test_crypter(private_crypto_tester_t *this,
- encryption_algorithm_t alg, size_t key_size, crypter_constructor_t create)
+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);
+ runs++;
+ 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,
+ private_crypto_tester_t *this, encryption_algorithm_t alg, size_t key_size,
+ crypter_constructor_t create, u_int *speed)
{
enumerator_t *enumerator;
crypter_test_vector_t *vector;
@@ -102,7 +197,7 @@ static bool test_crypter(private_crypto_tester_t *this,
key = chunk_create(vector->key, crypter->get_key_size(crypter));
crypter->set_key(crypter, key);
- iv = chunk_create(vector->iv, crypter->get_block_size(crypter));
+ iv = chunk_create(vector->iv, crypter->get_iv_size(crypter));
/* allocated encryption */
plain = chunk_create(vector->plain, vector->len);
@@ -136,8 +231,165 @@ static bool test_crypter(private_crypto_tester_t *this,
crypter->destroy(crypter);
if (failed)
{
- DBG1(DBG_LIB, "disabled %N: test vector %u 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_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;
+}
+
+/**
+ * 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);
+ runs += 2;
+ aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv),
+ chunk_from_thing(assoc), chunk_from_thing(iv), NULL);
+ runs += 2;
+ }
+ 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;
}
}
@@ -151,17 +403,64 @@ static bool test_crypter(private_crypto_tester_t *this,
}
if (!failed)
{
- DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
- encryption_algorithm_names, alg, tested);
+ 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;
}
/**
- * Implementation of crypto_tester_t.test_signer
+ * Benchmark a signer
*/
-static bool test_signer(private_crypto_tester_t *this,
- integrity_algorithm_t alg, signer_constructor_t create)
+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);
+ runs++;
+ 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,
+ private_crypto_tester_t *this, integrity_algorithm_t alg,
+ signer_constructor_t create, u_int *speed)
{
enumerator_t *enumerator;
signer_test_vector_t *vector;
@@ -226,11 +525,10 @@ static bool test_signer(private_crypto_tester_t *this,
/* signature to existing buffer, using append mode */
if (data.len > 2)
{
- memset(mac.ptr, 0, mac.len);
signer->allocate_signature(signer, chunk_create(data.ptr, 1), NULL);
signer->get_signature(signer, chunk_create(data.ptr + 1, 1), NULL);
- signer->get_signature(signer, chunk_skip(data, 2), mac.ptr);
- if (!memeq(vector->mac, mac.ptr, mac.len))
+ if (!signer->verify_signature(signer, chunk_skip(data, 2),
+ chunk_create(vector->mac, mac.len)))
{
failed = TRUE;
}
@@ -240,8 +538,8 @@ static bool test_signer(private_crypto_tester_t *this,
signer->destroy(signer);
if (failed)
{
- DBG1(DBG_LIB, "disabled %N: test vector %u failed",
- integrity_algorithm_names, alg, tested);
+ DBG1(DBG_LIB, "disabled %N: %s test vector failed",
+ integrity_algorithm_names, alg, get_name(vector));
break;
}
}
@@ -255,17 +553,58 @@ static bool test_signer(private_crypto_tester_t *this,
}
if (!failed)
{
- DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
- integrity_algorithm_names, alg, tested);
+ if (speed)
+ {
+ *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;
}
/**
- * Implementation of hasher_t.test_hasher
+ * Benchmark a hasher
*/
-static bool test_hasher(private_crypto_tester_t *this, hash_algorithm_t alg,
- hasher_constructor_t create)
+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,
+ private_crypto_tester_t *this, hash_algorithm_t alg,
+ hasher_constructor_t create, u_int *speed)
{
enumerator_t *enumerator;
hasher_test_vector_t *vector;
@@ -330,8 +669,8 @@ static bool test_hasher(private_crypto_tester_t *this, hash_algorithm_t alg,
hasher->destroy(hasher);
if (failed)
{
- DBG1(DBG_LIB, "disabled %N: test vector %u failed",
- hash_algorithm_names, alg, tested);
+ DBG1(DBG_LIB, "disabled %N: %s test vector failed",
+ hash_algorithm_names, alg, get_name(vector));
break;
}
}
@@ -345,17 +684,58 @@ static bool test_hasher(private_crypto_tester_t *this, hash_algorithm_t alg,
}
if (!failed)
{
- DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
- hash_algorithm_names, alg, tested);
+ if (speed)
+ {
+ *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;
}
/**
- * Implementation of crypto_tester_t.test_prf
+ * Benchmark a PRF
*/
-static bool test_prf(private_crypto_tester_t *this,
- pseudo_random_function_t alg, prf_constructor_t create)
+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,
+ private_crypto_tester_t *this, pseudo_random_function_t alg,
+ prf_constructor_t create, u_int *speed)
{
enumerator_t *enumerator;
prf_test_vector_t *vector;
@@ -431,8 +811,8 @@ static bool test_prf(private_crypto_tester_t *this,
prf->destroy(prf);
if (failed)
{
- DBG1(DBG_LIB, "disabled %N: test vector %u failed",
- pseudo_random_function_names, alg, tested);
+ DBG1(DBG_LIB, "disabled %N: %s test vector failed",
+ pseudo_random_function_names, alg, get_name(vector));
break;
}
}
@@ -446,17 +826,55 @@ static bool test_prf(private_crypto_tester_t *this,
}
if (!failed)
{
- DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
- pseudo_random_function_names, alg, tested);
+ if (speed)
+ {
+ *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;
}
/**
- * Implementation of crypto_tester_t.test_rng
+ * Benchmark a RNG
*/
-static bool test_rng(private_crypto_tester_t *this, rng_quality_t quality,
- rng_constructor_t create)
+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,
+ private_crypto_tester_t *this, rng_quality_t quality,
+ rng_constructor_t create, u_int *speed)
{
enumerator_t *enumerator;
rng_test_vector_t *vector;
@@ -515,8 +933,8 @@ static bool test_rng(private_crypto_tester_t *this, rng_quality_t quality,
rng->destroy(rng);
if (failed)
{
- DBG1(DBG_LIB, "disabled %N: test vector %u failed",
- rng_quality_names, quality, tested);
+ DBG1(DBG_LIB, "disabled %N: %s test vector failed",
+ rng_quality_names, quality, get_name(vector));
break;
}
}
@@ -530,63 +948,62 @@ static bool test_rng(private_crypto_tester_t *this, rng_quality_t quality,
}
if (!failed)
{
- DBG1(DBG_LIB, "enabled %N: passed %u test vectors",
- rng_quality_names, quality, tested);
+ if (speed)
+ {
+ *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;
}
-/**
- * Implementation of crypter_tester_t.add_crypter_vector
- */
-static void add_crypter_vector(private_crypto_tester_t *this,
- crypter_test_vector_t *vector)
+METHOD(crypto_tester_t, add_crypter_vector, void,
+ private_crypto_tester_t *this, crypter_test_vector_t *vector)
{
this->crypter->insert_last(this->crypter, vector);
}
-/**
- * Implementation of crypter_tester_t.add_signer_vector
- */
-static void add_signer_vector(private_crypto_tester_t *this,
- signer_test_vector_t *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)
{
this->signer->insert_last(this->signer, vector);
}
-/**
- * Implementation of crypter_tester_t.add_hasher_vector
- */
-static void add_hasher_vector(private_crypto_tester_t *this,
- hasher_test_vector_t *vector)
+METHOD(crypto_tester_t, add_hasher_vector, void,
+ private_crypto_tester_t *this, hasher_test_vector_t *vector)
{
this->hasher->insert_last(this->hasher, vector);
}
-/**
- * Implementation of crypter_tester_t.add_prf_vector
- */
-static void add_prf_vector(private_crypto_tester_t *this,
- prf_test_vector_t *vector)
+METHOD(crypto_tester_t, add_prf_vector, void,
+ private_crypto_tester_t *this, prf_test_vector_t *vector)
{
this->prf->insert_last(this->prf, vector);
}
-/**
- * Implementation of crypter_tester_t.add_rng_vector
- */
-static void add_rng_vector(private_crypto_tester_t *this,
- rng_test_vector_t *vector)
+METHOD(crypto_tester_t, add_rng_vector, void,
+ private_crypto_tester_t *this, rng_test_vector_t *vector)
{
this->rng->insert_last(this->rng, vector);
}
-/**
- * Implementation of crypto_tester_t.destroy.
- */
-static void destroy(private_crypto_tester_t *this)
+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);
@@ -599,30 +1016,43 @@ static void destroy(private_crypto_tester_t *this)
*/
crypto_tester_t *crypto_tester_create()
{
- private_crypto_tester_t *this = malloc_thing(private_crypto_tester_t);
-
- this->public.test_crypter = (bool(*)(crypto_tester_t*, encryption_algorithm_t alg,size_t key_size, crypter_constructor_t create))test_crypter;
- this->public.test_signer = (bool(*)(crypto_tester_t*, integrity_algorithm_t alg, signer_constructor_t create))test_signer;
- this->public.test_hasher = (bool(*)(crypto_tester_t*, hash_algorithm_t alg, hasher_constructor_t create))test_hasher;
- this->public.test_prf = (bool(*)(crypto_tester_t*, pseudo_random_function_t alg, prf_constructor_t create))test_prf;
- this->public.test_rng = (bool(*)(crypto_tester_t*, rng_quality_t quality, rng_constructor_t create))test_rng;
- this->public.add_crypter_vector = (void(*)(crypto_tester_t*, crypter_test_vector_t *vector))add_crypter_vector;
- this->public.add_signer_vector = (void(*)(crypto_tester_t*, signer_test_vector_t *vector))add_signer_vector;
- this->public.add_hasher_vector = (void(*)(crypto_tester_t*, hasher_test_vector_t *vector))add_hasher_vector;
- this->public.add_prf_vector = (void(*)(crypto_tester_t*, prf_test_vector_t *vector))add_prf_vector;
- this->public.add_rng_vector = (void(*)(crypto_tester_t*, rng_test_vector_t *vector))add_rng_vector;
- this->public.destroy = (void(*)(crypto_tester_t*))destroy;
-
- this->crypter = linked_list_create();
- this->signer = linked_list_create();
- this->hasher = linked_list_create();
- this->prf = linked_list_create();
- this->rng = linked_list_create();
-
- this->required = lib->settings->get_bool(lib->settings,
- "libstrongswan.crypto_test.required", FALSE);
- this->rng_true = lib->settings->get_bool(lib->settings,
- "libstrongswan.crypto_test.rng_true", FALSE);
+ private_crypto_tester_t *this;
+
+ 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,
+ .add_rng_vector = _add_rng_vector,
+ .destroy = _destroy,
+ },
+ .crypter = linked_list_create(),
+ .aead = linked_list_create(),
+ .signer = linked_list_create(),
+ .hasher = linked_list_create(),
+ .prf = linked_list_create(),
+ .rng = linked_list_create(),
+
+ .required = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.required", FALSE),
+ .rng_true = lib->settings->get_bool(lib->settings,
+ "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;
}
diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h
index ddcc2da51..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,48 +136,67 @@ 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
*/
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 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.
*
* @param alg algorithm to test
* @param create constructor function for the signer
+ * @param speed speed test result, NULL to omit
* @return TRUE if test passed
*/
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.
*
* @param alg algorithm to test
* @param create constructor function for the hasher
+ * @param speed speed test result, NULL to omit
* @return TRUE if test passed
*/
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.
*
* @param alg algorithm to test
* @param create constructor function for the PRF
+ * @param speed speed test result, NULL to omit
* @return TRUE if test passed
*/
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.
*
* @param alg algorithm to test
* @param create constructor function for the RNG
+ * @param speed speed test result, NULL to omit
* @return TRUE if test passed
*/
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.
*
@@ -164,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
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 9bd8991fc..5f7365321 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -38,9 +38,10 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, ECP_224_BIT, ECP_521_BIT,
"MODP_2048_256",
"ECP_192",
"ECP_224");
-ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, ECP_224_BIT,
- "MODP_NULL");
-ENUM_END(diffie_hellman_group_names, MODP_NULL);
+ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_CUSTOM, ECP_224_BIT,
+ "MODP_NULL",
+ "MODP_CUSTOM");
+ENUM_END(diffie_hellman_group_names, MODP_CUSTOM);
/**
@@ -441,3 +442,20 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group)
return NULL;
}
+/**
+ * See header.
+ */
+bool diffie_hellman_group_is_ec(diffie_hellman_group_t group)
+{
+ switch (group)
+ {
+ case ECP_256_BIT:
+ case ECP_384_BIT:
+ case ECP_521_BIT:
+ case ECP_192_BIT:
+ case ECP_224_BIT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index cdc9c785e..9ae772363 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -57,6 +57,8 @@ enum diffie_hellman_group_t {
ECP_224_BIT = 26,
/** insecure NULL diffie hellman group for testing, in PRIVATE USE */
MODP_NULL = 1024,
+ /** MODP group with custon generator, prime */
+ MODP_CUSTOM = 1025,
};
/**
@@ -145,4 +147,12 @@ struct diffie_hellman_params_t {
*/
diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group);
+/**
+ * Check if a given DH group is an ECDH group
+ *
+ * @param group group to check
+ * @return TUE if group is an ECP group
+ */
+bool diffie_hellman_group_is_ec(diffie_hellman_group_t group);
+
#endif /** DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c
index 8681a5b97..12e13ef57 100644
--- a/src/libstrongswan/crypto/prfs/prf.c
+++ b/src/libstrongswan/crypto/prfs/prf.c
@@ -16,12 +16,13 @@
#include "prf.h"
-ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1,
+ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_CAMELLIA128_XCBC,
"PRF_UNDEFINED",
"PRF_FIPS_SHA1_160",
"PRF_FIPS_DES",
- "PRF_KEYED_SHA1");
-ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CMAC, PRF_KEYED_SHA1,
+ "PRF_KEYED_SHA1",
+ "PRF_CAMELLIA128_XCBC");
+ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CMAC, PRF_CAMELLIA128_XCBC,
"PRF_HMAC_MD5",
"PRF_HMAC_SHA1",
"PRF_HMAC_TIGER",
diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h
index 6e853444f..ad15205d3 100644
--- a/src/libstrongswan/crypto/prfs/prf.h
+++ b/src/libstrongswan/crypto/prfs/prf.h
@@ -30,8 +30,7 @@ typedef struct prf_t prf_t;
/**
* Pseudo random function, as in IKEv2 RFC 3.3.2.
*
- * PRF algorithms not defined in IKEv2 are allocated in "private use"
- * space.
+ * PRF algorithms not defined in IKEv2 are allocated in "private use" space.
*/
enum pseudo_random_function_t {
PRF_UNDEFINED = 1024,
@@ -55,11 +54,12 @@ enum pseudo_random_function_t {
PRF_FIPS_SHA1_160 = 1025,
/** FIPS 186-2-change1, uses fixed output size of 160bit */
PRF_FIPS_DES = 1026,
- /**
- * Keyed hash algorithm using SHA1, used in EAP-AKA:
+ /** Keyed hash algorithm using SHA1, used in EAP-AKA:
* This PRF uses SHA1, but XORs the key into the IV. No "Final()" operation
* is applied to the SHA1 state. */
PRF_KEYED_SHA1 = 1027,
+ /** draft-kanno-ipsecme-camellia-xcbc, not yet assigned by IANA */
+ PRF_CAMELLIA128_XCBC = 1028,
};
/**
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c
index a43dde7ea..10ab9fc23 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.c
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c
@@ -1,6 +1,6 @@
/* C code produced by gperf version 3.0.3 */
/* Command-line: /usr/bin/gperf -N proposal_get_token -m 10 -C -G -c -t -D */
-/* Computed positions: -k'1,5,7,10,$' */
+/* Computed positions: -k'1,5,7,10,15,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -59,12 +59,12 @@ struct proposal_token {
u_int16_t keysize;
};
-#define TOTAL_KEYWORDS 95
+#define TOTAL_KEYWORDS 117
#define MIN_WORD_LENGTH 3
-#define MAX_WORD_LENGTH 12
-#define MIN_HASH_VALUE 5
-#define MAX_HASH_VALUE 137
-/* maximum key range = 133, duplicates = 0 */
+#define MAX_WORD_LENGTH 17
+#define MIN_HASH_VALUE 9
+#define MAX_HASH_VALUE 209
+/* maximum key range = 201, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -80,38 +80,45 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 3, 11,
- 2, 23, 29, 27, 21, 16, 5, 0, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 17, 138, 1, 0, 1,
- 9, 9, 50, 0, 4, 54, 138, 138, 1, 138,
- 35, 0, 138, 138, 71, 3, 38, 22, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 16, 9,
+ 4, 41, 66, 19, 8, 4, 5, 3, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 122, 210, 3, 22, 21,
+ 3, 111, 103, 48, 7, 4, 210, 210, 3, 210,
+ 57, 3, 210, 210, 78, 6, 3, 28, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210
};
register int hval = len;
switch (hval)
{
default:
+ hval += asso_values[(unsigned char)str[14]];
+ /*FALLTHROUGH*/
+ case 14:
+ case 13:
+ case 12:
+ case 11:
+ case 10:
hval += asso_values[(unsigned char)str[9]];
/*FALLTHROUGH*/
case 9:
@@ -135,115 +142,148 @@ hash (str, len)
static const struct proposal_token wordlist[] =
{
+ {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
{"null", ENCRYPTION_ALGORITHM, ENCR_NULL, 0},
+ {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
+ {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
+ {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192},
+ {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128},
+ {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
{"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
{"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192},
- {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0},
- {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192},
+ {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
{"aes128", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
- {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128},
- {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0},
- {"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"camellia192ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192},
+ {"camellia128ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128},
+ {"camellia192ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192},
+ {"camellia128ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128},
+ {"camellia192ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192},
+ {"camellia128ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128},
+ {"camellia192ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192},
+ {"camellia128ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128},
+ {"camellia192ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192},
+ {"camellia128ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128},
+ {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256},
+ {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
+ {"camellia256ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256},
+ {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256},
+ {"camellia256ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256},
+ {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192},
+ {"camellia256ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256},
+ {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
+ {"camellia256ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256},
+ {"camellia256ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256},
+ {"camelliaxcbc", INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0},
+ {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256},
{"aes192ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
- {"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
{"aes128ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
- {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
+ {"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
+ {"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
{"aes192ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
- {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
{"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
- {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
{"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
- {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
{"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0},
+ {"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0},
+ {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
+ {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
+ {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
+ {"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
+ {"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
+ {"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
+ {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0},
+ {"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
{"aes192gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
- {"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
{"aes128gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
- {"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
- {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0},
- {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128},
- {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256},
- {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
+ {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
+ {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
{"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
- {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
{"aes128gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
- {"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"camellia192ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192},
+ {"camellia128ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128},
+ {"camellia192ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 192},
+ {"camellia128ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 128},
+ {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0},
{"aes256gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
- {"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
- {"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0},
+ {"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
{"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
- {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
- {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
- {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256},
+ {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0},
{"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
- {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
- {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
{"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0},
- {"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
- {"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
- {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
- {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
- {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
- {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
- {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
- {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
- {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192},
- {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
- {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0},
{"aes256gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
- {"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
- {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
- {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
- {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0},
- {"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
- {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192},
- {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
- {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0},
+ {"camellia256ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256},
+ {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0},
+ {"camellia256ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256},
+ {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0},
+ {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0},
+ {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192},
+ {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128},
+ {"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
{"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0},
+ {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
+ {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
{"aes192ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192},
- {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
{"aes128ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128},
- {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0},
- {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0},
- {"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0},
- {"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
- {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
- {"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0},
- {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
- {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
- {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0},
- {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192},
- {"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
- {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0},
{"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192},
- {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
- {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0},
{"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0},
{"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
+ {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0},
+ {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256},
+ {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0},
+ {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256},
+ {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0},
+ {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
+ {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
+ {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192},
{"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256},
- {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0},
+ {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0},
+ {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
{"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
{"sha256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0},
- {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
{"sha2_256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0},
+ {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
+ {"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
+ {"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0},
+ {"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0},
+ {"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
{"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0},
- {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256},
- {"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
- {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256},
- {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256}
+ {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0}
};
static const short lookup[] =
{
- -1, -1, -1, -1, -1, 0, 1, -1, 2, -1, 3, -1, 4, 5,
- 6, 7, -1, -1, -1, -1, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, 26, -1, -1,
- 27, 28, 29, 30, 31, 32, 33, -1, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, -1, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, -1, 69, 70, 71, 72, 73, 74, 75, 76, -1, -1, 77,
- 78, 79, 80, 81, -1, -1, 82, 83, -1, -1, 84, 85, -1, 86,
- 87, 88, 89, -1, -1, -1, -1, -1, -1, -1, 90, 91, -1, -1,
- -1, -1, -1, -1, 92, -1, 93, -1, -1, -1, -1, 94
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,
+ 1, -1, -1, -1, -1, -1, 2, -1, -1, -1,
+ -1, 3, 4, -1, -1, -1, -1, -1, 5, 6,
+ 7, 8, -1, -1, -1, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, -1,
+ -1, -1, -1, 23, 24, 25, 26, 27, 28, 29,
+ 30, -1, 31, -1, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, -1, 49, -1, 50, -1, 51, -1, 52, -1,
+ 53, -1, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, -1, 70,
+ -1, 71, -1, 72, 73, 74, 75, 76, -1, 77,
+ 78, 79, 80, 81, -1, 82, 83, 84, 85, -1,
+ -1, 86, 87, 88, 89, 90, 91, 92, -1, -1,
+ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, -1, -1, -1, -1, -1, -1, 105, 106,
+ 107, 108, -1, -1, -1, -1, 109, -1, 110, -1,
+ -1, -1, -1, -1, 111, -1, -1, -1, -1, 112,
+ 113, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 114, 115, -1, -1, -1, 116
};
#ifdef __GNUC__
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.txt b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
index 338993821..208c6715b 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.txt
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
@@ -86,6 +86,27 @@ camellia, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128
camellia128, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128
camellia192, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192
camellia256, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256
+camellia128ctr, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 128
+camellia192ctr, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 192
+camellia256ctr, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256
+camellia128ccm8, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128
+camellia128ccm64, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128
+camellia128ccm12, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128
+camellia128ccm96, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128
+camellia128ccm16, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128
+camellia128ccm128,ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128
+camellia192ccm8, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192
+camellia192ccm64, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192
+camellia192ccm12, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192
+camellia192ccm96, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192
+camellia192ccm16, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192
+camellia192ccm128,ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192
+camellia256ccm8, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256
+camellia256ccm64, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256
+camellia256ccm12, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256
+camellia256ccm96, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256
+camellia256ccm16, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256
+camellia256ccm128,ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256
cast128, ENCRYPTION_ALGORITHM, ENCR_CAST, 128
serpent, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128
serpent128, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128
@@ -107,6 +128,7 @@ sha512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
sha2_512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
md5, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0
aesxcbc, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0
+camelliaxcbc, INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0
modpnull, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0
modp768, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0
modp1024, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0
diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c
index e98916bfe..d8659170b 100644
--- a/src/libstrongswan/crypto/signers/signer.c
+++ b/src/libstrongswan/crypto/signers/signer.c
@@ -16,11 +16,14 @@
#include "signer.h"
-ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA2_256_96,
+ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_CAMELLIA_XCBC_96,
"UNDEFINED",
"HMAC_SHA1_128",
- "HMAC_SHA2_256_96");
-ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_HMAC_SHA2_512_256, AUTH_HMAC_SHA2_256_96,
+ "HMAC_SHA2_256_96",
+ "HMAC_SHA2_256_256",
+ "HMAC_SHA2_384_384",
+ "CAMELLIA_XCBC_96");
+ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_HMAC_SHA2_512_256, AUTH_CAMELLIA_XCBC_96,
"HMAC_MD5_96",
"HMAC_SHA1_96",
"DES_MAC",
diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h
index 94e8c99b9..e2c224d8b 100644
--- a/src/libstrongswan/crypto/signers/signer.h
+++ b/src/libstrongswan/crypto/signers/signer.h
@@ -66,6 +66,12 @@ enum integrity_algorithm_t {
AUTH_HMAC_SHA1_128 = 1025,
/** SHA256 96 bit truncation variant, supported by Linux kernels */
AUTH_HMAC_SHA2_256_96 = 1026,
+ /** SHA256 full length tuncation variant, as used in TLS */
+ AUTH_HMAC_SHA2_256_256 = 1027,
+ /** SHA384 full length tuncation variant, as used in TLS */
+ AUTH_HMAC_SHA2_384_384 = 1028,
+ /** draft-kanno-ipsecme-camellia-xcbc, not yet assigned by IANA */
+ AUTH_CAMELLIA_XCBC_96 = 1029,
};
/**
@@ -102,6 +108,10 @@ struct signer_t {
/**
* Verify a signature.
*
+ * To verify a signature of multiple chunks of data, pass the
+ * data to get_signature() with a NULL buffer. verify_signature() acts
+ * as a final call and includes all data fed to get_signature().
+ *
* @param data a chunk containing the data to verify
* @param signature a chunk containing the signature
* @return TRUE, if signature is valid, FALSE otherwise
diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c
index af40f4de6..cec90a616 100644
--- a/src/libstrongswan/crypto/transform.c
+++ b/src/libstrongswan/crypto/transform.c
@@ -15,11 +15,12 @@
#include <crypto/transform.h>
-ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, RANDOM_NUMBER_GENERATOR,
+ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, AEAD_ALGORITHM,
"UNDEFINED_TRANSFORM_TYPE",
"HASH_ALGORITHM",
- "RANDOM_NUMBER_GENERATOR");
-ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, RANDOM_NUMBER_GENERATOR,
+ "RANDOM_NUMBER_GENERATOR",
+ "AEAD_ALGORITHM");
+ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, AEAD_ALGORITHM,
"ENCRYPTION_ALGORITHM",
"PSEUDO_RANDOM_FUNCTION",
"INTEGRITY_ALGORITHM",
diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h
index d11700a73..1a2660199 100644
--- a/src/libstrongswan/crypto/transform.h
+++ b/src/libstrongswan/crypto/transform.h
@@ -32,6 +32,7 @@ enum transform_type_t {
UNDEFINED_TRANSFORM_TYPE = 241,
HASH_ALGORITHM = 242,
RANDOM_NUMBER_GENERATOR = 243,
+ AEAD_ALGORITHM = 244,
ENCRYPTION_ALGORITHM = 1,
PSEUDO_RANDOM_FUNCTION = 2,
INTEGRITY_ALGORITHM = 3,