diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
commit | f73fba54dc8b30c6482e1e8abf15bbf455592fcd (patch) | |
tree | a449515607c5e51a5c703d7a9b1149c9e4a11560 /src/libstrongswan/crypto | |
parent | b8064f4099997a9e2179f3ad4ace605f5ccac3a1 (diff) | |
download | vyos-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.c | 162 | ||||
-rw-r--r-- | src/libstrongswan/crypto/aead.h | 119 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypters/crypter.c | 23 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypters/crypter.h | 39 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypto_factory.c | 507 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypto_factory.h | 54 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypto_tester.c | 614 | ||||
-rw-r--r-- | src/libstrongswan/crypto/crypto_tester.h | 60 | ||||
-rw-r--r-- | src/libstrongswan/crypto/diffie_hellman.c | 24 | ||||
-rw-r--r-- | src/libstrongswan/crypto/diffie_hellman.h | 10 | ||||
-rw-r--r-- | src/libstrongswan/crypto/prfs/prf.c | 7 | ||||
-rw-r--r-- | src/libstrongswan/crypto/prfs/prf.h | 8 | ||||
-rw-r--r-- | src/libstrongswan/crypto/proposal/proposal_keywords.c | 254 | ||||
-rw-r--r-- | src/libstrongswan/crypto/proposal/proposal_keywords.txt | 22 | ||||
-rw-r--r-- | src/libstrongswan/crypto/signers/signer.c | 9 | ||||
-rw-r--r-- | src/libstrongswan/crypto/signers/signer.h | 10 | ||||
-rw-r--r-- | src/libstrongswan/crypto/transform.c | 7 | ||||
-rw-r--r-- | src/libstrongswan/crypto/transform.h | 1 |
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**)¤t) == SUCCESS) + { + tmp->insert_last(tmp, current); + } + while (tmp->remove_first(tmp, (void**)¤t) == SUCCESS) + { + if (!inserted && + current->algo == algo && + current->speed < speed) + { + list->insert_last(list, entry); + inserted = TRUE; + } + list->insert_last(list, current); + } + tmp->destroy(tmp); + } + if (!inserted) { - 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, |