diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
commit | 5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (patch) | |
tree | 037f1ec5bb860846938ddcf29771c24e9c529be0 /src/libstrongswan | |
parent | b238cf34df3fe4476ae6b7012e7cb3e9769d4d51 (diff) | |
download | vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.tar.gz vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.zip |
Imported Upstream version 5.3.3
Diffstat (limited to 'src/libstrongswan')
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(§ions, 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(§ions, 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) { |