summaryrefslogtreecommitdiff
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-10-22 11:43:58 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-10-22 11:43:58 +0200
commit5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (patch)
tree037f1ec5bb860846938ddcf29771c24e9c529be0 /src/libstrongswan
parentb238cf34df3fe4476ae6b7012e7cb3e9769d4d51 (diff)
downloadvyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.tar.gz
vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.zip
Imported Upstream version 5.3.3
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/Makefile.am9
-rw-r--r--src/libstrongswan/Makefile.in65
-rw-r--r--src/libstrongswan/asn1/asn1.c2
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c39
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_request.h2
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_response.h2
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.c58
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.h12
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c8
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.h1
-rw-r--r--src/libstrongswan/crypto/iv/iv_gen.c1
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.c295
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.txt1
-rw-r--r--src/libstrongswan/networking/host.c4
-rw-r--r--src/libstrongswan/pen/pen.c6
-rw-r--r--src/libstrongswan/pen/pen.h3
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_private_key.c18
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_public_key.c19
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_utils.c83
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_utils.h10
-rw-r--r--src/libstrongswan/plugins/chapoly/Makefile.am29
-rw-r--r--src/libstrongswan/plugins/chapoly/Makefile.in810
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_aead.c333
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_aead.h52
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv.c43
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv.h113
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv_portable.c454
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv_portable.h31
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.c867
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.h31
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_plugin.c75
-rw-r--r--src/libstrongswan/plugins/chapoly/chapoly_plugin.h42
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.c2
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h2
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c11
-rw-r--r--src/libstrongswan/plugins/plugin_feature.c18
-rw-r--r--src/libstrongswan/plugins/plugin_feature.h10
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.am1
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in14
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors.h4
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c107
-rw-r--r--src/libstrongswan/selectors/traffic_selector.c3
-rw-r--r--src/libstrongswan/settings/settings.c69
-rw-r--r--src/libstrongswan/settings/settings.h54
-rw-r--r--src/libstrongswan/settings/settings_lexer.c233
-rw-r--r--src/libstrongswan/settings/settings_lexer.l19
-rw-r--r--src/libstrongswan/settings/settings_parser.c171
-rw-r--r--src/libstrongswan/settings/settings_parser.h8
-rw-r--r--src/libstrongswan/settings/settings_parser.y39
-rw-r--r--src/libstrongswan/tests/suites/test_chunk.c2
-rw-r--r--src/libstrongswan/tests/suites/test_host.c6
-rw-r--r--src/libstrongswan/tests/suites/test_identification.c91
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c172
-rw-r--r--src/libstrongswan/tests/suites/test_traffic_selector.c594
-rw-r--r--src/libstrongswan/tests/test_runner.c2
-rw-r--r--src/libstrongswan/tests/test_suite.c2
-rw-r--r--src/libstrongswan/tests/tests.c4
-rw-r--r--src/libstrongswan/utils/capabilities.c60
-rw-r--r--src/libstrongswan/utils/identification.c48
-rw-r--r--src/libstrongswan/utils/identification.h15
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_builtin.c3
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_builtin.h2
-rw-r--r--src/libstrongswan/utils/printf_hook/printf_hook_vstr.h2
-rw-r--r--src/libstrongswan/utils/utils.c107
-rw-r--r--src/libstrongswan/utils/utils/string.c2
65 files changed, 4800 insertions, 595 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index b3636cfb8..adf3687ae 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -100,7 +100,7 @@ resolver/rr.h resolver/resolver_manager.h \
plugins/plugin_loader.h plugins/plugin.h plugins/plugin_feature.h \
processing/jobs/job.h processing/jobs/callback_job.h processing/processor.h \
processing/scheduler.h processing/watcher.h selectors/traffic_selector.h \
-settings/settings.h threading/thread_value.h \
+settings/settings.h settings/settings_parser.h threading/thread_value.h \
threading/thread.h threading/windows/thread.h \
threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h \
threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \
@@ -540,6 +540,13 @@ if MONOLITHIC
endif
endif
+if USE_CHAPOLY
+ SUBDIRS += plugins/chapoly
+if MONOLITHIC
+ libstrongswan_la_LIBADD += plugins/chapoly/libstrongswan-chapoly.la
+endif
+endif
+
if USE_CTR
SUBDIRS += plugins/ctr
if MONOLITHIC
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index 5b20f6ea6..9598c8b51 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -203,19 +203,21 @@ host_triplet = @host@
@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_105 = plugins/keychain/libstrongswan-keychain.la
@USE_PKCS11_TRUE@am__append_106 = plugins/pkcs11
@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_107 = plugins/pkcs11/libstrongswan-pkcs11.la
-@USE_CTR_TRUE@am__append_108 = plugins/ctr
-@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_109 = plugins/ctr/libstrongswan-ctr.la
-@USE_CCM_TRUE@am__append_110 = plugins/ccm
-@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_111 = plugins/ccm/libstrongswan-ccm.la
-@USE_GCM_TRUE@am__append_112 = plugins/gcm
-@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_113 = plugins/gcm/libstrongswan-gcm.la
-@USE_NTRU_TRUE@am__append_114 = plugins/ntru
-@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_115 = plugins/ntru/libstrongswan-ntru.la
-@USE_BLISS_TRUE@am__append_116 = plugins/bliss
-@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_117 = plugins/bliss/libstrongswan-bliss.la
-@USE_TEST_VECTORS_TRUE@am__append_118 = plugins/test_vectors
-@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_119 = plugins/test_vectors/libstrongswan-test-vectors.la
-@USE_BLISS_TRUE@am__append_120 = plugins/bliss/tests
+@USE_CHAPOLY_TRUE@am__append_108 = plugins/chapoly
+@MONOLITHIC_TRUE@@USE_CHAPOLY_TRUE@am__append_109 = plugins/chapoly/libstrongswan-chapoly.la
+@USE_CTR_TRUE@am__append_110 = plugins/ctr
+@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_111 = plugins/ctr/libstrongswan-ctr.la
+@USE_CCM_TRUE@am__append_112 = plugins/ccm
+@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_113 = plugins/ccm/libstrongswan-ccm.la
+@USE_GCM_TRUE@am__append_114 = plugins/gcm
+@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_115 = plugins/gcm/libstrongswan-gcm.la
+@USE_NTRU_TRUE@am__append_116 = plugins/ntru
+@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_117 = plugins/ntru/libstrongswan-ntru.la
+@USE_BLISS_TRUE@am__append_118 = plugins/bliss
+@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_119 = plugins/bliss/libstrongswan-bliss.la
+@USE_TEST_VECTORS_TRUE@am__append_120 = plugins/test_vectors
+@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_121 = plugins/test_vectors/libstrongswan-test-vectors.la
+@USE_BLISS_TRUE@am__append_122 = plugins/bliss/tests
subdir = src/libstrongswan
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
settings/settings_parser.h settings/settings_parser.c \
@@ -295,7 +297,7 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__append_101) $(am__append_103) $(am__append_105) \
$(am__append_107) $(am__append_109) $(am__append_111) \
$(am__append_113) $(am__append_115) $(am__append_117) \
- $(am__append_119)
+ $(am__append_119) $(am__append_121)
am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c \
bio/bio_writer.c collections/blocking_queue.c \
@@ -558,15 +560,16 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
processing/jobs/job.h processing/jobs/callback_job.h \
processing/processor.h processing/scheduler.h \
processing/watcher.h selectors/traffic_selector.h \
- settings/settings.h threading/thread_value.h \
- threading/thread.h threading/windows/thread.h \
- threading/mutex.h threading/condvar.h threading/spinlock.h \
- threading/semaphore.h threading/rwlock.h \
- threading/rwlock_condvar.h threading/lock_profiler.h \
- utils/utils.h utils/chunk.h utils/debug.h utils/enum.h \
- utils/identification.h utils/lexparser.h utils/optionsfrom.h \
- utils/capabilities.h utils/backtrace.h utils/cpu_feature.h \
- utils/leak_detective.h utils/printf_hook/printf_hook.h \
+ settings/settings.h settings/settings_parser.h \
+ threading/thread_value.h threading/thread.h \
+ threading/windows/thread.h threading/mutex.h \
+ threading/condvar.h threading/spinlock.h threading/semaphore.h \
+ threading/rwlock.h threading/rwlock_condvar.h \
+ threading/lock_profiler.h utils/utils.h utils/chunk.h \
+ utils/debug.h utils/enum.h utils/identification.h \
+ utils/lexparser.h utils/optionsfrom.h utils/capabilities.h \
+ utils/backtrace.h utils/cpu_feature.h utils/leak_detective.h \
+ utils/printf_hook/printf_hook.h \
utils/printf_hook/printf_hook_vstr.h \
utils/printf_hook/printf_hook_builtin.h utils/parser_helper.h \
utils/test.h utils/integrity_checker.h utils/process.h \
@@ -615,9 +618,9 @@ DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \
plugins/files plugins/winhttp plugins/unbound plugins/soup \
plugins/ldap plugins/mysql plugins/sqlite plugins/padlock \
plugins/openssl plugins/gcrypt plugins/fips_prf plugins/agent \
- plugins/keychain plugins/pkcs11 plugins/ctr plugins/ccm \
- plugins/gcm plugins/ntru plugins/bliss plugins/test_vectors \
- tests plugins/bliss/tests
+ plugins/keychain plugins/pkcs11 plugins/chapoly plugins/ctr \
+ plugins/ccm plugins/gcm plugins/ntru plugins/bliss \
+ plugins/test_vectors tests plugins/bliss/tests
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -970,7 +973,7 @@ settings/settings_types.h
@USE_DEV_HEADERS_TRUE@plugins/plugin_loader.h plugins/plugin.h plugins/plugin_feature.h \
@USE_DEV_HEADERS_TRUE@processing/jobs/job.h processing/jobs/callback_job.h processing/processor.h \
@USE_DEV_HEADERS_TRUE@processing/scheduler.h processing/watcher.h selectors/traffic_selector.h \
-@USE_DEV_HEADERS_TRUE@settings/settings.h threading/thread_value.h \
+@USE_DEV_HEADERS_TRUE@settings/settings.h settings/settings_parser.h threading/thread_value.h \
@USE_DEV_HEADERS_TRUE@threading/thread.h threading/windows/thread.h \
@USE_DEV_HEADERS_TRUE@threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h \
@USE_DEV_HEADERS_TRUE@threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \
@@ -1004,7 +1007,7 @@ libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \
$(am__append_101) $(am__append_103) $(am__append_105) \
$(am__append_107) $(am__append_109) $(am__append_111) \
$(am__append_113) $(am__append_115) $(am__append_117) \
- $(am__append_119)
+ $(am__append_119) $(am__append_121)
AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \
-DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \
-DPLUGINDIR=\"${plugindir}\" \
@@ -1056,7 +1059,8 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
@MONOLITHIC_FALSE@ $(am__append_106) $(am__append_108) \
@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) \
@MONOLITHIC_FALSE@ $(am__append_114) $(am__append_116) \
-@MONOLITHIC_FALSE@ $(am__append_118) tests $(am__append_120)
+@MONOLITHIC_FALSE@ $(am__append_118) $(am__append_120) tests \
+@MONOLITHIC_FALSE@ $(am__append_122)
# build plugins with their own Makefile
#######################################
@@ -1085,7 +1089,8 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
@MONOLITHIC_TRUE@ $(am__append_106) $(am__append_108) \
@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) \
@MONOLITHIC_TRUE@ $(am__append_114) $(am__append_116) \
-@MONOLITHIC_TRUE@ $(am__append_118) . tests $(am__append_120)
+@MONOLITHIC_TRUE@ $(am__append_118) $(am__append_120) . tests \
+@MONOLITHIC_TRUE@ $(am__append_122)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index 37b89c61b..628bb99e6 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -340,7 +340,7 @@ static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 33
static const int tm_leap_1970 = 477;
/**
- * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
+ * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calendar time
*/
time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
{
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 0ca45a15b..1e93f021a 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -514,9 +514,10 @@ METHOD(auth_cfg_t, complies, bool,
private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
{
enumerator_t *e1, *e2;
- bool success = TRUE, group_match = FALSE, cert_match = FALSE;
+ bool success = TRUE, group_match = FALSE;
+ bool ca_match = FALSE, cert_match = FALSE;
identification_t *require_group = NULL;
- certificate_t *require_cert = NULL;
+ certificate_t *require_ca = NULL, *require_cert = NULL;
signature_scheme_t scheme = SIGN_UNKNOWN;
u_int strength = 0;
auth_rule_t t1, t2;
@@ -531,26 +532,21 @@ METHOD(auth_cfg_t, complies, bool,
case AUTH_RULE_CA_CERT:
case AUTH_RULE_IM_CERT:
{
- certificate_t *c1, *c2;
+ certificate_t *cert;
- c1 = (certificate_t*)value;
+ /* for CA certs, a match of a single cert is sufficient */
+ require_ca = (certificate_t*)value;
- success = FALSE;
e2 = create_enumerator(this);
- while (e2->enumerate(e2, &t2, &c2))
+ while (e2->enumerate(e2, &t2, &cert))
{
if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
- c1->equals(c1, c2))
+ cert->equals(cert, require_ca))
{
- success = TRUE;
+ ca_match = TRUE;
}
}
e2->destroy(e2);
- if (!success && log_error)
- {
- DBG1(DBG_CFG, "constraint check failed: peer not "
- "authenticated by CA '%Y'.", c1->get_subject(c1));
- }
break;
}
case AUTH_RULE_SUBJECT_CERT:
@@ -665,7 +661,9 @@ METHOD(auth_cfg_t, complies, bool,
}
case AUTH_RULE_EAP_TYPE:
{
- if ((uintptr_t)value != (uintptr_t)get(this, t1))
+ if ((uintptr_t)value != (uintptr_t)get(this, t1) &&
+ (uintptr_t)value != EAP_DYNAMIC &&
+ (uintptr_t)value != EAP_RADIUS)
{
success = FALSE;
if (log_error)
@@ -853,13 +851,22 @@ METHOD(auth_cfg_t, complies, bool,
}
return FALSE;
}
-
+ if (require_ca && !ca_match)
+ {
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint check failed: peer not "
+ "authenticated by CA '%Y'",
+ require_ca->get_subject(require_ca));
+ }
+ return FALSE;
+ }
if (require_cert && !cert_match)
{
if (log_error)
{
DBG1(DBG_CFG, "constraint check failed: peer not "
- "authenticated with peer cert '%Y'.",
+ "authenticated with peer cert '%Y'",
require_cert->get_subject(require_cert));
}
return FALSE;
diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h
index 0b1871309..730d95d70 100644
--- a/src/libstrongswan/credentials/certificates/ocsp_request.h
+++ b/src/libstrongswan/credentials/certificates/ocsp_request.h
@@ -31,7 +31,7 @@ typedef struct ocsp_request_t ocsp_request_t;
struct ocsp_request_t {
/**
- * Implements certificiate_t interface
+ * Implements certificate_t interface
*/
certificate_t interface;
};
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h
index 157577458..9c5637b9f 100644
--- a/src/libstrongswan/credentials/certificates/ocsp_response.h
+++ b/src/libstrongswan/credentials/certificates/ocsp_response.h
@@ -50,7 +50,7 @@ extern enum_name_t *ocsp_status_names;
struct ocsp_response_t {
/**
- * Implements certificiate_t interface
+ * Implements certificate_t interface
*/
certificate_t certificate;
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
index 7ad011b5e..4884c4bfa 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.c
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Tobias Brunner
+ * Copyright (C) 2010-2015 Tobias Brunner
* Hochschule fuer Technik Rapperwsil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -197,7 +197,7 @@ METHOD(mem_cred_t, get_cert_ref, certificate_t*,
{
certificate_t *cached;
- this->lock->write_lock(this->lock);
+ this->lock->read_lock(this->lock);
if (this->untrusted->find_first(this->untrusted,
(linked_list_match_t)certificate_equals,
(void**)&cached, cert) == SUCCESS)
@@ -643,6 +643,49 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
}
+static void reset_certs(private_mem_cred_t *this)
+{
+ this->trusted->destroy_offset(this->trusted,
+ offsetof(certificate_t, destroy));
+ this->untrusted->destroy_offset(this->untrusted,
+ offsetof(certificate_t, destroy));
+ this->trusted = linked_list_create();
+ this->untrusted = linked_list_create();
+}
+
+static void copy_certs(linked_list_t *dst, linked_list_t *src, bool clone)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+
+ enumerator = src->create_enumerator(src);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ if (clone)
+ {
+ cert = cert->get_ref(cert);
+ }
+ else
+ {
+ src->remove_at(src, enumerator);
+ }
+ dst->insert_last(dst, cert);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(mem_cred_t, replace_certs, void,
+ private_mem_cred_t *this, mem_cred_t *other_set, bool clone)
+{
+ private_mem_cred_t *other = (private_mem_cred_t*)other_set;
+
+ this->lock->write_lock(this->lock);
+ reset_certs(this);
+ copy_certs(this->untrusted, other->untrusted, clone);
+ copy_certs(this->trusted, other->trusted, clone);
+ this->lock->unlock(this->lock);
+}
+
static void reset_secrets(private_mem_cred_t *this)
{
this->keys->destroy_offset(this->keys, offsetof(private_key_t, destroy));
@@ -710,17 +753,11 @@ METHOD(mem_cred_t, clear_, void,
private_mem_cred_t *this)
{
this->lock->write_lock(this->lock);
- this->trusted->destroy_offset(this->trusted,
- offsetof(certificate_t, destroy));
- this->untrusted->destroy_offset(this->untrusted,
- offsetof(certificate_t, destroy));
this->cdps->destroy_function(this->cdps, (void*)cdp_destroy);
- this->trusted = linked_list_create();
- this->untrusted = linked_list_create();
this->cdps = linked_list_create();
+ reset_certs(this);
+ reset_secrets(this);
this->lock->unlock(this->lock);
-
- clear_secrets(this);
}
METHOD(mem_cred_t, destroy, void,
@@ -760,6 +797,7 @@ mem_cred_t *mem_cred_create()
.add_shared = _add_shared,
.add_shared_list = _add_shared_list,
.add_cdp = _add_cdp,
+ .replace_certs = _replace_certs,
.replace_secrets = _replace_secrets,
.clear = _clear_,
.clear_secrets = _clear_secrets,
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
index 3ce815abc..51f0b8c30 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.h
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Tobias Brunner
+ * Copyright (C) 2010-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -102,6 +102,7 @@ struct mem_cred_t {
*/
void (*add_shared_list)(mem_cred_t *this, shared_key_t *shared,
linked_list_t *owners);
+
/**
* Add a certificate distribution point to the set.
*
@@ -113,6 +114,15 @@ struct mem_cred_t {
identification_t *id, char *uri);
/**
+ * Replace all certificates in this credential set with those of another.
+ *
+ * @param other credential set to get certificates from
+ * @param clone TRUE to clone certs, FALSE to adopt them (they
+ * get removed from the other set)
+ */
+ void (*replace_certs)(mem_cred_t *this, mem_cred_t *other, bool clone);
+
+ /**
* Replace all secrets (private and shared keys) in this credential set
* with those of another.
*
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 1e73baa4e..3e33765b1 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -40,13 +40,14 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_NULL_AUTH_AES_GMAC
"AES_GCM_12",
"AES_GCM_16",
"NULL_AES_GMAC");
-ENUM_NEXT(encryption_algorithm_names, ENCR_CAMELLIA_CBC, ENCR_CAMELLIA_CCM_ICV16, ENCR_NULL_AUTH_AES_GMAC,
+ENUM_NEXT(encryption_algorithm_names, ENCR_CAMELLIA_CBC, ENCR_CHACHA20_POLY1305, ENCR_NULL_AUTH_AES_GMAC,
"CAMELLIA_CBC",
"CAMELLIA_CTR",
"CAMELLIA_CCM_8",
"CAMELLIA_CCM_12",
- "CAMELLIA_CCM_16");
-ENUM_NEXT(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_RC2_CBC, ENCR_CAMELLIA_CCM_ICV16,
+ "CAMELLIA_CCM_16",
+ "CHACHA20_POLY1305");
+ENUM_NEXT(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_RC2_CBC, ENCR_CHACHA20_POLY1305,
"UNDEFINED",
"DES_ECB",
"SERPENT_CBC",
@@ -184,6 +185,7 @@ bool encryption_algorithm_is_aead(encryption_algorithm_t alg)
case ENCR_CAMELLIA_CCM_ICV8:
case ENCR_CAMELLIA_CCM_ICV12:
case ENCR_CAMELLIA_CCM_ICV16:
+ case ENCR_CHACHA20_POLY1305:
return TRUE;
default:
return FALSE;
diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h
index 849aea500..19ba55d83 100644
--- a/src/libstrongswan/crypto/crypters/crypter.h
+++ b/src/libstrongswan/crypto/crypters/crypter.h
@@ -57,6 +57,7 @@ enum encryption_algorithm_t {
ENCR_CAMELLIA_CCM_ICV8 = 25,
ENCR_CAMELLIA_CCM_ICV12 = 26,
ENCR_CAMELLIA_CCM_ICV16 = 27,
+ ENCR_CHACHA20_POLY1305 = 28,
ENCR_UNDEFINED = 1024,
ENCR_DES_ECB = 1025,
ENCR_SERPENT_CBC = 1026,
diff --git a/src/libstrongswan/crypto/iv/iv_gen.c b/src/libstrongswan/crypto/iv/iv_gen.c
index e18843210..7d6570a74 100644
--- a/src/libstrongswan/crypto/iv/iv_gen.c
+++ b/src/libstrongswan/crypto/iv/iv_gen.c
@@ -48,6 +48,7 @@ iv_gen_t* iv_gen_create_for_alg(encryption_algorithm_t alg)
case ENCR_CAMELLIA_CCM_ICV8:
case ENCR_CAMELLIA_CCM_ICV12:
case ENCR_CAMELLIA_CCM_ICV16:
+ case ENCR_CHACHA20_POLY1305:
case ENCR_NULL_AUTH_AES_GMAC:
return iv_gen_seq_create();
case ENCR_NULL:
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.c b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
index 1da1421f4..51b9d782d 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c
@@ -59,12 +59,12 @@ struct proposal_token {
u_int16_t keysize;
};
-#define TOTAL_KEYWORDS 138
+#define TOTAL_KEYWORDS 139
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
-#define MIN_HASH_VALUE 20
-#define MAX_HASH_VALUE 295
-/* maximum key range = 276, duplicates = 0 */
+#define MIN_HASH_VALUE 18
+#define MAX_HASH_VALUE 276
+/* maximum key range = 259, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -80,32 +80,32 @@ hash (str, len)
{
static const unsigned short asso_values[] =
{
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 47, 6,
- 15, 8, 64, 24, 12, 14, 7, 5, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 120, 296, 9, 5, 22,
- 48, 114, 28, 76, 6, 5, 296, 296, 5, 20,
- 7, 14, 82, 7, 81, 98, 10, 86, 296, 296,
- 5, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 66, 6,
+ 18, 39, 81, 30, 9, 27, 3, 0, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 105, 277, 33, 0, 6,
+ 57, 60, 15, 96, 3, 0, 277, 277, 0, 0,
+ 0, 18, 126, 30, 111, 24, 36, 159, 277, 277,
+ 9, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277
};
register int hval = len;
@@ -144,178 +144,177 @@ hash (str, len)
static const struct proposal_token wordlist[] =
{
- {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
- {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"esn", EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0},
{"null", ENCRYPTION_ALGORITHM, ENCR_NULL, 0},
{"noesn", EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0},
- {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
- {"esn", EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0},
+ {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0},
+ {"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
{"aes128", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
- {"prfsha1", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0},
- {"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192},
+ {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
{"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0},
{"md5_128", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_128, 0},
- {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
- {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
- {"ntru128", DIFFIE_HELLMAN_GROUP, NTRU_128_BIT, 0},
- {"prfsha256", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0},
- {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256},
- {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0},
- {"ntru192", DIFFIE_HELLMAN_GROUP, NTRU_192_BIT, 0},
- {"ntru112", DIFFIE_HELLMAN_GROUP, NTRU_112_BIT, 0},
- {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
- {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0},
- {"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0},
- {"prfsha512", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_512, 0},
{"aes192ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
- {"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192},
{"aes128ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
- {"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
{"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
- {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
{"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
+ {"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
+ {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0},
+ {"aescmac", INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0},
{"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256},
+ {"ntru128", DIFFIE_HELLMAN_GROUP, NTRU_128_BIT, 0},
+ {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0},
{"aes192ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
- {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
- {"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
- {"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0},
- {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0},
- {"ntru256", DIFFIE_HELLMAN_GROUP, NTRU_256_BIT, 0},
- {"aescmac", INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0},
{"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
- {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
- {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128},
+ {"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
{"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
+ {"ntru192", DIFFIE_HELLMAN_GROUP, NTRU_192_BIT, 0},
+ {"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0},
{"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
- {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192},
- {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
- {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
+ {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"ntru112", DIFFIE_HELLMAN_GROUP, NTRU_112_BIT, 0},
+ {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192},
+ {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
{"camellia192ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192},
- {"camellia192ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192},
- {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0},
+ {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"camelliaxcbc", INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0},
{"camellia192ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192},
+ {"camellia192ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192},
+ {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
+ {"prfsha1", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0},
+ {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192},
+ {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0},
{"camellia192ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192},
- {"prfsha384", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0},
- {"camellia192ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192},
- {"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
+ {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
+ {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
+ {"ntru256", DIFFIE_HELLMAN_GROUP, NTRU_256_BIT, 0},
+ {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0},
+ {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128},
+ {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
{"camellia128ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128},
- {"camellia128ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128},
- {"prfmd5", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0},
- {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256},
+ {"camellia192ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192},
+ {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
{"camellia128ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128},
+ {"camellia128ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128},
+ {"prfsha256", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0},
{"camellia128ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128},
- {"camellia128ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128},
+ {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256},
{"camellia256ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256},
- {"camellia256ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256},
- {"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0},
- {"camelliaxcbc", INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0},
+ {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0},
{"camellia256ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256},
+ {"camellia256ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256},
+ {"camellia128ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128},
{"camellia256ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256},
+ {"prfsha512", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_512, 0},
+ {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
{"camellia256ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256},
+ {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
{"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
- {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
{"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
- {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
{"aes192gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
- {"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192},
{"aes128gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
+ {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
+ {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128},
+ {"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"prfaescmac", PSEUDO_RANDOM_FUNCTION, PRF_AES128_CMAC, 0},
{"aes128gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
- {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
- {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
- {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
- {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
{"aes192ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192},
+ {"prfaesxcbc", PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0},
+ {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
{"aes128ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128},
- {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0},
+ {"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
+ {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
+ {"prfcamelliaxcbc", PSEUDO_RANDOM_FUNCTION, PRF_CAMELLIA128_XCBC, 0},
{"aes256gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
- {"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
- {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0},
- {"ecp512bp", DIFFIE_HELLMAN_GROUP, ECP_512_BP, 0},
+ {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
+ {"prfmd5", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0},
{"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
+ {"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
+ {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256},
+ {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0},
+ {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256},
{"aes256gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
- {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0},
- {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0},
- {"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
- {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
- {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
+ {"camellia192ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192},
+ {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0},
{"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256},
- {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192},
- {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128},
+ {"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0},
+ {"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
+ {"ecp512bp", DIFFIE_HELLMAN_GROUP, ECP_512_BP, 0},
+ {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0},
{"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
- {"ecp256bp", DIFFIE_HELLMAN_GROUP, ECP_256_BP, 0},
- {"camellia192ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192},
- {"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0},
+ {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0},
+ {"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192},
+ {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0},
+ {"camellia128ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128},
{"camellia192ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 192},
- {"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
- {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0},
- {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0},
{"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0},
- {"camellia128ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128},
- {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256},
- {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0},
+ {"ecp256bp", DIFFIE_HELLMAN_GROUP, ECP_256_BP, 0},
+ {"camellia256ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256},
+ {"prfsha384", PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0},
+ {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
+ {"sha256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0},
{"camellia128ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 128},
- {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256},
{"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0},
- {"camellia256ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256},
- {"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192},
- {"camellia256ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256},
+ {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
{"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
- {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192},
- {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
- {"sha256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0},
- {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0},
{"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
- {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
- {"ecp384bp", DIFFIE_HELLMAN_GROUP, ECP_384_BP, 0},
+ {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
{"sha2_256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0},
- {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
- {"ecp224bp", DIFFIE_HELLMAN_GROUP, ECP_224_BP, 0},
+ {"camellia256ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256},
+ {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256},
+ {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
{"sha1_160", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_160, 0},
+ {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192},
+ {"ecp384bp", DIFFIE_HELLMAN_GROUP, ECP_384_BP, 0},
{"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
- {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
- {"prfcamelliaxcbc", PSEUDO_RANDOM_FUNCTION, PRF_CAMELLIA128_XCBC, 0},
- {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0},
+ {"chacha20poly1305", ENCRYPTION_ALGORITHM, ENCR_CHACHA20_POLY1305, 256},
+ {"ecp224bp", DIFFIE_HELLMAN_GROUP, ECP_224_BP, 0},
{"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
- {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
- {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0},
- {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256},
- {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192},
- {"prfaesxcbc", PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0},
- {"prfaescmac", PSEUDO_RANDOM_FUNCTION, PRF_AES128_CMAC, 0}
+ {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0}
};
static const short lookup[] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, -1,
+ -1, -1, 1, 2, -1, 3, -1, 4, -1, -1,
+ 5, -1, -1, 6, -1, 7, -1, 8, -1, -1,
+ 9, -1, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, -1, 26,
+ -1, 27, 28, -1, -1, 29, 30, 31, -1, 32,
+ -1, 33, 34, 35, 36, -1, -1, 37, 38, -1,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, 52, 53, 54, 55, 56, -1,
+ 57, 58, 59, -1, -1, -1, 60, 61, 62, 63,
+ -1, -1, 64, 65, -1, 66, -1, -1, 67, -1,
+ -1, -1, -1, 68, -1, 69, -1, 70, 71, -1,
+ 72, -1, -1, 73, 74, 75, 76, 77, 78, 79,
+ 80, -1, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, -1, 93, 94, 95, 96, -1,
+ 97, 98, -1, 99, 100, 101, -1, 102, -1, -1,
+ 103, -1, -1, 104, 105, 106, 107, -1, 108, 109,
+ -1, 110, 111, -1, -1, 112, 113, -1, 114, -1,
+ -1, -1, -1, 115, -1, 116, 117, -1, 118, -1,
+ 119, 120, 121, 122, 123, -1, 124, 125, -1, 126,
+ -1, -1, 127, -1, 128, 129, -1, -1, 130, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, -1, 1, 2, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 3, 4, -1, -1, -1, 5, -1,
- 6, 7, -1, -1, -1, -1, 8, -1, 9, 10,
- -1, -1, 11, -1, 12, -1, 13, -1, 14, 15,
- -1, 16, 17, 18, 19, 20, -1, -1, -1, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, -1, 38, 39, -1,
- 40, 41, 42, -1, 43, 44, 45, 46, 47, 48,
- -1, 49, 50, 51, -1, 52, 53, 54, 55, 56,
- 57, 58, 59, -1, -1, 60, 61, 62, 63, 64,
- 65, 66, -1, -1, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80, -1, 81,
- 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- 92, 93, -1, 94, -1, 95, -1, 96, 97, 98,
- 99, 100, -1, 101, -1, 102, 103, 104, -1, 105,
- 106, 107, 108, 109, -1, 110, -1, 111, -1, 112,
- -1, 113, 114, 115, 116, -1, 117, 118, 119, 120,
- 121, -1, -1, -1, 122, -1, -1, 123, -1, -1,
- 124, -1, 125, 126, 127, -1, -1, -1, 128, -1,
- -1, -1, -1, -1, 129, 130, -1, 131, -1, 132,
- -1, -1, -1, -1, 133, -1, -1, -1, -1, 134,
- -1, -1, -1, -1, -1, 135, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 131, -1, 132, 133, -1, -1, 134, -1, -1, -1,
+ -1, 135, -1, -1, -1, -1, -1, -1, 136, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 136, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 137
+ -1, -1, 137, -1, -1, -1, 138
};
#ifdef __GNUC__
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt
index 70e79157a..da92409ca 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt
@@ -78,6 +78,7 @@ aes256gcm128, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256
aes128gmac, ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128
aes192gmac, ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192
aes256gmac, ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256
+chacha20poly1305, ENCRYPTION_ALGORITHM, ENCR_CHACHA20_POLY1305, 256
blowfish, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128
blowfish128, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128
blowfish192, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192
diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c
index 07da3ef3b..2e464b0ad 100644
--- a/src/libstrongswan/networking/host.c
+++ b/src/libstrongswan/networking/host.c
@@ -354,6 +354,10 @@ host_t *host_create_from_string_and_family(char *string, int family,
struct sockaddr_in6 v6;
} addr;
+ if (!string)
+ {
+ return NULL;
+ }
if (streq(string, "%any"))
{
return host_create_any_port(family ? family : AF_INET, port);
diff --git a/src/libstrongswan/pen/pen.c b/src/libstrongswan/pen/pen.c
index 474a7a876..9fe47547e 100644
--- a/src/libstrongswan/pen/pen.c
+++ b/src/libstrongswan/pen/pen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -23,7 +23,9 @@ ENUM_NEXT(pen_names, PEN_MICROSOFT, PEN_MICROSOFT, PEN_IBM,
"Microsoft");
ENUM_NEXT(pen_names, PEN_REDHAT, PEN_REDHAT, PEN_MICROSOFT,
"Redhat");
-ENUM_NEXT(pen_names, PEN_ALTIGA, PEN_ALTIGA, PEN_REDHAT,
+ENUM_NEXT(pen_names, PEN_PWG, PEN_PWG, PEN_REDHAT,
+ "PWG");
+ENUM_NEXT(pen_names, PEN_ALTIGA, PEN_ALTIGA, PEN_PWG,
"Altiga");
ENUM_NEXT(pen_names, PEN_OSC, PEN_OSC, PEN_ALTIGA,
"OSC");
diff --git a/src/libstrongswan/pen/pen.h b/src/libstrongswan/pen/pen.h
index 1760a0578..2c5592330 100644
--- a/src/libstrongswan/pen/pen.h
+++ b/src/libstrongswan/pen/pen.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2012 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@ enum pen_t {
PEN_IBM = 0x000002, /* 2 */
PEN_MICROSOFT = 0x000137, /* 311 */
PEN_REDHAT = 0x000908, /* 2312 */
+ PEN_PWG = 0x000A8B, /* 2699 */
PEN_ALTIGA = 0x000c04, /* 3076 */
PEN_OSC = 0x002358, /* 9048 */
PEN_DEBIAN = 0x002572, /* 9586 */
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c
index e1064d2f2..1386eeb2d 100644
--- a/src/libstrongswan/plugins/bliss/bliss_private_key.c
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c
@@ -168,7 +168,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
bliss_sampler_t *sampler = NULL;
rng_t *rng;
hasher_t *hasher;
- hash_algorithm_t mgf1_alg;
+ hash_algorithm_t mgf1_alg, oracle_alg;
size_t mgf1_seed_len;
uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
chunk_t mgf1_seed, data_hash;
@@ -185,7 +185,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
/* Initialize signature */
*signature = chunk_empty;
- /* Create data hash */
+ /* Create data hash using configurable hash algorithm */
hasher = lib->crypto->create_hasher(lib->crypto, alg);
if (!hasher)
{
@@ -200,13 +200,6 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
}
hasher->destroy(hasher);
- /* Create SHA512 hasher for c_indices oracle */
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
- if (!hasher)
- {
- return FALSE;
- }
-
/* Set MGF1 hash algorithm and seed length based on security strength */
if (this->set->strength > 160)
{
@@ -223,10 +216,12 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
if (!rng)
{
- hasher->destroy(hasher);
return FALSE;
}
+ /* MGF1 hash algorithm to be used for random oracle */
+ oracle_alg = HASH_SHA512;
+
/* Initialize a couple of needed variables */
n = this->set->n;
q = this->set->q;
@@ -360,7 +355,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
DBG3(DBG_LIB, "%3d %6d %4d", i, u[i], ud[i]);
}
- if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+ if (!bliss_utils_generate_c(oracle_alg, data_hash, ud, this->set,
c_indices))
{
goto end;
@@ -495,7 +490,6 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
end:
/* cleanup */
DESTROY_IF(sampler);
- hasher->destroy(hasher);
sig->destroy(sig);
fft->destroy(fft);
rng->destroy(rng);
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c
index 0175b0f8e..2b305f6c2 100644
--- a/src/libstrongswan/plugins/bliss/bliss_public_key.c
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c
@@ -70,11 +70,12 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
uint8_t data_hash_buf[HASH_SIZE_SHA512];
chunk_t data_hash;
hasher_t *hasher;
+ hash_algorithm_t oracle_alg;
bliss_fft_t *fft;
bliss_signature_t *sig;
bool success = FALSE;
- /* Create data hash */
+ /* Create data hash using configurable hash algorithm */
hasher = lib->crypto->create_hasher(lib->crypto, alg);
if (!hasher )
{
@@ -89,28 +90,22 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
}
hasher->destroy(hasher);
- /* Create SHA512 hasher for c_indices oracle */
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
- if (!hasher)
- {
- return FALSE;
- }
-
sig = bliss_signature_create_from_data(this->set, signature);
if (!sig)
{
- hasher->destroy(hasher);
return FALSE;
}
sig->get_parameters(sig, &z1, &z2d, &c_indices);
if (!bliss_utils_check_norms(this->set, z1, z2d))
{
- hasher->destroy(hasher);
sig->destroy(sig);
return FALSE;
}
+ /* MGF1 hash algorithm to be used for random oracle */
+ oracle_alg = HASH_SHA512;
+
/* Initialize a couple of needed variables */
n = this->set->n;
q = this->set->q;
@@ -165,8 +160,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
DBG3(DBG_LIB, "%3d %6d %4d %4d", i, u[i], ud[i], z2d[i]);
}
- if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
- indices))
+ if (!bliss_utils_generate_c(oracle_alg, data_hash, ud, this->set, indices))
{
goto end;
}
@@ -183,7 +177,6 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
end:
/* cleanup */
- hasher->destroy(hasher);
sig->destroy(sig);
fft->destroy(fft);
free(az);
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.c b/src/libstrongswan/plugins/bliss/bliss_utils.c
index 5a069989c..5e313ff26 100644
--- a/src/libstrongswan/plugins/bliss/bliss_utils.c
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.c
@@ -17,6 +17,7 @@
#include <asn1/asn1.h>
#include <crypto/hashers/hasher.h>
+#include <crypto/mgf1/mgf1_bitspender.h>
#include <utils/debug.h>
/**
@@ -54,55 +55,63 @@ void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd)
/**
* See header.
*/
-bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
- int n, uint16_t kappa, uint16_t *c_indices)
+bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
+ uint16_t *ud, bliss_param_set_t *set,
+ uint16_t *c_indices)
{
- int i, j;
- uint64_t extra_bits;
- uint16_t index, rounds = 0;
- uint8_t hash[HASH_SIZE_SHA512], un16_buf[2];
- chunk_t un16 = { un16_buf, 2 };
- bool index_taken[n];
-
- while (TRUE)
+ int i, index_trials = 0, index_found = 0;
+ bool index_taken[set->n];
+ uint32_t index;
+ uint8_t *seed_pos;
+ chunk_t seed;
+ mgf1_bitspender_t *bitspender;
+
+ seed = chunk_alloca(data_hash.len + set->n * sizeof(uint16_t));
+
+ /* the data hash makes up the first part of the oracle seed */
+ memcpy(seed.ptr, data_hash.ptr, data_hash.len);
+ seed_pos = seed.ptr + data_hash.len;
+
+ /* followed by the n elements of the ud vector in network order */
+ for (i = 0; i < set->n; i++)
{
- if (!hasher->get_hash(hasher, data_hash, NULL))
- {
- return FALSE;
- }
+ htoun16(seed_pos, ud[i]);
+ seed_pos += sizeof(uint16_t);
+ }
- for (i = 0; i < n; i++)
- {
- htoun16(un16_buf, ud[i]);
- if (!hasher->get_hash(hasher, un16, NULL))
- {
- return FALSE;
- }
- index_taken[i] = FALSE;
- }
+ bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+ if (!bitspender)
+ {
+ return NULL;
+ }
- htoun16(un16_buf, rounds++);
- if (!hasher->get_hash(hasher, un16, hash))
- {
- return FALSE;
- }
+ for (i = 0; i < set->n; i++)
+ {
+ index_taken[i] = FALSE;
+ }
- extra_bits = untoh64(hash + sizeof(hash) - sizeof(uint64_t));
+ DBG3(DBG_LIB, " i c_index[i]");
+ while (bitspender->get_bits(bitspender, set->n_bits, &index))
+ {
+ index_trials++;
- for (i = 0, j = 0; j < sizeof(hash); j++)
+ if (!index_taken[index])
{
- index = 2 * (uint16_t)hash[i] + (extra_bits & 1);
- if (!index_taken[index])
- {
- c_indices[i++] = index;
- index_taken[index] = TRUE;
- }
- if (i == kappa)
+ DBG3(DBG_LIB, "%2u %8u", index_found, index);
+ c_indices[index_found++] = index;
+ index_taken[index] = TRUE;
+
+ if (index_found == set->kappa)
{
+ DBG3(DBG_LIB, "%2d index trials", index_trials);
+ bitspender->destroy(bitspender);
return TRUE;
}
}
}
+
+ bitspender->destroy(bitspender);
+ return FALSE;
}
/**
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.h b/src/libstrongswan/plugins/bliss/bliss_utils.h
index 063fd91c8..156968dd7 100644
--- a/src/libstrongswan/plugins/bliss/bliss_utils.h
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.h
@@ -47,15 +47,15 @@ void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd)
/**
* Generate the binary challenge vector c as an array of kappa indices
*
- * @param hasher hasher used as an oracle
+ * @param alg hash algorithm to be used for the internal oracle
* @param data_hash hash of the data to be signed
* @param ud input vector ud of size n
- * @param n size of input vector ud
- * @param kappa parameter kappa
+ * @param set BLISS parameter set to be used (n, n_bits, kappa)
* @param c_indices indexes of non-zero challenge coefficients
*/
-bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
- int n, uint16_t kappa, uint16_t *c_indices);
+bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
+ uint16_t *ud, bliss_param_set_t *set,
+ uint16_t *c_indices);
/**
* Check the infinity and l2 norms of the vectors z1 and z2d << d
diff --git a/src/libstrongswan/plugins/chapoly/Makefile.am b/src/libstrongswan/plugins/chapoly/Makefile.am
new file mode 100644
index 000000000..1753de0c7
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/Makefile.am
@@ -0,0 +1,29 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+noinst_LTLIBRARIES =
+if MONOLITHIC
+noinst_LTLIBRARIES += libstrongswan-chapoly.la
+else
+plugin_LTLIBRARIES = libstrongswan-chapoly.la
+endif
+
+libstrongswan_chapoly_la_SOURCES = \
+ chapoly_plugin.h chapoly_plugin.c \
+ chapoly_drv.h chapoly_drv.c \
+ chapoly_drv_portable.h chapoly_drv_portable.c \
+ chapoly_aead.h chapoly_aead.c
+
+noinst_LTLIBRARIES += libchapoly-drv-ssse3.la
+libchapoly_drv_ssse3_la_SOURCES = chapoly_drv_ssse3.h chapoly_drv_ssse3.c
+if USE_X86X64
+ libchapoly_drv_ssse3_la_CFLAGS = $(PLUGIN_CFLAGS) -mssse3
+endif
+
+libstrongswan_chapoly_la_LIBADD = \
+ libchapoly-drv-ssse3.la
+
+libstrongswan_chapoly_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/chapoly/Makefile.in b/src/libstrongswan/plugins/chapoly/Makefile.in
new file mode 100644
index 000000000..98e1f4d9e
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/Makefile.in
@@ -0,0 +1,810 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@MONOLITHIC_TRUE@am__append_1 = libstrongswan-chapoly.la
+subdir = src/libstrongswan/plugins/chapoly
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/split-package-version.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libchapoly_drv_ssse3_la_LIBADD =
+am_libchapoly_drv_ssse3_la_OBJECTS = \
+ libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo
+libchapoly_drv_ssse3_la_OBJECTS = \
+ $(am_libchapoly_drv_ssse3_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libchapoly_drv_ssse3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libchapoly_drv_ssse3_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+libstrongswan_chapoly_la_DEPENDENCIES = libchapoly-drv-ssse3.la
+am_libstrongswan_chapoly_la_OBJECTS = chapoly_plugin.lo chapoly_drv.lo \
+ chapoly_drv_portable.lo chapoly_aead.lo
+libstrongswan_chapoly_la_OBJECTS = \
+ $(am_libstrongswan_chapoly_la_OBJECTS)
+libstrongswan_chapoly_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_chapoly_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_chapoly_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_chapoly_la_rpath =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libchapoly_drv_ssse3_la_SOURCES) \
+ $(libstrongswan_chapoly_la_SOURCES)
+DIST_SOURCES = $(libchapoly_drv_ssse3_la_SOURCES) \
+ $(libstrongswan_chapoly_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+noinst_LTLIBRARIES = $(am__append_1) libchapoly-drv-ssse3.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-chapoly.la
+libstrongswan_chapoly_la_SOURCES = \
+ chapoly_plugin.h chapoly_plugin.c \
+ chapoly_drv.h chapoly_drv.c \
+ chapoly_drv_portable.h chapoly_drv_portable.c \
+ chapoly_aead.h chapoly_aead.c
+
+libchapoly_drv_ssse3_la_SOURCES = chapoly_drv_ssse3.h chapoly_drv_ssse3.c
+@USE_X86X64_TRUE@libchapoly_drv_ssse3_la_CFLAGS = $(PLUGIN_CFLAGS) -mssse3
+libstrongswan_chapoly_la_LIBADD = \
+ libchapoly-drv-ssse3.la
+
+libstrongswan_chapoly_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/chapoly/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/chapoly/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libchapoly-drv-ssse3.la: $(libchapoly_drv_ssse3_la_OBJECTS) $(libchapoly_drv_ssse3_la_DEPENDENCIES) $(EXTRA_libchapoly_drv_ssse3_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libchapoly_drv_ssse3_la_LINK) $(libchapoly_drv_ssse3_la_OBJECTS) $(libchapoly_drv_ssse3_la_LIBADD) $(LIBS)
+
+libstrongswan-chapoly.la: $(libstrongswan_chapoly_la_OBJECTS) $(libstrongswan_chapoly_la_DEPENDENCIES) $(EXTRA_libstrongswan_chapoly_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_chapoly_la_LINK) $(am_libstrongswan_chapoly_la_rpath) $(libstrongswan_chapoly_la_OBJECTS) $(libstrongswan_chapoly_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chapoly_aead.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chapoly_drv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chapoly_drv_portable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chapoly_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libchapoly_drv_ssse3_la-chapoly_drv_ssse3.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo: chapoly_drv_ssse3.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libchapoly_drv_ssse3_la_CFLAGS) $(CFLAGS) -MT libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo -MD -MP -MF $(DEPDIR)/libchapoly_drv_ssse3_la-chapoly_drv_ssse3.Tpo -c -o libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo `test -f 'chapoly_drv_ssse3.c' || echo '$(srcdir)/'`chapoly_drv_ssse3.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libchapoly_drv_ssse3_la-chapoly_drv_ssse3.Tpo $(DEPDIR)/libchapoly_drv_ssse3_la-chapoly_drv_ssse3.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chapoly_drv_ssse3.c' object='libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libchapoly_drv_ssse3_la_CFLAGS) $(CFLAGS) -c -o libchapoly_drv_ssse3_la-chapoly_drv_ssse3.lo `test -f 'chapoly_drv_ssse3.c' || echo '$(srcdir)/'`chapoly_drv_ssse3.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-pluginLTLIBRARIES install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_aead.c b/src/libstrongswan/plugins/chapoly/chapoly_aead.c
new file mode 100644
index 000000000..50ad84b21
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_aead.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 "chapoly_aead.h"
+#include "chapoly_drv.h"
+
+#include <crypto/iv/iv_gen_seq.h>
+
+/* maximum plain message size */
+#define P_MAX 247877906880
+
+typedef struct private_chapoly_aead_t private_chapoly_aead_t;
+
+/**
+ * Private data of an chapoly_aead_t object.
+ */
+struct private_chapoly_aead_t {
+
+ /**
+ * Public chapoly_aead_t interface.
+ */
+ chapoly_aead_t public;
+
+ /**
+ * IV generator.
+ */
+ iv_gen_t *iv_gen;
+
+ /**
+ * Driver backend
+ */
+ chapoly_drv_t *drv;
+};
+
+/**
+ * Include a partial block to ICV by padding it with zero bytes
+ */
+static bool poly_update_padded(private_chapoly_aead_t *this,
+ u_char *in, size_t len)
+{
+ u_char b[POLY_BLOCK_SIZE];
+
+ memset(b, 0, sizeof(b));
+ memcpy(b, in, len);
+
+ return this->drv->poly(this->drv, b, 1);
+}
+
+/**
+ * Include associated data with padding to ICV
+ */
+static bool poly_head(private_chapoly_aead_t *this, u_char *assoc, size_t len)
+{
+ u_int blocks, rem;
+
+ blocks = len / POLY_BLOCK_SIZE;
+ rem = len % POLY_BLOCK_SIZE;
+ if (!this->drv->poly(this->drv, assoc, blocks))
+ {
+ return FALSE;
+ }
+ if (rem)
+ {
+ return poly_update_padded(this, assoc + blocks * POLY_BLOCK_SIZE, rem);
+ }
+ return TRUE;
+}
+
+/**
+ * Include length fields to ICV
+ */
+static bool poly_tail(private_chapoly_aead_t *this, size_t alen, size_t clen)
+{
+ struct {
+ u_int64_t alen;
+ u_int64_t clen;
+ } b;
+
+ b.alen = htole64(alen);
+ b.clen = htole64(clen);
+
+ return this->drv->poly(this->drv, (u_char*)&b, 1);
+}
+
+/**
+ * Perform ChaCha20 encryption inline and generate an ICV tag
+ */
+static bool do_encrypt(private_chapoly_aead_t *this, size_t len, u_char *data,
+ u_char *iv, size_t alen, u_char *assoc, u_char *icv)
+{
+ u_int blocks, rem, prem;
+
+ if (!this->drv->init(this->drv, iv) ||
+ !poly_head(this, assoc, alen))
+ {
+ return FALSE;
+ }
+ blocks = len / CHACHA_BLOCK_SIZE;
+ if (!this->drv->encrypt(this->drv, data, blocks))
+ {
+ return FALSE;
+ }
+ rem = len % CHACHA_BLOCK_SIZE;
+ if (rem)
+ {
+ u_char stream[CHACHA_BLOCK_SIZE];
+
+ data += blocks * CHACHA_BLOCK_SIZE;
+ if (!this->drv->chacha(this->drv, stream))
+ {
+ return FALSE;
+ }
+ memxor(data, stream, rem);
+
+ blocks = rem / POLY_BLOCK_SIZE;
+ if (!this->drv->poly(this->drv, data, blocks))
+ {
+ return FALSE;
+ }
+ prem = rem % POLY_BLOCK_SIZE;
+ if (prem)
+ {
+ poly_update_padded(this, data + blocks * POLY_BLOCK_SIZE, prem);
+ }
+ }
+ return poly_tail(this, alen, len) &&
+ this->drv->finish(this->drv, icv);
+}
+
+/**
+ * Perform ChaCha20 decryption inline and generate an ICV tag
+ */
+static bool do_decrypt(private_chapoly_aead_t *this, size_t len, u_char *data,
+ u_char *iv, size_t alen, u_char *assoc, u_char *icv)
+{
+ u_int blocks, rem, prem;
+
+ if (!this->drv->init(this->drv, iv) ||
+ !poly_head(this, assoc, alen))
+ {
+ return FALSE;
+ }
+ blocks = len / CHACHA_BLOCK_SIZE;
+ if (!this->drv->decrypt(this->drv, data, blocks))
+ {
+ return FALSE;
+ }
+ rem = len % CHACHA_BLOCK_SIZE;
+ if (rem)
+ {
+ u_char stream[CHACHA_BLOCK_SIZE];
+
+ data += blocks * CHACHA_BLOCK_SIZE;
+
+ blocks = rem / POLY_BLOCK_SIZE;
+ if (!this->drv->poly(this->drv, data, blocks))
+ {
+ return FALSE;
+ }
+ prem = rem % POLY_BLOCK_SIZE;
+ if (prem)
+ {
+ poly_update_padded(this, data + blocks * POLY_BLOCK_SIZE, prem);
+ }
+ if (!this->drv->chacha(this->drv, stream))
+ {
+ return FALSE;
+ }
+ memxor(data, stream, rem);
+ }
+ return poly_tail(this, alen, len) &&
+ this->drv->finish(this->drv, icv);
+}
+
+METHOD(aead_t, encrypt, bool,
+ private_chapoly_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
+ chunk_t *encr)
+{
+ u_char *out;
+
+ if (sizeof(plain.len) > sizeof(u_int32_t) && plain.len > P_MAX)
+ {
+ return FALSE;
+ }
+ if (iv.len != CHACHA_IV_SIZE)
+ {
+ return FALSE;
+ }
+ out = plain.ptr;
+ if (encr)
+ {
+ *encr = chunk_alloc(plain.len + POLY_ICV_SIZE);
+ out = encr->ptr;
+ memcpy(out, plain.ptr, plain.len);
+ }
+ do_encrypt(this, plain.len, out, iv.ptr, assoc.len, assoc.ptr,
+ out + plain.len);
+ return TRUE;
+}
+
+METHOD(aead_t, decrypt, bool,
+ private_chapoly_aead_t *this, chunk_t encr, chunk_t assoc, chunk_t iv,
+ chunk_t *plain)
+{
+ u_char *out, icv[POLY_ICV_SIZE];
+ if (iv.len != CHACHA_IV_SIZE || encr.len < POLY_ICV_SIZE)
+ {
+ return FALSE;
+ }
+ encr.len -= POLY_ICV_SIZE;
+ if (sizeof(encr.len) > sizeof(u_int32_t) && encr.len > P_MAX)
+ {
+ return FALSE;
+ }
+ out = encr.ptr;
+ if (plain)
+ {
+ *plain = chunk_alloc(encr.len);
+ out = plain->ptr;
+ memcpy(out, encr.ptr, encr.len);
+ }
+ do_decrypt(this, encr.len, out, iv.ptr, assoc.len, assoc.ptr, icv);
+ return memeq_const(icv, encr.ptr + encr.len, POLY_ICV_SIZE);
+}
+
+METHOD(aead_t, get_block_size, size_t,
+ private_chapoly_aead_t *this)
+{
+ return 1;
+}
+
+METHOD(aead_t, get_icv_size, size_t,
+ private_chapoly_aead_t *this)
+{
+ return POLY_ICV_SIZE;
+}
+
+METHOD(aead_t, get_iv_size, size_t,
+ private_chapoly_aead_t *this)
+{
+ return CHACHA_IV_SIZE;
+}
+
+METHOD(aead_t, get_iv_gen, iv_gen_t*,
+ private_chapoly_aead_t *this)
+{
+ return this->iv_gen;
+}
+
+METHOD(aead_t, get_key_size, size_t,
+ private_chapoly_aead_t *this)
+{
+ return CHACHA_KEY_SIZE + CHACHA_SALT_SIZE;
+}
+
+METHOD(aead_t, set_key, bool,
+ private_chapoly_aead_t *this, chunk_t key)
+{
+ if (key.len != CHACHA_KEY_SIZE + CHACHA_SALT_SIZE)
+ {
+ return FALSE;
+ }
+ return this->drv->set_key(this->drv, "expand 32-byte k",
+ key.ptr, key.ptr + CHACHA_KEY_SIZE);
+}
+
+METHOD(aead_t, destroy, void,
+ private_chapoly_aead_t *this)
+{
+ this->drv->destroy(this->drv);
+ this->iv_gen->destroy(this->iv_gen);
+ free(this);
+}
+
+/**
+ * See header
+ */
+chapoly_aead_t *chapoly_aead_create(encryption_algorithm_t algo,
+ size_t key_size, size_t salt_size)
+{
+ private_chapoly_aead_t *this;
+ chapoly_drv_t *drv;
+
+ if (algo != ENCR_CHACHA20_POLY1305)
+ {
+ return NULL;
+ }
+ if (key_size && key_size != CHACHA_KEY_SIZE)
+ {
+ return NULL;
+ }
+ if (salt_size && salt_size != CHACHA_SALT_SIZE)
+ {
+ return NULL;
+ }
+ drv = chapoly_drv_probe();
+ if (!drv)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .aead = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_block_size = _get_block_size,
+ .get_icv_size = _get_icv_size,
+ .get_iv_size = _get_iv_size,
+ .get_iv_gen = _get_iv_gen,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ },
+ .iv_gen = iv_gen_seq_create(),
+ .drv = drv,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_aead.h b/src/libstrongswan/plugins/chapoly/chapoly_aead.h
new file mode 100644
index 000000000..e090541dd
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_aead.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 chapoly_aead chapoly_aead
+ * @{ @ingroup chapoly
+ */
+
+#ifndef CHAPOLY_AEAD_H_
+#define CHAPOLY_AEAD_H_
+
+#include <crypto/aead.h>
+
+typedef struct chapoly_aead_t chapoly_aead_t;
+
+/**
+ * ChaCha20/Poly1305 AEAD implementation.
+ *
+ * TODO-Chapoly: draft-ietf-ipsecme-chacha20-poly1305-05
+ */
+struct chapoly_aead_t {
+
+ /**
+ * Implements aead_t interface.
+ */
+ aead_t aead;
+};
+
+/**
+ * Create a chapoly_aead instance.
+ *
+ * @param algo algorithm to implement, ENCR_CHACHA20_POLY1305
+ * @param key_size key size in bytes, 32
+ * @param salt_size size of implicit salt length, 0
+ * @return AEAD, NULL if not supported
+ */
+chapoly_aead_t *chapoly_aead_create(encryption_algorithm_t algo,
+ size_t key_size, size_t salt_size);
+
+#endif /** CHAPOLY_AEAD_H_ @}*/
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv.c b/src/libstrongswan/plugins/chapoly/chapoly_drv.c
new file mode 100644
index 000000000..ca5e2be08
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 "chapoly_drv.h"
+#include "chapoly_drv_portable.h"
+#include "chapoly_drv_ssse3.h"
+
+typedef chapoly_drv_t*(*chapoly_drv_create)();
+
+/**
+ * See header.
+ */
+chapoly_drv_t *chapoly_drv_probe()
+{
+ chapoly_drv_create drivers[] = {
+ chapoly_drv_ssse3_create,
+ chapoly_drv_portable_create,
+ };
+ chapoly_drv_t *driver;
+ int i;
+
+ for (i = 0; i < countof(drivers); i++)
+ {
+ driver = drivers[i]();
+ if (driver)
+ {
+ return driver;
+ }
+ }
+ return NULL;
+}
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv.h b/src/libstrongswan/plugins/chapoly/chapoly_drv.h
new file mode 100644
index 000000000..bffc43447
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 chapoly_drv chapoly_drv
+ * @{ @ingroup chapoly
+ */
+
+#ifndef CHAPOLY_DRV_H_
+#define CHAPOLY_DRV_H_
+
+#include <library.h>
+
+#define CHACHA_BLOCK_SIZE 64
+#define CHACHA_IV_SIZE 8
+#define CHACHA_SALT_SIZE 4
+#define CHACHA_KEY_SIZE 32
+#define POLY_BLOCK_SIZE 16
+#define POLY_ICV_SIZE 16
+
+typedef struct chapoly_drv_t chapoly_drv_t;
+
+/**
+ * ChaCha20/Poly1305 backend implementation.
+ */
+struct chapoly_drv_t {
+
+ /**
+ * Set the ChaCha20 encryption key.
+ *
+ * @param constant 16 byte key constant to use
+ * @param key 32 byte encryption key
+ * @param salt 4 byte nonce salt
+ * @return TRUE if key set
+ */
+ bool (*set_key)(chapoly_drv_t *this, u_char *constant, u_char *key,
+ u_char *salt);
+
+ /**
+ * Start an AEAD en/decryption session, reset state.
+ *
+ * @param iv 8 byte initialization vector for nonce
+ * @return TRUE if initialized
+ */
+ bool (*init)(chapoly_drv_t *this, u_char *iv);
+
+ /**
+ * Poly1305 update multiple blocks.
+ *
+ * @param data data to update Poly1305 for
+ * @param blocks number of 16-byte blocks to process
+ * @return TRUE if updated
+ */
+ bool (*poly)(chapoly_drv_t *this, u_char *data, u_int blocks);
+
+ /**
+ * Create a single ChaCha20 keystream block.
+ *
+ * @param stream 64-byte block to write key stream data to
+ * @return TRUE if keystream returned
+ */
+ bool (*chacha)(chapoly_drv_t *this, u_char *stream);
+
+ /**
+ * Encrypt multiple blocks of data inline, update Poly1305.
+ *
+ * @param data data to process
+ * @param blocks number of 64-byte blocks to process
+ * @return TRUE if encrypted
+ */
+ bool (*encrypt)(chapoly_drv_t *this, u_char *data, u_int blocks);
+
+ /**
+ * Decrypt multiple blocks of data inline, update Poly1305.
+ *
+ * @param data data to process
+ * @param blocks number of 64-byte blocks to process
+ * @return TRUE if decrypted
+ */
+ bool (*decrypt)(chapoly_drv_t *this, u_char *data, u_int blocks);
+
+ /**
+ * End a AEAD encryption session, return MAC.
+ *
+ * @param mac 16-byte block to write MAC to
+ * @return TRUE if MAC returned
+ */
+ bool (*finish)(chapoly_drv_t *this, u_char *mac);
+
+ /**
+ * Destroy a chapoly_drv_t.
+ */
+ void (*destroy)(chapoly_drv_t *this);
+};
+
+/**
+ * Create a chapoly_drv instance.
+ */
+chapoly_drv_t *chapoly_drv_probe();
+
+#endif /** CHAPOLY_DRV_H_ @}*/
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.c b/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.c
new file mode 100644
index 000000000..54e934e6a
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
+ *
+ * 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 "chapoly_drv_portable.h"
+
+#define CHACHA_DOUBLEROUNDS 10
+/* index of some state fields */
+#define CHACHA_BLOCKCOUNT 12
+#define CHACHA_NONCE1 13
+#define CHACHA_NONCE2 14
+#define CHACHA_NONCE3 15
+
+typedef struct private_chapoly_drv_portable_t private_chapoly_drv_portable_t;
+
+/**
+ * Private data of an chapoly_drv_portable_t object.
+ */
+struct private_chapoly_drv_portable_t {
+
+ /**
+ * Public chapoly_drv_portable_t interface.
+ */
+ chapoly_drv_t public;
+
+ /**
+ * ChaCha20 state matrix
+ */
+ u_int32_t m[16];
+
+ /**
+ * Poly1305 update key
+ */
+ u_int32_t r[5];
+
+ /**
+ * Poly1305 state
+ */
+ u_int32_t h[5];
+
+ /**
+ * Poly1305 finalize key
+ */
+ u_int32_t s[4];
+};
+
+/**
+ * Convert unaligned little endian to host byte order
+ */
+static inline u_int32_t uletoh32(void *p)
+{
+ u_int32_t ret;
+
+ memcpy(&ret, p, sizeof(ret));
+ ret = le32toh(ret);
+ return ret;
+}
+
+/**
+ * Convert host byte order to unaligned little endian
+ */
+static inline void htoule32(void *p, u_int32_t v)
+{
+ v = htole32(v);
+ memcpy(p, &v, sizeof(v));
+}
+
+/**
+ * XOR a 32-bit integer into an unaligned destination
+ */
+static inline void xor32u(void *p, u_int32_t x)
+{
+ u_int32_t y;
+
+ memcpy(&y, p, sizeof(y));
+ y ^= x;
+ memcpy(p, &y, sizeof(y));
+}
+
+/**
+ * Multiply two 64-bit words
+ */
+static inline u_int64_t mlt(u_int64_t a, u_int64_t b)
+{
+ return a * b;
+}
+
+/**
+ * Shift a 64-bit unsigned integer v right by n bits, clamp to 32 bit
+*/
+static inline u_int32_t sr(u_int64_t v, u_char n)
+{
+ return v >> n;
+}
+
+/**
+ * Circular left shift by n bits
+ */
+static inline u_int32_t rotl32(u_int32_t v, u_char n)
+{
+ return (v << n) | (v >> (sizeof(v) * 8 - n));
+}
+
+/**
+ * AND two values, using a native integer size >= sizeof(u_int32_t)
+ */
+static inline u_long and(u_long v, u_long mask)
+{
+ return v & mask;
+}
+
+/**
+ * XOR a Chacha20 keystream block into data, increment counter
+ */
+static void chacha_block_xor(private_chapoly_drv_portable_t *this, void *data)
+{
+ u_int32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf;
+ u_int32_t *out = data;
+ u_int i;
+
+ x0 = this->m[ 0];
+ x1 = this->m[ 1];
+ x2 = this->m[ 2];
+ x3 = this->m[ 3];
+ x4 = this->m[ 4];
+ x5 = this->m[ 5];
+ x6 = this->m[ 6];
+ x7 = this->m[ 7];
+ x8 = this->m[ 8];
+ x9 = this->m[ 9];
+ xa = this->m[10];
+ xb = this->m[11];
+ xc = this->m[12];
+ xd = this->m[13];
+ xe = this->m[14];
+ xf = this->m[15];
+
+ for (i = 0; i < CHACHA_DOUBLEROUNDS; i++)
+ {
+ x0 += x4; xc = rotl32(xc ^ x0, 16);
+ x1 += x5; xd = rotl32(xd ^ x1, 16);
+ x2 += x6; xe = rotl32(xe ^ x2, 16);
+ x3 += x7; xf = rotl32(xf ^ x3, 16);
+
+ x8 += xc; x4 = rotl32(x4 ^ x8, 12);
+ x9 += xd; x5 = rotl32(x5 ^ x9, 12);
+ xa += xe; x6 = rotl32(x6 ^ xa, 12);
+ xb += xf; x7 = rotl32(x7 ^ xb, 12);
+
+ x0 += x4; xc = rotl32(xc ^ x0, 8);
+ x1 += x5; xd = rotl32(xd ^ x1, 8);
+ x2 += x6; xe = rotl32(xe ^ x2, 8);
+ x3 += x7; xf = rotl32(xf ^ x3, 8);
+
+ x8 += xc; x4 = rotl32(x4 ^ x8, 7);
+ x9 += xd; x5 = rotl32(x5 ^ x9, 7);
+ xa += xe; x6 = rotl32(x6 ^ xa, 7);
+ xb += xf; x7 = rotl32(x7 ^ xb, 7);
+
+ x0 += x5; xf = rotl32(xf ^ x0, 16);
+ x1 += x6; xc = rotl32(xc ^ x1, 16);
+ x2 += x7; xd = rotl32(xd ^ x2, 16);
+ x3 += x4; xe = rotl32(xe ^ x3, 16);
+
+ xa += xf; x5 = rotl32(x5 ^ xa, 12);
+ xb += xc; x6 = rotl32(x6 ^ xb, 12);
+ x8 += xd; x7 = rotl32(x7 ^ x8, 12);
+ x9 += xe; x4 = rotl32(x4 ^ x9, 12);
+
+ x0 += x5; xf = rotl32(xf ^ x0, 8);
+ x1 += x6; xc = rotl32(xc ^ x1, 8);
+ x2 += x7; xd = rotl32(xd ^ x2, 8);
+ x3 += x4; xe = rotl32(xe ^ x3, 8);
+
+ xa += xf; x5 = rotl32(x5 ^ xa, 7);
+ xb += xc; x6 = rotl32(x6 ^ xb, 7);
+ x8 += xd; x7 = rotl32(x7 ^ x8, 7);
+ x9 += xe; x4 = rotl32(x4 ^ x9, 7);
+ }
+
+ xor32u(out + 0, le32toh(x0 + this->m[ 0]));
+ xor32u(out + 1, le32toh(x1 + this->m[ 1]));
+ xor32u(out + 2, le32toh(x2 + this->m[ 2]));
+ xor32u(out + 3, le32toh(x3 + this->m[ 3]));
+ xor32u(out + 4, le32toh(x4 + this->m[ 4]));
+ xor32u(out + 5, le32toh(x5 + this->m[ 5]));
+ xor32u(out + 6, le32toh(x6 + this->m[ 6]));
+ xor32u(out + 7, le32toh(x7 + this->m[ 7]));
+ xor32u(out + 8, le32toh(x8 + this->m[ 8]));
+ xor32u(out + 9, le32toh(x9 + this->m[ 9]));
+ xor32u(out + 10, le32toh(xa + this->m[10]));
+ xor32u(out + 11, le32toh(xb + this->m[11]));
+ xor32u(out + 12, le32toh(xc + this->m[12]));
+ xor32u(out + 13, le32toh(xd + this->m[13]));
+ xor32u(out + 14, le32toh(xe + this->m[14]));
+ xor32u(out + 15, le32toh(xf + this->m[15]));
+
+ this->m[CHACHA_BLOCKCOUNT]++;
+}
+
+METHOD(chapoly_drv_t, set_key, bool,
+ private_chapoly_drv_portable_t *this, u_char *constant, u_char *key,
+ u_char *salt)
+{
+ this->m[ 0] = uletoh32(constant + 0);
+ this->m[ 1] = uletoh32(constant + 4);
+ this->m[ 2] = uletoh32(constant + 8);
+ this->m[ 3] = uletoh32(constant + 12);
+
+ this->m[ 4] = uletoh32(key + 0);
+ this->m[ 5] = uletoh32(key + 4);
+ this->m[ 6] = uletoh32(key + 8);
+ this->m[ 7] = uletoh32(key + 12);
+ this->m[ 8] = uletoh32(key + 16);
+ this->m[ 9] = uletoh32(key + 20);
+ this->m[10] = uletoh32(key + 24);
+ this->m[11] = uletoh32(key + 28);
+
+ this->m[CHACHA_NONCE1] = uletoh32(salt);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, init, bool,
+ private_chapoly_drv_portable_t *this, u_char *iv)
+{
+ u_char key[CHACHA_BLOCK_SIZE];
+
+ this->m[CHACHA_BLOCKCOUNT] = 0;
+ this->m[CHACHA_NONCE2] = uletoh32(iv + 0);
+ this->m[CHACHA_NONCE3] = uletoh32(iv + 4);
+
+ memset(key, 0, CHACHA_BLOCK_SIZE);
+ chacha_block_xor(this, key);
+
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ this->r[0] = (uletoh32(key + 0) >> 0) & 0x3ffffff;
+ this->r[1] = (uletoh32(key + 3) >> 2) & 0x3ffff03;
+ this->r[2] = (uletoh32(key + 6) >> 4) & 0x3ffc0ff;
+ this->r[3] = (uletoh32(key + 9) >> 6) & 0x3f03fff;
+ this->r[4] = (uletoh32(key + 12) >> 8) & 0x00fffff;
+
+ /* h = 0 */
+ memwipe(this->h, sizeof(this->h));
+
+ this->s[0] = uletoh32(key + 16);
+ this->s[1] = uletoh32(key + 20);
+ this->s[2] = uletoh32(key + 24);
+ this->s[3] = uletoh32(key + 28);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, poly, bool,
+ private_chapoly_drv_portable_t *this, u_char *data, u_int blocks)
+{
+ u_int32_t r0, r1, r2, r3, r4;
+ u_int32_t s1, s2, s3, s4;
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int64_t d0, d1, d2, d3, d4;
+ u_int i;
+
+ r0 = this->r[0];
+ r1 = this->r[1];
+ r2 = this->r[2];
+ r3 = this->r[3];
+ r4 = this->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ h0 = this->h[0];
+ h1 = this->h[1];
+ h2 = this->h[2];
+ h3 = this->h[3];
+ h4 = this->h[4];
+
+ for (i = 0; i < blocks; i++)
+ {
+ /* h += m[i] */
+ h0 += (uletoh32(data + 0) >> 0) & 0x3ffffff;
+ h1 += (uletoh32(data + 3) >> 2) & 0x3ffffff;
+ h2 += (uletoh32(data + 6) >> 4) & 0x3ffffff;
+ h3 += (uletoh32(data + 9) >> 6) & 0x3ffffff;
+ h4 += (uletoh32(data + 12) >> 8) | (1 << 24);
+
+ /* h *= r */
+ d0 = mlt(h0, r0) + mlt(h1, s4) + mlt(h2, s3) + mlt(h3, s2) + mlt(h4, s1);
+ d1 = mlt(h0, r1) + mlt(h1, r0) + mlt(h2, s4) + mlt(h3, s3) + mlt(h4, s2);
+ d2 = mlt(h0, r2) + mlt(h1, r1) + mlt(h2, r0) + mlt(h3, s4) + mlt(h4, s3);
+ d3 = mlt(h0, r3) + mlt(h1, r2) + mlt(h2, r1) + mlt(h3, r0) + mlt(h4, s4);
+ d4 = mlt(h0, r4) + mlt(h1, r3) + mlt(h2, r2) + mlt(h3, r1) + mlt(h4, r0);
+
+ /* (partial) h %= p */
+ d1 += sr(d0, 26); h0 = and(d0, 0x3ffffff);
+ d2 += sr(d1, 26); h1 = and(d1, 0x3ffffff);
+ d3 += sr(d2, 26); h2 = and(d2, 0x3ffffff);
+ d4 += sr(d3, 26); h3 = and(d3, 0x3ffffff);
+ h0 += sr(d4, 26) * 5; h4 = and(d4, 0x3ffffff);
+ h1 += h0 >> 26; h0 = h0 & 0x3ffffff;
+
+ data += POLY_BLOCK_SIZE;
+ }
+
+ this->h[0] = h0;
+ this->h[1] = h1;
+ this->h[2] = h2;
+ this->h[3] = h3;
+ this->h[4] = h4;
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, chacha, bool,
+ private_chapoly_drv_portable_t *this, u_char *stream)
+{
+ memset(stream, 0, CHACHA_BLOCK_SIZE);
+ chacha_block_xor(this, stream);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, encrypt, bool,
+ private_chapoly_drv_portable_t *this, u_char *data, u_int blocks)
+{
+ u_int i;
+
+ for (i = 0; i < blocks; i++)
+ {
+ chacha_block_xor(this, data);
+ poly(this, data, 4);
+ data += CHACHA_BLOCK_SIZE;
+ }
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, decrypt, bool,
+ private_chapoly_drv_portable_t *this, u_char *data, u_int blocks)
+{
+ u_int i;
+
+ for (i = 0; i < blocks; i++)
+ {
+ poly(this, data, 4);
+ chacha_block_xor(this, data);
+ data += CHACHA_BLOCK_SIZE;
+ }
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, finish, bool,
+ private_chapoly_drv_portable_t *this, u_char *mac)
+{
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int32_t g0, g1, g2, g3, g4;
+ u_int32_t mask;
+ u_int64_t f = 0;
+
+ /* fully carry h */
+ h0 = this->h[0];
+ h1 = this->h[1];
+ h2 = this->h[2];
+ h3 = this->h[3];
+ h4 = this->h[4];
+
+ h2 += (h1 >> 26); h1 = h1 & 0x3ffffff;
+ h3 += (h2 >> 26); h2 = h2 & 0x3ffffff;
+ h4 += (h3 >> 26); h3 = h3 & 0x3ffffff;
+ h0 += (h4 >> 26) * 5; h4 = h4 & 0x3ffffff;
+ h1 += (h0 >> 26); h0 = h0 & 0x3ffffff;
+
+ /* compute h + -p */
+ g0 = h0 + 5;
+ g1 = h1 + (g0 >> 26); g0 &= 0x3ffffff;
+ g2 = h2 + (g1 >> 26); g1 &= 0x3ffffff;
+ g3 = h3 + (g2 >> 26); g2 &= 0x3ffffff;
+ g4 = h4 + (g3 >> 26) - (1 << 26); g3 &= 0x3ffffff;
+
+ /* select h if h < p, or h + -p if h >= p */
+ mask = (g4 >> ((sizeof(u_int32_t) * 8) - 1)) - 1;
+ g0 &= mask;
+ g1 &= mask;
+ g2 &= mask;
+ g3 &= mask;
+ g4 &= mask;
+ mask = ~mask;
+ h0 = (h0 & mask) | g0;
+ h1 = (h1 & mask) | g1;
+ h2 = (h2 & mask) | g2;
+ h3 = (h3 & mask) | g3;
+ h4 = (h4 & mask) | g4;
+
+ /* h = h % (2^128) */
+ h0 = (h0 >> 0) | (h1 << 26);
+ h1 = (h1 >> 6) | (h2 << 20);
+ h2 = (h2 >> 12) | (h3 << 14);
+ h3 = (h3 >> 18) | (h4 << 8);
+
+ /* mac = (h + s) % (2^128) */
+ f = (f >> 32) + h0 + this->s[0]; htoule32(mac + 0, f);
+ f = (f >> 32) + h1 + this->s[1]; htoule32(mac + 4, f);
+ f = (f >> 32) + h2 + this->s[2]; htoule32(mac + 8, f);
+ f = (f >> 32) + h3 + this->s[3]; htoule32(mac + 12, f);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, destroy, void,
+ private_chapoly_drv_portable_t *this)
+{
+ memwipe(this->m, sizeof(this->m));
+ memwipe(this->h, sizeof(this->h));
+ memwipe(this->r, sizeof(this->r));
+ memwipe(this->s, sizeof(this->s));
+ free(this);
+}
+
+/**
+ * See header
+ */
+chapoly_drv_t *chapoly_drv_portable_create()
+{
+ private_chapoly_drv_portable_t *this;
+
+ INIT(this,
+ .public = {
+ .set_key = _set_key,
+ .init = _init,
+ .poly = _poly,
+ .chacha = _chacha,
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .finish = _finish,
+ .destroy = _destroy,
+ },
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.h b/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.h
new file mode 100644
index 000000000..a320b2d41
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv_portable.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 chapoly_drv_portable chapoly_drv_portable
+ * @{ @ingroup chapoly
+ */
+
+#include "chapoly_drv.h"
+
+#ifndef CHAPOLY_DRV_PORTABLE_H_
+#define CHAPOLY_DRV_PORTABLE_H_
+
+/**
+ * Create a chapoly_drv_portable instance.
+ */
+chapoly_drv_t *chapoly_drv_portable_create();
+
+#endif /** CHAPOLY_drv_PORTABLE_H_ @}*/
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.c b/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.c
new file mode 100644
index 000000000..df88e7d77
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.c
@@ -0,0 +1,867 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
+ *
+ * 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 "chapoly_drv_ssse3.h"
+
+#ifdef __SSSE3__
+
+#include <utils/cpu_feature.h>
+
+#include <tmmintrin.h>
+
+#define CHACHA_DOUBLEROUNDS 10
+
+typedef struct private_chapoly_drv_ssse3_t private_chapoly_drv_ssse3_t;
+
+/**
+ * Private data of an chapoly_drv_ssse3_t object.
+ */
+struct private_chapoly_drv_ssse3_t {
+
+ /**
+ * Public chapoly_drv_ssse3_t interface.
+ */
+ chapoly_drv_t public;
+
+ /**
+ * ChaCha20 state matrix, as 128-bit vectors
+ */
+ __m128i m[4];
+
+ /**
+ * Poly1305 update key
+ */
+ u_int32_t r[5];
+
+ /**
+ * Poly1305 update key r^2
+ */
+ u_int32_t u[5];
+
+ /**
+ * Poly1305 state
+ */
+ u_int32_t h[5];
+
+ /**
+ * Poly1305 finalize key
+ */
+ u_int32_t s[4];
+};
+
+/**
+ * Read a 32-bit integer from an unaligned address
+ */
+static inline u_int32_t ru32(void *p)
+{
+ u_int32_t ret;
+
+ memcpy(&ret, p, sizeof(ret));
+ return ret;
+}
+
+/**
+ * Write a 32-bit word to an unaligned address
+ */
+static inline void wu32(void *p, u_int32_t v)
+{
+ memcpy(p, &v, sizeof(v));
+}
+
+/**
+ * Shift a 64-bit unsigned integer v right by n bits, clamp to 32 bit
+*/
+static inline u_int32_t sr(u_int64_t v, u_char n)
+{
+ return v >> n;
+}
+
+/**
+ * AND two values, using a native integer size >= sizeof(u_int32_t)
+ */
+static inline u_long and(u_long v, u_long mask)
+{
+ return v & mask;
+}
+
+/**
+ * r = shuffle(a ^ b, s)
+ */
+static inline __m128i sfflxor32(__m128i a, __m128i b, __m128i s)
+{
+ return _mm_shuffle_epi8(_mm_xor_si128(a, b), s);
+}
+
+/**
+ * r = rotl32(a ^ b, r)
+ */
+static inline __m128i rotlxor32(__m128i a, __m128i b, u_char r)
+{
+ a = _mm_xor_si128(a, b);
+ return _mm_or_si128(_mm_slli_epi32(a, r), _mm_srli_epi32(a, 32 - r));
+}
+
+/**
+ * XOR a Chacha20 keystream block into data, increment counter
+ */
+static void chacha_block_xor(private_chapoly_drv_ssse3_t *this, void *data)
+{
+ __m128i x0, x1, x2, x3, r8, r16, *out = data;
+ u_int i;
+
+ r8 = _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+ r16 = _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+
+ x0 = this->m[0];
+ x1 = this->m[1];
+ x2 = this->m[2];
+ x3 = this->m[3];
+
+ for (i = 0 ; i < CHACHA_DOUBLEROUNDS; i++)
+ {
+ x0 = _mm_add_epi32(x0, x1);
+ x3 = sfflxor32(x3, x0, r16);
+
+ x2 = _mm_add_epi32(x2, x3);
+ x1 = rotlxor32(x1, x2, 12);
+
+ x0 = _mm_add_epi32(x0, x1);
+ x3 = sfflxor32(x3, x0, r8);
+
+ x2 = _mm_add_epi32(x2, x3);
+ x1 = rotlxor32(x1, x2, 7);
+
+ x1 = _mm_shuffle_epi32(x1, _MM_SHUFFLE(0, 3, 2, 1));
+ x2 = _mm_shuffle_epi32(x2, _MM_SHUFFLE(1, 0, 3, 2));
+ x3 = _mm_shuffle_epi32(x3, _MM_SHUFFLE(2, 1, 0, 3));
+
+ x0 = _mm_add_epi32(x0, x1);
+ x3 = sfflxor32(x3, x0, r16);
+
+ x2 = _mm_add_epi32(x2, x3);
+ x1 = rotlxor32(x1, x2, 12);
+
+ x0 = _mm_add_epi32(x0, x1);
+ x3 = sfflxor32(x3, x0, r8);
+
+ x2 = _mm_add_epi32(x2, x3);
+ x1 = rotlxor32(x1, x2, 7);
+
+ x1 = _mm_shuffle_epi32(x1, _MM_SHUFFLE(2, 1, 0, 3));
+ x2 = _mm_shuffle_epi32(x2, _MM_SHUFFLE(1, 0, 3, 2));
+ x3 = _mm_shuffle_epi32(x3, _MM_SHUFFLE(0, 3, 2, 1));
+ }
+
+ x0 = _mm_add_epi32(x0, this->m[0]);
+ x1 = _mm_add_epi32(x1, this->m[1]);
+ x2 = _mm_add_epi32(x2, this->m[2]);
+ x3 = _mm_add_epi32(x3, this->m[3]);
+ x0 = _mm_xor_si128(x0, _mm_loadu_si128(out + 0));
+ x1 = _mm_xor_si128(x1, _mm_loadu_si128(out + 1));
+ x2 = _mm_xor_si128(x2, _mm_loadu_si128(out + 2));
+ x3 = _mm_xor_si128(x3, _mm_loadu_si128(out + 3));
+ _mm_storeu_si128(out + 0, x0);
+ _mm_storeu_si128(out + 1, x1);
+ _mm_storeu_si128(out + 2, x2);
+ _mm_storeu_si128(out + 3, x3);
+
+ this->m[3] = _mm_add_epi32(this->m[3], _mm_set_epi32(0, 0, 0, 1));
+}
+
+/**
+ * XOR four Chacha20 keystream blocks into data, increment counter
+ */
+static void chacha_4block_xor(private_chapoly_drv_ssse3_t *this, void *data)
+{
+ __m128i x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf;
+ __m128i r8, r16, ctrinc, t, *out = data;
+ u_int32_t *m = (u_int32_t*)this->m;
+ u_int i;
+
+ r8 = _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+ r16 = _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+ ctrinc = _mm_set_epi32(3, 2, 1, 0);
+
+ x0 = _mm_set1_epi32(m[ 0]);
+ x1 = _mm_set1_epi32(m[ 1]);
+ x2 = _mm_set1_epi32(m[ 2]);
+ x3 = _mm_set1_epi32(m[ 3]);
+ x4 = _mm_set1_epi32(m[ 4]);
+ x5 = _mm_set1_epi32(m[ 5]);
+ x6 = _mm_set1_epi32(m[ 6]);
+ x7 = _mm_set1_epi32(m[ 7]);
+ x8 = _mm_set1_epi32(m[ 8]);
+ x9 = _mm_set1_epi32(m[ 9]);
+ xa = _mm_set1_epi32(m[10]);
+ xb = _mm_set1_epi32(m[11]);
+ xc = _mm_set1_epi32(m[12]);
+ xd = _mm_set1_epi32(m[13]);
+ xe = _mm_set1_epi32(m[14]);
+ xf = _mm_set1_epi32(m[15]);
+
+ xc = _mm_add_epi32(xc, ctrinc);
+
+ for (i = 0 ; i < CHACHA_DOUBLEROUNDS; i++)
+ {
+ x0 = _mm_add_epi32(x0, x4); xc = sfflxor32(xc, x0, r16);
+ x1 = _mm_add_epi32(x1, x5); xd = sfflxor32(xd, x1, r16);
+ x2 = _mm_add_epi32(x2, x6); xe = sfflxor32(xe, x2, r16);
+ x3 = _mm_add_epi32(x3, x7); xf = sfflxor32(xf, x3, r16);
+
+ x8 = _mm_add_epi32(x8, xc); x4 = rotlxor32(x4, x8, 12);
+ x9 = _mm_add_epi32(x9, xd); x5 = rotlxor32(x5, x9, 12);
+ xa = _mm_add_epi32(xa, xe); x6 = rotlxor32(x6, xa, 12);
+ xb = _mm_add_epi32(xb, xf); x7 = rotlxor32(x7, xb, 12);
+
+ x0 = _mm_add_epi32(x0, x4); xc = sfflxor32(xc, x0, r8);
+ x1 = _mm_add_epi32(x1, x5); xd = sfflxor32(xd, x1, r8);
+ x2 = _mm_add_epi32(x2, x6); xe = sfflxor32(xe, x2, r8);
+ x3 = _mm_add_epi32(x3, x7); xf = sfflxor32(xf, x3, r8);
+
+ x8 = _mm_add_epi32(x8, xc); x4 = rotlxor32(x4, x8, 7);
+ x9 = _mm_add_epi32(x9, xd); x5 = rotlxor32(x5, x9, 7);
+ xa = _mm_add_epi32(xa, xe); x6 = rotlxor32(x6, xa, 7);
+ xb = _mm_add_epi32(xb, xf); x7 = rotlxor32(x7, xb, 7);
+
+ x0 = _mm_add_epi32(x0, x5); xf = sfflxor32(xf, x0, r16);
+ x1 = _mm_add_epi32(x1, x6); xc = sfflxor32(xc, x1, r16);
+ x2 = _mm_add_epi32(x2, x7); xd = sfflxor32(xd, x2, r16);
+ x3 = _mm_add_epi32(x3, x4); xe = sfflxor32(xe, x3, r16);
+
+ xa = _mm_add_epi32(xa, xf); x5 = rotlxor32(x5, xa, 12);
+ xb = _mm_add_epi32(xb, xc); x6 = rotlxor32(x6, xb, 12);
+ x8 = _mm_add_epi32(x8, xd); x7 = rotlxor32(x7, x8, 12);
+ x9 = _mm_add_epi32(x9, xe); x4 = rotlxor32(x4, x9, 12);
+
+ x0 = _mm_add_epi32(x0, x5); xf = sfflxor32(xf, x0, r8);
+ x1 = _mm_add_epi32(x1, x6); xc = sfflxor32(xc, x1, r8);
+ x2 = _mm_add_epi32(x2, x7); xd = sfflxor32(xd, x2, r8);
+ x3 = _mm_add_epi32(x3, x4); xe = sfflxor32(xe, x3, r8);
+
+ xa = _mm_add_epi32(xa, xf); x5 = rotlxor32(x5, xa, 7);
+ xb = _mm_add_epi32(xb, xc); x6 = rotlxor32(x6, xb, 7);
+ x8 = _mm_add_epi32(x8, xd); x7 = rotlxor32(x7, x8, 7);
+ x9 = _mm_add_epi32(x9, xe); x4 = rotlxor32(x4, x9, 7);
+ }
+
+ x0 = _mm_add_epi32(x0, _mm_set1_epi32(m[ 0]));
+ x1 = _mm_add_epi32(x1, _mm_set1_epi32(m[ 1]));
+ x2 = _mm_add_epi32(x2, _mm_set1_epi32(m[ 2]));
+ x3 = _mm_add_epi32(x3, _mm_set1_epi32(m[ 3]));
+ x4 = _mm_add_epi32(x4, _mm_set1_epi32(m[ 4]));
+ x5 = _mm_add_epi32(x5, _mm_set1_epi32(m[ 5]));
+ x6 = _mm_add_epi32(x6, _mm_set1_epi32(m[ 6]));
+ x7 = _mm_add_epi32(x7, _mm_set1_epi32(m[ 7]));
+ x8 = _mm_add_epi32(x8, _mm_set1_epi32(m[ 8]));
+ x9 = _mm_add_epi32(x9, _mm_set1_epi32(m[ 9]));
+ xa = _mm_add_epi32(xa, _mm_set1_epi32(m[10]));
+ xb = _mm_add_epi32(xb, _mm_set1_epi32(m[11]));
+ xc = _mm_add_epi32(xc, _mm_set1_epi32(m[12]));
+ xd = _mm_add_epi32(xd, _mm_set1_epi32(m[13]));
+ xe = _mm_add_epi32(xe, _mm_set1_epi32(m[14]));
+ xf = _mm_add_epi32(xf, _mm_set1_epi32(m[15]));
+
+ xc = _mm_add_epi32(xc, ctrinc);
+
+ /* transpose state matrix by interleaving 32-, then 64-bit words */
+ t = x0; x0 = _mm_unpacklo_epi32(t, x1);
+ x1 = _mm_unpackhi_epi32(t, x1);
+ t = x2; x2 = _mm_unpacklo_epi32(t, x3);
+ x3 = _mm_unpackhi_epi32(t, x3);
+ t = x4; x4 = _mm_unpacklo_epi32(t, x5);
+ x5 = _mm_unpackhi_epi32(t, x5);
+ t = x6; x6 = _mm_unpacklo_epi32(t, x7);
+ x7 = _mm_unpackhi_epi32(t, x7);
+ t = x8; x8 = _mm_unpacklo_epi32(t, x9);
+ x9 = _mm_unpackhi_epi32(t, x9);
+ t = xa; xa = _mm_unpacklo_epi32(t, xb);
+ xb = _mm_unpackhi_epi32(t, xb);
+ t = xc; xc = _mm_unpacklo_epi32(t, xd);
+ xd = _mm_unpackhi_epi32(t, xd);
+ t = xe; xe = _mm_unpacklo_epi32(t, xf);
+ xf = _mm_unpackhi_epi32(t, xf);
+
+ t = x0; x0 = _mm_unpacklo_epi64(t, x2);
+ x2 = _mm_unpackhi_epi64(t, x2);
+ t = x1; x1 = _mm_unpacklo_epi64(t, x3);
+ x3 = _mm_unpackhi_epi64(t, x3);
+ t = x4; x4 = _mm_unpacklo_epi64(t, x6);
+ x6 = _mm_unpackhi_epi64(t, x6);
+ t = x5; x5 = _mm_unpacklo_epi64(t, x7);
+ x7 = _mm_unpackhi_epi64(t, x7);
+ t = x8; x8 = _mm_unpacklo_epi64(t, xa);
+ xa = _mm_unpackhi_epi64(t, xa);
+ t = x9; x9 = _mm_unpacklo_epi64(t, xb);
+ xb = _mm_unpackhi_epi64(t, xb);
+ t = xc; xc = _mm_unpacklo_epi64(t, xe);
+ xe = _mm_unpackhi_epi64(t, xe);
+ t = xd; xd = _mm_unpacklo_epi64(t, xf);
+ xf = _mm_unpackhi_epi64(t, xf);
+
+ x0 = _mm_xor_si128(_mm_loadu_si128(out + 0), x0);
+ x1 = _mm_xor_si128(_mm_loadu_si128(out + 8), x1);
+ x2 = _mm_xor_si128(_mm_loadu_si128(out + 4), x2);
+ x3 = _mm_xor_si128(_mm_loadu_si128(out + 12), x3);
+ x4 = _mm_xor_si128(_mm_loadu_si128(out + 1), x4);
+ x5 = _mm_xor_si128(_mm_loadu_si128(out + 9), x5);
+ x6 = _mm_xor_si128(_mm_loadu_si128(out + 5), x6);
+ x7 = _mm_xor_si128(_mm_loadu_si128(out + 13), x7);
+ x8 = _mm_xor_si128(_mm_loadu_si128(out + 2), x8);
+ x9 = _mm_xor_si128(_mm_loadu_si128(out + 10), x9);
+ xa = _mm_xor_si128(_mm_loadu_si128(out + 6), xa);
+ xb = _mm_xor_si128(_mm_loadu_si128(out + 14), xb);
+ xc = _mm_xor_si128(_mm_loadu_si128(out + 3), xc);
+ xd = _mm_xor_si128(_mm_loadu_si128(out + 11), xd);
+ xe = _mm_xor_si128(_mm_loadu_si128(out + 7), xe);
+ xf = _mm_xor_si128(_mm_loadu_si128(out + 15), xf);
+
+ _mm_storeu_si128(out + 0, x0);
+ _mm_storeu_si128(out + 8, x1);
+ _mm_storeu_si128(out + 4, x2);
+ _mm_storeu_si128(out + 12, x3);
+ _mm_storeu_si128(out + 1, x4);
+ _mm_storeu_si128(out + 9, x5);
+ _mm_storeu_si128(out + 5, x6);
+ _mm_storeu_si128(out + 13, x7);
+ _mm_storeu_si128(out + 2, x8);
+ _mm_storeu_si128(out + 10, x9);
+ _mm_storeu_si128(out + 6, xa);
+ _mm_storeu_si128(out + 14, xb);
+ _mm_storeu_si128(out + 3, xc);
+ _mm_storeu_si128(out + 11, xd);
+ _mm_storeu_si128(out + 7, xe);
+ _mm_storeu_si128(out + 15, xf);
+
+ this->m[3] = _mm_add_epi32(this->m[3], _mm_set_epi32(0, 0, 0, 4));
+}
+
+METHOD(chapoly_drv_t, set_key, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *constant, u_char *key,
+ u_char *salt)
+{
+ this->m[0] = _mm_loadu_si128((__m128i*)constant);
+ this->m[1] = _mm_loadu_si128((__m128i*)key + 0);
+ this->m[2] = _mm_loadu_si128((__m128i*)key + 1);
+ this->m[3] = _mm_set_epi32(0, 0, ru32(salt), 0);
+
+ return TRUE;
+}
+
+/**
+ * r[127:64] = h[95:64] * a, r[63:0] = h[31:0] * b
+ */
+static inline __m128i mul2(__m128i h, u_int32_t a, u_int32_t b)
+{
+ return _mm_mul_epu32(h, _mm_set_epi32(0, a, 0, b));
+}
+
+/**
+ * c = a[127:64] + a[63:0] + b[127:64] + b[63:0]
+ * z = x[127:64] + x[63:0] + y[127:64] + y[63:0]
+ */
+static inline void sum2(__m128i a, __m128i b, __m128i x, __m128i y,
+ u_int64_t *c, u_int64_t *z)
+{
+ __m128i r, s;
+
+ a = _mm_add_epi64(a, b);
+ x = _mm_add_epi64(x, y);
+ r = _mm_unpacklo_epi64(x, a);
+ s = _mm_unpackhi_epi64(x, a);
+ r = _mm_add_epi64(r, s);
+
+ _mm_storel_epi64((__m128i*)z, r);
+ _mm_storel_epi64((__m128i*)c, _mm_srli_si128(r, 8));
+}
+
+/**
+ * r = a[127:64] + b[127:64] + c[127:64] + d[127:64] + e[127:64]
+ * + a[63:0] + b[63:0] + c[63:0] + d[63:0] + e[63:0]
+ */
+static inline u_int64_t sum5(__m128i a, __m128i b, __m128i c,
+ __m128i d, __m128i e)
+{
+ u_int64_t r;
+
+ a = _mm_add_epi64(a, b);
+ c = _mm_add_epi64(c, d);
+ a = _mm_add_epi64(a, e);
+ a = _mm_add_epi64(a, c);
+
+ a = _mm_add_epi64(a, _mm_srli_si128(a, 8));
+ _mm_storel_epi64((__m128i*)&r, a);
+
+ return r;
+}
+
+/**
+ * Make second Poly1305 key u = r^2
+ */
+static void make_u(private_chapoly_drv_ssse3_t *this)
+{
+ __m128i r01, r23, r44, x0, x1, y0, y1, z0;
+ u_int32_t r0, r1, r2, r3, r4;
+ u_int32_t u0, u1, u2, u3, u4;
+ u_int32_t s1, s2, s3, s4;
+ u_int64_t d0, d1, d2, d3, d4;
+
+ r0 = this->r[0];
+ r1 = this->r[1];
+ r2 = this->r[2];
+ r3 = this->r[3];
+ r4 = this->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ r01 = _mm_set_epi32(0, r0, 0, r1);
+ r23 = _mm_set_epi32(0, r2, 0, r3);
+ r44 = _mm_set_epi32(0, r4, 0, r4);
+
+ /* u = r^2 */
+ x0 = mul2(r01, r0, s4);
+ x1 = mul2(r01, r1, r0);
+ y0 = mul2(r23, s3, s2);
+ y1 = mul2(r23, s4, s3);
+ z0 = mul2(r44, s1, s2);
+ y0 = _mm_add_epi64(y0, _mm_srli_si128(z0, 8));
+ y1 = _mm_add_epi64(y1, _mm_slli_si128(z0, 8));
+ sum2(x0, y0, x1, y1, &d0, &d1);
+
+ x0 = mul2(r01, r2, r1);
+ x1 = mul2(r01, r3, r2);
+ y0 = mul2(r23, r0, s4);
+ y1 = mul2(r23, r1, r0);
+ z0 = mul2(r44, s3, s4);
+ y0 = _mm_add_epi64(y0, _mm_srli_si128(z0, 8));
+ y1 = _mm_add_epi64(y1, _mm_slli_si128(z0, 8));
+ sum2(x0, y0, x1, y1, &d2, &d3);
+
+ x0 = mul2(r01, r4, r3);
+ y0 = mul2(r23, r2, r1);
+ z0 = mul2(r44, r0, 0);
+ y0 = _mm_add_epi64(y0, z0);
+ x0 = _mm_add_epi64(x0, y0);
+ x0 = _mm_add_epi64(x0, _mm_srli_si128(x0, 8));
+ _mm_storel_epi64((__m128i*)&d4, x0);
+
+ /* (partial) r %= p */
+ d1 += sr(d0, 26); u0 = and(d0, 0x3ffffff);
+ d2 += sr(d1, 26); u1 = and(d1, 0x3ffffff);
+ d3 += sr(d2, 26); u2 = and(d2, 0x3ffffff);
+ d4 += sr(d3, 26); u3 = and(d3, 0x3ffffff);
+ u0 += sr(d4, 26) * 5; u4 = and(d4, 0x3ffffff);
+ u1 += u0 >> 26; u0 &= 0x3ffffff;
+
+ this->u[0] = u0;
+ this->u[1] = u1;
+ this->u[2] = u2;
+ this->u[3] = u3;
+ this->u[4] = u4;
+}
+
+METHOD(chapoly_drv_t, init, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *iv)
+{
+ u_char key[CHACHA_BLOCK_SIZE];
+
+ this->m[3] = _mm_or_si128(
+ _mm_set_epi32(ru32(iv + 4), ru32(iv + 0), 0, 0),
+ _mm_and_si128(this->m[3], _mm_set_epi32(0, 0, ~0, 0)));
+
+ memset(key, 0, CHACHA_BLOCK_SIZE);
+ chacha_block_xor(this, key);
+
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ this->r[0] = (ru32(key + 0) >> 0) & 0x3ffffff;
+ this->r[1] = (ru32(key + 3) >> 2) & 0x3ffff03;
+ this->r[2] = (ru32(key + 6) >> 4) & 0x3ffc0ff;
+ this->r[3] = (ru32(key + 9) >> 6) & 0x3f03fff;
+ this->r[4] = (ru32(key + 12) >> 8) & 0x00fffff;
+
+ make_u(this);
+
+ /* h = 0 */
+ memwipe(this->h, sizeof(this->h));
+
+ this->s[0] = ru32(key + 16);
+ this->s[1] = ru32(key + 20);
+ this->s[2] = ru32(key + 24);
+ this->s[3] = ru32(key + 28);
+
+ return TRUE;
+}
+
+/**
+ * Update Poly1305 for a multiple of two blocks
+ */
+static void poly2(private_chapoly_drv_ssse3_t *this, u_char *data, u_int dblks)
+{
+ u_int32_t r0, r1, r2, r3, r4, u0, u1, u2, u3, u4;
+ u_int32_t s1, s2, s3, s4, v1, v2, v3, v4;
+ __m128i hc0, hc1, hc2, hc3, hc4;
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int32_t c0, c1, c2, c3, c4;
+ u_int64_t d0, d1, d2, d3, d4;
+ u_int i;
+
+ r0 = this->r[0];
+ r1 = this->r[1];
+ r2 = this->r[2];
+ r3 = this->r[3];
+ r4 = this->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ u0 = this->u[0];
+ u1 = this->u[1];
+ u2 = this->u[2];
+ u3 = this->u[3];
+ u4 = this->u[4];
+
+ v1 = u1 * 5;
+ v2 = u2 * 5;
+ v3 = u3 * 5;
+ v4 = u4 * 5;
+
+ h0 = this->h[0];
+ h1 = this->h[1];
+ h2 = this->h[2];
+ h3 = this->h[3];
+ h4 = this->h[4];
+
+ /* h = (h + c1) * r^2 + c2 * r */
+ for (i = 0; i < dblks; i++)
+ {
+ /* h += m[i] */
+ h0 += (ru32(data + 0) >> 0) & 0x3ffffff;
+ h1 += (ru32(data + 3) >> 2) & 0x3ffffff;
+ h2 += (ru32(data + 6) >> 4) & 0x3ffffff;
+ h3 += (ru32(data + 9) >> 6) & 0x3ffffff;
+ h4 += (ru32(data + 12) >> 8) | (1 << 24);
+ data += POLY_BLOCK_SIZE;
+
+ /* c = m[i + 1] */
+ c0 = (ru32(data + 0) >> 0) & 0x3ffffff;
+ c1 = (ru32(data + 3) >> 2) & 0x3ffffff;
+ c2 = (ru32(data + 6) >> 4) & 0x3ffffff;
+ c3 = (ru32(data + 9) >> 6) & 0x3ffffff;
+ c4 = (ru32(data + 12) >> 8) | (1 << 24);
+ data += POLY_BLOCK_SIZE;
+
+ hc0 = _mm_set_epi32(0, h0, 0, c0);
+ hc1 = _mm_set_epi32(0, h1, 0, c1);
+ hc2 = _mm_set_epi32(0, h2, 0, c2);
+ hc3 = _mm_set_epi32(0, h3, 0, c3);
+ hc4 = _mm_set_epi32(0, h4, 0, c4);
+
+ /* h = h * r^2 + c * r */
+ d0 = sum5(mul2(hc0, u0, r0),
+ mul2(hc1, v4, s4),
+ mul2(hc2, v3, s3),
+ mul2(hc3, v2, s2),
+ mul2(hc4, v1, s1));
+ d1 = sum5(mul2(hc0, u1, r1),
+ mul2(hc1, u0, r0),
+ mul2(hc2, v4, s4),
+ mul2(hc3, v3, s3),
+ mul2(hc4, v2, s2));
+ d2 = sum5(mul2(hc0, u2, r2),
+ mul2(hc1, u1, r1),
+ mul2(hc2, u0, r0),
+ mul2(hc3, v4, s4),
+ mul2(hc4, v3, s3));
+ d3 = sum5(mul2(hc0, u3, r3),
+ mul2(hc1, u2, r2),
+ mul2(hc2, u1, r1),
+ mul2(hc3, u0, r0),
+ mul2(hc4, v4, s4));
+ d4 = sum5(mul2(hc0, u4, r4),
+ mul2(hc1, u3, r3),
+ mul2(hc2, u2, r2),
+ mul2(hc3, u1, r1),
+ mul2(hc4, u0, r0));
+
+ /* (partial) h %= p */
+ d1 += sr(d0, 26); h0 = and(d0, 0x3ffffff);
+ d2 += sr(d1, 26); h1 = and(d1, 0x3ffffff);
+ d3 += sr(d2, 26); h2 = and(d2, 0x3ffffff);
+ d4 += sr(d3, 26); h3 = and(d3, 0x3ffffff);
+ h0 += sr(d4, 26) * 5; h4 = and(d4, 0x3ffffff);
+ h1 += h0 >> 26; h0 = h0 & 0x3ffffff;
+ }
+
+ this->h[0] = h0;
+ this->h[1] = h1;
+ this->h[2] = h2;
+ this->h[3] = h3;
+ this->h[4] = h4;
+}
+
+/**
+ * Update Poly1305 for a single block
+ */
+static void poly1(private_chapoly_drv_ssse3_t *this, u_char *data)
+{
+ u_int32_t r0, r1, r2, r3, r4;
+ u_int32_t s1, s2, s3, s4;
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int64_t d0, d1, d2, d3, d4;
+ __m128i h01, h23, h44;
+ __m128i x0, x1, y0, y1, z0;
+ u_int32_t t0, t1;
+
+ r0 = this->r[0];
+ r1 = this->r[1];
+ r2 = this->r[2];
+ r3 = this->r[3];
+ r4 = this->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ h0 = this->h[0];
+ h1 = this->h[1];
+ h2 = this->h[2];
+ h3 = this->h[3];
+ h4 = this->h[4];
+
+ h01 = _mm_set_epi32(0, h0, 0, h1);
+ h23 = _mm_set_epi32(0, h2, 0, h3);
+ h44 = _mm_set_epi32(0, h4, 0, h4);
+
+ /* h += m[i] */
+ t0 = (ru32(data + 0) >> 0) & 0x3ffffff;
+ t1 = (ru32(data + 3) >> 2) & 0x3ffffff;
+ h01 = _mm_add_epi32(h01, _mm_set_epi32(0, t0, 0, t1));
+ t0 = (ru32(data + 6) >> 4) & 0x3ffffff;
+ t1 = (ru32(data + 9) >> 6) & 0x3ffffff;
+ h23 = _mm_add_epi32(h23, _mm_set_epi32(0, t0, 0, t1));
+ t0 = (ru32(data + 12) >> 8) | (1 << 24);
+ h44 = _mm_add_epi32(h44, _mm_set_epi32(0, t0, 0, t0));
+
+ /* h *= r */
+ x0 = mul2(h01, r0, s4);
+ x1 = mul2(h01, r1, r0);
+ y0 = mul2(h23, s3, s2);
+ y1 = mul2(h23, s4, s3);
+ z0 = mul2(h44, s1, s2);
+ y0 = _mm_add_epi64(y0, _mm_srli_si128(z0, 8));
+ y1 = _mm_add_epi64(y1, _mm_slli_si128(z0, 8));
+ sum2(x0, y0, x1, y1, &d0, &d1);
+
+ x0 = mul2(h01, r2, r1);
+ x1 = mul2(h01, r3, r2);
+ y0 = mul2(h23, r0, s4);
+ y1 = mul2(h23, r1, r0);
+ z0 = mul2(h44, s3, s4);
+ y0 = _mm_add_epi64(y0, _mm_srli_si128(z0, 8));
+ y1 = _mm_add_epi64(y1, _mm_slli_si128(z0, 8));
+ sum2(x0, y0, x1, y1, &d2, &d3);
+
+ x0 = mul2(h01, r4, r3);
+ y0 = mul2(h23, r2, r1);
+ z0 = mul2(h44, r0, 0);
+ y0 = _mm_add_epi64(y0, z0);
+ x0 = _mm_add_epi64(x0, y0);
+ x0 = _mm_add_epi64(x0, _mm_srli_si128(x0, 8));
+ _mm_storel_epi64((__m128i*)&d4, x0);
+
+ /* (partial) h %= p */
+ d1 += sr(d0, 26); h0 = and(d0, 0x3ffffff);
+ d2 += sr(d1, 26); h1 = and(d1, 0x3ffffff);
+ d3 += sr(d2, 26); h2 = and(d2, 0x3ffffff);
+ d4 += sr(d3, 26); h3 = and(d3, 0x3ffffff);
+ h0 += sr(d4, 26) * 5; h4 = and(d4, 0x3ffffff);
+ h1 += h0 >> 26; h0 = h0 & 0x3ffffff;
+
+ this->h[0] = h0;
+ this->h[1] = h1;
+ this->h[2] = h2;
+ this->h[3] = h3;
+ this->h[4] = h4;
+}
+
+METHOD(chapoly_drv_t, poly, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *data, u_int blocks)
+{
+ poly2(this, data, blocks / 2);
+ if (blocks-- % 2)
+ {
+ poly1(this, data + POLY_BLOCK_SIZE * blocks);
+ }
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, chacha, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *stream)
+{
+ memset(stream, 0, CHACHA_BLOCK_SIZE);
+ chacha_block_xor(this, stream);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, encrypt, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *data, u_int blocks)
+{
+ while (blocks >= 4)
+ {
+ chacha_4block_xor(this, data);
+ poly2(this, data, 8);
+ data += CHACHA_BLOCK_SIZE * 4;
+ blocks -= 4;
+ }
+ while (blocks--)
+ {
+ chacha_block_xor(this, data);
+ poly2(this, data, 2);
+ data += CHACHA_BLOCK_SIZE;
+ }
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, decrypt, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *data, u_int blocks)
+{
+ while (blocks >= 4)
+ {
+ poly2(this, data, 8);
+ chacha_4block_xor(this, data);
+ data += CHACHA_BLOCK_SIZE * 4;
+ blocks -= 4;
+ }
+ while (blocks--)
+ {
+ poly2(this, data, 2);
+ chacha_block_xor(this, data);
+ data += CHACHA_BLOCK_SIZE;
+ }
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, finish, bool,
+ private_chapoly_drv_ssse3_t *this, u_char *mac)
+{
+ u_int32_t h0, h1, h2, h3, h4;
+ u_int32_t g0, g1, g2, g3, g4;
+ u_int32_t mask;
+ u_int64_t f = 0;
+
+ /* fully carry h */
+ h0 = this->h[0];
+ h1 = this->h[1];
+ h2 = this->h[2];
+ h3 = this->h[3];
+ h4 = this->h[4];
+
+ h2 += (h1 >> 26); h1 = h1 & 0x3ffffff;
+ h3 += (h2 >> 26); h2 = h2 & 0x3ffffff;
+ h4 += (h3 >> 26); h3 = h3 & 0x3ffffff;
+ h0 += (h4 >> 26) * 5; h4 = h4 & 0x3ffffff;
+ h1 += (h0 >> 26); h0 = h0 & 0x3ffffff;
+
+ /* compute h + -p */
+ g0 = h0 + 5;
+ g1 = h1 + (g0 >> 26); g0 &= 0x3ffffff;
+ g2 = h2 + (g1 >> 26); g1 &= 0x3ffffff;
+ g3 = h3 + (g2 >> 26); g2 &= 0x3ffffff;
+ g4 = h4 + (g3 >> 26) - (1 << 26); g3 &= 0x3ffffff;
+
+ /* select h if h < p, or h + -p if h >= p */
+ mask = (g4 >> ((sizeof(u_int32_t) * 8) - 1)) - 1;
+ g0 &= mask;
+ g1 &= mask;
+ g2 &= mask;
+ g3 &= mask;
+ g4 &= mask;
+ mask = ~mask;
+ h0 = (h0 & mask) | g0;
+ h1 = (h1 & mask) | g1;
+ h2 = (h2 & mask) | g2;
+ h3 = (h3 & mask) | g3;
+ h4 = (h4 & mask) | g4;
+
+ /* h = h % (2^128) */
+ h0 = (h0 >> 0) | (h1 << 26);
+ h1 = (h1 >> 6) | (h2 << 20);
+ h2 = (h2 >> 12) | (h3 << 14);
+ h3 = (h3 >> 18) | (h4 << 8);
+
+ /* mac = (h + s) % (2^128) */
+ f = (f >> 32) + h0 + this->s[0]; wu32(mac + 0, f);
+ f = (f >> 32) + h1 + this->s[1]; wu32(mac + 4, f);
+ f = (f >> 32) + h2 + this->s[2]; wu32(mac + 8, f);
+ f = (f >> 32) + h3 + this->s[3]; wu32(mac + 12, f);
+
+ return TRUE;
+}
+
+METHOD(chapoly_drv_t, destroy, void,
+ private_chapoly_drv_ssse3_t *this)
+{
+ memwipe(this->m, sizeof(this->m));
+ memwipe(this->h, sizeof(this->h));
+ memwipe(this->r, sizeof(this->r));
+ memwipe(this->u, sizeof(this->u));
+ memwipe(this->s, sizeof(this->s));
+ free_align(this);
+}
+
+/**
+ * See header
+ */
+chapoly_drv_t *chapoly_drv_ssse3_create()
+{
+ private_chapoly_drv_ssse3_t *this;
+
+ if (!cpu_feature_available(CPU_FEATURE_SSSE3))
+ {
+ return FALSE;
+ }
+
+ INIT_ALIGN(this, sizeof(__m128i),
+ .public = {
+ .set_key = _set_key,
+ .init = _init,
+ .poly = _poly,
+ .chacha = _chacha,
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .finish = _finish,
+ .destroy = _destroy,
+ },
+ );
+
+ return &this->public;
+}
+
+#else /* !__SSSE3__ */
+
+chapoly_drv_t *chapoly_drv_ssse3_create()
+{
+ return NULL;
+}
+
+#endif /* !__SSSE3__ */
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.h b/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.h
new file mode 100644
index 000000000..7e0e8084c
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_drv_ssse3.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 chapoly_drv_ssse3 chapoly_drv_ssse3
+ * @{ @ingroup chapoly
+ */
+
+#include "chapoly_drv.h"
+
+#ifndef CHAPOLY_DRV_SSSE3_H_
+#define CHAPOLY_DRV_SSSE3_H_
+
+/**
+ * Create a chapoly_drv_ssse3 instance.
+ */
+chapoly_drv_t *chapoly_drv_ssse3_create();
+
+#endif /** CHAPOLY_DRV_SSSE3_H_ @}*/
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_plugin.c b/src/libstrongswan/plugins/chapoly/chapoly_plugin.c
new file mode 100644
index 000000000..02e7121d6
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_plugin.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 "chapoly_plugin.h"
+#include "chapoly_aead.h"
+
+#include <library.h>
+
+typedef struct private_chapoly_plugin_t private_chapoly_plugin_t;
+
+/**
+ * Private data of chapoly_plugin
+ */
+struct private_chapoly_plugin_t {
+
+ /**
+ * Public functions
+ */
+ chapoly_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_chapoly_plugin_t *this)
+{
+ return "chapoly";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_chapoly_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(AEAD, chapoly_aead_create),
+ PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_chapoly_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *chapoly_plugin_create()
+{
+ private_chapoly_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/chapoly/chapoly_plugin.h b/src/libstrongswan/plugins/chapoly/chapoly_plugin.h
new file mode 100644
index 000000000..f2b62e73c
--- /dev/null
+++ b/src/libstrongswan/plugins/chapoly/chapoly_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 chapoly chapoly
+ * @ingroup plugins
+ *
+ * @defgroup chapoly_plugin chapoly_plugin
+ * @{ @ingroup chapoly
+ */
+
+#ifndef CHAPOLY_PLUGIN_H_
+#define CHAPOLY_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct chapoly_plugin_t chapoly_plugin_t;
+
+/**
+ * Plugin providing a ChaCha20/Poly1305 AEAD.
+ */
+struct chapoly_plugin_t {
+
+ /**
+ * Implements plugin interface.
+ */
+ plugin_t plugin;
+};
+
+#endif /** CHAPOLY_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
index c81318b19..6010f9d8b 100644
--- a/src/libstrongswan/plugins/des/des_crypter.c
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -112,7 +112,7 @@ struct private_des_crypter_t {
#endif
/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
+ * units. It reduces register dependencies at the expense of 2 more
* registers */
#ifndef DES_RISC1
#define DES_RISC1
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
index 2d2b2b45d..bb45d7b4f 100644
--- a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
@@ -15,7 +15,7 @@
*/
/**
- * @defgroup sha1_hasher sha1_hasher
+ * @defgroup padlock_sha1_hasher padlock_sha1_hasher
* @{ @ingroup padlock_p
*/
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
index 6d5211657..384777610 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
@@ -439,12 +439,17 @@ static bool encode_rsa(private_pkcs11_public_key_t *this,
attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0)
{
chunk_t n, e;
- n = chunk_create(attr[0].pValue, attr[0].ulValueLen);
+ /* some tokens/libraries add unnecessary 0x00 prefixes */
+ n = chunk_skip_zero(chunk_create(attr[0].pValue, attr[0].ulValueLen));
if (n.ptr[0] & 0x80)
- { /* add leading 0x00, encoders expect it already like this */
+ { /* add leading 0x00, encoders might expect it in two's complement */
n = chunk_cata("cc", chunk_from_chars(0x00), n);
}
- e = chunk_create(attr[1].pValue, attr[1].ulValueLen);
+ e = chunk_skip_zero(chunk_create(attr[1].pValue, attr[1].ulValueLen));
+ if (e.ptr[0] & 0x80)
+ {
+ e = chunk_cata("cc", chunk_from_chars(0x00), e);
+ }
success = lib->encoding->encode(lib->encoding, type, cache, encoding,
CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
}
diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c
index 2d0ce8a4c..0ea5eeaf8 100644
--- a/src/libstrongswan/plugins/plugin_feature.c
+++ b/src/libstrongswan/plugins/plugin_feature.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2011 Martin Willi
@@ -59,7 +59,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
*/
u_int32_t plugin_feature_hash(plugin_feature_t *feature)
{
- chunk_t data;
+ chunk_t data = chunk_empty;
switch (feature->type)
{
@@ -185,7 +185,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
return a->arg.container == b->arg.container;
case FEATURE_EAP_SERVER:
case FEATURE_EAP_PEER:
- return a->arg.eap == b->arg.eap;
+ return a->arg.eap.vendor == b->arg.eap.vendor &&
+ a->arg.eap.type == b->arg.eap.type;
case FEATURE_DATABASE:
return a->arg.database == DB_ANY ||
a->arg.database == b->arg.database;
@@ -368,8 +369,15 @@ char* plugin_feature_get_string(plugin_feature_t *feature)
break;
case FEATURE_EAP_SERVER:
case FEATURE_EAP_PEER:
- if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
- eap_type_short_names, feature->arg.eap) > 0)
+ if (feature->arg.eap.vendor &&
+ asprintf(&str, "%N:%d-%d", plugin_feature_names, feature->type,
+ feature->arg.eap.type, feature->arg.eap.vendor) > 0)
+ {
+ return str;
+ }
+ else if (!feature->arg.eap.vendor &&
+ asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ eap_type_short_names, feature->arg.eap.type) > 0)
{
return str;
}
diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h
index ea23f766c..03f1ba8cc 100644
--- a/src/libstrongswan/plugins/plugin_feature.h
+++ b/src/libstrongswan/plugins/plugin_feature.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2011 Martin Willi
@@ -196,7 +196,7 @@ struct plugin_feature_t {
/** FEATURE_CONTAINER_DECODE/ENCODE */
container_type_t container;
/** FEATURE_EAP_SERVER/CLIENT */
- eap_type_t eap;
+ eap_vendor_type_t eap;
/** FEATURE_DATABASE */
db_driver_t database;
/** FEATURE_FETCHER */
@@ -292,8 +292,10 @@ struct plugin_feature_t {
#define _PLUGIN_FEATURE_CERT_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CERT_ENCODE, .cert = type)
#define _PLUGIN_FEATURE_CONTAINER_DECODE(kind, type) __PLUGIN_FEATURE(kind, CONTAINER_DECODE, .container = type)
#define _PLUGIN_FEATURE_CONTAINER_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CONTAINER_ENCODE, .container = type)
-#define _PLUGIN_FEATURE_EAP_SERVER(kind, type) __PLUGIN_FEATURE(kind, EAP_SERVER, .eap = type)
-#define _PLUGIN_FEATURE_EAP_PEER(kind, type) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = type)
+#define _PLUGIN_FEATURE_EAP_SERVER(kind, type) _PLUGIN_FEATURE_EAP_SERVER_VENDOR(kind, type, 0)
+#define _PLUGIN_FEATURE_EAP_PEER(kind, type) _PLUGIN_FEATURE_EAP_PEER_VENDOR(kind, type, 0)
+#define _PLUGIN_FEATURE_EAP_SERVER_VENDOR(kind, type, vendor)__PLUGIN_FEATURE(kind, EAP_SERVER, .eap = { type, vendor })
+#define _PLUGIN_FEATURE_EAP_PEER_VENDOR(kind, type, vendor) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = { type, vendor })
#define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type)
#define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type)
#define _PLUGIN_FEATURE_RESOLVER(kind, ...) __PLUGIN_FEATURE(kind, RESOLVER, .custom = NULL)
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.am b/src/libstrongswan/plugins/test_vectors/Makefile.am
index bde27b873..72ba4ceef 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.am
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.am
@@ -19,6 +19,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/aes_cmac.c \
test_vectors/aes_ccm.c \
test_vectors/aes_gcm.c \
+ test_vectors/chacha20poly1305.c \
test_vectors/blowfish.c \
test_vectors/camellia_cbc.c \
test_vectors/camellia_ctr.c \
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index e98119b85..fa7c3cb82 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -133,11 +133,11 @@ am_libstrongswan_test_vectors_la_OBJECTS = test_vectors_plugin.lo \
test_vectors/3des_cbc.lo test_vectors/aes_cbc.lo \
test_vectors/aes_ctr.lo test_vectors/aes_xcbc.lo \
test_vectors/aes_cmac.lo test_vectors/aes_ccm.lo \
- test_vectors/aes_gcm.lo test_vectors/blowfish.lo \
- test_vectors/camellia_cbc.lo test_vectors/camellia_ctr.lo \
- test_vectors/camellia_xcbc.lo test_vectors/cast.lo \
- test_vectors/des.lo test_vectors/idea.lo test_vectors/null.lo \
- test_vectors/rc2.lo test_vectors/rc5.lo \
+ test_vectors/aes_gcm.lo test_vectors/chacha20poly1305.lo \
+ test_vectors/blowfish.lo test_vectors/camellia_cbc.lo \
+ test_vectors/camellia_ctr.lo test_vectors/camellia_xcbc.lo \
+ test_vectors/cast.lo test_vectors/des.lo test_vectors/idea.lo \
+ test_vectors/null.lo test_vectors/rc2.lo test_vectors/rc5.lo \
test_vectors/serpent_cbc.lo test_vectors/twofish_cbc.lo \
test_vectors/md2.lo test_vectors/md4.lo test_vectors/md5.lo \
test_vectors/md5_hmac.lo test_vectors/sha1.lo \
@@ -461,6 +461,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/aes_cmac.c \
test_vectors/aes_ccm.c \
test_vectors/aes_gcm.c \
+ test_vectors/chacha20poly1305.c \
test_vectors/blowfish.c \
test_vectors/camellia_cbc.c \
test_vectors/camellia_ctr.c \
@@ -589,6 +590,8 @@ test_vectors/aes_ccm.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
test_vectors/aes_gcm.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
+test_vectors/chacha20poly1305.lo: test_vectors/$(am__dirstamp) \
+ test_vectors/$(DEPDIR)/$(am__dirstamp)
test_vectors/blowfish.lo: test_vectors/$(am__dirstamp) \
test_vectors/$(DEPDIR)/$(am__dirstamp)
test_vectors/camellia_cbc.lo: test_vectors/$(am__dirstamp) \
@@ -666,6 +669,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/camellia_ctr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/camellia_xcbc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/cast.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/chacha20poly1305.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/des.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/ecp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test_vectors/$(DEPDIR)/ecpbp.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h
index f7450aa9e..57c218c16 100644
--- a/src/libstrongswan/plugins/test_vectors/test_vectors.h
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h
@@ -113,6 +113,10 @@ TEST_VECTOR_AEAD(aes_gcm21)
TEST_VECTOR_AEAD(aes_gcm22)
TEST_VECTOR_AEAD(aes_gcm23)
+TEST_VECTOR_AEAD(chacha20poly1305_1)
+TEST_VECTOR_AEAD(chacha20poly1305_2)
+TEST_VECTOR_AEAD(chacha20poly1305_3)
+
TEST_VECTOR_SIGNER(aes_xcbc_s1)
TEST_VECTOR_SIGNER(aes_xcbc_s2)
TEST_VECTOR_SIGNER(aes_xcbc_s3)
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c b/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c
new file mode 100644
index 000000000..21726cbbb
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/chacha20poly1305.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 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 Licenseor (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 usefulbut
+ * 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 <crypto/crypto_tester.h>
+
+/**
+ * From draft-irtf-cfrg-chacha20-poly1305
+ */
+aead_test_vector_t chacha20poly1305_1 = {
+ .alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
+ .len = 265, .alen = 12,
+ .key = "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
+ "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0"
+ "\x00\x00\x00\x00",
+ .iv = "\x01\x02\x03\x04\x05\x06\x07\x08",
+ .adata = "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91",
+ .plain = "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20"
+ "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65"
+ "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20"
+ "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d"
+ "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65"
+ "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63"
+ "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64"
+ "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65"
+ "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e"
+ "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72"
+ "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65"
+ "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72"
+ "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61"
+ "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65"
+ "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20"
+ "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67"
+ "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d",
+ .cipher = "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd"
+ "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2"
+ "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0"
+ "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf"
+ "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81"
+ "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55"
+ "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38"
+ "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4"
+ "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9"
+ "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e"
+ "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a"
+ "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a"
+ "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e"
+ "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10"
+ "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30"
+ "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29"
+ "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b\xee\xad\x9d\x67\x89\x0c\xbb"
+ "\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38",
+};
+
+/**
+ * ESP example from draft-ietf-ipsecme-chacha20-poly1305-06
+ */
+aead_test_vector_t chacha20poly1305_2 = {
+ .alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
+ .len = 88, .alen = 8,
+ .key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3",
+ .iv = "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .adata = "\x01\x02\x03\x04\x00\x00\x00\x05",
+ .plain = "\x45\x00\x00\x54\xa6\xf2\x00\x00\x40\x01\xe7\x78\xc6\x33\x64\x05"
+ "\xc0\x00\x02\x05\x08\x00\x5b\x7a\x3a\x08\x00\x00\x55\x3b\xec\x10"
+ "\x00\x07\x36\x27\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23"
+ "\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33"
+ "\x34\x35\x36\x37\x01\x02\x02\x04",
+ .cipher = "\x24\x03\x94\x28\xb9\x7f\x41\x7e\x3c\x13\x75\x3a\x4f\x05\x08\x7b"
+ "\x67\xc3\x52\xe6\xa7\xfa\xb1\xb9\x82\xd4\x66\xef\x40\x7a\xe5\xc6"
+ "\x14\xee\x80\x99\xd5\x28\x44\xeb\x61\xaa\x95\xdf\xab\x4c\x02\xf7"
+ "\x2a\xa7\x1e\x7c\x4c\x4f\x64\xc9\xbe\xfe\x2f\xac\xc6\x38\xe8\xf3"
+ "\xcb\xec\x16\x3f\xac\x46\x9b\x50\x27\x73\xf6\xfb\x94\xe6\x64\xda"
+ "\x91\x65\xb8\x28\x29\xf6\x41\xe0\x76\xaa\xa8\x26\x6b\x7f\xb0\xf7"
+ "\xb1\x1b\x36\x99\x07\xe1\xad\x43",
+};
+
+/**
+ * IKEv2 example from draft-ietf-ipsecme-chacha20-poly1305-06
+ */
+aead_test_vector_t chacha20poly1305_3 = {
+ .alg = ENCR_CHACHA20_POLY1305, .key_size = 32, .salt_size = 4,
+ .len = 13, .alen = 32,
+ .key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3",
+ .iv = "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .adata = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\x2e\x20\x25\x00\x00\x00\x00\x09\x00\x00\x00\x45\x29\x00\x00\x29",
+ .plain = "\x00\x00\x00\x0c\x00\x00\x40\x01\x00\x00\x00\x0a\x00",
+ .cipher = "\x61\x03\x94\x70\x1f\x8d\x01\x7f\x7c\x12\x92\x48\x89\x6b\x71\xbf"
+ "\xe2\x52\x36\xef\xd7\xcd\xc6\x70\x66\x90\x63\x15\xb2",
+};
diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c
index 3b7f8c5a0..668632459 100644
--- a/src/libstrongswan/selectors/traffic_selector.c
+++ b/src/libstrongswan/selectors/traffic_selector.c
@@ -849,8 +849,7 @@ traffic_selector_t *traffic_selector_create_from_rfc3779_format(ts_type_t type,
memcpy(this->to, to.ptr+1, to.len-1);
this->to[to.len-2] |= mask;
}
- this->netbits = chunk_equals(from, to) ? (from.len-1)*8 - from.ptr[0]
- : NON_SUBNET_ADDRESS_RANGE;
+ calc_netbits(this);
return (&this->public);
}
diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c
index acf9160d2..305ebe620 100644
--- a/src/libstrongswan/settings/settings.c
+++ b/src/libstrongswan/settings/settings.c
@@ -37,9 +37,10 @@
typedef struct private_settings_t private_settings_t;
/**
- * Parse function provided by the generated parser.
+ * Parse functions provided by the generated parser.
*/
bool settings_parser_parse_file(section_t *root, char *name);
+bool settings_parser_parse_string(section_t *root, char *settings);
/**
* Private data of settings
@@ -843,16 +844,17 @@ METHOD(settings_t, add_fallback, void,
}
/**
- * Load settings from files matching the given file pattern.
+ * Load settings from files matching the given file pattern or from a string.
* All sections and values are added relative to "parent".
* All files (even included ones) have to be loaded successfully.
* If merge is FALSE the contents of parent are replaced with the parsed
* contents, otherwise they are merged together.
*/
-static bool load_files_internal(private_settings_t *this, section_t *parent,
- char *pattern, bool merge)
+static bool load_internal(private_settings_t *this, section_t *parent,
+ char *pattern, bool merge, bool string)
{
section_t *section;
+ bool loaded;
if (pattern == NULL || !pattern[0])
{ /* TODO: Clear parent if merge is FALSE? */
@@ -860,7 +862,9 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
}
section = settings_section_create(NULL);
- if (!settings_parser_parse_file(section, pattern))
+ loaded = string ? settings_parser_parse_string(section, pattern) :
+ settings_parser_parse_file(section, pattern);
+ if (!loaded)
{
settings_section_destroy(section, NULL);
return FALSE;
@@ -877,7 +881,7 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
METHOD(settings_t, load_files, bool,
private_settings_t *this, char *pattern, bool merge)
{
- return load_files_internal(this, this->top, pattern, merge);
+ return load_internal(this, this->top, pattern, merge, FALSE);
}
METHOD(settings_t, load_files_section, bool,
@@ -894,7 +898,30 @@ METHOD(settings_t, load_files_section, bool,
{
return FALSE;
}
- return load_files_internal(this, section, pattern, merge);
+ return load_internal(this, section, pattern, merge, FALSE);
+}
+
+METHOD(settings_t, load_string, bool,
+ private_settings_t *this, char *settings, bool merge)
+{
+ return load_internal(this, this->top, settings, merge, TRUE);
+}
+
+METHOD(settings_t, load_string_section, bool,
+ private_settings_t *this, char *settings, bool merge, char *key, ...)
+{
+ section_t *section;
+ va_list args;
+
+ va_start(args, key);
+ section = ensure_section(this, this->top, key, args);
+ va_end(args);
+
+ if (!section)
+ {
+ return FALSE;
+ }
+ return load_internal(this, section, settings, merge, TRUE);
}
METHOD(settings_t, destroy, void,
@@ -906,10 +933,7 @@ METHOD(settings_t, destroy, void,
free(this);
}
-/*
- * see header file
- */
-settings_t *settings_create(char *file)
+static private_settings_t *settings_create_base()
{
private_settings_t *this;
@@ -931,14 +955,37 @@ settings_t *settings_create(char *file)
.add_fallback = _add_fallback,
.load_files = _load_files,
.load_files_section = _load_files_section,
+ .load_string = _load_string,
+ .load_string_section = _load_string_section,
.destroy = _destroy,
},
.top = settings_section_create(NULL),
.contents = array_create(0, 0),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
+ return this;
+}
+
+/*
+ * see header file
+ */
+settings_t *settings_create(char *file)
+{
+ private_settings_t *this = settings_create_base();
load_files(this, file, FALSE);
return &this->public;
}
+
+/*
+ * see header file
+ */
+settings_t *settings_create_string(char *settings)
+{
+ private_settings_t *this = settings_create_base();
+
+ load_string(this, settings, FALSE);
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/settings/settings.h b/src/libstrongswan/settings/settings.h
index 3b87c8feb..4ef80d0f6 100644
--- a/src/libstrongswan/settings/settings.h
+++ b/src/libstrongswan/settings/settings.h
@@ -335,6 +335,50 @@ struct settings_t {
char *section, ...);
/**
+ * Load settings from the given string.
+ *
+ * If merge is TRUE, existing sections are extended, existing values
+ * replaced, by those found in the string. If it is FALSE, existing
+ * sections are purged before reading the new config.
+ *
+ * @note If the string contains _include_ statements they should be
+ * absolute paths.
+ *
+ * @note If any failures occur, no settings are added at all. So, it's all
+ * or nothing.
+ *
+ * @param settings string to parse
+ * @param merge TRUE to merge config with existing values
+ * @return TRUE, if settings were loaded successfully
+ */
+ bool (*load_string)(settings_t *this, char *settings, bool merge);
+
+ /**
+ * Load settings from the given string.
+ *
+ * If merge is TRUE, existing sections are extended, existing values
+ * replaced, by those found in the string. If it is FALSE, existing
+ * sections are purged before reading the new config.
+ *
+ * All settings are loaded relative to the given section. The section is
+ * created, if it does not yet exist.
+ *
+ * @note If the string contains _include_ statements they should be
+ * absolute paths.
+ *
+ * @note If any failures occur, no settings are added at all. So, it's all
+ * or nothing.
+ *
+ * @param settings string to parse
+ * @param merge TRUE to merge config with existing values
+ * @param section section name of parent section, printf style
+ * @param ... argument list for section
+ * @return TRUE, if settings were loaded successfully
+ */
+ bool (*load_string_section)(settings_t *this, char *settings, bool merge,
+ char *section, ...);
+
+ /**
* Destroy a settings instance.
*/
void (*destroy)(settings_t *this);
@@ -350,4 +394,14 @@ struct settings_t {
*/
settings_t *settings_create(char *file);
+/**
+ * Load settings from a string.
+ *
+ * @note If parsing the file fails the object is still created.
+ *
+ * @param settings string to read settings from
+ * @return settings object, or NULL
+ */
+settings_t *settings_create_string(char *settings);
+
#endif /** SETTINGS_H_ @}*/
diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c
index 0d71a1d01..6e64e15a6 100644
--- a/src/libstrongswan/settings/settings_lexer.c
+++ b/src/libstrongswan/settings/settings_lexer.c
@@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
yyg->yy_c_buf_p = yy_cp;
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 26
-#define YY_END_OF_BUFFER 27
+#define YY_NUM_RULES 23
+#define YY_END_OF_BUFFER 24
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -465,14 +465,13 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[52] =
+static yyconst flex_int16_t yy_accept[49] =
{ 0,
- 0, 0, 0, 0, 0, 0, 27, 9, 2, 3,
+ 0, 0, 0, 0, 0, 0, 24, 9, 2, 3,
8, 1, 6, 9, 4, 5, 14, 10, 11, 12,
- 25, 16, 15, 17, 9, 2, 1, 1, 3, 9,
- 14, 13, 25, 24, 23, 24, 21, 22, 18, 19,
- 20, 1, 9, 9, 9, 9, 9, 0, 7, 7,
- 0
+ 22, 15, 16, 9, 2, 1, 1, 3, 9, 14,
+ 13, 22, 21, 20, 21, 17, 18, 19, 1, 9,
+ 9, 9, 9, 9, 0, 7, 7, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -486,11 +485,11 @@ static yyconst flex_int32_t yy_ec[256] =
8, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 9, 1, 1, 1, 1, 1, 10, 11, 12,
+ 1, 9, 1, 1, 1, 1, 1, 1, 10, 11,
- 13, 14, 1, 1, 15, 1, 1, 16, 1, 17,
- 1, 1, 1, 18, 1, 19, 20, 1, 1, 1,
- 1, 1, 21, 1, 22, 1, 1, 1, 1, 1,
+ 12, 1, 1, 1, 13, 1, 1, 14, 1, 15,
+ 1, 1, 1, 16, 1, 17, 18, 1, 1, 1,
+ 1, 1, 19, 1, 20, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -507,92 +506,91 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[23] =
+static yyconst flex_int32_t yy_meta[21] =
{ 0,
1, 2, 3, 1, 4, 5, 4, 6, 7, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 8, 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 8, 9
} ;
-static yyconst flex_int16_t yy_base[62] =
+static yyconst flex_int16_t yy_base[60] =
{ 0,
- 0, 0, 21, 42, 26, 28, 63, 0, 31, 155,
- 155, 59, 155, 44, 155, 155, 0, 155, 155, 0,
- 0, 155, 155, 62, 0, 48, 0, 57, 155, 47,
- 0, 155, 0, 155, 155, 49, 155, 155, 155, 155,
- 155, 0, 30, 21, 28, 12, 37, 52, 155, 54,
- 155, 81, 89, 97, 104, 112, 117, 122, 130, 138,
- 146
+ 0, 0, 19, 38, 21, 23, 55, 0, 47, 161,
+ 161, 50, 161, 37, 161, 161, 0, 161, 161, 0,
+ 0, 161, 56, 0, 44, 0, 47, 161, 39, 0,
+ 161, 0, 161, 161, 45, 161, 161, 161, 0, 32,
+ 24, 26, 11, 29, 31, 161, 33, 161, 73, 82,
+ 91, 97, 101, 110, 115, 124, 133, 142, 151
} ;
-static yyconst flex_int16_t yy_def[62] =
+static yyconst flex_int16_t yy_def[60] =
{ 0,
- 51, 1, 52, 52, 53, 53, 51, 54, 51, 51,
- 51, 55, 51, 54, 51, 51, 56, 51, 51, 57,
- 58, 51, 51, 59, 54, 51, 60, 55, 51, 54,
- 56, 51, 58, 51, 51, 51, 51, 51, 51, 51,
- 51, 60, 54, 54, 54, 54, 54, 61, 51, 61,
- 0, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51
+ 48, 1, 49, 49, 50, 50, 48, 51, 52, 48,
+ 48, 53, 48, 51, 48, 48, 54, 48, 48, 55,
+ 56, 48, 57, 51, 52, 58, 53, 48, 51, 54,
+ 48, 56, 48, 48, 48, 48, 48, 48, 58, 51,
+ 51, 51, 51, 51, 59, 48, 59, 0, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48
} ;
-static yyconst flex_int16_t yy_nxt[178] =
+static yyconst flex_int16_t yy_nxt[182] =
{ 0,
8, 9, 10, 8, 9, 11, 12, 13, 8, 8,
- 8, 8, 8, 8, 14, 8, 8, 8, 8, 8,
- 15, 16, 18, 18, 47, 18, 19, 18, 22, 20,
- 22, 23, 26, 23, 24, 26, 24, 27, 48, 46,
- 45, 48, 18, 18, 18, 44, 18, 19, 18, 26,
- 20, 35, 26, 50, 27, 50, 50, 43, 50, 29,
- 30, 29, 51, 18, 35, 36, 51, 51, 51, 51,
- 51, 37, 51, 51, 51, 38, 51, 51, 39, 40,
- 41, 17, 17, 17, 17, 17, 17, 17, 17, 21,
- 21, 21, 21, 21, 21, 21, 21, 25, 51, 51,
-
- 51, 51, 51, 25, 28, 28, 28, 28, 28, 28,
- 28, 28, 31, 51, 51, 51, 51, 31, 51, 31,
- 32, 32, 33, 33, 51, 33, 51, 33, 51, 33,
- 34, 34, 34, 34, 34, 34, 34, 34, 42, 42,
- 51, 42, 42, 42, 42, 42, 49, 49, 49, 49,
- 49, 51, 49, 49, 7, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51
+ 8, 8, 14, 8, 8, 8, 8, 8, 15, 16,
+ 18, 18, 44, 18, 19, 18, 22, 20, 22, 23,
+ 45, 23, 47, 45, 47, 47, 43, 47, 18, 18,
+ 18, 42, 18, 19, 18, 41, 20, 34, 40, 28,
+ 26, 29, 28, 26, 48, 48, 48, 18, 34, 35,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 36, 37, 38, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 24, 48, 48, 48, 48, 48, 24, 25, 48,
+
+ 25, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 30, 48, 48, 48, 48, 30, 48, 30, 31, 31,
+ 48, 48, 48, 31, 32, 32, 32, 32, 48, 32,
+ 48, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 39, 39, 48, 39, 39, 39, 39, 39,
+ 39, 46, 46, 46, 46, 46, 48, 46, 46, 46,
+ 7, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48
} ;
-static yyconst flex_int16_t yy_chk[178] =
+static yyconst flex_int16_t yy_chk[182] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 3, 3, 46, 3, 3, 3, 5, 3,
- 6, 5, 9, 6, 5, 9, 6, 9, 47, 45,
- 44, 47, 3, 4, 4, 43, 4, 4, 4, 26,
- 4, 36, 26, 48, 26, 50, 48, 30, 50, 28,
- 14, 12, 7, 4, 24, 24, 0, 0, 0, 0,
- 0, 24, 0, 0, 0, 24, 0, 0, 24, 24,
- 24, 52, 52, 52, 52, 52, 52, 52, 52, 53,
- 53, 53, 53, 53, 53, 53, 53, 54, 0, 0,
-
- 0, 0, 0, 54, 55, 55, 55, 55, 55, 55,
- 55, 55, 56, 0, 0, 0, 0, 56, 0, 56,
- 57, 57, 58, 58, 0, 58, 0, 58, 0, 58,
- 59, 59, 59, 59, 59, 59, 59, 59, 60, 60,
- 0, 60, 60, 60, 60, 60, 61, 61, 61, 61,
- 61, 0, 61, 61, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51
+ 3, 3, 43, 3, 3, 3, 5, 3, 6, 5,
+ 44, 6, 45, 44, 47, 45, 42, 47, 3, 4,
+ 4, 41, 4, 4, 4, 40, 4, 35, 29, 27,
+ 25, 14, 12, 9, 7, 0, 0, 4, 23, 23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 23, 23, 23, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 51, 0, 0, 0, 0, 0, 51, 52, 0,
+
+ 52, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 54, 0, 0, 0, 0, 54, 0, 54, 55, 55,
+ 0, 0, 0, 55, 56, 56, 56, 56, 0, 56,
+ 0, 56, 56, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 58, 58, 0, 58, 58, 58, 58, 58,
+ 58, 59, 59, 59, 59, 59, 0, 59, 59, 59,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[27] =
+static yyconst flex_int32_t yy_rule_can_match_eol[24] =
{ 0,
-0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, };
+0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 0, };
-static yyconst flex_int16_t yy_rule_linenum[26] =
+static yyconst flex_int16_t yy_rule_linenum[23] =
{ 0,
59, 60, 61, 63, 64, 65, 67, 72, 77, 85,
- 105, 108, 111, 114, 120, 122, 123, 146, 147, 148,
- 149, 150, 151, 152, 153
+ 105, 108, 111, 114, 120, 122, 141, 142, 143, 144,
+ 145, 146
} ;
/* The intent behind this definition is that it'll catch
@@ -640,7 +638,7 @@ static void include_files(parser_helper_t *ctx);
/* state used to scan quoted strings */
-#line 644 "settings/settings_lexer.c"
+#line 642 "settings/settings_lexer.c"
#define INITIAL 0
#define inc 1
@@ -952,7 +950,7 @@ YY_DECL
#line 57 "settings/settings_lexer.l"
-#line 956 "settings/settings_lexer.c"
+#line 954 "settings/settings_lexer.c"
yylval = yylval_param;
@@ -1017,13 +1015,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 52 )
+ if ( yy_current_state >= 49 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 155 );
+ while ( yy_base[yy_current_state] != 161 );
yy_find_action:
/* %% [10.0] code to find the action number goes here */
@@ -1058,13 +1056,13 @@ do_action: /* This label is used only to access EOF actions. */
{
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
- else if ( yy_act < 26 )
+ else if ( yy_act < 23 )
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
(long)yy_rule_linenum[yy_act], yytext );
- else if ( yy_act == 26 )
+ else if ( yy_act == 23 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
- else if ( yy_act == 27 )
+ else if ( yy_act == 24 )
fprintf( stderr, "--(end of buffer or a NUL)\n" );
else
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1197,21 +1195,13 @@ case 15:
case YY_STATE_EOF(str):
#line 121 "settings/settings_lexer.l"
case 16:
-/* rule 16 can match eol */
-#line 123 "settings/settings_lexer.l"
-case 17:
-/* rule 17 can match eol */
YY_RULE_SETUP
-#line 123 "settings/settings_lexer.l"
+#line 122 "settings/settings_lexer.l"
{
if (!streq(yytext, "\""))
{
- if (streq(yytext, "\n"))
- { /* put the newline back to fix the line numbers */
- unput('\n');
- yy_set_bol(0);
- }
PARSER_DBG1(yyextra, "unterminated string detected");
+ return STRING_ERROR;
}
if (yy_top_state(yyscanner) == inc)
{ /* string include */
@@ -1227,52 +1217,43 @@ YY_RULE_SETUP
}
}
YY_BREAK
-case 18:
+case 17:
YY_RULE_SETUP
-#line 146 "settings/settings_lexer.l"
+#line 141 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\n");
YY_BREAK
-case 19:
+case 18:
YY_RULE_SETUP
-#line 147 "settings/settings_lexer.l"
+#line 142 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\r");
YY_BREAK
-case 20:
+case 19:
YY_RULE_SETUP
-#line 148 "settings/settings_lexer.l"
+#line 143 "settings/settings_lexer.l"
yyextra->string_add(yyextra, "\t");
YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 149 "settings/settings_lexer.l"
-yyextra->string_add(yyextra, "\b");
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 150 "settings/settings_lexer.l"
-yyextra->string_add(yyextra, "\f");
- YY_BREAK
-case 23:
-/* rule 23 can match eol */
+case 20:
+/* rule 20 can match eol */
YY_RULE_SETUP
-#line 151 "settings/settings_lexer.l"
+#line 144 "settings/settings_lexer.l"
/* merge lines that end with EOL characters */
YY_BREAK
-case 24:
+case 21:
YY_RULE_SETUP
-#line 152 "settings/settings_lexer.l"
+#line 145 "settings/settings_lexer.l"
yyextra->string_add(yyextra, yytext+1);
YY_BREAK
-case 25:
+case 22:
+/* rule 22 can match eol */
YY_RULE_SETUP
-#line 153 "settings/settings_lexer.l"
+#line 146 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
-#line 158 "settings/settings_lexer.l"
+#line 151 "settings/settings_lexer.l"
{
settings_parser_pop_buffer_state(yyscanner);
if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1281,12 +1262,12 @@ case YY_STATE_EOF(INITIAL):
}
}
YY_BREAK
-case 26:
+case 23:
YY_RULE_SETUP
-#line 166 "settings/settings_lexer.l"
+#line 159 "settings/settings_lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1290 "settings/settings_lexer.c"
+#line 1271 "settings/settings_lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1599,7 +1580,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 52 )
+ if ( yy_current_state >= 49 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1633,11 +1614,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 52 )
+ if ( yy_current_state >= 49 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 51);
+ yy_is_jam = (yy_current_state == 48);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2654,7 +2635,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner)
/* %ok-for-header */
-#line 166 "settings/settings_lexer.l"
+#line 159 "settings/settings_lexer.l"
@@ -2692,3 +2673,11 @@ static void include_files(parser_helper_t *ctx)
settings_parser_open_next_file(ctx);
}
+/**
+ * Load the given string to be parsed next
+ */
+void settings_parser_load_string(parser_helper_t *ctx, const char *content)
+{
+ settings_parser__scan_string(content, ctx->scanner);
+}
+
diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l
index 176387f1f..ce9d4eedc 100644
--- a/src/libstrongswan/settings/settings_lexer.l
+++ b/src/libstrongswan/settings/settings_lexer.l
@@ -119,16 +119,11 @@ static void include_files(parser_helper_t *ctx);
<str>{
"\"" |
<<EOF>> |
- \n |
\\ {
if (!streq(yytext, "\""))
{
- if (streq(yytext, "\n"))
- { /* put the newline back to fix the line numbers */
- unput('\n');
- yy_set_bol(0);
- }
PARSER_DBG1(yyextra, "unterminated string detected");
+ return STRING_ERROR;
}
if (yy_top_state(yyscanner) == inc)
{ /* string include */
@@ -146,11 +141,9 @@ static void include_files(parser_helper_t *ctx);
\\n yyextra->string_add(yyextra, "\n");
\\r yyextra->string_add(yyextra, "\r");
\\t yyextra->string_add(yyextra, "\t");
- \\b yyextra->string_add(yyextra, "\b");
- \\f yyextra->string_add(yyextra, "\f");
\\\r?\n /* merge lines that end with EOL characters */
\\. yyextra->string_add(yyextra, yytext+1);
- [^\\\n"]+ {
+ [^\\"]+ {
yyextra->string_add(yyextra, yytext);
}
}
@@ -198,3 +191,11 @@ static void include_files(parser_helper_t *ctx)
settings_parser_open_next_file(ctx);
}
+
+/**
+ * Load the given string to be parsed next
+ */
+void settings_parser_load_string(parser_helper_t *ctx, const char *content)
+{
+ settings_parser__scan_string(content, ctx->scanner);
+}
diff --git a/src/libstrongswan/settings/settings_parser.c b/src/libstrongswan/settings/settings_parser.c
index be805efc9..6cd3b177a 100644
--- a/src/libstrongswan/settings/settings_parser.c
+++ b/src/libstrongswan/settings/settings_parser.c
@@ -110,6 +110,7 @@ int settings_parser_get_leng(void *scanner);
int settings_parser_get_lineno(void *scanner);
/* Custom functions in lexer */
bool settings_parser_open_next_file(parser_helper_t *ctx);
+bool settings_parser_load_string(parser_helper_t *ctx, const char *content);
/**
* Forward declarations
@@ -130,7 +131,7 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx)
}
-#line 134 "settings/settings_parser.c" /* yacc.c:339 */
+#line 135 "settings/settings_parser.c" /* yacc.c:339 */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
@@ -167,26 +168,28 @@ extern int settings_parser_debug;
{
NAME = 258,
STRING = 259,
- NEWLINE = 260
+ NEWLINE = 260,
+ STRING_ERROR = 261
};
#endif
/* Tokens. */
#define NAME 258
#define STRING 259
#define NEWLINE 260
+#define STRING_ERROR 261
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
-#line 76 "settings/settings_parser.y" /* yacc.c:355 */
+#line 77 "settings/settings_parser.y" /* yacc.c:355 */
char *s;
struct section_t *sec;
struct kv_t *kv;
-#line 190 "settings/settings_parser.c" /* yacc.c:355 */
+#line 193 "settings/settings_parser.c" /* yacc.c:355 */
};
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
@@ -200,7 +203,7 @@ int settings_parser_parse (parser_helper_t *ctx);
/* Copy the second part of user declarations. */
-#line 204 "settings/settings_parser.c" /* yacc.c:358 */
+#line 207 "settings/settings_parser.c" /* yacc.c:358 */
#ifdef short
# undef short
@@ -445,7 +448,7 @@ union yyalloc
#define YYLAST 13
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 9
+#define YYNTOKENS 10
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 8
/* YYNRULES -- Number of rules. */
@@ -456,7 +459,7 @@ union yyalloc
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 260
+#define YYMAXUTOK 261
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -471,13 +474,13 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 8, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 9, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 7, 2, 6, 2, 2, 2, 2,
+ 2, 2, 2, 8, 2, 7, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -491,15 +494,15 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5
+ 5, 6
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 104, 104, 106, 107, 111, 115, 122, 130, 135,
- 142, 147, 154, 155, 169, 170
+ 0, 105, 105, 107, 108, 112, 116, 123, 131, 136,
+ 143, 148, 155, 156, 170, 171
};
#endif
@@ -508,9 +511,9 @@ static const yytype_uint8 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "NAME", "STRING", "NEWLINE", "'}'",
- "'{'", "'='", "$accept", "statements", "statement", "section",
- "section_start", "setting", "value", "valuepart", YY_NULLPTR
+ "$end", "error", "$undefined", "NAME", "STRING", "NEWLINE",
+ "STRING_ERROR", "'}'", "'{'", "'='", "$accept", "statements",
+ "statement", "section", "section_start", "setting", "value", "valuepart", YY_NULLPTR
};
#endif
@@ -519,14 +522,14 @@ static const char *const yytname[] =
(internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
- 0, 256, 257, 258, 259, 260, 125, 123, 61
+ 0, 256, 257, 258, 259, 260, 261, 125, 123, 61
};
# endif
-#define YYPACT_NINF -5
+#define YYPACT_NINF -11
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-5)))
+ (!!((Yystate) == (-11)))
#define YYTABLE_NINF -1
@@ -537,8 +540,8 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int8 yypact[] =
{
- -5, 0, -5, -1, -5, -5, -5, -5, -5, 2,
- -5, -2, 5, -5, -5, -5, -2, -5, -5, -5
+ -11, 0, -11, -1, -11, -11, -11, -11, -11, 2,
+ -11, -2, 6, -11, -11, -11, -2, -11, -11, -11
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -553,7 +556,7 @@ static const yytype_uint8 yydefact[] =
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -5, 6, -5, -5, -5, -5, -5, -4
+ -11, 5, -11, -11, -11, -11, -11, -10
};
/* YYDEFGOTO[NTERM-NUM]. */
@@ -567,29 +570,29 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 2, 14, 15, 3, 9, 4, 10, 11, 3, 13,
- 4, 18, 19, 12
+ 2, 14, 15, 3, 9, 4, 19, 10, 11, 3,
+ 13, 4, 12, 18
};
static const yytype_uint8 yycheck[] =
{
- 0, 3, 4, 3, 5, 5, 7, 8, 3, 7,
- 5, 6, 16, 7
+ 0, 3, 4, 3, 5, 5, 16, 8, 9, 3,
+ 8, 5, 7, 7
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 10, 0, 3, 5, 11, 12, 13, 14, 5,
- 7, 8, 10, 7, 3, 4, 15, 16, 6, 16
+ 0, 11, 0, 3, 5, 12, 13, 14, 15, 5,
+ 8, 9, 11, 8, 3, 4, 16, 17, 7, 17
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 9, 10, 10, 10, 11, 11, 12, 13, 13,
- 14, 14, 15, 15, 16, 16
+ 0, 10, 11, 11, 11, 12, 12, 13, 14, 14,
+ 15, 15, 16, 16, 17, 17
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -1022,45 +1025,45 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_helper_t *c
switch (yytype)
{
case 3: /* NAME */
-#line 90 "settings/settings_parser.y" /* yacc.c:1257 */
+#line 91 "settings/settings_parser.y" /* yacc.c:1257 */
{ free(((*yyvaluep).s)); }
-#line 1028 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1031 "settings/settings_parser.c" /* yacc.c:1257 */
break;
case 4: /* STRING */
-#line 90 "settings/settings_parser.y" /* yacc.c:1257 */
+#line 91 "settings/settings_parser.y" /* yacc.c:1257 */
{ free(((*yyvaluep).s)); }
-#line 1034 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1037 "settings/settings_parser.c" /* yacc.c:1257 */
break;
- case 12: /* section */
-#line 92 "settings/settings_parser.y" /* yacc.c:1257 */
+ case 13: /* section */
+#line 93 "settings/settings_parser.y" /* yacc.c:1257 */
{ pop_section(ctx); settings_section_destroy(((*yyvaluep).sec), NULL); }
-#line 1040 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1043 "settings/settings_parser.c" /* yacc.c:1257 */
break;
- case 13: /* section_start */
-#line 92 "settings/settings_parser.y" /* yacc.c:1257 */
+ case 14: /* section_start */
+#line 93 "settings/settings_parser.y" /* yacc.c:1257 */
{ pop_section(ctx); settings_section_destroy(((*yyvaluep).sec), NULL); }
-#line 1046 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1049 "settings/settings_parser.c" /* yacc.c:1257 */
break;
- case 14: /* setting */
-#line 93 "settings/settings_parser.y" /* yacc.c:1257 */
+ case 15: /* setting */
+#line 94 "settings/settings_parser.y" /* yacc.c:1257 */
{ settings_kv_destroy(((*yyvaluep).kv), NULL); }
-#line 1052 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1055 "settings/settings_parser.c" /* yacc.c:1257 */
break;
- case 15: /* value */
-#line 90 "settings/settings_parser.y" /* yacc.c:1257 */
+ case 16: /* value */
+#line 91 "settings/settings_parser.y" /* yacc.c:1257 */
{ free(((*yyvaluep).s)); }
-#line 1058 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1061 "settings/settings_parser.c" /* yacc.c:1257 */
break;
- case 16: /* valuepart */
-#line 90 "settings/settings_parser.y" /* yacc.c:1257 */
+ case 17: /* valuepart */
+#line 91 "settings/settings_parser.y" /* yacc.c:1257 */
{ free(((*yyvaluep).s)); }
-#line 1064 "settings/settings_parser.c" /* yacc.c:1257 */
+#line 1067 "settings/settings_parser.c" /* yacc.c:1257 */
break;
@@ -1326,64 +1329,64 @@ yyreduce:
switch (yyn)
{
case 5:
-#line 112 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 113 "settings/settings_parser.y" /* yacc.c:1646 */
{
add_section(ctx, (yyvsp[0].sec));
}
-#line 1334 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1337 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 6:
-#line 116 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 117 "settings/settings_parser.y" /* yacc.c:1646 */
{
add_setting(ctx, (yyvsp[0].kv));
}
-#line 1342 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1345 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 7:
-#line 123 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 124 "settings/settings_parser.y" /* yacc.c:1646 */
{
pop_section(ctx);
(yyval.sec) = (yyvsp[-2].sec);
}
-#line 1351 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1354 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 8:
-#line 131 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 132 "settings/settings_parser.y" /* yacc.c:1646 */
{
(yyval.sec) = push_section(ctx, (yyvsp[-1].s));
}
-#line 1359 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1362 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 9:
-#line 136 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 137 "settings/settings_parser.y" /* yacc.c:1646 */
{
(yyval.sec) = push_section(ctx, (yyvsp[-2].s));
}
-#line 1367 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1370 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 10:
-#line 143 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 144 "settings/settings_parser.y" /* yacc.c:1646 */
{
(yyval.kv) = settings_kv_create((yyvsp[-2].s), (yyvsp[0].s));
}
-#line 1375 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1378 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 11:
-#line 148 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 149 "settings/settings_parser.y" /* yacc.c:1646 */
{
(yyval.kv) = settings_kv_create((yyvsp[-1].s), NULL);
}
-#line 1383 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1386 "settings/settings_parser.c" /* yacc.c:1646 */
break;
case 13:
-#line 156 "settings/settings_parser.y" /* yacc.c:1646 */
+#line 157 "settings/settings_parser.y" /* yacc.c:1646 */
{ /* just put a single space between them, use strings for more */
if (asprintf(&(yyval.s), "%s %s", (yyvsp[-1].s), (yyvsp[0].s)) < 0)
{
@@ -1394,11 +1397,11 @@ yyreduce:
free((yyvsp[-1].s));
free((yyvsp[0].s));
}
-#line 1398 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1401 "settings/settings_parser.c" /* yacc.c:1646 */
break;
-#line 1402 "settings/settings_parser.c" /* yacc.c:1646 */
+#line 1405 "settings/settings_parser.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1626,7 +1629,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 173 "settings/settings_parser.y" /* yacc.c:1906 */
+#line 174 "settings/settings_parser.y" /* yacc.c:1906 */
/**
@@ -1743,3 +1746,39 @@ bool settings_parser_parse_file(section_t *root, char *name)
helper->destroy(helper);
return success;
}
+
+/**
+ * Parse the given string and add all sections and key/value pairs to the
+ * given section.
+ */
+bool settings_parser_parse_string(section_t *root, char *settings)
+{
+ parser_helper_t *helper;
+ array_t *sections = NULL;
+ bool success = FALSE;
+
+ array_insert_create(&sections, ARRAY_TAIL, root);
+ helper = parser_helper_create(sections);
+ helper->get_lineno = settings_parser_get_lineno;
+ if (settings_parser_lex_init_extra(helper, &helper->scanner) != 0)
+ {
+ helper->destroy(helper);
+ array_destroy(sections);
+ return FALSE;
+ }
+ settings_parser_load_string(helper, settings);
+ if (getenv("DEBUG_SETTINGS_PARSER"))
+ {
+ yydebug = 1;
+ settings_parser_set_debug(1, helper->scanner);
+ }
+ success = yyparse(helper) == 0;
+ if (!success)
+ {
+ DBG1(DBG_CFG, "failed to parse settings '%s'", settings);
+ }
+ array_destroy(sections);
+ settings_parser_lex_destroy(helper->scanner);
+ helper->destroy(helper);
+ return success;
+}
diff --git a/src/libstrongswan/settings/settings_parser.h b/src/libstrongswan/settings/settings_parser.h
index 9d56465ef..d887777a2 100644
--- a/src/libstrongswan/settings/settings_parser.h
+++ b/src/libstrongswan/settings/settings_parser.h
@@ -47,26 +47,28 @@ extern int settings_parser_debug;
{
NAME = 258,
STRING = 259,
- NEWLINE = 260
+ NEWLINE = 260,
+ STRING_ERROR = 261
};
#endif
/* Tokens. */
#define NAME 258
#define STRING 259
#define NEWLINE 260
+#define STRING_ERROR 261
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
-#line 76 "settings/settings_parser.y" /* yacc.c:1909 */
+#line 77 "settings/settings_parser.y" /* yacc.c:1909 */
char *s;
struct section_t *sec;
struct kv_t *kv;
-#line 70 "settings/settings_parser.h" /* yacc.c:1909 */
+#line 72 "settings/settings_parser.h" /* yacc.c:1909 */
};
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
diff --git a/src/libstrongswan/settings/settings_parser.y b/src/libstrongswan/settings/settings_parser.y
index d95a24b2a..96ab36faf 100644
--- a/src/libstrongswan/settings/settings_parser.y
+++ b/src/libstrongswan/settings/settings_parser.y
@@ -39,6 +39,7 @@ int settings_parser_get_leng(void *scanner);
int settings_parser_get_lineno(void *scanner);
/* Custom functions in lexer */
bool settings_parser_open_next_file(parser_helper_t *ctx);
+bool settings_parser_load_string(parser_helper_t *ctx, const char *content);
/**
* Forward declarations
@@ -79,7 +80,7 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx)
struct kv_t *kv;
}
%token <s> NAME STRING
-%token NEWLINE
+%token NEWLINE STRING_ERROR
/* ...and other symbols */
%type <s> value valuepart
@@ -286,3 +287,39 @@ bool settings_parser_parse_file(section_t *root, char *name)
helper->destroy(helper);
return success;
}
+
+/**
+ * Parse the given string and add all sections and key/value pairs to the
+ * given section.
+ */
+bool settings_parser_parse_string(section_t *root, char *settings)
+{
+ parser_helper_t *helper;
+ array_t *sections = NULL;
+ bool success = FALSE;
+
+ array_insert_create(&sections, ARRAY_TAIL, root);
+ helper = parser_helper_create(sections);
+ helper->get_lineno = settings_parser_get_lineno;
+ if (settings_parser_lex_init_extra(helper, &helper->scanner) != 0)
+ {
+ helper->destroy(helper);
+ array_destroy(sections);
+ return FALSE;
+ }
+ settings_parser_load_string(helper, settings);
+ if (getenv("DEBUG_SETTINGS_PARSER"))
+ {
+ yydebug = 1;
+ settings_parser_set_debug(1, helper->scanner);
+ }
+ success = yyparse(helper) == 0;
+ if (!success)
+ {
+ DBG1(DBG_CFG, "failed to parse settings '%s'", settings);
+ }
+ array_destroy(sections);
+ settings_parser_lex_destroy(helper->scanner);
+ helper->destroy(helper);
+ return success;
+}
diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c
index 312a187ac..6272ca795 100644
--- a/src/libstrongswan/tests/suites/test_chunk.c
+++ b/src/libstrongswan/tests/suites/test_chunk.c
@@ -1020,7 +1020,7 @@ START_TEST(test_printf_hook)
int len;
/* %B should be the same as %b, which is what we check, comparing the
- * acutal result could be tricky as %b prints the chunk's memory address */
+ * actual result could be tricky as %b prints the chunk's memory address */
len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
ck_assert(len >= 0 && len < sizeof(buf));
len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 7161b2c5b..5cb8013ff 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -104,6 +104,9 @@ START_TEST(test_create_from_string_v4)
{
host_t *host;
+ host = host_create_from_string(NULL, 500);
+ ck_assert(!host);
+
host = host_create_from_string("%any", 500);
verify_any(host, AF_INET, 500);
host->destroy(host);
@@ -196,6 +199,7 @@ static void test_create_from_string_and_family_addr(char *string, chunk_t addr,
START_TEST(test_create_from_string_and_family_v4)
{
+ test_create_from_string_and_family_any(NULL, AF_INET, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_INET, AF_INET);
test_create_from_string_and_family_any("%any4", AF_INET, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_INET, AF_INET);
@@ -210,6 +214,7 @@ END_TEST
START_TEST(test_create_from_string_and_family_v6)
{
+ test_create_from_string_and_family_any(NULL, AF_INET6, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("%any6", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("::", AF_INET6, AF_INET6);
@@ -224,6 +229,7 @@ END_TEST
START_TEST(test_create_from_string_and_family_other)
{
+ test_create_from_string_and_family_any(NULL, AF_UNSPEC, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("%any4", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_UNSPEC, AF_INET);
diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c
index de00e4afd..ff14ba897 100644
--- a/src/libstrongswan/tests/suites/test_identification.c
+++ b/src/libstrongswan/tests/suites/test_identification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2015 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -727,6 +727,88 @@ START_TEST(test_matches_empty_reverse)
END_TEST
/*******************************************************************************
+ * identification hashing
+ */
+
+static bool id_hash_equals(char *str, char *b_str)
+{
+ identification_t *a, *b;
+ bool success = FALSE;
+
+ a = identification_create_from_string(str);
+ b = identification_create_from_string(b_str ?: str);
+ success = a->hash(a, 0) == b->hash(b, 0);
+ a->destroy(a);
+ b->destroy(b);
+ return success;
+}
+
+START_TEST(test_hash)
+{
+ ck_assert(id_hash_equals("moon@strongswan.org", NULL));
+ ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
+ ck_assert(id_hash_equals("192.168.1.1", NULL));
+ ck_assert(id_hash_equals("C=CH", NULL));
+
+ ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
+ ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
+ ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
+ ck_assert(!id_hash_equals("C=CH", "C=DE"));
+ ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
+}
+END_TEST
+
+START_TEST(test_hash_any)
+{
+ ck_assert(id_hash_equals("%any", NULL));
+ ck_assert(id_hash_equals("%any", "0.0.0.0"));
+ ck_assert(id_hash_equals("%any", "*"));
+ ck_assert(id_hash_equals("%any", ""));
+
+ ck_assert(!id_hash_equals("%any", "any"));
+}
+END_TEST
+
+START_TEST(test_hash_dn)
+{
+ identification_t *a, *b;
+
+ /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
+ * UTF8STRING) */
+ a = identification_create_from_data(chunk_from_chars(
+ 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x53, 0x77, 0x61, 0x6e));
+ b = identification_create_from_data(chunk_from_chars(
+ 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x53, 0x77, 0x61, 0x6e));
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ ck_assert(a->equals(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_hash_inc)
+{
+ identification_t *a;
+
+ a = identification_create_from_string("vpn.strongswan.org");
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ a->destroy(a);
+
+ a = identification_create_from_string("C=CH, O=strongSwan");
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ a->destroy(a);
+}
+END_TEST
+
+/*******************************************************************************
* identification part enumeration
*/
@@ -851,6 +933,13 @@ Suite *identification_suite_create()
tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
suite_add_tcase(s, tc);
+ tc = tcase_create("hash");
+ tcase_add_test(tc, test_hash);
+ tcase_add_test(tc, test_hash_any);
+ tcase_add_test(tc, test_hash_dn);
+ tcase_add_test(tc, test_hash_inc);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("part enumeration");
tcase_add_test(tc, test_parts);
suite_add_tcase(s, tc);
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index 9601a34a9..bead9d795 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -58,6 +58,10 @@ START_SETUP(setup_base_config)
" }\n"
" key2 = with space\n"
" key3 = \"string with\\nnewline\"\n"
+ " key4 = \"multi line\n"
+ "string\"\n"
+ " key5 = \"escaped \\\n"
+ "newline\"\n"
"}\n"
"out = side\n"
"other {\n"
@@ -88,6 +92,8 @@ START_TEST(test_get_str)
verify_string("", "main.empty");
verify_string("with space", "main.key2");
verify_string("string with\nnewline", "main.key3");
+ verify_string("multi line\nstring", "main.key4");
+ verify_string("escaped newline", "main.key5");
verify_string("value", "main.sub1.key");
verify_string("value2", "main.sub1.key2");
verify_string("bar", "main.sub1.subsub.foo");
@@ -97,7 +103,7 @@ START_TEST(test_get_str)
verify_string("other val", "other.key1");
verify_null("main.none");
- verify_null("main.key4");
+ verify_null("main.key6");
verify_null("other.sub");
}
END_TEST
@@ -131,7 +137,7 @@ START_TEST(test_get_str_printf)
* probably document it at least */
verify_null("main.%s%u.key%d", "sub", 1, 2);
- verify_null("%s.%s%d", "main", "key", 4);
+ verify_null("%s.%s%d", "main", "key", 6);
}
END_TEST
@@ -529,9 +535,7 @@ END_TEST
# define include2 "/tmp/strongswan-settings-test-include2"
#endif
-START_SETUP(setup_include_config)
-{
- chunk_t inc1 = chunk_from_str(
+static char *include_content1 =
"main {\n"
" key1 = n1\n"
" key2 = n2\n"
@@ -544,14 +548,17 @@ START_SETUP(setup_include_config)
" sub3 = val3\n"
" }\n"
" include " include2 "\n"
- "}");
- chunk_t inc2 = chunk_from_str(
+ "}";
+static char *include_content2 =
"key2 = v2\n"
"sub1 {\n"
" key = val\n"
- "}");
- ck_assert(chunk_write(inc1, include1, 0022, TRUE));
- ck_assert(chunk_write(inc2, include2, 0022, TRUE));
+ "}";
+
+START_SETUP(setup_include_config)
+{
+ ck_assert(chunk_write(chunk_from_str(include_content1), include1, 0022, TRUE));
+ ck_assert(chunk_write(chunk_from_str(include_content2), include2, 0022, TRUE));
}
END_SETUP
@@ -600,6 +607,27 @@ START_TEST(test_include)
}
END_TEST
+START_TEST(test_include_string)
+{
+ chunk_t contents = chunk_from_str(
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include this/does/not/exist.conf\n"
+ " include = value\n"
+ " key2 = value2\n"
+ " include \"" include2 "\"\n"
+ " }\n"
+ "}\n"
+ "include \"" include1 "\"");
+
+ create_settings(contents);
+ verify_include();
+}
+END_TEST
+
START_TEST(test_load_files)
{
chunk_t contents = chunk_from_str(
@@ -784,6 +812,104 @@ START_TEST(test_order_section)
}
END_TEST
+
+START_TEST(test_load_string)
+{
+ char *content =
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " key3 = val3\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include = value\n"
+ " key2 = v2\n"
+ " sub1 {\n"
+ " key = val\n"
+ " }\n"
+ " }\n"
+ "}";
+ char *val1, *val2, *val3;
+
+ settings = settings_create_string(content);
+
+ val1 = settings->get_str(settings, "main.key1", NULL);
+ val2 = settings->get_str(settings, "main.sub1.key2", NULL);
+ /* loading the same content twice should not change anything, with... */
+ ck_assert(settings->load_string(settings, content, TRUE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+ /* ...or without merging */
+ ck_assert(settings->load_string(settings, content, FALSE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+
+ val1 = settings->get_str(settings, "main.key2", NULL);
+ val2 = settings->get_str(settings, "main.key3", NULL);
+ val3 = settings->get_str(settings, "main.none", NULL);
+ /* only pointers for modified settings should change, but still be valid */
+ ck_assert(settings->load_string(settings, include_content1, FALSE));
+ ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
+ ck_assert_str_eq(val1, "val2");
+ ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
+ ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
+ ck_assert_str_eq(val3, "x");
+
+ settings->destroy(settings);
+ settings = settings_create_string(content);
+ ck_assert(settings);
+
+ ck_assert(settings->load_string(settings, include_content1, TRUE));
+ verify_include();
+
+ ck_assert(settings->load_string(settings, include_content2, FALSE));
+ verify_null("main.key1");
+ verify_string("v2", "key2");
+ verify_string("val", "sub1.key");
+ verify_null("main.sub1.key3");
+}
+END_TEST
+
+
+START_TEST(test_load_string_section)
+{
+ char *content =
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include = value\n"
+ " key2 = value2\n"
+ " }\n"
+ "}";
+
+ settings = settings_create_string(content);
+
+ ck_assert(settings->load_string_section(settings, include_content1, TRUE, ""));
+ ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub1"));
+ verify_include();
+
+ /* invalid strings are a failure */
+ ck_assert(!settings->load_string_section(settings, "conf {", TRUE, ""));
+ /* NULL or empty strings are OK though */
+ ck_assert(settings->load_string_section(settings, "", TRUE, ""));
+ ck_assert(settings->load_string_section(settings, NULL, TRUE, ""));
+ verify_include();
+
+ ck_assert(settings->load_string_section(settings, include_content2, FALSE, "main"));
+ verify_null("main.key1");
+ verify_string("v2", "main.key2");
+ verify_string("val", "main.sub1.key");
+ verify_null("main.sub1.key3");
+ verify_null("main.sub2.sub3");
+
+ ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub2"));
+ verify_string("v2", "main.sub2.key2");
+ verify_string("val", "main.sub2.sub1.key");
+}
+END_TEST
+
START_SETUP(setup_fallback_config)
{
create_settings(chunk_from_str(
@@ -904,11 +1030,10 @@ END_TEST
START_SETUP(setup_string_config)
{
create_settings(chunk_from_str(
- "string = \" with accurate\twhitespace\"\n"
+ "string = \" with accurate\twhite\\tspace\"\n"
"special = \"all { special } characters # can be used.\"\n"
- "unterminated = \"is fine\n"
- "but = produces a warning\n"
- "newlines = \"can either be encoded\\nor \\\n"
+ "newlines = \"can be encoded explicitly\\nor implicitly\n"
+ "or \\\n"
"escaped\"\n"
"quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
"multiple = \"strings\" are \"combined\"\n"
@@ -918,11 +1043,9 @@ END_SETUP
START_TEST(test_strings)
{
- verify_string(" with accurate\twhitespace", "string");
+ verify_string(" with accurate\twhite\tspace", "string");
verify_string("all { special } characters # can be used.", "special");
- verify_string("is fine", "unterminated");
- verify_string("produces a warning", "but");
- verify_string("can either be encoded\nor escaped", "newlines");
+ verify_string("can be encoded explicitly\nor implicitly\nor escaped", "newlines");
verify_string("\"and\" slashes \\ can \\ be", "quotes");
verify_string("strings are combined", "multiple");
}
@@ -990,6 +1113,12 @@ START_TEST(test_invalid)
ck_assert(!settings->load_files(settings, path, FALSE));
contents = chunk_from_str(
+ "unterminated {\n"
+ " strings = \"are invalid\n");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
+
+ contents = chunk_from_str(
"spaces in name {}");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
@@ -1054,12 +1183,19 @@ Suite *settings_suite_create()
tc = tcase_create("include/load_files[_section]");
tcase_add_checked_fixture(tc, setup_include_config, teardown_include_config);
tcase_add_test(tc, test_include);
+ tcase_add_test(tc, test_include_string);
tcase_add_test(tc, test_load_files);
tcase_add_test(tc, test_load_files_section);
tcase_add_test(tc, test_order_kv);
tcase_add_test(tc, test_order_section);
suite_add_tcase(s, tc);
+ tc = tcase_create("load_string[_section]");
+ tcase_add_checked_fixture(tc, setup_include_config, teardown_config);
+ tcase_add_test(tc, test_load_string);
+ tcase_add_test(tc, test_load_string_section);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("fallback");
tcase_add_checked_fixture(tc, setup_fallback_config, teardown_config);
tcase_add_test(tc, test_add_fallback);
diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c
index 4312c6ce1..bec32d2d8 100644
--- a/src/libstrongswan/tests/suites/test_traffic_selector.c
+++ b/src/libstrongswan/tests/suites/test_traffic_selector.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2015 Martin Willi
* Copyright (C) 2015 revosec AG
*
@@ -22,10 +25,9 @@ static void verify(const char *str, const char *alt, traffic_selector_t *ts)
{
char buf[512];
- ck_assert(ts != NULL);
snprintf(buf, sizeof(buf), "%R", ts);
- ts->destroy(ts);
- if (!streq(buf, str) && !streq(buf, alt))
+ DESTROY_IF(ts);
+ if (!streq(buf, str) && (!alt || !streq(buf, alt)))
{
fail("%s != %s or %s", buf, str, alt);
}
@@ -43,6 +45,16 @@ START_TEST(test_create_from_string)
verify("fec1::/64", NULL,
traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
"fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+ verify("fec1::1..fec1::ffff:ffff:ffff:ffff", NULL,
+ traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
+ "fec1::1", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, 0,
+ "10.1.0.0", 80, "10.1.255.255", 80));
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+ "a.b.c.d", 80, "10.1.255.255", 80));
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+ "10.1.0.0", 80, "a.b.c.d", 80));
}
END_TEST
@@ -53,6 +65,10 @@ START_TEST(test_create_from_cidr)
verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]",
traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
1234, 1235));
+ verify("10.1.0.0/16[OPAQUE]", NULL,
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 65535, 0));
+
+ ck_assert(!traffic_selector_create_from_cidr("a.b.c.d/16", 0, 0, 65535));
}
END_TEST
@@ -62,6 +78,16 @@ START_TEST(test_create_from_bytes)
traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+
+ ck_assert(!traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
+ chunk_empty, 0,
+ chunk_empty, 65535));
+ ck_assert(!traffic_selector_create_from_bytes(0, TS_IPV6_ADDR_RANGE,
+ chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+ chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+ ck_assert(!traffic_selector_create_from_bytes(0, 0,
+ chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+ chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
}
END_TEST
@@ -73,6 +99,175 @@ START_TEST(test_create_from_subnet)
}
END_TEST
+struct {
+ char *net;
+ ts_type_t type;
+ chunk_t enc;
+} rfc3779_prefix_tests[] = {
+ /* some examples from RFC 3779, for addressPrefix elements we pass the same
+ * value twice to the constructor */
+ { "10.0.0.0/8", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a), },
+ { "10.0.32.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x00,0x20), },
+ { "10.0.64.0/24", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x00,0x40), },
+ { "10.1.0.0/16", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x01), },
+ { "10.5.0.1/32", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x05,0x00,0x01), },
+ { "10.5.0.0/23", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x01,0x0a,0x05,0x00), },
+ { "10.64.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40), },
+ { "10.64.0.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40,0x00), },
+ { "128.0.0.0/4", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x80), },
+ { "172.16.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0xac,0x10), },
+ { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00), },
+ /* FIXME: not a correct encoding, so we might want to fail here */
+ { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, {NULL, 0}, },
+ { "2001:0:2::/48", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00,0x20,0x01,0x00,0x00,0x00,0x02),},
+ { "2001:0:200::/39",TS_IPV6_ADDR_RANGE, chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),},
+ { "::/0", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00), },
+ /* FIXME: not a correct encoding, so we might want to fail here */
+ { "::/0", TS_IPV6_ADDR_RANGE, {NULL, 0}, },
+};
+
+START_TEST(test_create_from_rfc3779_format_prefix)
+{
+ verify(rfc3779_prefix_tests[_i].net, NULL,
+ traffic_selector_create_from_rfc3779_format(rfc3779_prefix_tests[_i].type,
+ rfc3779_prefix_tests[_i].enc, rfc3779_prefix_tests[_i].enc));
+}
+END_TEST
+
+START_TEST(test_create_from_rfc3779_format_range)
+{
+ /* addressRange elements encode a from and to address, which may still
+ * represent prefixes */
+ verify("10.5.0.0/23", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x00,0x0a,0x05),
+ chunk_from_chars(0x01,0x0a,0x05,0x00)));
+ verify("2001:0:200::/39", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV6_ADDR_RANGE,
+ chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),
+ chunk_from_chars(0x02,0x20,0x01,0x00,0x00,0x00)));
+ verify("10.2.48.0..10.2.64.255", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x04,0x0a,0x02,0x30),
+ chunk_from_chars(0x00,0x0a,0x02,0x40)));
+ verify("129.64.0.0..143.255.255.255", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x06,0x81,0x40),
+ chunk_from_chars(0x04,0x80)));
+}
+END_TEST
+
+
+static void verify_address(char *addr_from, char *addr_to, traffic_selector_t *ts)
+{
+ host_t *from, *to;
+
+ from = host_create_from_string(addr_from, 0);
+ to = host_create_from_string(addr_to, 0);
+
+ ck_assert_chunk_eq(from->get_address(from), ts->get_from_address(ts));
+ ck_assert_chunk_eq(to->get_address(to), ts->get_to_address(ts));
+ from->destroy(from);
+ to->destroy(to);
+ ts->destroy(ts);
+}
+
+START_TEST(test_get_address_range)
+{
+ verify_address("10.1.0.1", "10.1.0.10",
+ traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+ "10.1.0.1", 0, "10.1.0.10", 65535));
+ /* currently not reordered */
+ verify_address("10.1.0.10", "10.1.0.1",
+ traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+ "10.1.0.10", 0, "10.1.0.1", 65535));
+}
+END_TEST
+
+START_TEST(test_get_address_cidr)
+{
+ verify_address("10.1.0.0", "10.1.255.255",
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
+ verify_address("fec1::", "fec1::ffff:ffff:ffff:ffff",
+ traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535));
+}
+END_TEST
+
+struct {
+ ts_type_t type;
+ char *from;
+ char *to;
+ char *net;
+ u_int8_t mask;
+ bool exact;
+} to_subnet_tests[] = {
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.1", "10.0.0.1", 32, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.255.255.255", "10.0.0.0", 8, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.255", "10.0.0.0", 24, FALSE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.0.0.15", "10.0.0.0", 28, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.15", "10.0.0.0", 28, FALSE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.16", "10.0.0.0", 27, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::1", "fec1::1", 128, TRUE },
+ { TS_IPV6_ADDR_RANGE, "fec1::0", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, TRUE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::7fff", "fec1::", 113, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::efff", "fec1::", 112, FALSE },
+};
+
+START_TEST(test_to_subnet)
+{
+ traffic_selector_t *ts;
+ host_t *net, *exp_net;
+ u_int8_t mask;
+
+ ts = traffic_selector_create_from_string(0, to_subnet_tests[_i].type,
+ to_subnet_tests[_i].from, 0, to_subnet_tests[_i].to, 0);
+ ck_assert(ts->to_subnet(ts, &net, &mask) == to_subnet_tests[_i].exact);
+ exp_net = host_create_from_string(to_subnet_tests[_i].net, 0);
+ ck_assert(exp_net->ip_equals(exp_net, net));
+ ck_assert_int_eq(to_subnet_tests[_i].mask, mask);
+ exp_net->destroy(exp_net);
+ net->destroy(net);
+ ts->destroy(ts);
+}
+END_TEST
+
+struct {
+ char *cidr;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ u_int16_t port;
+} to_subnet_port_tests[] = {
+ { "10.0.0.0/8", 0, 0, 0 },
+ { "10.0.0.1/32", 80, 80, 80 },
+ { "10.0.0.1/32", 123, 465, 0 },
+ { "0.0.0.0/0", 0, 65535, 0 },
+ { "fec1::/64", 0, 0, 0 },
+ { "fec1::1/128", 80, 80, 80 },
+ { "fec1::1/128", 123, 465, 0 },
+ { "::/0", 0, 65535, 0 },
+};
+
+START_TEST(test_to_subnet_port)
+{
+ traffic_selector_t *ts;
+ host_t *net, *exp_net;
+ u_int8_t mask;
+ int exp_mask;
+
+ ts = traffic_selector_create_from_cidr(to_subnet_port_tests[_i].cidr, 0,
+ to_subnet_port_tests[_i].from_port,
+ to_subnet_port_tests[_i].to_port);
+ ck_assert(ts->to_subnet(ts, &net, &mask));
+ exp_net = host_create_from_subnet(to_subnet_port_tests[_i].cidr, &exp_mask);
+ ck_assert(exp_net->ip_equals(exp_net, net));
+ ck_assert_int_eq(exp_mask, mask);
+ ck_assert_int_eq(to_subnet_port_tests[_i].port, net->get_port(net));
+ exp_net->destroy(exp_net);
+ net->destroy(net);
+ ts->destroy(ts);
+}
+END_TEST
START_TEST(test_subset)
{
@@ -81,6 +276,14 @@ START_TEST(test_subset)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535);
verify("10.1.5.0/24", NULL, a->get_subset(a, b));
+ verify("10.1.5.0/24", NULL, b->get_subset(b, a));
+ a->destroy(a);
+ b->destroy(b);
+
+ a = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
+ b = traffic_selector_create_from_cidr("fec1::1/128", 0, 0, 65535);
+ verify("fec1::1/128", NULL, a->get_subset(a, b));
+ verify("fec1::1/128", NULL, b->get_subset(b, a));
a->destroy(a);
b->destroy(b);
}
@@ -117,7 +320,7 @@ START_TEST(test_subset_nonet)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -129,7 +332,7 @@ START_TEST(test_subset_noport)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999);
b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -141,7 +344,7 @@ START_TEST(test_subset_noproto)
a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535);
b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -153,7 +356,43 @@ START_TEST(test_subset_nofamily)
a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_dynamic)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_dynamic(0, 0, 65535);
+ b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+ ck_assert(!a->get_subset(a, b));
+ ck_assert(!b->get_subset(b, a));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_opaque)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 65535, 0);
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 80, 80);
+ ck_assert(!a->get_subset(a, b));
+ ck_assert(!b->get_subset(b, a));
+ b->destroy(b);
+
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 65535, 0);
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
+ b->destroy(b);
+
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 0, 65535);
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
a->destroy(a);
b->destroy(b);
}
@@ -189,6 +428,130 @@ START_TEST(test_includes)
END_TEST
struct {
+ bool contained;
+ struct {
+ char *net;
+ u_int8_t proto;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ } a, b;
+} is_contained_in_tests[] = {
+ { TRUE, { "10.0.0.0/16", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 17, 123, 456 },},
+ { FALSE, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { FALSE, { "10.0.1.0/24", 17, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
+ { FALSE, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
+};
+
+START_TEST(test_is_contained_in)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr(
+ is_contained_in_tests[_i].a.net, is_contained_in_tests[_i].a.proto,
+ is_contained_in_tests[_i].a.from_port, is_contained_in_tests[_i].a.to_port);
+ b = traffic_selector_create_from_cidr(
+ is_contained_in_tests[_i].b.net, is_contained_in_tests[_i].b.proto,
+ is_contained_in_tests[_i].b.from_port, is_contained_in_tests[_i].b.to_port);
+ ck_assert(a->is_contained_in(a, b) == is_contained_in_tests[_i].contained);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+struct {
+ char *net;
+ char *host;
+ bool is_host;
+ bool when_null;
+} is_host_tests[] = {
+ { "0.0.0.0/0", "192.168.1.2", FALSE, FALSE },
+ { "::/0", "fec2::1", FALSE, FALSE },
+ { "192.168.1.2/32", "192.168.1.2", TRUE, TRUE },
+ { "192.168.1.2/32", "192.168.1.1", FALSE, TRUE },
+ { "192.168.1.2/32", "fec2::1", FALSE, TRUE },
+ { "fec2::1/128", "fec2::1", TRUE, TRUE },
+ { "fec2::1/128", "fec2::2", FALSE, TRUE },
+ { "fec2::1/128", "192.168.1.2", FALSE, TRUE },
+};
+
+START_TEST(test_is_host)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_from_cidr(is_host_tests[_i].net, 0, 0, 65535);
+ h = host_create_from_string(is_host_tests[_i].host, 0);
+ ck_assert(ts->is_host(ts, h) == is_host_tests[_i].is_host);
+ ck_assert(ts->is_host(ts, NULL) == is_host_tests[_i].when_null);
+ ts->destroy(ts);
+ h->destroy(h);
+}
+END_TEST
+
+START_TEST(test_is_host_dynamic)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ h = host_create_from_string(is_host_tests[_i].host, 0);
+ ck_assert(!ts->is_host(ts, h));
+ ck_assert(ts->is_host(ts, NULL));
+ ts->destroy(ts);
+ h->destroy(h);
+}
+END_TEST
+
+
+struct {
+ char *orig;
+ char *host;
+ char *after;
+} set_address_tests[] = {
+ { "0.0.0.0/0", "192.168.1.2", "0.0.0.0/0" },
+ { "::/0", "fec2::1", "::/0" },
+ { "192.168.1.2/32", "192.168.1.1", "192.168.1.1/32" },
+ { "192.168.1.2/32", "fec2::1", "fec2::1/128" },
+ { "192.168.1.2/32", "%any", "0.0.0.0/0" },
+ { "192.168.1.2/32", "%any6", "::/0" },
+ { "fec2::1/128", "192.168.1.1", "192.168.1.1/32" },
+ { "fec2::1/128", "fec2::2", "fec2::2/128" },
+ { "fec2::1/128", "%any", "0.0.0.0/0" },
+ { "fec2::1/128", "%any6", "::/0" },
+ { NULL, "192.168.1.1", "192.168.1.1/32" },
+ { NULL, "fec2::1", "fec2::1/128" },
+ { NULL, "%any", "0.0.0.0/0" },
+ { NULL, "%any6", "::/0" },
+};
+
+START_TEST(test_set_address)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ if (set_address_tests[_i].orig)
+ {
+ ts = traffic_selector_create_from_cidr(set_address_tests[_i].orig, 0, 0, 65535);
+ ck_assert(!ts->is_dynamic(ts));
+ }
+ else
+ {
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ ck_assert(ts->is_dynamic(ts));
+ }
+ h = host_create_from_string(set_address_tests[_i].host, 0);
+ ts->set_address(ts, h);
+ ck_assert(!ts->is_dynamic(ts));
+ verify(set_address_tests[_i].after, NULL, ts);
+ h->destroy(h);
+}
+END_TEST
+
+
+struct {
int res;
struct {
char *net;
@@ -206,6 +569,10 @@ struct {
{ 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
{ -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, },
{ 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
+ { -1, { "fec1::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
+ { 1, { "fec2::/64", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
+ { -1, { "fec1::/48", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
+ { 1, { "fec1::/64", 0, 0, 65535 }, { "fec1::/48", 0, 0, 65535 }, },
{ -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
{ 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
@@ -235,12 +602,15 @@ START_TEST(test_cmp)
{
case 0:
ck_assert(traffic_selector_cmp(a, b, NULL) == 0);
+ ck_assert(a->equals(a, b));
break;
case 1:
ck_assert(traffic_selector_cmp(a, b, NULL) > 0);
+ ck_assert(!a->equals(a, b));
break;
case -1:
ck_assert(traffic_selector_cmp(a, b, NULL) < 0);
+ ck_assert(!a->equals(a, b));
break;
}
a->destroy(a);
@@ -248,6 +618,172 @@ START_TEST(test_cmp)
}
END_TEST
+static void verify_clone(traffic_selector_t *ts)
+{
+ traffic_selector_t *clone;
+
+ clone = ts->clone(ts);
+ if (!ts->equals(ts, clone))
+ {
+ fail("%R != %R", ts, clone);
+ }
+ /* equals() already compares most of these but not all */
+ ck_assert(ts->get_type(ts) == clone->get_type(clone));
+ ck_assert(ts->get_protocol(ts) == clone->get_protocol(clone));
+ ck_assert(ts->get_from_port(ts) == clone->get_from_port(clone));
+ ck_assert(ts->get_to_port(ts) == clone->get_to_port(clone));
+ ck_assert_chunk_eq(ts->get_from_address(ts), clone->get_from_address(clone));
+ ck_assert_chunk_eq(ts->get_to_address(ts), clone->get_to_address(clone));
+ ck_assert(ts->is_host(ts, NULL) == clone->is_host(clone, NULL));
+ ck_assert(ts->is_dynamic(ts) == clone->is_dynamic(clone));
+ clone->destroy(clone);
+ ts->destroy(ts);
+}
+
+START_TEST(test_clone)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_dynamic(0, 0, 0);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 0, 65535);
+ verify_clone(ts);
+
+ h = host_create_from_string("192.168.1.1", 0);
+ ts = traffic_selector_create_dynamic(0, 0, 0);
+ ts->set_address(ts, h);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
+ ts->set_address(ts, h);
+ verify_clone(ts);
+ h->destroy(h);
+
+ ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "10.0.0.1", 0, "10.0.0.16", 65535);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV6_ADDR_RANGE, "fec1::1", 80, "fec1::1:0000", 80);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 0, 65535);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
+ verify_clone(ts);
+}
+END_TEST
+
+START_TEST(test_hash)
+{
+ traffic_selector_t *a, *b;
+ host_t *h;
+
+ a = traffic_selector_create_dynamic(0, 0, 0);
+ b = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 0);
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ ck_assert_int_eq(a->hash(a, 1), b->hash(b, 1));
+
+ h = host_create_from_string("192.168.1.1", 0);
+ a->set_address(a, h);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ h->destroy(h);
+
+ a->destroy(a);
+ a = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "192.168.0.0", 0, "192.168.0.255", 65535);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 0, 65535);
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", IPPROTO_TCP, 0, 65535);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 123, 456);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ a->destroy(a);
+}
+END_TEST
+
+struct {
+ u_int8_t proto;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ u_int8_t from_type;
+ u_int8_t from_code;
+ u_int8_t to_type;
+ u_int8_t to_code;
+ char *str;
+ char *str_alt;
+} icmp_tests[] = {
+ { IPPROTO_ICMP, 0, 0, 0, 0, 0, 0, "dynamic[icmp/0]", "dynamic[1/0]" },
+ { IPPROTO_ICMP, 3, 3, 3, 0, 3, 0, "dynamic[icmp/3]", "dynamic[1/3]" },
+ { IPPROTO_ICMP, 0x0307, 0x0307, 3, 7, 3, 7, "dynamic[icmp/3(7)]", "dynamic[1/3(7)]" },
+ { IPPROTO_ICMP, 0x0300, 0x040f, 3, 0, 4, 15, "dynamic[icmp/3-4(15)]", "dynamic[1/3-4(15)]" },
+ { IPPROTO_ICMP, 0x0301, 0x040f, 3, 1, 4, 15, "dynamic[icmp/3(1)-4(15)]", "dynamic[1/3(1)-4(15)]" },
+ { IPPROTO_ICMPV6, 0, 0, 0, 0, 0, 0, "dynamic[ipv6-icmp/0]", "dynamic[58/0]" },
+ { IPPROTO_ICMPV6, 1, 1, 1, 0, 1, 0, "dynamic[ipv6-icmp/1]", "dynamic[58/1]" },
+ { IPPROTO_ICMPV6, 0x0104, 0x0104, 1, 4, 1, 4, "dynamic[ipv6-icmp/1(4)]", "dynamic[58/1(4)]" },
+ { IPPROTO_ICMPV6, 0x0100, 0x040f, 1, 0, 4, 15, "dynamic[ipv6-icmp/1-4(15)]", "dynamic[58/1-4(15)]" },
+ { IPPROTO_ICMPV6, 0x0101, 0x040f, 1, 1, 4, 15, "dynamic[ipv6-icmp/1(1)-4(15)]", "dynamic[58/1(1)-4(15)]" },
+};
+
+START_TEST(test_icmp)
+{
+ traffic_selector_t *ts;
+ u_int16_t from, to;
+
+ ts = traffic_selector_create_dynamic(icmp_tests[_i].proto,
+ icmp_tests[_i].from_port, icmp_tests[_i].to_port);
+ from = ts->get_from_port(ts);
+ to = ts->get_to_port(ts);
+ ck_assert_int_eq(icmp_tests[_i].from_type, traffic_selector_icmp_type(from));
+ ck_assert_int_eq(icmp_tests[_i].from_code, traffic_selector_icmp_code(from));
+ ck_assert_int_eq(icmp_tests[_i].to_type, traffic_selector_icmp_type(to));
+ ck_assert_int_eq(icmp_tests[_i].to_code, traffic_selector_icmp_code(to));
+ verify(icmp_tests[_i].str, icmp_tests[_i].str_alt, ts);
+}
+END_TEST
+
+static void verify_list(const char *str, const char *alt, linked_list_t *list)
+{
+ char buf[512];
+
+ snprintf(buf, sizeof(buf), "%#R", list);
+ list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
+ if (!streq(buf, str) && !streq(buf, alt))
+ {
+ fail("%s != %s or %s", buf, str, alt);
+ }
+}
+
+START_TEST(test_printf_hook_null)
+{
+ verify("(null)", NULL, NULL);
+}
+END_TEST
+
+START_TEST(test_printf_hook_hash)
+{
+ linked_list_t *list;
+
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ NULL);
+ verify_list("10.1.0.0/16 ", NULL, list);
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP, 1234, 1235),
+ NULL);
+ verify_list("10.1.0.0/16 10.1.0.1/32[udp/1234-1235] ", "10.1.0.0/16 10.1.0.1/32[17/1234-1235] ", list);
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE, "10.1.0.1", 1234, "10.1.0.99", 1235),
+ NULL);
+ verify_list("10.1.0.0/16 10.1.0.1..10.1.0.99[udp/1234-1235] ", "10.1.0.0/16 10.1.0.1..10.1.0.99[17/1234-1235] ", list);
+}
+END_TEST
+
Suite *traffic_selector_suite_create()
{
Suite *s;
@@ -260,6 +796,18 @@ Suite *traffic_selector_suite_create()
tcase_add_test(tc, test_create_from_cidr);
tcase_add_test(tc, test_create_from_bytes);
tcase_add_test(tc, test_create_from_subnet);
+ tcase_add_loop_test(tc, test_create_from_rfc3779_format_prefix, 0, countof(rfc3779_prefix_tests));
+ tcase_add_test(tc, test_create_from_rfc3779_format_range);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("addresses");
+ tcase_add_test(tc, test_get_address_range);
+ tcase_add_test(tc, test_get_address_cidr);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("to_subnet");
+ tcase_add_loop_test(tc, test_to_subnet, 0, countof(to_subnet_tests));
+ tcase_add_loop_test(tc, test_to_subnet_port, 0, countof(to_subnet_port_tests));
suite_add_tcase(s, tc);
tc = tcase_create("subset");
@@ -270,15 +818,47 @@ Suite *traffic_selector_suite_create()
tcase_add_test(tc, test_subset_noport);
tcase_add_test(tc, test_subset_noproto);
tcase_add_test(tc, test_subset_nofamily);
+ tcase_add_test(tc, test_subset_dynamic);
+ tcase_add_test(tc, test_subset_opaque);
suite_add_tcase(s, tc);
tc = tcase_create("includes");
tcase_add_loop_test(tc, test_includes, 0, countof(include_tests));
suite_add_tcase(s, tc);
+ tc = tcase_create("is_contained_in");
+ tcase_add_loop_test(tc, test_is_contained_in, 0, countof(is_contained_in_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("is_host");
+ tcase_add_loop_test(tc, test_is_host, 0, countof(is_host_tests));
+ tcase_add_loop_test(tc, test_is_host_dynamic, 0, countof(is_host_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("set_address");
+ tcase_add_loop_test(tc, test_set_address, 0, countof(is_host_tests));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("cmp");
tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests));
suite_add_tcase(s, tc);
+ tc = tcase_create("clone");
+ tcase_add_test(tc, test_clone);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("hash");
+ tcase_add_test(tc, test_hash);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("icmp");
+ tcase_add_loop_test(tc, test_icmp, 0, countof(icmp_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("printf hook");
+ tcase_add_test(tc, test_printf_hook_null);
+ tcase_add_test(tc, test_printf_hook_hash);
+ suite_add_tcase(s, tc);
+
return s;
}
diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c
index 0bae9c8cd..66d0e612d 100644
--- a/src/libstrongswan/tests/test_runner.c
+++ b/src/libstrongswan/tests/test_runner.c
@@ -265,7 +265,7 @@ static bool pre_test(test_runner_init_t init, char *cfg)
*/
typedef struct {
char *name;
- char msg[512 - sizeof(char*) - 2 * sizeof(int)];
+ char msg[4096 - sizeof(char*) - 2 * sizeof(int)];
const char *file;
int line;
int i;
diff --git a/src/libstrongswan/tests/test_suite.c b/src/libstrongswan/tests/test_suite.c
index 00ac31830..0af34c847 100644
--- a/src/libstrongswan/tests/test_suite.c
+++ b/src/libstrongswan/tests/test_suite.c
@@ -27,7 +27,7 @@
/**
* Failure message buf
*/
-static char failure_buf[512];
+static char failure_buf[4096];
/**
* Source file failure occurred
diff --git a/src/libstrongswan/tests/tests.c b/src/libstrongswan/tests/tests.c
index aed600fbc..0fdfac52d 100644
--- a/src/libstrongswan/tests/tests.c
+++ b/src/libstrongswan/tests/tests.c
@@ -25,8 +25,8 @@
static test_configuration_t tests[] = {
#define TEST_SUITE(x) \
{ .suite = x, },
-#define TEST_SUITE_DEPEND(x, type, args) \
- { .suite = x, .feature = PLUGIN_DEPENDS(type, args) },
+#define TEST_SUITE_DEPEND(x, type, ...) \
+ { .suite = x, .feature = PLUGIN_DEPENDS(type, __VA_ARGS__) },
#include "tests.h"
{ .suite = NULL, }
};
diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c
index 923b7d4db..ce5f550b5 100644
--- a/src/libstrongswan/utils/capabilities.c
+++ b/src/libstrongswan/utils/capabilities.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
@@ -288,13 +288,25 @@ METHOD(capabilities_t, resolve_uid, bool,
#ifdef HAVE_GETPWNAM_R
struct passwd passwd;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- err = getpwnam_r(username, &passwd, buf, sizeof(buf), &pwp);
- if (pwp)
+ while (TRUE)
{
- this->uid = pwp->pw_uid;
+ buf = realloc(buf, buflen);
+ err = getpwnam_r(username, &passwd, buf, buflen, &pwp);
+ if (err == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (pwp)
+ {
+ this->uid = pwp->pw_uid;
+ }
+ break;
}
+ free(buf);
#else /* HAVE GETPWNAM_R */
this->mutex->lock(this->mutex);
pwp = getpwnam(username);
@@ -324,13 +336,25 @@ METHOD(capabilities_t, resolve_gid, bool,
#ifdef HAVE_GETGRNAM_R
struct group group;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- err = getgrnam_r(groupname, &group, buf, sizeof(buf), &grp);
- if (grp)
+ while (TRUE)
{
- this->gid = grp->gr_gid;
+ buf = realloc(buf, buflen);
+ err = getgrnam_r(groupname, &group, buf, buflen, &grp);
+ if (err == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (grp)
+ {
+ this->gid = grp->gr_gid;
+ }
+ break;
}
+ free(buf);
#else /* HAVE_GETGRNAM_R */
this->mutex->lock(this->mutex);
grp = getgrnam(groupname);
@@ -362,12 +386,24 @@ static bool init_supplementary_groups(private_capabilities_t *this)
#ifdef HAVE_GETPWUID_R
struct passwd pwd;
- char buf[1024];
+ size_t buflen = 1024;
+ char *buf = NULL;
- if (getpwuid_r(this->uid, &pwd, buf, sizeof(buf), &pwp) == 0 && pwp)
+ while (TRUE)
{
- res = initgroups(pwp->pw_name, this->gid);
+ buf = realloc(buf, buflen);
+ if (getpwuid_r(this->uid, &pwd, buf, buflen, &pwp) == ERANGE)
+ {
+ buflen *= 2;
+ continue;
+ }
+ if (pwp)
+ {
+ res = initgroups(pwp->pw_name, this->gid);
+ }
+ break;
}
+ free(buf);
#else /* HAVE_GETPWUID_R */
this->mutex->lock(this->mutex);
pwp = getpwuid(this->uid);
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index b69adf399..da23d143c 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -47,10 +47,9 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_DER_ASN1_DN",
"ID_DER_ASN1_GN",
"ID_KEY_ID");
-ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_USER_ID, ID_KEY_ID,
- "ID_DER_ASN1_GN_URI",
- "ID_USER_ID");
-ENUM_END(id_type_names, ID_USER_ID);
+ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID,
+ "ID_DER_ASN1_GN_URI");
+ENUM_END(id_type_names, ID_DER_ASN1_GN_URI);
/**
* coding of X.501 distinguished name
@@ -478,7 +477,7 @@ static status_t atodn(char *src, chunk_t *dn)
name.len -= whitespace;
rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING
&& !asn1_is_printablestring(name))
- ? ASN1_T61STRING : x501rdns[i].type;
+ ? ASN1_UTF8STRING : x501rdns[i].type;
if (rdn_count < RDN_MAX)
{
@@ -579,6 +578,19 @@ METHOD(identification_t, contains_wildcards_memchr, bool,
return memchr(this->encoded.ptr, '*', this->encoded.len) != NULL;
}
+METHOD(identification_t, hash_binary, u_int,
+ private_identification_t *this, u_int inc)
+{
+ u_int hash;
+
+ hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
+ if (this->type != ID_ANY)
+ {
+ hash = chunk_hash_inc(this->encoded, hash);
+ }
+ return hash;
+}
+
METHOD(identification_t, equals_binary, bool,
private_identification_t *this, identification_t *other)
{
@@ -687,6 +699,24 @@ METHOD(identification_t, equals_dn, bool,
return compare_dn(this->encoded, other->get_encoding(other), NULL);
}
+METHOD(identification_t, hash_dn, u_int,
+ private_identification_t *this, u_int inc)
+{
+ enumerator_t *rdns;
+ chunk_t oid, data;
+ u_char type;
+ u_int hash;
+
+ hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
+ rdns = create_rdn_enumerator(this->encoded);
+ while (rdns->enumerate(rdns, &oid, &type, &data))
+ {
+ hash = chunk_hash_inc(data, chunk_hash_inc(oid, hash));
+ }
+ rdns->destroy(rdns);
+ return hash;
+}
+
METHOD(identification_t, equals_strcasecmp, bool,
private_identification_t *this, identification_t *other)
{
@@ -828,7 +858,6 @@ int identification_printf_hook(printf_hook_data_t *data,
case ID_FQDN:
case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI:
- case ID_USER_ID:
chunk_printable(this->encoded, &proper, '?');
snprintf(buf, sizeof(buf), "%.*s", (int)proper.len, proper.ptr);
chunk_free(&proper);
@@ -903,23 +932,26 @@ static private_identification_t *identification_create(id_type_t type)
switch (type)
{
case ID_ANY:
+ this->public.hash = _hash_binary;
this->public.matches = _matches_any;
this->public.equals = _equals_binary;
this->public.contains_wildcards = return_true;
break;
case ID_FQDN:
case ID_RFC822_ADDR:
- case ID_USER_ID:
+ this->public.hash = _hash_binary;
this->public.matches = _matches_string;
this->public.equals = _equals_strcasecmp;
this->public.contains_wildcards = _contains_wildcards_memchr;
break;
case ID_DER_ASN1_DN:
+ this->public.hash = _hash_dn;
this->public.equals = _equals_dn;
this->public.matches = _matches_dn;
this->public.contains_wildcards = _contains_wildcards_dn;
break;
default:
+ this->public.hash = _hash_binary;
this->public.equals = _equals_binary;
this->public.matches = _matches_binary;
this->public.contains_wildcards = return_false;
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index e6a9fe1c6..5f27ba112 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -129,11 +129,6 @@ enum id_type_t {
* Private ID type which represents a GeneralName of type URI
*/
ID_DER_ASN1_GN_URI = 201,
-
- /**
- * Private ID type which represents a user ID
- */
- ID_USER_ID = 202
};
/**
@@ -219,6 +214,14 @@ struct identification_t {
id_type_t (*get_type) (identification_t *this);
/**
+ * Create a hash value for this identification_t object.
+ *
+ * @param inc optional value for incremental hashing
+ * @return hash value
+ */
+ u_int (*hash) (identification_t *this, u_int inc);
+
+ /**
* Check if two identification_t objects are equal.
*
* @param other other identification_t object
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
index 466c673d9..af5494052 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c
@@ -843,7 +843,8 @@ int builtin_vsnprintf(char *buffer, size_t n, const char *format, va_list ap)
/* String */
sarg = va_arg(ap, const char *);
sarg = sarg ? sarg : "(null)";
- slen = strlen(sarg);
+ slen = prec != -1 ? strnlen(sarg, prec)
+ : strlen(sarg);
goto is_string;
}
case 'm':
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
index 409b5bf3d..efbacff6f 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.h
@@ -15,7 +15,7 @@
/**
* @defgroup printf_hook_builtin printf_hook_builtin
- * @{ @ingroup utils
+ * @{ @ingroup printf_hook
*/
#ifndef PRINTF_HOOK_BUILTIN_H_
diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h b/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
index 2f9ee5983..7c24b05e2 100644
--- a/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
+++ b/src/libstrongswan/utils/printf_hook/printf_hook_vstr.h
@@ -16,7 +16,7 @@
/**
* @defgroup printf_hook_vstr printf_hook_vstr
- * @{ @ingroup utils
+ * @{ @ingroup printf_hook
*/
#ifndef PRINTF_HOOK_VSTR_H_
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c
index 9b516accd..b4a4db802 100644
--- a/src/libstrongswan/utils/utils.c
+++ b/src/libstrongswan/utils/utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2014 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -16,15 +16,38 @@
#include "utils.h"
+#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
+#include <ctype.h>
#ifndef WIN32
# include <signal.h>
#endif
+#ifndef HAVE_CLOSEFROM
+#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <sys/syscall.h>
+/* This is from the kernel sources. We limit the length of directory names to
+ * 256 as we only use it to enumerate FDs. */
+struct linux_dirent64 {
+ u_int64_t d_ino;
+ int64_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+};
+#else /* !defined(__linux__) || !defined(HAVE_SYS_SYSCALL_H) */
+# include <dirent.h>
+#endif /* defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) */
+#endif
+
#include <library.h>
#include <collections/enumerator.h>
+#define FD_DIR "/proc/self/fd"
+
#ifdef WIN32
#include <threading/mutex.h>
@@ -110,43 +133,89 @@ void wait_sigint()
/**
* Described in header.
*/
-void closefrom(int lowfd)
+void closefrom(int low_fd)
{
- char fd_dir[PATH_MAX];
- int maxfd, fd, len;
+ int max_fd, dir_fd, fd;
/* try to close only open file descriptors on Linux... */
- len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
- if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
+#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
+ /* By directly using a syscall we avoid any calls that might be unsafe after
+ * fork() (e.g. malloc()). */
+ char buffer[sizeof(struct linux_dirent64)];
+ struct linux_dirent64 *entry;
+ int offset, len;
+
+ dir_fd = open("/proc/self/fd", O_RDONLY);
+ if (dir_fd != -1)
{
- enumerator_t *enumerator = enumerator_create_directory(fd_dir);
- if (enumerator)
+ while ((len = syscall(SYS_getdents64, dir_fd, buffer,
+ sizeof(buffer))) > 0)
{
- char *rel;
- while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
+ for (offset = 0; offset < len; offset += entry->d_reclen)
{
- fd = atoi(rel);
- if (fd >= lowfd)
+ entry = (struct linux_dirent64*)(buffer + offset);
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+ fd = atoi(entry->d_name);
+ if (fd != dir_fd && fd >= low_fd)
{
close(fd);
}
}
- enumerator->destroy(enumerator);
- return;
}
+ close(dir_fd);
+ return;
+ }
+#else /* !defined(__linux__) || !defined(HAVE_SYS_SYSCALL_H) */
+ /* This is potentially unsafe when called after fork() in multi-threaded
+ * applications. In particular opendir() will require an allocation.
+ * Depends on how the malloc() implementation handles such situations. */
+ DIR *dir;
+ struct dirent *entry;
+
+#ifndef HAVE_DIRFD
+ /* if we don't have dirfd() lets close the lowest FD and hope it gets reused
+ * by opendir() */
+ close(low_fd);
+ dir_fd = low_fd++;
+#endif
+
+ dir = opendir(FD_DIR);
+ if (dir)
+ {
+#ifdef HAVE_DIRFD
+ dir_fd = dirfd(dir);
+#endif
+ while ((entry = readdir(dir)))
+ {
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+ fd = atoi(entry->d_name);
+ if (fd != dir_fd && fd >= low_fd)
+ {
+ close(fd);
+ }
+ }
+ closedir(dir);
+ return;
}
+#endif /* defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) */
/* ...fall back to closing all fds otherwise */
#ifdef WIN32
- maxfd = _getmaxstdio();
+ max_fd = _getmaxstdio();
#else
- maxfd = (int)sysconf(_SC_OPEN_MAX);
+ max_fd = (int)sysconf(_SC_OPEN_MAX);
#endif
- if (maxfd < 0)
+ if (max_fd < 0)
{
- maxfd = 256;
+ max_fd = 256;
}
- for (fd = lowfd; fd < maxfd; fd++)
+ for (fd = low_fd; fd < max_fd; fd++)
{
close(fd);
}
diff --git a/src/libstrongswan/utils/utils/string.c b/src/libstrongswan/utils/utils/string.c
index 14087e765..56910ed79 100644
--- a/src/libstrongswan/utils/utils/string.c
+++ b/src/libstrongswan/utils/utils/string.c
@@ -44,7 +44,7 @@ char* translate(char *str, const char *from, const char *to)
char* strreplace(const char *str, const char *search, const char *replace)
{
size_t len, slen, rlen, count = 0;
- char *res, *pos, *found, *dst;
+ char *res, *pos, *found = NULL, *dst;
if (!str || !*str || !search || !*search || !replace)
{